word2vecを試してみたいけど使ったことがないという人が対象
とりあえず動かしてみるのが目的。
※python2.7.12で動かしているけど、3系でも大丈夫なはず。
word2vecとは
word2vecとは、ざっくり言えば
「単語をベクトル表現にでき、意味の足し算や引き算ができるニューラルネット」
これまでの言語処理ではone hotという表現で単語の数だけ次元を持つベクトルで処理していたけれど、次元圧縮したベクトルで単語を意味(的なもの)で表せるようになったってのが凄いよねって話。
よく使われる有名な例がこれ
king - man + woman = queen
とりあえずこれを動かしてみたい!というのが今回の記事
詳しい解説は下の参考サイトがめっちゃ分かりやすかったのでそちらを参照して欲しい。
学習用のデータセット
日本語でもできるが、簡単に手に入るデータセットがないので英語で試してみる。
英語では簡単に手に入るデータセットが用意されているのでそれを使う。
wget http://mattmahoney.net/dc/text8.zip unzip text8.zip
学習用のスクリプト
learning.pyという名前で保存
from gensim.models import word2vec import logging logging.basicConfig(format='%(asctime)s : %(levelname)s', level=logging.INFO) sentences = word2vec.Text8Corpus('text8') model = word2vec.Word2Vec(sentences, size=200, min_count=20, window=15) model.save("sample.model") print("Finish!")
モデルを試してみるスクリプト
result.pyという名前で保存
from gensim.models import word2vec import logging import sys model = word2vec.Word2Vec.load("sample.model") def neighbor_word(posi, nega=[], n=10): count = 1 result = model.most_similar(positive = posi, negative = nega, topn = n) for r in result: print(str(count)+" "+str(r[0])+" "+str(r[1])) count += 1 def calc(equation): if "+" not in equation or "-" not in equation: neighbor_word([equation]) else: posi,nega = [],[] positives = equation.split("+") for positive in positives: negatives = positive.split("-") posi.append(negatives[0]) nega = nega + negatives[1:] neighbor_word(posi = posi, nega = nega) if __name__=="__main__": equation = sys.argv[1] calc(equation)
使い方
python leraning.py python result.py king python result.py king-man+woman
learning.pyはモデルを作るためのものなので1回だけで充分。結構(3分くらい)時間がかかった。
足し算引き算はスペースを入れないで書くこと。
確かに第一候補が
1 queen 0.660548448563
になった!嬉しい!
参考サイト:
Word2VecをPythonでやってみる | Foolean
Word2vec Tutorial | RaRe Technologies
word2vecについてわかりやすい記事:
Word2Vec のニューラルネットワーク学習過程を理解する · けんごのお屋敷