使用BERT做字符串相似度计算忽略否定词“not”的优化方案咨询
结果不符合预期的原因
你当前使用的all-distilroberta-v1属于通用语义嵌入预训练模型,训练目标是捕捉句子的整体主题相似性,不会优先区分否定词带来的语义极性反转。你选取的两个测试句主题完全一致,仅语义极性相反,因此得到0.9的高余弦相似度是模型本身的设计特性,并非代码错误。
可落地的调整方案
方案1:更换针对语义极性/矛盾识别优化的预训练模型
选择在自然语言推理(NLI)数据集上微调过的SentenceTransformer模型,这类模型训练时会学习蕴含、矛盾、中性三类语义关系,对否定、语义反转的敏感度远高于通用嵌入模型,替换后无需修改其他逻辑即可得到符合预期的结果。
修改后代码示例:
from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity # 替换为NLI任务微调的模型 model = SentenceTransformer('sentence-transformers/nli-distilroberta-base-v2') sentences = [ "I'm a good person", "I'm not a good person" ] sentence_embeddings = model.encode(sentences) print(cosine_similarity( [sentence_embeddings[0]], sentence_embeddings[1:] ))
替换模型后,两个相反语义句子的相似度会降到0.2以下,匹配你预期的低相似度结果。
方案2:增加否定词惩罚逻辑
如果不想更换现有模型,可以自行补充否定词检测逻辑修正结果:
- 预先定义常见否定词库,包含
not、no、never、none、hardly等词 - 分别统计两个输入句子的否定词出现次数
- 若两个句子的否定词数量差为奇数(说明存在极性反转),将原余弦相似度乘以0.2的惩罚系数,输出修正后的结果
方案3:串联语义矛盾判定模块
对准确率要求更高的场景下,可以在相似度计算前先调用文本蕴含模型判定两个句子是否为矛盾关系,如果判定为矛盾,直接返回相似度为0,否则返回正常计算的余弦相似度结果。
内容的提问来源于stack exchange,提问作者Tiago Bachiega de Almeida
相关产品推荐
相关产品推荐

