我正在利用文档向量表示的相似性构建一个基于内容的推荐系统。 我的文档是书籍的描述。其中大部分是英语,但也有一些是其他语言。我使用 gensim 的 Doc2Vec 来构建文档的矢量表示。
根据我对这个模型的理解,不同语言的文档相似度应该很低,因为单词甚至不重叠。但事实并非如此。我的数据集中不同语言的文档相似度可以达到 0.9。
为什么会出现这种情况?
import pandas as pd
from pathlib import Path
from gensim.models.doc2vec import TaggedDocument, Doc2Vec
from gensim.utils import simple_preprocess
import numpy as np
from tqdm import tqdm
from sklearn.metrics.pairwise import cosine_similarity
data_folder = Path.cwd().parent / 'data'
transformed_folder = data_folder / 'transformed'
BOOKS_PATH = Path(transformed_folder, "books_final.csv")
import seaborn as sns
book_df = pd.read_csv(BOOKS_PATH)
languages=book_df.language.unique()
training_corpus = np.empty(len(book_df), dtype=object)
for i, (isbn, desc) in tqdm(enumerate(zip(book_df['isbn'], book_df['description']))):
training_corpus[i] = TaggedDocument(simple_preprocess(desc), [str(i)])
model=Doc2Vec(vector_size=50, min_count=2, epochs=40)
model.build_vocab(training_corpus)
#train the model
model.train(training_corpus, total_examples=model.corpus_count, epochs=model.epochs)
#get the keys of the trained model
model_keys=list(model.dv.key_to_index.keys())
matrix = model.dv.vectors
similarity_matrix = cosine_similarity(matrix)
indices_for_language = {}
for language, group_df in book_df.groupby('language'):
indices_for_language[language] = group_df.index.to_list()
sim_japanese_italian = similarity_matrix[indices_for_language['Japanese']][:, indices_for_language['Italian']]
#make a heatmap
sns.heatmap(sim_japanese_italian)
与
Doc2Vec
(“段落向量”)算法的已发布结果相比,您的语料库有点小,该算法通常在数万到数百万个文档集上进行演示。
特别是,如果您只有 (4742-4655=) 93 个非英语
description
文本,并且这些文本分为 16 种非英语语言,那么在我看来,来自其他语言的 any 单词似乎不太可能将有足够的上下文使用示例,以便 (1) 在 min_count
截止值中幸存下来(通常不应低至 2!);或 (2) 在模型中获得有意义/可推广的含义。
也就是说:所有这些非常罕见的单词都将具有相当特殊/任意的含义,并且充满所有罕见/难以理解的单词的
description
文本往往具有弱的、几乎随机的文档向量。因此,虚假的相似性并不令人意外。
如果那些“非英语”
description
文本中确实有一些看起来像英语或全语言的标记——杂散单词或错误同源词或标点符号或小故障——这些也可能主导description
与description
的比较.
您应该检查,在可疑的过于相似的对上,每个文档中有多少单词实际上在训练模型中 - 请记住,不在训练模型中的单词在训练或训练后推理中基本上会被忽略。 (一份 100 字的文档,在只有少数其他 100 字文档的语言中,实际上可能以单一出现的单词为主,甚至不符合
min_count=2
,因此当精简为幸存的单词是简短的文档,里面充满了难以理解的单词。)
如果英语文档之间的相似度得分总体上是合理的,那么该模型正在尽其所能,并且有足够的数据。您确实希望这一系列算法(word2vec、
Doc2Vec
、FastText 等)能够在合理的对比上下文中为任何单词的用法提供许多不同的代表性示例,以便能够对这些单词进行任何有意义的后续建模(并且包含它们的文档)。
因此:如果您无法设法使用至少为通常默认值 (
min_count
) 或理想情况下更高的 5
,那么您可能没有足够的数据来让这些算法展示其优势。扩展您的语料库 - 即使是其他不直接感兴趣的文本,但具有足够的多样性以更好地表示您感兴趣的文本中使用的语言 - 可能会有所帮助。 (也就是说:即使你的推荐范围是 <5000 descriptions
,从其他来源混合另外 200,000 个类似的简短简介,以便感兴趣的单词和语言有足够的覆盖范围,可能是值得的。)