Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
162
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

[gensim]Doc2Vecの使い方

大抵はgensimの公式に書いてあるけど、日本語の資料はそんなに多くないので、自分がよく使う基本的なやつを初心者向けにまとめときます。

準備(インストール)

pip install gensim

学習データの形成

サイトによって書き方違うんですが、個人的にはこの書き方で落ち着いてます

#coding: UTF-8
from gensim.models.doc2vec import Doc2Vec
from gensim.models.doc2vec import TaggedDocument

f = open('学習データ.txt','r')#空白で単語を区切り、改行で文書を区切っているテキストデータ

#1文書ずつ、単語に分割してリストに入れていく[([単語1,単語2,単語3],文書id),...]こんなイメージ
#words:文書に含まれる単語のリスト(単語の重複あり)
# tags:文書の識別子(リストで指定.1つの文書に複数のタグを付与できる)
trainings = [TaggedDocument(words = data.split(),tags = [i]) for i,data in enumerate(f)]

ちなみに今回学習したのは、読書メーターのレビュー1200万件のデータです。こそこそとスクレイピングで収集しました。1GB超えてるので、メモリに乗っけるのもPCによってはなかなか大変

モデルの学習

# トレーニング(パラメータについては後日)
m = Doc2Vec(documents= trainings, dm = 1, size=300, window=8, min_count=10, workers=4)

# モデルのセーブ
m.save("model/doc2vec.model")

# モデルのロード(モデルが用意してあれば、ここからで良い)
m = Doc2Vec.load('model/doc2vec2.model')

学習データのサイズによってはかなり時間かかるので注意

よく使う機能

学習文書の中で、指定したidの文書と類似度の高い文書を調べる

#引数は文書id
print m.docvecs.most_similar(0)

#文書0と類似している上位10件の文書idと類似度のセットが返ってくる
>> [(55893, 0.6868613362312317), (85550, 0.6866280436515808), (80831, 0.6864551305770874), (61463, 0.6863148212432861), (72602, 0.6847503185272217), (56876, 0.6835699081420898), (80847, 0.6832736134529114), (92838, 0.6829516291618347), (24495, 0.6820268630981445), (45589, 0.679581880569458)]

任意の文書間の類似度を調べる

print m.docvecs.similarity(1,307)
#文書1と文書307の間の類似度
>> 0.279532733106

学習したモデルを使って、新規に与えた文書の同士の類似度を調べる

#例えば、以下の4つの新規文書の、いくつかの組み合わせの類似度を計算してみる
doc_words1 = ["ラスト", "展開" ,"早い" ,"他" ,"作品", "衝撃", "受ける" ,"裏の裏" ,"つく", "トリック" ,"毎度" ,"こと", "脱帽", "する", "読む", "やすい" ,"め" ,"ミステリー"]
doc_words2 = [ "イニシエーション・ラブ", "同様" ,"最後", "数行", "どんでん返し", "いく", "時", "時", "様々", "シーン", "する" ,"れる", "伏線" ,"散りばめる", "られる" ,"いる", "こと", "気づく"]
doc_words3 = ["ラスト", "展開" ,"早い" ,"他" ,"作品", "衝撃", "受ける" ,"裏の裏" ,"つく","ミステリー"]
doc_words4 = ["独特", "世界観", "日常" ,"離れる","落ち着く","時","読む","本"]

print "1-2 sim"
sim_value = m.docvecs.similarity_unseen_docs(m, doc_words1, doc_words2, alpha=1, min_alpha=0.0001, steps=5)
print sim_value

print "1-3 sim"
print m.docvecs.similarity_unseen_docs(m, doc_words1, doc_words3, alpha=1, min_alpha=0.0001, steps=5)

print "1-4 sim"
print m.docvecs.similarity_unseen_docs(m, doc_words1, doc_words4, alpha=1, min_alpha=0.0001, steps=5)

print "2-3 sim"
print m.docvecs.similarity_unseen_docs(m, doc_words2, doc_words3, alpha=1, min_alpha=0.0001, steps=5)

>> 1-2 sim
   0.10429317017
   1-3 sim
   0.472984922936
   1-4 sim
   -0.02320307339
   2-3 sim
   0.228117846023

人が見ても、文書1-3とか2-3は似てるし、逆に文書1-4は似てないのは明らかなので、なかなか良い感じに類似度が出てます

新規文書の圧縮ベクトルを出力(学習するときにsizeで指定した次元数のベクトルで出力される)

newvec = m.infer_vector(doc_words1)

print newvec

>> [  1.19107231e-01  -4.06390838e-02  -2.55129002e-02   1.16982162e-01
  -1.47758834e-02   1.07912444e-01  -4.76960577e-02  -9.73785818e-02
   #...(中略)
  -1.61364377e-02  -9.76370368e-03   4.98018935e-02  -8.88026431e-02
   1.34409174e-01  -1.01136886e-01  -4.24979888e-02   7.16169327e-02]

今後追加したいこと

  • モデルを学習する際のパラメータの調整
  • どんなことに応用できるか

あと、doc2vecのアルゴリズム自体に関して
工学院大学の北山研のブログで説明している記事を見つけました
doc2vec(Paragraph Vector) のアルゴリズム

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
162
Help us understand the problem. What are the problem?