この前は自然言語処理の基本を勉強していました。
今回は、今どきの自然言語処理で普通に使われているword2vecについて勉強していきます。
今回もこちらの本を使って勉強しました。
ゼロから作るDeep Learning ? ―自然言語処理編
- 作者: 斎藤康毅
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/07/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (3件) を見る
細かい数式や概念については、上の本をぜひご参照ください。めちゃくちゃ分かりやすいので。
word2vec
元論文
word2vecの本家の論文はこちら。あんまりよくわかんないですが。
解説論文はこちら。
シソーラス/カウントベースの問題点
シソーラスやカウントベースでは下記のような問題がありました。
このように、どちらもうまく使えるとは言い難いものでした。
推論ベースのイメージ
シソーラス/カウントベースの単語の意味の取得とは異なり、word2vecは推論ベースの手法です。 word2vecでの単語の推定は、CBOWモデルかskip-gramモデルの2種類あり、それぞれ微妙に違いますが大体こんな感じです。
CBOWモデル
skip-gramモデル
ある単語の隣になんの単語が来るかを推論することで、単語のベクトル表現を得るというやり方です。
単語2つから近傍の単語を推論するか、単語1つから両側の単語を推論するかの違いですね。 詳しいことはあんまりわからなかったですが、skip-gramモデルの方が良いらしいです。
Word2Vecひとめぐり
ネットワーク
word2vecでは、CBOWでは下記のような2層NNを使用します。(あとでいろいろ修正します)
入力層は、着目する位置の前後にある暫定単語ベクトル(One-hot ベクトル)を表していて、出力層が着目する単語ベクトルになっています。 このNNを学習させると, がそのうち収束します。
ここで行列について確認するとこんな感じになっています。
この行列において、横ベクトルが各単語のベクトル表記(ベクトルは中間層でのベクトルと同じ長さ)になっています。
学習させたネットワークを単語のベクトルとして扱うところがトリッキーですね。
改良
上のやり方でも間違いではないんですが、コーパスのサイズが大きくなるとNNで使用するデータ量が大きくメモリに乗り切らなくなる問題があります。
そこで改良を加えていきます。
Embedding レイヤ
まず、コーパスの単語をone-hotベクトルで表現していたのを、インデックスで表現するように変換します。 これを行うのがEmbedding レイヤです。
変換のイメージはこんな感じです。
ワンクッションかますので、はこんな感じに小さくなります。
二値推定とNegative Sampling
embedding レイヤだけだとは小さくなりますが、は依然として大きいままです。 そのため、こちらの行列を小さくすることを考えます。
まず多値推定(one-hotベクトルを推論)を2値推定(yes/no問題)にすり替えます。
これだけだと、コーパスに登場する単語全てに2値推定することになってしまうので、コーパスから不正解データ(Negative)をいくつかサンプリングして使用することを考えます。
コーパスから単語の登場回数を予め計算しておき、その分布に基づいてサンプリングしてやることで登場頻度に応じた単語のサンプリングが可能になります。
このようにして、2値推定する母集団自体を圧縮し、メモリ使用量を削減します。
最終的にはこんな感じになっているかと思います。
word2vecの特徴
word2vecを含めた単語の分散表現の特徴として、概念の加減算ができることが挙げられます。 イメージとしてはこんな感じです。
この例だとKINGに複数形の概念を加えたらKINGSだし、女性の概念を加えたらqueenになるといいます。
このように、単語それぞれが持つベクトルの加算結果が指し示すベクトルを、概念の足し算引き算にすり替えることが可能のようです。
実装
省略します。詳しくは本買っていただければと。
そのうちなんかやるんで、コードについてはその時まとめて勉強します。 まずは概念だけお勉強します。
感想
記事を書くにあたり、こちらも参考にさせていただきました。
ありがとうございます。非常にわかりやすかったです。
理解はなんとかできますが、やはりまだまだ難しいですね。 次回、RNNを勉強して基本的な部分については終了したいと思います。