[自然言語処理/NLP] Word2Vec触ったので備忘録としてざっくりまとめておく (理論編)

2019.09.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、Mr.Moです。
最近Word2Vecに触れる機会があったので備忘録の意味も込めて自分なりにまとめておこうと思います。

Word2Vecとは

簡単にまとめると下記です。

> Word2vecでは、2層のニューラルネットワーク構造を用いて大量のテキストデータのコーパスに対し単語の分散表現を生成して各単語の特徴を数百次元のベクトル空間で表現する。このベクトル空間ではコーパスにおける共通のコンテキストを共有している単語を類似しているとして、ベクトル空間上で近い位置になるよう各単語にベクトルの割り当てを行う。

上記により何が嬉しいかという所ですが、単語の意味を捉えられているかのような結果が得られる点です。例えば有名な話ですが下記のような演算を行うこともできてしまいます。

 King - Man + Woman = Queen

image.png

上記図が少し分かりやすいのですが、左図のように単語の意味的な情報を踏まえた関係性をベクトルの方向で表現しており、右図のようなsyntaxの違いにおける問いにも有効な結果が得られる期待感があります。

単語の分散表現とは

単語のベクトル化における手法はいくつかあります。その中でもシンプルな単語ベクトル化の手法であるone-hotベクトル(one-hot表現)と比較すると単語の分散表現のメリットが分かりやすくなるので軽く触れておきます。

one-hotベクトル(one-hot表現、局所表現)

one-hotベクトルでは、1つの単語に対し(1,0,0,0,...,0)のように1つだけ「1」として残り全てを「0」で表現します。そのため扱う単語が多くなればなるほど巨大でスパースな行列ができあがることになります。「0」の部分はあまり意味が無いにもかかわらず計算量は増えてしまいますね。

みかん = (1,0,0,...,0)
スイカ = (0,1,0,...,0)
...

また、単語ベクトル間の類似についてはコサイン類似度を用いることが多いと思いますが単語のベクトル化で出てくるようなスパース行列(1と0の組み合わせが重複しない)だとベクトルの内積は「0」になるため、全ての単語が類似していないという結果になってしまいます。(下記はAとBの2つの単語ベクトルがあった時のコサイン類似度の計算式)

image.png

ちなみにone-hotベクトルのように各概念(みかん、スイカ)を1つの割り当てで表現する方法は局所表現と呼ばれています。

単語の分散表現

上記に対して分散表現では下記のように1つの単語を複数の要素と共に表現します。これが単語の意味を捉えるのに効果を発揮しているのではないかということが言われています。また、大量の単語を扱う場合に次元数を削減できるのも大きなメリットですね。

みかん スイカ
植物 0.95 0.95
果物 0.96 0.88
野菜 0.55 0.83
... 0.07 0.80

Word2Vec モデルの種類

image.png

Word2VecのモデルにはCBOW、skip-gramの2種類があり、いずれも2層のニューラルネットワーク(入力層、中間層、出力層)からなります。

  • CBOW
  • skip-gram

CBOW

image.png

CBOWでは上記のようにコンテキスト(周囲の単語)からターゲットの単語を予測します。ちなみにここで扱う文章は「You can do it!」 にしています。

image.png

コンテキストを入力値としてターゲットとする単語の事後確率が最大になるよう学習するモデルです。ざっくり上記の図のようなイメージで入力値はone-hotベクトルの形式で入力し単語の分散表現は中間層で得ています。ここではターゲットとなる単語は「can」ですので予測した出力結果(確率)と正解値(1)の差(1 - 0.93)をみて誤差が小さくなるよう重みを更新することで学習を行います。

skip-gram

image.png

次にskip-gramですが中央の単語からコンテキスト(周囲の単語)を予測するモデルです。

image.png

簡単に言うとCBOWを逆転させたイメージです。ここまで見てきた2つのモデルはニューラルネットワーク(人間の脳の神経細胞を模したもの)を用いているということで、確かに人間も記憶が怪しい英単語が出てきたときに周辺の単語から推測することがあるなぁということを考えると人間の脳でも似たような仕組みで結果を導いている可能性はあるのかもしれませんね。

まとめ

自分なりにざっくりまとめてみました。詳細については実際の論文や解説記事もたくさん出ているので探してみてください。 理論がなんとなく理解できたので次は実際にWord2Vecを使ったプログラムを書いてみたいと思います。

Word2Vec使ってみた記事書きました

[自然言語処理/NLP] Word2VecをSageMaker上で使ってみる (実行編)

論文