2019年12月29日

doc2vecのinfer_vectorの値を固定する方法

gensimのdoc2vecのinfer_vectorメソッドを使用すると、同一文書であっても毎回値が変わる。
同一文書に対しては、毎回同じ値が返ってきてほしかったので、やり方を調査した。

起こったこと


gensimのdoc2vecのinfer_vectorは毎回異なる値を返す。
もう古いと言われそうだが、米津玄師のLemonでやってみる。
import numpy as np from gensim.models.doc2vec import Doc2Vec, TaggedDocument doc = {0: ['夢', 'なら', 'ば', 'どれ', 'ほど', 'よかっ', 'た', 'でしょう'], 1: ['未だ', 'に', 'あなた', 'の', 'こと', 'を', '夢', 'に', 'みる'], 2: ['忘れ', 'た', '物', 'を', '取り', 'に', '帰る', 'よう', 'に'], 3: ['古び', 'た', '思い出', 'の', '埃', 'を', '払う'], 4: ['戻ら', 'ない', '幸せ', 'が', 'ある', 'こと', 'を'], 5: ['最後', 'に', 'あなた', 'が', '教え', 'て', 'くれ', 'た'], 6: ['言え', 'ず', 'に', '隠し', 'て', 'た', '昏い', '過去', 'も'], 7: ['あなた', 'が', 'い', 'なきゃ', '永遠', 'に', '昏い', 'まま'], 8: ['きっと', 'もう', 'これ', '以上', '傷つく', 'こと', 'など'], 9: ['あり', 'は', 'し', 'ない', 'と', 'わかっ', 'て', 'いる']} documents = [TaggedDocument(words=words, tags=[id]) for id, words in doc.items()] model = Doc2Vec(documents=documents, min_count=1) vector1 = model.infer_vector(['あの', '日', 'の', '悲しみ']) vector2 = model.infer_vector(['あの', '日', 'の', '悲しみ']) np.testing.assert_allclose(vector1, vector2)

これの実行結果が以下の通り

AssertionError: Not equal to tolerance rtol=1e-07, atol=0 Mismatched elements: 100 / 100 (100%) Max absolute difference: 5.7297293e-06 Max relative difference: 0.01785335 x: array([ 2.877934e-03, 2.113050e-03, 3.681447e-04, 2.641888e-03, -2.766988e-03, 2.866727e-03, -2.180564e-03, 1.779506e-03, -4.327289e-03, 1.271801e-03, 2.148317e-03, 3.596367e-03,... y: array([ 2.878453e-03, 2.113626e-03, 3.679718e-04, 2.641014e-03, -2.765669e-03, 2.867198e-03, -2.182420e-03, 1.779415e-03, -4.330555e-03, 1.271682e-03, 2.149219e-03, 3.595186e-03,...

やはり、同一モデル、同一文書でも異なるベクトルが出力されてしまう。

対応方法


infer_vectorする前に、毎回モデルのseedを毎回指定する。

# infer_vectorより上は省略 # infer_vectorの前にmodelのseedを指定する model.random.seed(0) vector1 = model.infer_vector(['あの', '日', 'の', '悲しみ']) # infer_vectorする前に毎回seedの指定が必要 model.random.seed(0) vector2 = model.infer_vector(['あの', '日', 'の', '悲しみ']) np.testing.assert_allclose(vector1, vector2)

こうすれば無事同じベクトルが出力される。

まとめ


ググるとすぐに出てくるが、日本語のページが見当たらなかったので、残しておく。

今回はseedを適当に0にして、infer_vectorだけに付けたが、
実際に使う際はmodelと同一seedにするなどしたほうが良い気がする。

参考

https://github.com/RaRe-Technologies/gensim/issues/447

0 件のコメント:

コメントを投稿