word2vecは、大量のテキストデータを解析し、各単語の意味をベクトル表現化する手法。
単語をベクトル化することで、単語同士の意味の近さを計算することや単語同士の意味を足したり引いたりということが可能。
基本的には、同じような意味や使われ方をする単語は同じような文脈の中に登場するという考えのもと、単語をベクトル化している。
同じような意味や使われ方をする単語同士はベクトル空間上で近い場所に存在する=コサイン類似度が高くなる。
ベクトル同士の成す角度の近さを表現する。
三角関数の普通のコサインの通り、1に近ければ類似しており、0に近ければ似ていないことになる。
(範囲は-1~1。+1に近ければ、同じ方向に近いベクトル同士。-1に近ければ、逆向きに近いベクトル同士)
pip install gensim
Mecabの使える環境下にてインストールすること。
単語をベクトルに変換するためのモデルは「学習」させる必要がある。
- 学習済みのモデルを活用する
- 単語リストから学習させる
今日のインターネット上では、さまざまな学習済みのモデルが配布されている。(数MB~数十GBまで)
はじめのうちは、白ヤギコーポレーションのモデルの使用を勧める。
軽量でありつつ、十分に単語を含めているため。
各自、ダウンロードおよび解凍して、使いやすいディレクトリに置くこと。
以下は、白ヤギコーポレーションのモデルを使用する例。 パスは各自で設定すること。
# word2vec本体のインポート
from gensim.models.word2vec import Word2Vec
# 学習済みのモデルのパスを設定
model_path = '/path/word2vec.gensim.model'
# 読み込み
model = Word2Vec.load(model_path)
モデルによっては、以下の方法で読み込むものもある。
import gensim
model = gensim.models.KeyedVectors.load_word2vec_format(model_path)
# size: 圧縮次元数
# min_count: 出現頻度の低いものをカットする
# window: 前後の単語を拾う際の窓の広さを決める
# iter: 機械学習の繰り返し回数(デフォルト:5)十分学習できていないときにこの値を調整する
# model.wv.most_similarの結果が1に近いものばかりで、model.dict['wv']のベクトル値が小さい値ばかりの
# ときは、学習回数が少ないと考えられます。
# その場合、iterの値を大きくして、再度学習を行います。
# 事前準備したword_listを使ってWord2Vecの学習実施
model = word2vec.Word2Vec(word_list, size=100,min_count=5,window=5,iter=100)
# 一つ一つの単語は100次元のベクトルになっています。
# 「世間」のベクトル値を確認します。
# 各要素の値が0に近いものばかりの場合は学習不足なので、繰り返し回数を多くして学習量を増やします。
print(model.__dict__['wv']['世間'])
例)国王と皇帝
print(model.similarity('国王', '皇帝'))
実行結果(warning等が表示されるかもしれないが、問題はない)
0.87497294
例)女王
print(model.most_similar(positive=['女王']))
実行結果
[('王妃', 0.8575930595397949), ('王女', 0.8321217894554138), ('女帝', 0.8226272463798523), ('国王', 0.7967036962509155
), ('エリザベス女王', 0.7964159846305847), ('妃', 0.7897101640701294), ('エリザベス2世', 0.785266637802124), ('王子',
0.7833946943283081), ('王太', 0.7667813897132874), ('アルバート公', 0.748985767364502)]
例)女 + 国王 - 男
print(model.most_similar(positive=['女', '国王'], negative=['男']))
実行結果
[('ツァーリ', 0.8346272706985474), ('王室', 0.8306275606155396), ('女帝', 0.814156174659729), ('皇帝', 0.8072190284729
004), ('スルタン', 0.806735098361969), ('君主', 0.7971755862236023), ('スルターン', 0.7930727601051331), ('イギリス国
王', 0.7902869582176208), ('女王', 0.7883061170578003), ('摂政', 0.7820892333984375)]
「女王」に類似した言葉を求める。
言葉と類似度を以下のように出力しなさい。
('王妃', 0.8575930595397949)
('王女', 0.8321217894554138)
('女帝', 0.8226272463798523)
('国王', 0.7967036962509155)
('エリザベス女王', 0.7964159846305847)
('妃', 0.7897101640701294)
('エリザベス2世', 0.785266637802124)
('王子', 0.7833946943283081)
('王太', 0.7667813897132874)
('アルバート公', 0.748985767364502)
リスト(ex:[a,b,c])のまま出力するプログラムは既に示した。出力方法のみ考えればよい。
同じく、「女王」に類似した言葉を求める。
今度は、以下のように言葉と類似度を分けて出力しなさい。
key=王妃, score=0.8575930595397949
key=王女, score=0.8321217894554138
key=女帝, score=0.8226272463798523
key=国王, score=0.7967036962509155
key=エリザベス女王, score=0.7964159846305847
key=妃, score=0.7897101640701294
key=エリザベス2世, score=0.785266637802124
key=王子, score=0.7833946943283081
key=王太, score=0.7667813897132874
key=アルバート公, score=0.748985767364502
類似語と類似度はタプルになっている。タプルから個々の値を得るにはどうすればよいか。
print("key=XXX, score=XXX")とすれば正しく出力できそうである。
XXXに値を埋め込むにはformatメソッドやf式(python3.6以上)などがある。
これを機にさまざまなやり方を調べること。
同じく「女王」を引数として与えるが、以下のように、より多くの結果を得たい。
「女王」に対する20件の類似語(およびその類似度)を出力しなさい。
key=王妃, score=0.8575930595397949
key=王女, score=0.8321217894554138
key=女帝, score=0.8226272463798523
key=国王, score=0.7967036962509155
key=エリザベス女王, score=0.7964159846305847
key=妃, score=0.7897101640701294
key=エリザベス2世, score=0.785266637802124
key=王子, score=0.7833946943283081
key=王太, score=0.7667813897132874
key=アルバート公, score=0.748985767364502
key=王, score=0.7484933733940125
key=王太子, score=0.742463231086731
key=ダイアナ, score=0.7418729066848755
key=マリー・アントワネット, score=0.7342186570167542
key=皇太子, score=0.7293393015861511
key=公爵, score=0.720671534538269
key=エリザベス1世, score=0.7202358245849609
key=公妾, score=0.7180596590042114
key=アレクサンドラ, score=0.7174392342567444
key=イサベル, score=0.7171486020088196
以下は、most_similarメソッドに関するドキュメントである。
gensim: models.keyedvectors ? Store and query word vectors
このページを参考にする、もしくは自分で調べるなどして、most_similarメソッドに与えるべき引数を見つけなさい。
また、「発見した引数名=20」をmost_similarメソッドに与え、実行しなさい。
「女王」を与えたときの類似語に関して以下のようにスコア、品詞とともに出力しなさい。
key=王妃, score=0.8575930595397949, hinshi=名詞-一般
key=王女, score=0.8321217894554138, hinshi=名詞-一般
key=女帝, score=0.8226272463798523, hinshi=名詞-一般
key=国王, score=0.7967036962509155, hinshi=名詞-一般
key=エリザベス女王, score=0.7964159846305847, hinshi=名詞-固有名詞-人名-名
Ex3のプログラムにMecabを応用する。
Mecabの出力はリストである。何番目の要素が品詞であるか確認する。
以下のテキストファイルは、「知能」に類似する言葉100個をカンマ区切りにて出力したものである。
テキストファイルを読み込み、「知性」との類似度を計算し、非常によく似た言葉のみを類似度とともにテキストファイル(word2vec-ex5-output.txt)に1行ずつ出力しなさい。
本問題では、類似度が0.8以上のものを非常によく似ていると定義する。
出力結果の例を以下に示す。
key=知性, score=0.9999999403953552
テキストファイルを読み込むには、open('path', 'mode')を使う。
※ 読み込み、書き込みテキストが文字化けする場合は、open('path', 'mode', encoding='code')とする必要がある。
ファイルの読み込み、および書き込みは今後も頻繁に使う。ドキュメントなどを読んで理解しておくこと。
7. 入力と出力 ? Python 3.6.5 ドキュメント
読み込んだ結果はカンマ区切りの文字列になっている。Mecabの時の演習問題を思い出そう。
open('path', 'w')では、テキストファイルを上書きすることができない。
'w'は、書き込み専用モード。上書きが可能なモードを調べよう。