Wed Mar 13 2019

日記 - 2019/03/12

朝の五時半頃に起きて六時半ごろに家を出た. 東京駅にツイたのが七時少し前. 東京駅のみどりの窓口は朝の五時半に開くそうで、さすがだ. 窓際の席を確保するのに便を二本見送って乗り込んだ. ところで駅弁を眺めていたら私と同様に眺める外国人のおっさんがいたのだが、見間違いでなければ知り合いだった. でも向こうは私の顔に覚えがないようだったので無視した.

日記 - 2019/03/13

やはりお手軽ツールとして fastText をみんな使っていてよい. 私も好き. facebook AI research は実は fastText の後に StarSpace というのも出していたそうで、それを使って実験をしてる人も一人だけいた. そんなの全然聞いたことなかった. どうもテキストだけでなく画像なんかにも使えるツールらしい.

ところで単語、ないしはワードピースの埋め込み表現として当然に数ベクトルを使う. ユークリッド空間の中の点として扱えるのが嬉しいのだろう. 類似度には内積かユークリッド距離なんかが使えるのも分かりやすい. 足し算が出来ることはあまり使われない性質だけど、関係を見るのには使うらしい. "知識グラフの埋め込み" というのは実質的に、関係を距離と思って距離学習をするような枠組みと一致するかもしれないと思った.

さて実際のNLPへの応用を考えると本当に欲しかったのは別に単語ベクトルではなく、文や文章のベクトルであってことを思い出す. そういう場合に雑だがそれなりに効果があることもあるような方法として平均というのがある. つまり文や文章は単語の列だと思えるから、各単語について単語ベクトルを取ってその平均を取る. これは語順を考慮しないのである意味 Bag-of-Words のようなことをしてるようにも思える.

この至極単純な方法による文ベクトルの構成は, 長さの等しいベクトルは足せるという性質を使っているとも言える. そして問題点は \(u+v = v+u\) という可換性だと言った. 語順は可換ではないから, 明らかに単語の和を取る操作は文や語句の構成を表現していない.

というわけで行列を使う. 単語を \(n \times n\) 行列で表現することを考える. 行列には積があってこれは非可換である. これが語の合成に相当していたら間違いなく面白い.

行列の積という操作は 線形写像 \(\mathbb R^n \to \mathbb R^n\) のことにほかならない. つまり長さ \(n\) のベクトルの左に行列を掛ければ, やはり長さ \(n\) のベクトルを得る. 語が行列の場合, 何かがベクトルになって語はそれを変形するものとみなせる.

ベクトル同士の類似度には内積を取った. 行列同士の類似度は何で測るのが自然なんだろう.

あと行列の積の計算が遅いから (頑張っても \(O(n^2.3737)\)), 再現できても実用化シにくそう.

追記

計算量はまあどうでもいいとして (定数バイ増えるだけなので), 行列を掛けることは NN の言葉で言うと bias の無い全結合層のこと. というわけで単語 \(w\) を一つの全結合層 \(L_w\) だと思うことにする.

入力は文脈. 文脈がわからないときは適当なゼロでない定数 \(c\) を使う. 今までの単語分散表現 とは \(L_w c\) のこと. \(c\) はなんでもいいので仮に \([1,0,\ldots,0]^T\) とすると, \(L_w\) の1行目に今までの結果を代入すればよい. 他の行は他の文脈でのベクトルと, また, 合成の仕方を表している.

単語列 \(w_1, w_2, w_3, s_4\) について, skip-gram 的に \(w_2 w_3\) を学習するには \[w_{23} = L_3 L_2 c\] として, このベクトルから \(w_1, w_4\) を予測させればよい. これは skip-gram の一般化になっている.