Chainerでword2vecを動かして学習経過を見てみる

機械学習やディープラーニングを動かせるフレームワーク Chainerを用いて、今回はword2vecの学習経過を見てみます。

まずデフォルトのexamplesの中にあるword2vecでは、epoch（勉強させたテスト量）が10回に達すると、学習をやめ、自分でそのデータからsearchしてベクトル量として近くにある単語を5つ取得してくる設定になっています。

このままだとword2vecの教えこまれる途中経過が全く見えないため、このためにpythonを勉強したド素人な自分が少し書き換えていきます。

1. search.py -> my_search.py にしてクラス化
2. train_word2vec.py -> my_train_word2vec.py に名前変更
3. my_train_word2vec.pyの最初にimport my_search as S を書き換え
4. 保存機構をメソッド化

```
def save_to_model(model, index2word, word2index): 
  model.to_cpu() 
  with open(‘model.pickle’, ‘wb’) as f: 
  obj = (model, index2word, word2index) 
  pickle.dump(obj, f) 
  return
```

5.epoch のループ内に

save_to_model(model, index2word, word2index) print(S.MySearch.search(“シリコンバレー”)) #クラスメソッドで呼び出し

また、今回はコーパスとして、[新風 Silicon Valley（日経産業新聞）](http://www.nikkei.com/tech/business/index/?uah=DF190320148127)の15記事を実験のために拝借して参りました。

## まずは実験結果

### １回目の10回転：
シリコンバレーの一番近いワードが「D」となった。原因不明だが、終始Dがトップでした。ベクトル量としてはどれも0.4–0.2の間（推測ですがkが0.333だからでしょうか）。学習量が少ないのと、コーパスが少ないから動きが少ないのはしょうがないか。。epoch9では、”D”,”苦労”,”IT”,”営む”,”する”となり__シリコンバレー感__は若干匂います。

```
==========
epoch: 0
accumulates loss: 1112031.500000
query: シリコンバレー
Ｄ: 0.385320752859
外れる: 0.316111475229
苦労: 0.311353355646
ＩＴ: 0.308985322714
かも: 0.293527036905
None

==========
epoch: 1
accumulates loss: 982020.395020
query: シリコンバレー
Ｄ: 0.380901038647
外れる: 0.319994270802
ＩＴ: 0.315405249596
苦労: 0.310255050659
かも: 0.294104635715
None

==========
epoch: 2
accumulates loss: 902829.900146
query: シリコンバレー
Ｄ: 0.376115381718
外れる: 0.320046186447
ＩＴ: 0.31905066967
苦労: 0.311782300472
かも: 0.296858221292
None

==========
epoch: 3
accumulates loss: 820047.656860
query: シリコンバレー
Ｄ: 0.371634662151
ＩＴ: 0.320495575666
外れる: 0.318237453699
苦労: 0.313952356577
かも: 0.302201360464
None

==========
epoch: 4
accumulates loss: 681908.571655
query: シリコンバレー
Ｄ: 0.368631154299
ＩＴ: 0.320828229189
外れる: 0.316797375679
苦労: 0.316728383303
かも: 0.306283533573
None

==========
epoch: 5
accumulates loss: 641440.961914
query: シリコンバレー
Ｄ: 0.365578979254
ＩＴ: 0.320439100266
苦労: 0.3194886446
外れる: 0.315234780312
営む: 0.309817075729
None

==========
epoch: 6
accumulates loss: 586475.438599
query: シリコンバレー
Ｄ: 0.363178402185
苦労: 0.321959197521
ＩＴ: 0.319732785225
営む: 0.315447598696
外れる: 0.313367664814
None

==========
epoch: 7
accumulates loss: 556348.893921
query: シリコンバレー
Ｄ: 0.361127972603
苦労: 0.324909359217
ＩＴ: 0.319623440504
営む: 0.31960016489
する: 0.318533718586
None

==========
epoch: 8
100000 words, 77.92 sec, 1283.30 words/sec
accumulates loss: 517327.874512
query: シリコンバレー
Ｄ: 0.359653770924
苦労: 0.327609688044
する: 0.326554596424
営む: 0.321017146111
ＩＴ: 0.318472921848
None

==========
epoch: 9
accumulates loss: 551470.435913
query: シリコンバレー
Ｄ: 0.358295291662
する: 0.334549129009
苦労: 0.328947871923
営む: 0.324358165264
ＩＴ: 0.31878477335
None
```

### 2・3回目：
2回目は最終的に”薄利多売”,”サイト”,”思い立っ”,”す”,”いろいろ”、3回目はデータは書きませんが、”閉じ込め”,”い”,“DECODED”,“れる”,“差別”という結果に。2回目はなにかを伝えようとしていますが、、

```
==========
epoch: 0
accumulates loss: 1155921.383301
query: シリコンバレー
サイト: 0.34277588129
薄利多売: 0.338559865952
ツール: 0.291590571404
いろいろ: 0.288147270679
思い立っ: 0.280256956816
None

==========
epoch: 1
accumulates loss: 921329.687744
query: シリコンバレー
薄利多売: 0.344960749149
サイト: 0.34360229969
いろいろ: 0.292381823063
ツール: 0.289981007576
思い立っ: 0.287175774574
None

==========
epoch: 2
accumulates loss: 891724.701904
query: シリコンバレー
薄利多売: 0.349293321371
サイト: 0.343631505966
いろいろ: 0.295914918184
思い立っ: 0.291843622923
ツール: 0.288331329823
None

==========
epoch: 3
accumulates loss: 757185.654785
query: シリコンバレー
薄利多売: 0.352725356817
サイト: 0.344897687435
いろいろ: 0.297841370106
思い立っ: 0.295309871435
ツール: 0.286360681057
None

==========
epoch: 4
accumulates loss: 678935.693481
query: シリコンバレー
薄利多売: 0.355262964964
サイト: 0.347212970257
思い立っ: 0.299321830273
いろいろ: 0.298689037561
す: 0.285281300545
None

==========
epoch: 5
accumulates loss: 610247.023926
query: シリコンバレー
薄利多売: 0.35762360692
サイト: 0.348474025726
思い立っ: 0.300522983074
いろいろ: 0.300092220306
す: 0.289157003164
None

==========
epoch: 6
accumulates loss: 600056.776855
query: シリコンバレー
薄利多売: 0.360702127218
サイト: 0.350107192993
思い立っ: 0.303010463715
いろいろ: 0.300860673189
す: 0.292713105679
None

==========
epoch: 7
accumulates loss: 589747.635376
query: シリコンバレー
薄利多売: 0.364328920841
サイト: 0.351830333471
思い立っ: 0.304481714964
いろいろ: 0.299699604511
す: 0.295893192291
None

==========
epoch: 8
100000 words, 77.42 sec, 1291.68 words/sec
accumulates loss: 523010.348755
query: シリコンバレー
薄利多売: 0.367006063461
サイト: 0.353862285614
思い立っ: 0.305754393339
す: 0.299977868795
いろいろ: 0.298767507076
None

==========
epoch: 9
accumulates loss: 508688.538574
query: シリコンバレー
薄利多売: 0.370497822762
サイト: 0.355607360601
思い立っ: 0.306706368923
す: 0.303147226572
いろいろ: 0.297139495611
None
```

# 結論と考察 
今回は3回同じデータを回してみましたが、2つ

## 1. 最初に学習して近いと思われたワードは終始近いワードである 
epoch0からあたりがついたデータは終始そのままでした。人間で言えば、一度学習した内容は確かに固定観念がつくので、それと同じような感覚でしょうか。
<br />
## 2. 3回とも全く違う結論に達する 
学習させた内容は全て同じデータなのに、最終的に近いワードとして出力されたデータは3つとも全く異なるものでした。人間で言えば、同じことを学習（修得）しても、考え方はそれぞれ違うといったところでしょうか。

lossした値がまだまだ大きすぎるということと、word2vecでは、近いワードは0.2–0.4に配置されそうということが途中経過からわかりました。

毎回違う結果が出たというのが、ディープラーニングらしさですね。人間の学習と同じで答えはないので、もっと機械にも勉強してかしこくなってもらいたいと思います。