使用 doc2vec 嵌入的相似性得分是很远的

similarity score is way off using doc2vec embedding

我正在尝试对最近准备的 NY-Times 语料库进行文档去重。它包含与金融欺诈相关的数据。

首先,我将文章片段转换为 TaggedDocument 个对象的列表。

nlp = spacy.load("en_core_web_sm")

def create_tagged_doc(doc, nlp):        
    toks = nlp(doc)
    lemmatized_toks = [tok.lemma_ for tok in toks if not tok.is_stop]
    return lemmatized_toks

df_fraud = pd.read_csv('...local_path...')
df_fraud_list = df_fraud['snippet'].to_list()
documents = [TaggedDocument(create_tagged_doc(doc, nlp), [i]) for i, doc in enumerate(df_fraud_list)]

示例 TaggedDocument 如下所示:

TaggedDocument(words=['Chicago', 'woman', 'fall', 'mortgage', 'payment', 
'victim', 'common', 'fraud', 'know', 'equity', 'strip', '.'], tags=[1])

现在我编译并训练 Doc2Vec 模型。

cores = multiprocessing.cpu_count()
model_dbow = Doc2Vec(dm=0, vector_size=100, negative=5, hs=0, min_count=2, sample = 0, workers=cores)
model_dbow.build_vocab(documents)
model_dbow.train(documents, 
                total_examples=model_dbow.corpus_count, 
                epochs=model_dbow.epochs)

让我们定义余弦相似度:

cosine_sim = lambda x, y: np.inner(x, y) / (norm(x) * norm(y))

现在,问题是,如果我定义两个几乎相似的句子并计算它们的余弦相似度分数,它会变得非常低。例如

a = model_dbow.infer_vector(create_tagged_doc('That was a fradulent transaction.', nlp))
b = model_dbow.infer_vector(create_tagged_doc('That transaction was fradulant.', nlp))

print(cosine_sim(a, b)) # 0.07102317

为了确定,我重复检查了完全相同的向量,它是正确的。

a = model_dbow.infer_vector(create_tagged_doc('That was a fradulent transaction.', nlp))
b = model_dbow.infer_vector(create_tagged_doc('That was a fradulent transaction.', nlp))

print(cosine_sim(a, b)) # 0.9980062

这里出了什么问题?

看来是纪元数的问题。在不指定纪元数的情况下创建 Doc2Vec 实例时,例如model_dbow = Doc2Vec(dm=0, vector_size=100, negative=5, hs=0, min_count=2, sample = 0, workers=cores),默认设置为5。显然这对我的语料库来说还不够。我将 epochs 设置为 50,然后重新训练模型,瞧!成功了。

让我们看看您传递给 infer_vector() 的实际令牌:

In [4]: create_tagged_doc('That was a fradulent transaction.', nlp)                                                           
Out[4]: ['fradulent', 'transaction', '.']

In [5]: create_tagged_doc('That transaction was fradulant.', nlp)                                                             
Out[5]: ['transaction', 'fradulant', '.']

拼写错误 'fraudulant' 可能不在您的 NYT 语料库中,因此 Doc2Vec 模型可能不知道,因此会被忽略。所以你真的在计算文档向量:

['fradulent', 'transaction', '.'] 对比 ['transaction', '.']

此外,'.' 可能不是很重要 - 特别是如果它出现在 所有 训练示例中。请注意,微小的例子(一到几个词)没有很多微妙的对比影响来平衡——它们是直截了当的话语,可能与大部分训练数据不同,并且推理将相对较短且平衡最小影响(与较长的文本相比)。

例如,在单词和向量共同训练和比较的 Doc2Vec 模型中,如 PV-DM 模型 (dm=1),我不确定是否对于单个 -像 ['transaction'] 这样的单词文档,更有用的向量是对该标记列表的推断,或者只是 'transaction'.

的单词向量

最后,由于相似度的范围是 -1.01.00.07 可能 对于一个有效的['fradulent', 'transaction', '.']['transaction', '.'].

之间的比较