言語処理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を使うのは別の機会にします。