word2vector | 単語の分散表現
分散表現(ゴール)
単語を的確なベクトルで表現することを自然言語処理の分野では単語の 分散表現 と呼びます。p67
単語の分散表現は、単語を固定長のベクトルで表現する。そのベクトルは密(多くの要素が 0 でない)なベクトルで表されるのが特徴です。
分布仮説( distributional hypothesis )
単語の意味は、周囲の単語によって形成される という仮説を分布仮説と呼びます。
上記を仮定した場合、単語のベクトル化(つまり分散表現)も 分布仮説 を反映している必要があります。
分布仮説に基づいて単語をベクトルで表す方法にはカウントベースと推論ベースがあります。
カウントベース(統計的手法)
ある 単語 に着目した場合に、周囲の単語をカウントします。
カウントして得られる行列を共起行列( co-occurrence matrix )と呼びます。
you say goodbye and i say hello . の共起行列は以下のとおりです。
| you | say | goodbye | and | i | hello | . | |
|---|---|---|---|---|---|---|---|
| you | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| say | 1 | 0 | 1 | 0 | 1 | 1 | 0 |
| goodbye | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
| and | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
| i | 0 | 1 | 0 | 1 | 0 | 0 | 0 |
| hello | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
| . | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
- you のベクトル
[0, 1, 0, 0, 0, 0, 0]はカウントベース(統計的手法)で分布仮説を表したベクトル、つまり you の分散表現 - say のベクトル
[1, 0, 1, 0, 1, 1, 0]はカウントベース(統計的手法)で分布仮説を表したベクトル、つまり say の分散表現
カウントベースの問題点
コーパスが巨大(英語では 100 万を超える)にしたがって共起行列も巨大になります( 100 万 X 100 万)。 カウントベースは $N \times N$ の行列の計算コストは $O(n^3)$ です。
推論ベース( word2vec )
推論とは既知の事柄から未知の事柄を推測することです。 word2vec の推論モデルはニューラルネットワークです。 つまり推論ベースのベクトル化はモデルとしてニューラルネットワークを使いカウントベースでは共起行列を使います
you ? goodbye and i say hello の ? を分布仮説に基づいて周りの単語(コンテキスト)から 推測する例を考えます。
つまりコンテキスト(例は you 、 goodbye )を入力として与えればモデル(ニューラルネットワーク)は各単語の出現確率を出力します。
wor2vec のニューラルネットワーク
word2vec が使用するニューラルネットワーク(モデル)は CBOW (シーボウ continuous bag-of-words )と skip-gram があります。
CBOW
CBOW は上述のコンテキスト( you 、 goodbye )からターゲット( ? )を推測することを目的としたモデルです。
そして CBOW における単語の分散表現とは入力層から出力層への重み行列( $W_in$ )を指す。
CBOW モデルの簡単は Python コード( p105 )
import sys
sys.path.append('..')
import numpy as np
# サンプルのコンテキストデータ
c0 = np.array([[1, 0, 0, 0, 0, 0, 0]])
c1 = np.array([[0., 0, 0, 0, 0, 0, 0]])
# 入力層から中間層の重み行列(中間層は 1 x 3 )
W_in = np.random.randn(7, 3)
# 中間層から出力層の重み行列(出力は 1 x 7 )
W_out = np.random.randn(3, 7)
# 順伝播 簡単化のために逆伝播を考慮しない
# 入力層から中間層の順伝播
h0 = np.dot(c0, W_in)
h1 = np.dot(c1, W_in)
h = 0.5 * (h0 + h1)
# 中間層から出力層の順伝播( s は確率化する前のスコア)
s = np.dot(h, W_out)