北野坂備忘録

主にインストールやプログラミングのメモを載せています。

言語処理100本ノック 2015年版 第9章再訪(2)

(再)85. 主成分分析による次元圧縮

84で得られた単語文脈行列に対して,主成分分析を適用し,単語の意味ベクトルを300次元に圧縮せよ.

で、こちらを分散処理基盤で処理していこうと思いました。
岩波データサイエンスvol.2ではどうやって主成分分析してるのかな~(本を開く)
特異値分解やないかい!(本を床に叩きつける)

岩波データサイエンス Vol.2
本当にこの問題普通の主成分分析で処理できるのか……? ただ岩波データサイエンスで特異値分解がメインに取り上げられているということは、別に主成分分析でなくても精度に問題はないということでしょう。その点は安心しました。

とりあえずsparkに疎行列を渡したいんですが、sparkは DictVectorizerから出力されるcsr_matrixを受け取ってくれません。
そこで DictVectorizerから吐き出される疎行列をsparkの疎行列に変換しようとしていたのですが、その時点でミスに気づきました。
DictVectorizerが作成した疎行列を吐き出させると、0と1しか入っていません。
問題の箇所はここです。

contextdic[context[:-1]]=value[1:] #二重辞書化

ここは

contextdic[context[:-1]]=float(value[1:]) #二重辞書化

とすべきでした。
で、「0と1しかない疎行列」を計算させるより「0とfloatが入っている疎行列」を計算させたほうが時間がかかるだろうな、と思っていたのですが、少量で計算させると逆に今までより速く終わる。
試しに全行処理させてみると、現実的な時間で終了しました。
一晩中計算したあげくメモリエラーを起こしていたのがウソのようです。

全行処理ができたので、今度は性能を確認していきます。

(再)87. 単語の類似度

85で得た単語の意味ベクトルを読み込み,"United States"と"U.S."のコサイン類似度を計算せよ.ただし,"U.S."は内部的に"U.S"と表現されていることに注意せよ.

0.811330719848

高い。

88. (再)類似度の高い単語10件

85で得た単語の意味ベクトルを読み込み,"England"とコサイン類似度が高い10語と,その類似度を出力せよ.

01 Scotland 0.660267
02 Wales 0.658858
03 Australia 0.629681
04 Spain 0.555941
05 Italy 0.552960
06 Ireland 0.542140
07 France 0.501127
08 Britain 0.499419
09 Cheshire 0.498761
10 Japan 0.490661
11 United_Kingdom 0.488238

United_Kingdomが11位だったのであえて11位まで。かなりいい出来です。

89. (再)加法構成性によるアナロジー

85で得た単語の意味ベクトルを読み込み,vec("Spain") - vec("Madrid") + vec("Athens")を計算し,そのベクトルと類似度の高い10語とその類似度を出力せよ.

01 Spain 0.827281
02 Sweden 0.795910
03 Austria 0.758082
04 Italy 0.742489
05 Belgium 0.737295
06 France 0.716874
07 Germany 0.716224
08 Netherlands 0.711587
09 Télévisions 0.694451
10 Switzerland 0.676019
11 Greece 0.670006

 これもGreeceがちょうど11位に入っていたので11位まで。やたらとTélévisionsが高いのが気になりますが。

 性能も十分と言えるでしょう。

 分かってみれば単純なミスでしたが、一見まともなベクトルが吐き出されていたので気づきませんでした。DictVectorizerの調査をしなかったら気づかなかったろうな。
 結局分散処理基盤を使うまでもなく終わってしまいました。pysparkを使うのは別の機会にします。