与BERT的字符串比较似乎忽略了句子中的"not"



我使用SentenceTransformers和BERT实现了一个字符串比较方法,如下所示

from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
model = SentenceTransformer('sentence-transformers/all-distilroberta-v1')
sentences = [
"I'm a good person",
"I'm not a good person"
]
sentence_embeddings = model.encode(sentences)
cosine_similarity(
[sentence_embeddings[0]],
sentence_embeddings[1:]
)

请注意,我的句子示例非常相似,但意义相反。问题是余弦相似度返回0.9,这表明这两个字符串在上下文中非常相似,当我期望它返回更接近于零的东西时,因为它们具有相反的含义。

我如何调整我的代码,以返回更准确的结果?

TL;DR: NLI是所有你需要的

首先,余弦相似度相当高,因为这两个句子在以下意义上相似:

  • 它们是关于相同的主题(一个人的评价)
  • 它们是关于相同的主题("我")和相同的属性("做一个好人")
  • 它们有相似的句法结构
  • 他们有几乎相同的词汇

因此,从形式的角度来看,它们应该被认为是相似的。此外,从实际的角度来看,它们通常应该被认为是相似的。例如,如果你在谷歌上搜索"转基因生物致癌",你可能会发现带有"转基因生物"标签的文本不是致癌的。相关。

第二,如果你想衡量句子之间的逻辑联系,余弦相似度嵌入只是不够表达。这是因为嵌入包含大量语义、文体、词汇和句法信息,但它们是固定大小的(在您的例子中是768维),因此它们不能包含关于两个句子含义的完整信息。因此您需要另一个具有以下属性的模型:

  1. 它同时编码两个文本,所以它比较文本本身,而不仅仅是固定大小的嵌入
  2. 它被明确地训练来评估句子之间的逻辑联系

评估文本之间逻辑联系的任务被称为自然语言推理(NLI),其最常见的表述是识别文本蕴涵(RTE):它是预测第一个句子是否包含第二个句子的问题。

在Huggingface代码库中有很多针对这个任务训练的模型,roberta-large-mnli就是一个很好的模型。你可以用它来评估两个文本的等价性。如果每个文本包含另一个文本,则它们是等效的,因此您可以估计等效程度为两个方向的蕴涵分数的乘积。

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained("roberta-large-mnli")
model = AutoModelForSequenceClassification.from_pretrained("roberta-large-mnli")
def test_entailment(text1, text2):
batch = tokenizer(text1, text2, return_tensors='pt').to(model.device)
with torch.no_grad():
proba = torch.softmax(model(**batch).logits, -1)
return proba.cpu().numpy()[0, model.config.label2id['ENTAILMENT']]
def test_equivalence(text1, text2):
return test_entailment(text1, text2) * test_entailment(text2, text1)
print(test_equivalence("I'm a good person", "I'm not a good person"))  # 2.0751484e-07
print(test_equivalence("I'm a good person", "You are a good person"))  # 0.49342492
print(test_equivalence("I'm a good person", "I'm not a bad person"))   # 0.94236994

结果并不令人惊讶。你的两个句子非常相似,但意思相反。句子嵌入是由在通用语料库上训练的模型得到的,因此,如果句子相似,通常期望模型给出的嵌入彼此接近。这就是发生的事情,余弦相似度表明嵌入是彼此接近的句子也是如此。例句中的句子可能有相反的意思,但它们彼此相似。

在这种情况下,如果你期望两个意义相反的相似句子彼此远离,那么你必须使用一种分类模型进一步微调模型(例如情感分析,如果你的例子是基于积极和消极的情绪)。或者其他相关的任务

没什么好惊讶的。这可能是一个基于单词的模型。如果你看这两个句子,除了not,它们是完全相似的。这就是人类的直觉依赖于语法的地方,而不是否定事实。然而,BERT和其他基于词包的模型并不是这样学习的。就像这里的其他答案一样,再训练可能会有所帮助,但底线是,如果你想让它现成地工作,你可能需要考虑一些包含语法的模型,比如基于量子自然语言处理的模型。

相关内容

  • 没有找到相关文章

最新更新