自然言語処理お勉強教室-word2vec-(1)

はじめに

言語処理の勉強しよーと思った次第で,始めた記事です.この記事で取り扱うのは,word2vecを扱おうと思っています.word2vecの記事は他にも大量にあるので,他の記事と対して差分はありませんので,これは私の勉強備忘録となります.今回はcbowを扱っていきます(skip-gramはやらないと思います.).

cbow

you say goodbye and I say hello 

というのがよく,例に出されますが,このうち例えば,

you [] goodbye and I say hello 

と来た時に,このを予測する問題がcbowとなります.基本となるのは,前後にどのような単語をとるかです.この前後となる単語を捉えることで,このの単語を推測するという流れです.よく,以下の図形を見かけます.

f:id:tatsuya_happy:20210228233838p:plain

これはsayを予測するものだと思ってください.この場合,入力層は以下のようになる(コンテクストサイズが1ね). f:id:tatsuya_happy:20210228234319p:plain なぜ,1or0かというと,前後の周りの単語がこいつ「you,goodbye」であるから,この単語があるよ!!というのをモデルに教えているからです.この時,入力層のベクトルの次元は(1,V)であると考えるとわかりやすいと思う.このVはvocaburaryの数です.この図表では,you say goodbye...の7文字しかありませんが,学習させた単語の数と同値になります.

さて,これを中間層に放り込みます.入力層と中間層の計算は以下のようになります. f:id:tatsuya_happy:20210228235453p:plain 中間層は画像のような感じになっており,計算すると1*3の行列が作成できます.入力層の1の部分だけが残り,中間層の上の部分だけが抽出された感じになります.このベクトルがよく「女王+男=王様」とかに利用される,ベクトル表現となります.この1*3のベクトル表現はyouに対してのベクトルであったので,goodbyeでも同様に作ります.こうすることで,二つの1*3のベクトル表現ができることになります.これを積とって割ることで,中間層を作ります(平均みたいなことをする). 出力層では,普通のLinear関数で計算をし,vocaburary分のwordを出力します.今回は7文字しか扱ってないので,7次元で出力していますが,100文字のvocaburaryを学習している場合,100次元が出力されます(一般的には,この時にnegative samplingをするが,省略).この100次元をsoftmaxにかけ,cross entropyでtargetとなる単語を推測するモデルを構築すれば,完成です.

数式を少し見よう.

cbowの数式は以下のような感じです.

f:id:tatsuya_happy:20210301000508p:plain

w_tは予測対象の単語であり,後ろの単語は前後の単語を表しています.Tはテキストの単語数です.条件付き確率ですね.ここを見るだけでも,前後から単語を予測していることは容易にわかると思います.次に,最適化です. f:id:tatsuya_happy:20210301000651p:plain logをとることで和としています(1/Tで割る必要があると思う).マイナスになっているのは,cross entropy 誤差です.ターゲットとなる単語をかけた後の数式となります.このP()うんたらの数式ですが,以下のようになります. f:id:tatsuya_happy:20210301001016p:plain この数式が少しややこしいのですが,分母から見ていきます.この数式はsoftmax関数です.このV_oが先ほどの中間層に当たる部分となります.u_iが出力層の一つとなるものです.分子のu_cがターゲットとなる単語の出力層です.以下,画像です(イメージ図です). f:id:tatsuya_happy:20210301001640p:plain 中間層と出力層の重みをかけると値が出力されるので,それをsoftmaxでやっているという感じです.

実装(PyTorch)

以下のサイトに実装を書きました.PyTorch tutorialを参考に書いてあります. www.kaggle.com

終わりに

word2vecって難しいですね.次は何を勉強しましょうかね...