JOVANA
Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Word2Vec 與意義的幾何

如果一個詞的意義可以是空間中的一個點,挨著它的朋友、遠離陌生者,會怎樣?這正是詞嵌入背後那場安靜的革命——也是為什麼「國王減男人加女人」會落在「女王」附近。

從符號到座標

在上一篇裡你學會了把文字切成 token。但像「狗」這樣的 token 仍然只是一個符號——一個沒有內部結構的標籤。最古老的解決辦法是獨熱編碼:給每個詞在一個巨大向量裡分配專屬的一格,一個 1 周圍全是 0。在五萬詞的詞表裡,「狗」和「貓」就變成了五萬維的向量,彼此完美而無用地正交。機器沒有任何辦法知道它們都是動物;任意兩個不同的詞之間,距離都一樣、都無限遠。

詞嵌入的飛躍,是把那個稀疏、毫無意義的格子,換成一個簡短而稠密的實數向量——比如 300 個數——從資料中學出來。每個詞都成了 300 維空間裡的一個點,而關鍵的承諾是:距離反映意義——「狗」和「貓」彼此挨近,「狗」和「民主」相距甚遠。一個嵌入正是如此:一張從離散符號到連續空間的、學習得來的地圖,在那裡幾何承載著信息。

這也悄悄解決了前面階梯裡的一個問題:維度災難。獨熱向量隨詞表一起膨脹,並且永遠稀疏;而一個稠密的 300 維嵌入是一份緊湊的摘要,模型的其餘部分真的能用它來計算。維度更少,每個維度承載的意義更多。

「觀其伴,知其詞」

這些座標從哪來?沒有人手工標註。答案立足於分布假說——語言學家 J. R. Firth 在 1957 年的名言:「觀其伴,知其詞。」出現在相似上下文裡的詞,往往意義相近。從沒人告訴過你「wug」是什麼意思,但讀到「我餵了那隻餓壞的 wug」和「那隻 wug 蜷在火爐旁」,你已經懷疑它是隻寵物了。這個假說斷言:意義會從上下文裡滲出來。

早期的 NLP 其實已經用了一半這個想法。詞袋n 元計數,再經 TF-IDF 打磨,會注意到哪些詞共同出現,但它們把每個詞當作獨立的一欄,從不把這種共現壓縮進一套共享的幾何裡。嵌入則把分布假說當真,並把它變成一個學習目標:安排好這些向量,使一個詞的位置能預測它的鄰居。

word2vec 究竟是怎麼學的

2013 年,Mikolov 與他在 Google 的同事發布了 word2vec,它讓嵌入既便宜又出奇地好。最流行的變體 skip-gram 玩一個簡單的猜謎遊戲。在文字上滑動一個視窗;在每個位置取中心詞,去預測它周圍的詞。「The cat sat on the mat」——給定「sat」,模型應當讓「cat」「on」「the」變得可能。沒有人提供標籤;文字給自己打標籤。這就是自監督學習——從原始資料中變出監督訊號。

機制上它是可能最淺的神經網路:每個詞有一個輸入向量和一個輸出向量,模型用兩者的點積給一個上下文詞打分。點積高意味著「這兩個屬於一起」。這些分數經過一個 softmax 變成機率,訓練則透過普通的梯度下降微調這些向量,使真正的鄰居得高分、隨機詞得低分。在經過數百萬個視窗之後,那些總是結交相似夥伴的詞,會漂移到空間的同一片區域。嵌入並不是輸出;它是副產品——輸入矩陣的那些列。

一個實用技巧讓它得以擴展:與其每一步都在整個五萬詞的詞表上算 softmax(代價高昂),word2vec 採用負採樣——把真正鄰居的分數推高,把少數幾個隨機「負」詞的分數壓低。幾年後 GloVe(史丹佛,2014)從另一個方向得到了相似的向量:它不掃描局部視窗,而是對一個全域的詞共現計數矩陣做分解。兩條路,一個目的地——它們都是表示學習的不同口味。

# skip-gram, in one breath
for (center, context) in slide_window(corpus):
    # raise the true neighbor, lower a few random words
    score      = dot(vec_in[center], vec_out[context])
    neg_scores = [dot(vec_in[center], vec_out[w]) for w in sample_negatives()]
    loss       = -log_sigmoid(score) - sum(log_sigmoid(-s) for s in neg_scores)
    update(loss)            # tiny gradient-descent step
# the embedding you keep = the rows of vec_in
帶負採樣的 skip-gram,剝到只剩內核:預測一個詞所結交的夥伴。

向量算術:可以加減的意義

這就是登上頭條的結果。取「國王」「男人」「女人」的向量,計算 國王 − 男人 + 女人。離這個結果點最近的詞是「女王」。同樣的把戲給出 巴黎 − 法國 + 義大利 ≈ 羅馬,以及 walked − walk + swim ≈ swam。這讓人覺得模型*理解*了性別、首都和動詞時態。可究竟發生了什麼?

誠實的解釋是幾何的,而非魔法的。因為訓練把每個詞與它的上下文綁在一起,某個一致的*差異*——「男→女」的位移,或「國家→首都」的位移——會在許多詞對上呈現為大致相同的方向和長度。從「男人」指向「女人」的箭頭,幾乎與從「國王」指向「女王」的箭頭平行。於是減去「男人」、加上「女人」,就讓你沿著那條性別方向滑動;落在「女王」附近便是回報。關係變成了空間中的方向

要找最接近的詞,用的不是直線距離,而是餘弦相似度——向量之間的夾角,它忽略長度,只問「這倆指向同一個方向嗎?」兩個幾乎指向同一方向的詞會被判為相似,哪怕其中一個向量更長。這種基於夾角的搜尋,是「幫我找相關詞」背後的引擎,也正是後來驅動對整篇文件做向量檢索的同一個想法。

幾何在哪裡失靈

word2vec 和 GloVe 有一個你必須刻進腦子裡的硬限制:每個詞永遠只得到一個向量。於是「bank」——河岸的與銀行的——被強行塞進同一個渾濁的點,成為它所有義項的一個模糊平均。沒有任何辦法讓上下文把它磨銳。讓這些向量得以存在的那件事(一次性從所有上下文裡學習),恰恰也是阻止它們消歧任何單一用法的那件事。

這些是靜態嵌入:「bank」在「river bank」和「central bank」裡的座標完全相同。修復之道——讓每一次出現都有一個由其實際句子塑造的向量——正是接下來幾篇要經由語言建模、並最終經由基於注意力的模型所搭建的目標,在那些模型裡,一個詞的表示每次都從它的鄰居重新算出。word2vec 是那道門;上下文嵌入是門後的那個房間。

還有一道值得正面直視的倫理稜角。因為嵌入吸收了人類文字的統計規律,它也一併吸收了其中的偏見:word2vec 有個著名例子,把「男人→程式設計師」與「女人→家庭主婦」擺在一起。捕捉「國王→女王」的那套幾何,用同一套機器捕捉刻板印象——它根本沒有「哪些方向無害、哪些有害」的概念。有用的表示與不想要的偏見,是由完全相同的過程學來的,這也正是為什麼每一個現代大語言模型至今仍繼承著這個問題。

為什麼這個想法比演算法本身活得更久

今天你很少會從零訓練 word2vec,而這正是關鍵所在。它持久的饋贈不是那個具體演算法,而是一個信念:意義可以是一個向量——正確的著手方式,是學出一個稠密空間,讓幾何替你幹活。這個信念如今貫穿了下游的一切:每一個進入 Transformer 的 token 都先變成一個嵌入,而句子、圖像、使用者的「嵌入」驅動著全行業的搜尋、推薦與檢索。

  1. Token 本身仍只是符號——孤立時毫無意義,又被獨熱的稀疏性所拖累。
  2. 分布假說說上下文揭示意義:相似的夥伴意味著相似的義項。
  3. word2vec/GloVe 把它變成一個自監督遊戲,給每個詞產出一個稠密向量。
  4. 於是距離與方向編碼了相似性與關係——向量算術與餘弦搜尋。
  5. 但每個詞只有一個靜態向量,無法處理歧義——這正是接下來幾篇要解開的懸念。