web-dev-qa-db-ja.com

Doc2Vec最も類似したドキュメントを取得

クエリまたは検索文字列に関して関連性の高い順に並べられたほとんどのドキュメントを返すドキュメント取得モデルを構築しようとしています。このために、gensimでDoc2Vecモデルを使用してdoc2vecモデルをトレーニングしました。私のデータセットは、各ドキュメントが各行に文字列として保存されているpandasデータセットの形式です。これは私がこれまでに持っているコードです

import gensim, re
import pandas as pd

# TOKENIZER
def tokenizer(input_string):
    return re.findall(r"[\w']+", input_string)

# IMPORT DATA
data = pd.read_csv('mp_1002_prepd.txt')
data.columns = ['merged']
data.loc[:, 'tokens'] = data.merged.apply(tokenizer)
sentences= []
for item_no, line in enumerate(data['tokens'].values.tolist()):
    sentences.append(LabeledSentence(line,[item_no]))

# MODEL PARAMETERS
dm = 1 # 1 for distributed memory(default); 0 for dbow 
cores = multiprocessing.cpu_count()
size = 300
context_window = 50
seed = 42
min_count = 1
alpha = 0.5
max_iter = 200

# BUILD MODEL
model = gensim.models.doc2vec.Doc2Vec(documents = sentences,
dm = dm,
alpha = alpha, # initial learning rate
seed = seed,
min_count = min_count, # ignore words with freq less than min_count
max_vocab_size = None, # 
window = context_window, # the number of words before and after to be used as context
size = size, # is the dimensionality of the feature vector
sample = 1e-4, # ?
negative = 5, # ?
workers = cores, # number of cores
iter = max_iter # number of iterations (epochs) over the corpus)

# QUERY BASED DOC RANKING ??

私が苦労しているのは、クエリに最も類似/関連するドキュメントを見つけることです。 infer_vectorを使用しましたが、クエリをドキュメントと見なし、モデルを更新して結果を返すことに気付きました。 most_similarメソッドとmost_similar_cosmulメソッドを使用してみましたが、代わりに単語と類似性スコア(推測)を取得しました。私がやりたいのは、検索文字列(クエリ)を入力するとき、類似性スコア(コサインなど)とともに最も関連性の高いドキュメント(id)を取得することです。この部分をどうやってやるの?

31
Clock Slave

infer_vectorを使用して、新しいテキストのドキュメントベクトルを取得する必要があります-これは、基礎となるモデルを変更しません。

方法は次のとおりです。

tokens = "a new sentence to match".split()

new_vector = model.infer_vector(tokens)
sims = model.docvecs.most_similar([new_vector]) #gives you top 10 document tags and their cosine similarity

編集:

以下は、infer_vecが呼び出された後、基礎となるモデルがどのように変化しないかの例です。

import numpy as np

words = "king queen man".split()

len_before =  len(model.docvecs) #number of docs

#Word vectors for king, queen, man
w_vec0 = model[words[0]]
w_vec1 = model[words[1]]
w_vec2 = model[words[2]]

new_vec = model.infer_vector(words)

len_after =  len(model.docvecs)

print np.array_equal(model[words[0]], w_vec0) # True
print np.array_equal(model[words[1]], w_vec1) # True
print np.array_equal(model[words[2]], w_vec2) # True

print len_before == len_after #True
45
Erock