2021/11/16 word2vecにおけるコード記述に適切性を欠く点がありましたので修正、検証結果まとめ含め、修正しました。
#はじめに
前回の記事で、word2vec を取り上げました。
word は単語、vec はベクトルということで、単語を足したり、引いたりすることができるから、たとえば『「王様」から「男性」を引いて「女性」を足すと?』→『女王』といった感じで単語の候補が出せたりする。すごいですね。
「学習済みデータ(日本語単語ベクトル)」を利用するにあたり、いくつか種類がありましたので試してみることにしました。
以下が試した学習済みデータと自然言語処理の手法です。
##確認した学習済みデータ(日本語単語ベクトル)
① entity_vector.model.bin(日本語 Wikipediaベース(東北大学))…word2vec
② chive-1.1-mc90-aunit(国語研日本語ウェブコーパス(NWJC)がベース)…Magnitude
③ cc.ja.300.vec(日本語 Wikipediaベース)…fastText
④ NEologd(Web 上の言語資源から得た新語を追加した MeCab 用のシステム辞書)…fastText
※②は『日本語単語ベクトル"chiVe"をgensimやMagnitudeで使う』 の内容をそのまま利用させていただきました。
##実行条件など
- Google colabで実行
#比較した内容と結果
###1. 処理開始までに要する時間
① gensim、ローカルに保存した学習データの読込みに約30秒 …Bestパフォーマンス
② Magnitude、学習データリモート読込みに約6分強
③ gensim、ローカルに保存した学習データの読込みに約11分
④ gensim、ローカルに保存した学習データの読込みに約2分
いちばんサクッと始められるのは①、次いで④となりました。
①と④は現実的な待ち時間でした。
②③は、すこし待つ必要があるのでサクッと始めたい時はつらいかもしれません。
###2. 比較した類似語や単語加減算
- 指原莉乃
- 矛盾
- 公務員+ピストル
- 松本人志+浜田雅功
- 漫才+コント
- 悪魔-悪
- イチロー-野球+サッカー
- 王様-男+女
Bestパフォーマンスは④でした。
おおむね満足いく結果を示したのは①と③でした。
※具体的な結果は以下を確認してください。
記事のタイトルである『機械学習が「𝑥 = ‘松本人志’ + ‘浜田雅功’ 」を解くと?』にそれらしくこたえてくれたのは①(entity_vector.model+word2vec)と④(vector_neologd+fastText)でした。
①は、「ダウンタウン_(お笑いコンビ)」が表示されました。ズバリ!ですね。
④は、「ダウンタウンDX」「ダウンタウンのごっつええかんじ」「水曜日のダウンタウン」が表示されました。
②(chiVe+Magnitude)は、‘松本人志’, ‘浜田雅功’ は「ただの苗字(もしくは地名?)」と判断された感じです。
③(cc.ja.300.vec+fastText)も苗字と判断された感じですが、類似語は他の芸人さんの苗字が表示されました。
それぞれ一長一短ありますが、Google colabでの使用+個人的な嗜好から、私は①④を普段使いにすることにしました。
どれか一つに決めなかったのは、①④はほぼ同じコードで実行できるからです。
#事前準備
以下から、学習済みデータをダウンロードし、GoogleDriveに保存します。
※私は、学習済モデルも.ipynbファイルも「content/drive/My Drive/NLP」に格納しましたので、このフォルダを指定するコードにしています。これは任意に設定してください。
#実行に際しての補足
- ランタイムでセルを実行すると、URLが表示されます。これにアクセスしてログインするとauthorization codeが表示されるのでコピーし、コード実行後にセルに表示されるauthorization code入力枠にペーストしてください。
- 類似語、加算、減算、加減算等は任意に書き換え、セルを実行してください。
- 対象単語が学習済モデル内にない場合はエラーになります。長い単語の場合は分割すればできることが多いですが、精度はいまいちです。学習させることもできるようですが、この記事では扱いません。
#学習済モデル & ライブラリインポート
from google.colab import drive
drive.mount('/content/drive')
%cd /content/drive/My Drive/NLP #学習済モデル保存場所の指定
#!unzip vector_neologd.zip #これは④の場合のみ必要です
import gensim
model = gensim.models.KeyedVectors.load_word2vec_format('entity_vector.model.bin', binary=True) #①の場合
#model = gensim.models.KeyedVectors.load_word2vec_format('model.vec', binary=False) #④の場合
#類似語
追記:word2vecもfastTextも(positive=['単語'])という記述で実行できるが、word2vecは(positive=u'[単語]')という記述の方がよい結果が得られることが多いです。
※王様-男+女のケースでは、(positive=['単語'])とした方がもっともらしい結果が得られました。
model.most_similar(positive=['指原莉乃']) #word2vecは(positive=u'[指原莉乃]')がよい
model.most_similar(positive=['矛盾'])
#加算
model.most_similar(positive=['公務員','ピストル'])
model.most_similar(positive=['漫才','コント'])
model.most_similar(positive=['松本人志','浜田雅功']) #word2vecは(positive=[u'[松本人志]',u'[浜田雅功]'])がよい
#減算
model.most_similar(positive=['悪魔'], negative=['悪']) #word2vecは(positive=[u'[悪魔]'], negative=[u'[悪]'])がよい
#加減算
model.most_similar(positive=['イチロー','サッカー'], negative=['野球']) #word2vecは(positive=[u'[イチロー]',u'[サッカー]'], negative=[u'[野球]'])がよい
model.most_similar(positive=['王様','女'], negative=['男'])
#類似度
print(model.similarity('猫', '犬'))
print(model.similarity('猫', '人'))
#最後に
単語が加減算できるって、おもしろいですね。
#参考サイト