我尝试训练模型以获得句子相似性(在我的情况下,某些组织的名称)
我用来训练模型
names_tok = [TaggedDocument(words=word_tokenize(name.lower()), tags=[str(i)])
for (i, name) in enumerate(names)]
# train model
max_epochs = 50
vec_size = 50
alpha = 0.025
model = Doc2Vec(size=vec_size,
alpha=alpha,
min_alpha=0.00025,
min_count=1,
dm=1)
我得到了结果
name = word_tokenize(name.lower())
infer_v = model.infer_vector(name)
results = model.docvecs.most_similar([infer_v]))
它会为所有测试返回奇怪的结果。我已经尝试过使用火车数据的例子而我没有相似性。例如Филип Моррис Продактс С.А.
我得到下一个结果
Найк Инноувейт С.В.: 0.9336682558059692
СОСЬЕТЕ ДЕ ПРОДЮИ НЕСТЛЕ С.А.: 0.9370058178901672
Юнилевер Н.В.: 0.9347286224365234
Мерк Шарп и Доум Корп.: 0.9339677095413208
我无法理解为什么我得到这个。我有18万个列车数据的例子。如何改善模型的结果?
看起来您的相似性代码没有任何明显的错误,但请注意,由于您没有在模型创建时提供epochs
参数,因此它将在内部配置为仅使用5次推断。 (通常Doc2Vec工作使用10-20或更多,推理有时可以从更多,尤其是较小的文本中受益。)
此外,您的问题没有显示您的培训代码 - 许多在线示例包括处理epochs
和alpha
的严重错误。
我看不懂你的名字 - 我猜是俄罗斯,也许是公司名称?但正如我的评论一样,Doc2Vec
在长文本中效果最佳。我只期望它对于较小的文本是有用的,如果存在有用的各种令牌到令牌的相关性,这也反映了你正在寻找的那种“相似性”。
但目前尚不清楚你正在寻求什么样的相似性。如果它纯粹是表面的/形态学的,你可以通过子句片段(字符n-gram)来分析名称,而不是用空格分隔的单词。如果它是一种更微妙的目的,行业或公众感知的相似性,那么除了文字名称之外的元数据可能更有用,例如:
保留甚至只出现一次的令牌 - min_count=1
- 也可以削弱单词向量/ doc向量,因为可以从可能特异性单次出现中学到很少的泛化意义,但是所有这些罕见单词的总体外观会将嘈杂的干扰注入训练其他周围更常见的单词。对于大型自然语言语料库,有大量相关单词标记的例子,通常增加min_count
可以提高模型质量。