手算一次:用「每個字只有 2 個數字」的玩具例子,走完詞類比的全程

真的詞向量有 100 個數字,沒辦法手算。所以先用一個只有 2 個數字的玩具例子走一遍。步驟跟真的完全一樣,只是數字少。

前提(這個例子假設了什麼):

⟦IMG:toy_analogy⟧

第 1 小步:做加減,算出一個新的點 ★

公式是 B − A + C,也就是 queen − king + man。兩個數字各自算:

第 1 個數字:3.2 − 1 + 1 = 3.2
第 2 個數字:4.1 − 4 + 1 = 1.1
所以 ★ = (3.2, 1.1)

圖上紅色兩條箭頭幾乎一樣長、一樣方向:這就是「king 變 queen」和「man 變 woman」是同一步。所以從 man 走同一步,就走到 ★。

第 2 小步:把題目自己的三個字排除

king、queen、man 是題目給的字,不能拿來當答案。剩下的候選字是 woman、girl、apple。(Gensim 的 most_similar 會自動做這一步。)

第 3 小步:算 ★ 跟每個候選字有多像(cosine similarity)

cosine similarity 的算法,照做就好:

  1. 內積:兩個字的第 1 個數字相乘,加上第 2 個數字相乘。
  2. 長度:每個字的「第 1 個數字平方+第 2 個數字平方」再開根號。
  3. 相似度=內積 ÷(兩個長度相乘)。越接近 1 越像,0 是沒關係,負的是方向相反。
候選字① 內積② 長度③ 相似度
woman (3, 1)3.2×3 + 1.1×1 = 10.70★ 3.384;woman 3.16210.70 ÷ (3.384×3.162) = 1.000
girl (3, 0.3)3.2×3 + 1.1×0.3 = 9.93★ 3.384;girl 3.0159.93 ÷ (3.384×3.015) = 0.973
apple (−2, 3)3.2×(−2) + 1.1×3 = −3.10★ 3.384;apple 3.606−3.10 ÷ (3.384×3.606) = −0.254

表裡的數字由程式算出(make_toy_figures.py),四捨五入到小數點後 2~3 位。woman 的 1.000 是四捨五入後的值,實際比 1 小一點點。

第 4 小步:分數最高的就是答案

woman 1.000 最高,所以電腦答 woman,答對。

第 5 小步(例外):如果題目的字不在字典裡

例如題目有一個字典裡沒有的字,第 1 小步就算不出來。這種題目在作業裡直接算答錯(叫 OOV,字典外的字)。

真的作業就是把這 4 步,對 19,544 題、每次在 30~40 萬個候選字裡做一遍。girl 0.973 也很接近——在真的詞向量裡,像 girl 這種「很像但不是答案」的字很多,所以正確答案常常排第 2、3 名(第 12 節實驗 ④)。