Estoy tratando de construir un modelo de recuperación de documentos que devuelva la mayoría de los documentos ordenados por su relevancia con respecto a una consulta o una cadena de búsqueda. Para esto entrené un modelo doc2vec usando el modelo Doc2Vec en gensim. Mi conjunto de datos tiene la forma de un conjunto de datos de pandas que tiene cada documento almacenado como una cadena en cada línea. Este es el código que tengo hasta ahora.
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 ?? La parte en la que estoy luchando es en encontrar documentos que sean más similares/relevantes para la consulta. infer_vector pero luego me di cuenta de que considera la consulta como un documento, actualiza el modelo y devuelve los resultados. Intenté usar los métodos most_similar y most_similar_cosmul pero obtengo palabras junto con un puntaje de similitud (supongo) a cambio. Lo que quiero hacer es cuando ingreso una cadena de búsqueda (una consulta), debo obtener los documentos (identificadores) que son más relevantes junto con un puntaje de similitud (coseno, etc.). ¿Cómo hago esta parte?
Debe usar infer_vector para obtener un vector de documento del nuevo texto, que no altera el modelo subyacente.
Así es como lo haces:
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 similarityEditar:
Este es un ejemplo de cómo el modelo subyacente no cambia después de llamar a 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