
書記が数学やるだけ#799 Word2Vecの概要
単語ベクトル表現を用いたモデルであるWord2Vecについて概要を示す。
問題

説明
Word2Vecは,単語の埋め込みを生成するために使用される一連のモデル群で,大きくCBoWモデルとskip-gramモデルに分けられる。CBoWモデルでは周囲のコンテキスト単語から現在の単語を予測し,skip-gramモデルでは現在の単語を使用して周囲のコンテキスト単語を予測する。

一つ一つの単語がベクトルとして生成されることで,単語間の関係などを推測することができるようになる。

単語の集合をそのまま扱おうとすると膨大な計算量になるため,階層化ソフトマックスや負例サンプリングといった方法で計算量を減らす。

Word2Vecの派生モデルとして,サブワードを用いるFastTextが重要である。

解答
CBoWモデルでは,youとgoodbyからsayを当てる,といった問題となる。入力層はyouのone-hotベクトルとgoodbyのone-hotベクトルであり,これにWinをかけて足すことで中間層を作り,Woutをかけることで出力層として,softmaxを通すことで確率を出して,ラベルとのlossを導出する。あとは逆伝播によりWinとWoutを最適化する。
一方で,skip-gramモデルでは,sayからyouとgoodbyを当てる,といった問題となる。モデルはほぼCBoWモデルを反転したものとなっている。

ここで,最適化するWに何の意味があるのか見ていく。モデルは以下書籍より引用,Wを適当に用意して計算してみる:

ここでWinを見ると,one-hotベクトルとの内積を取ることで,その単語の分散表現が得られる。よってWinは単語全体の分散表現を表している。

CBoWモデルにおいては,1つの正解とそれ以外の不正解を学習することになり,単語数が大きいと計算量が膨大になってしまう。そこで,問題を1つの正例と少数のk個の負例の二値分類に置き換えることっで計算量を減らすことができる(負例サンプリング)。

最後に,有名な問題である「女 + 国王 - 男 = 女王」を実装してみる。今回はgensimからWord2Vecモデルを使用,学習済みモデルとして以下を使用した:
import gensim
import pprint
model = gensim.models.KeyedVectors.load_word2vec_format('model.vec', binary=False)
#「女 + 国王 - 男 = 女王」
pprint.pprint(word2vec_model.most_similar(positive=['女', '国王'], negative=['男']))結果:[('王妃', 0.7062159180641174),
('王室', 0.6530475616455078),
('王族', 0.6122198104858398),
('王太子', 0.6098779439926147),
('王家', 0.6084121465682983),
確かに「王妃」と女王に相当する単語が当てられた。

本記事のもくじはこちら: