鴨川にあこがれる日々

軽い技術っぽい記事かいてます

word2vecよりも高性能らしいGloVeを触ってみた

はじめに

word2vecというツールが,かなり流行りました.
そのあといくつも単語の分散表現に関する論文もでてきています.

最近,目にした中で,word2vecよりも性能がよいらしいGloVeが気になったので,簡単に触ってみました.nlp.stanford.edu

論文はこちら
http://nlp.stanford.edu/projects/glove/glove.pdf


英語が拙いため,論文自体は理解できていませんが,
word2vecと比べて,コーパス全体の情報もうまく使って学習してやろうというのがこのGloVeの特徴のようです.

使い方

私が行った環境は,Mac(yosemite)です.

上にあげたGloVeのページに使い方がありますので,そちらに従うのが良いかと思います.

demo.shで呼び出されているgloveが,word2vecでいうベクトルの学習を行います.
ファイルのダウンロードを除くと5分かからないくらいで学習が終わりました.

GloVeのdemo.shは,最後まで行くとmatlabスクリプトを実行させようとしますが,matlabなんて高級品を持ってないので,類似度計算のスクリプト*1を書きました...


後々思いましたがdistanceやanaogyを使うのであれば,3CosMulもあるgensimから呼び出すのがいいと思います.
gensimで読み込む場合は1行目に語彙数と次元数を明記する必要があります.(word2vecの学習結果をテキストファイルで出力したときと形式を合わせればよい)




demo.shが終わるとvectors.txtというファイルができます.

> head -n 1 vectors.txt
the -0.014104 0.244983 -0.102183 0.931406 -1.423655 0.848837 1.069455 -1.759019 0.183791 0.325009 -0.577931 -0.134837 0.131595 0.599334 0.319254 -0.003343 0.276794 -0.835341 -0.498232 -0.278226 0.352279 -1.052580 -0.739449 0.124482 -0.227393 -0.489001 -0.418558 0.078085 1.100896 -0.460302 -1.127222 -0.437221 -0.256813 -0.512607 2.119612 -0.910066 0.743753 -0.902334 0.178241 -0.542029 -0.789696 -1.062941 0.017945 -0.360390 -0.158945 -0.730876 0.014632 -0.823559 -0.046100 3.302891
...

一行が一つの単語ベクトルになっているので,これを読み込んで内積計算させます.

word2vecでいうところのdistanceをやってみましょう.

theと近い単語

which	0.8836077000782545
this	0.862593192458247
in	0.8466619457387068
part	0.8455464997287052
first	0.8327288270472374
also	0.827886592187664
on	0.826488119539377
known	0.8242618727678825
it	0.8184213636549925
from	0.8163444274002506
as	0.8156857823656436
of	0.8156603273912373
its	0.8125787097711226
however	0.8111641164124543

ストップワードや似た使われ方をする単語がとれていますね.

つづいて
kingと近い単語

iii	0.7977789126397291
son	0.7845445241736492
ii	0.7813233562384672
prince	0.7594748345203723
alexander	0.7508548836050832
scotland	0.744305549934188
henry	0.7435721660152305
queen	0.7403030238067019
kings	0.7398113951737952
kingdom	0.7365645683116556
iv	0.7345363416457015
throne	0.7332238853701482
emperor	0.7215290336805449
brother	0.7185234067724647

iiiはなんとか三世のIIIでしょうか.
ちょっと微妙ですね.


類推もやってみましょう.
king - man - woman を入力とします.
kingベクトルから manベクトル引いて womanベクトル足したベクトルとcos類似度が高い単語を出します.

son	0.764509012110369
queen	0.7469945801148958
throne	0.745999222146287
elizabeth	0.721411059983216
wife	0.7209514606861995
daughter	0.7123102037037861
henry	0.7110046078055418
prince	0.706369182240951
married	0.7021124897551239

欲しかったqueenは2番目です.

所感

今回のGloveのパラメータは,word2vecとは違っているため,単純に比較することは難しいですので,あくまで参考程度ということで...

word2vecのnegative samplingとGloVeを日本語のデータで比較した論文があり,そちらではword2vecよりもGloveが良い性能だったという結果が報告されています.ci.nii.ac.jp


ちなみに,分かち書きされた日本語テキストでも試してみましたが,うまくいきました.


2015年6月14日追記
もしかすると言語の違いのせいもあるかもしれませんが,
↑で挙げた日本語論文は,ハイパーパラメータの調節をサボりすぎように感じていて,
https://www.aclweb.org/anthology/Q/Q15/Q15-1016.pdf

のほうがより多くのパラメータで比較しているため参考になるかと思いました.


個人的にはword2vec使うかな...

*1:rubyです