word2vecをpythonで使ってみる（HR領域モデル）

# はじめに
自然言語処理のWord2Vecについて調べてみました。

その中でも、特に、[HR領域](http://www.aand.co.jp/service/hr_system/)の単語で学習されたモデルを使ってみました。

# Word2Vecについて
自然言語処理の一つであり、単語をベクトル化して次元を圧縮する手法です。

ベクトル化することで、以下のような単語同士の演算が可能になります。

`「king」-「man」+「woman」=「Queen」`

さらに、ベクトル化したデータを次のディープニューラルネットワークの入出力データに利用することで、分類や認識、予測を行うことができます。

# Word2Vecのアルゴリズム
Word2Vecは教師あり学習であり、２層（隠れ層と出力層）から成るニューラルネットワークです。

<img width="506" alt="スクリーンショット 2018-04-18 12.35.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/de196e65-b398-e3ff-2a5c-50179a2acd0c.png">

学習アルゴリズムにはCBoWとSkip-gramの２種類があり、CBoWは前後の単語から対象単語を予測するアルゴリズムです。

一方で、Skip-gramは対象単語からその周辺単語を予測するアルゴリズムです。

一般にSkip-gramの方が精度が高い（らしい）ので、今回はSkip-gramについて紹介します。

学習データには、一般に対象単語とその周辺５単語を取ります。

例えば、次のような１４個の単語から成るテキストがあるとします。

（実際には、何百万の単語から成るテキストを使用する。）

`「I usually go to the library near Shiniizuka station on the Fukuhoku Yutaka line .」`

「I」を入力データとすると学習データは、（I,usually）、（I,go）、（I,to）、（I,the）、（I,library）になります。

学習データはone-hotベクトルに変換し、下図のようなニューラルネットワークに学習させます。

(one-hotベクトルについては、[こちら](https://deepage.net/bigdata/machine_learning/2016/09/02/word2vec_power_of_word_vector.html)をご覧ください。)

<img width="721" alt="スクリーンショット 2018-04-18 12.47.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/a8c4c148-6406-ccde-470f-96b1a8a63d2d.png">


上図の場合は、「I」を入力すると「usually」が出力されるように学習させた場合です。

実際にWord2Vecを用いる際は、入力層を数万次元のベクトル、入力層から隠れ層への重み行列を数万×数百の次元に設定することが多いです。

つまり、次元を数万から数百に圧縮するということです。

このように学習させることで、入力層から隠れ層への重み行列Wを得ることができます。

次に学習で以下のような重みが得られたとし、入力データが「usually」であるとすると隠れ層の値は、

<img width="411" alt="スクリーンショット 2018-04-18 14.43.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/e0acf48c-7d18-0238-fb38-59fdf0cb57fa.png">

となり、重み行列の第２行がそのまま入ります。

つまり、重み行列の各行が入力単語それぞれのベクトルになります。

以上が簡単なSkip-gramのアルゴリズムです。


# ベクトルの可視化
実際に（[HR領域の単語](https://www.bizreach.co.jp/technology/research/word2vec/)で)学習済みのモデルを使って実装してみようと思います。

プログラムはPython3を使用しており、[”こちら”](https://github.com/hokuto-HIRANO/Word2Vec)にソースコードは載せています。

まずは、単語のベクトルを確認してみます。

下図は"Java"という単語を例にした場合です。

<img width="703" alt="スクリーンショット 2018-04-18 14.18.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/7411a7de-3dbd-ce30-1264-4199983ec48f.png">

このモデルの場合、単語は５０次元で表されているようです。

次に、"Java"と"機械"という単語について似ている順に１０個見てみます。

ここでは、cos類似度を基に似ているかどうか判断しています。

<img width="511" alt="スクリーンショット 2018-04-18 14.14.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/64f4024b-8b28-7adf-d9e3-308f142fb23e.png">

<img width="462" alt="スクリーンショット 2018-04-18 14.15.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/85778521-9500-0aeb-e979-5366f413d748.png">

"Java"ではプログラミングに関係する単語、"機械"では工学系の単語が得られていることが確認できます。

では最後に、これらの単語を２次元でプロットしてみます。

（１０単語では２次元に落とし込む際に特徴量が足りないので、３０単語ぐらい使用しました。）

<img width="1506" alt="スクリーンショット 2018-04-18 14.07.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/34dc695e-4191-f1d7-f510-e6341bceace3.png">

結果は、２つの単語に似た単語でグループ分けすることができました。

# botの作成
Word2Vecを使って似たような単語を返す簡単なボットをつくってみました。

ソースコードは[”こちら”](https://github.com/hokuto-HIRANO/Word2Vec)に載せています。

<img width="593" alt="スクリーンショット 2018-04-18 14.55.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/247972/ea9d4fe2-ba22-a873-c9e6-c6ae8279c82e.png">

それなりに似たような言葉が帰ってきました。

しかし、最後の「好き」については少しヘンでした。

これは、学習時に「類似性」と「関連性」を区別して学習していないからです。

ここで、類似性とは「パソコン」と「コンピュータ」、関連性とは「パソコン」と「キーボード」といったような関係です。

「類似性」と「関連性」を区別できないことに関連して、対義語に弱いことがあります。

例えば、「私はあなたのことが好きです。」と「私はあなたのことが嫌いです。」では、学習データセットが同じになるからです。

# 課題点
Word2Vecは面白い技術ですが、以下のような課題点が挙げられます。

1. 「類似性」と「関連性」を区別していない。

2. 対義語に弱い。

3. 学習していない単語のベクトルは得られない。

4. 複数の意味をもつ単語に関して考慮していない。

# 応用例
+ **レコメンドシステム**  
単語ベクトルの類似度を計算し、アイテムレコメンドの精度向上が可能。
+ **機械翻訳**  
従来の確率的翻訳よりも翻訳精度が高い。
+ **Q&A・チャットボット**  
従来の確率的翻訳では難しかった、固有名詞や数値表現（日付など）の抽出が可能。
+ **文章のクラスタリング**  
トピックの抽出やニュースやエンタメといったジャンル分けが可能。
+ **感情分析**  
Twitterなどの文章から感情分析が可能。

他にも、パターンが識別される可能性のある、遺伝子、コード、再生リスト、その他の文字列や記号列にも適用できる。

# 最後に
Word2Vecは、学習済みのモデルを使うことで簡単に試すことができました。

簡単なアルゴリズムですが、なかなか良さそうな結果が得られたと思います。

また、HR領域モデルの応用にも期待です。

他にも、Word2Vecの強化版であるfastTextというものがあるらしいので気になります。

# 参考
+ [Word2Vec：発明した本人も驚く単語ベクトルの驚異的な力](https://deepage.net/bigdata/machine_learning/2016/09/02/word2vec_power_of_word_vector.html)
+ [絵で理解するWord2vecの仕組み](https://qiita.com/Hironsan/items/11b388575a058dc8a46a)
+ [word2vec（Skip-Gram Model）の仕組みを恐らく日本一簡潔にまとめてみたつもり](http://www.randpy.tokyo/entry/word2vec_skip_gram_model])
+ [276万件の求人情報を基にしたHR領域の「単語ベクトル」を公開](https://www.sankeibiz.jp/business/news/180313/prl1803131133071-n1.htm)
+ [word2vecの学習済み日本語モデルを公開します](http://aial.shiroyagi.co.jp/2017/02/japanese-word2vec-model-builder/)