Skip to content

如何比较文本的相似度? ​

  • 标签:自然语言处理(NLP)、文本分类

🏛 业务架构师 ​

比较文本相似度的方法,我按"从经典到现代"的层次讲,并给业务选型:

1. 字面相似度(编辑距离、Jaccard):字符级差异或词集合重叠——快但无语义("退货"和"退款"Jaccard 可能是 0)。用途:去重、拼写纠错,不做语义匹配。

2. 词频统计向量(TF-IDF + 余弦):词加权后的向量夹角——比字面强一点,仍不理解同义。用途:长文档粗分类、规则检索兜底。

3. 词向量聚合(Word2Vec/GloVe 平均 + 余弦/欧氏):把词向量平均成句向量——有了基础语义,但"一词多义"和语序信息丢失。用途:轻量语义去重、推荐召回的粗排。

4. 上下文向量(BERT/句向量模型 + 余弦相似度):预训练模型输出句级向量——语义、语序、上下文都考虑到,"苹果手机坏了"和"iPhone 故障"能匹配上。当前语义匹配的主力。注意:要用句向量优化的模型(BGE、GTE 类),裸 BERT 的 [CLS] 向量做相似度效果差。

5. 交叉编码器(Cross-Encoder):两段文本拼一起进模型直接输出相似分——精度最高但每对都要跑一次模型(不能预计算),只适合精排小候选集——这就是 Rerank 的原理。

距离度量选择:文本语义普遍用余弦相似度(与 Embedding 训练目标匹配);欧氏距离在需要考虑"量级差异"时用。

我的选型决策:海量粗召回→句向量+余弦;小候选精排→Cross-Encoder;完全无关语义的场景(对账、查重)→编辑距离/规则。分层组合是标准打法。

🏗 系统架构师 ​

文本相似度方法我按精度-成本谱系排,生产选型看任务与量级:

词/字符级(轻量,粗筛):

  • 编辑距离(Levenshtein)、Jaccard(词集合交并比)——拼写纠错、精确去重,O(n²) 但 n 小;不适合语义("退款"与"退货"相似度为 0);
  • BM25/TF-IDF 余弦——词频统计的"词汇相似",关键词匹配场景(搜索粗排)依然主力。

向量语义级(主流):

  • 句/文档 embedding + 余弦相似度:语义相关的不同表述能匹配("怎么退货"≈"退款流程"),是 RAG、去重、聚类、推荐召回的标配。生产形态:双塔模型(query/doc 独立编码,可离线建索引,在线毫秒级)——注意归一化后余弦与欧氏等价,训练度量与检索度量要一致;
  • 交互式(Cross-Encoder):query+doc 拼接联合编码——精度最高但每对都要跑一次模型,只适合 Rerank 场景(Top 50 内精排)。

混合策略(生产标配):双塔召回(快、可扩到亿级)→ Cross-Encoder 精排(准、只处理几十条)——搜索推荐的经典漏斗,RAG 完全套用。

工程要点:语义相似 ≠ 相关(否定句"不支持退款"与"支持退款"向量很近—— Embedding 对否定、数字、实体不敏感,这类差异靠关键词层或结构化比对补);跨语言用多语 embedding;批量比对用矩阵运算 + GPU(百万级对几秒)。

选型口诀:精确匹配用编辑距离,词汇匹配用 BM25,语义匹配用双塔 + 余弦,精度敏感加 Cross-Encoder 精排。

💻 全栈开发专家 ​

文本相似度我分三个层次做,按需选:

1. 字面相似度(快,无语义):

  • 编辑距离(Levenshtein):拼写纠错、模糊匹配;
  • Jaccard(词集合交并比)、n-gram 重叠:查重、去重粗筛;
  • BM25/TF-IDF:关键词检索的相关性打分(ES 内置)。

2. 语义相似度(主力):Embedding + 余弦相似度:

python
from sklearn.metrics.pairwise import cosine_similarity
q = model.encode(["退货政策"])          # 归一化后的向量
d = model.encode(["售后退换货流程"])
sim = cosine_similarity(q, d)[0][0]    # 语义相近即使零字面重叠

选中文模型(bge-m3/Qwen3-Embedding),两边的文本必须同一模型编码。

3. 混合方案(生产标配):语义(召回广)+ BM25(精确词保底)+ Rerank(精排)——Cross-Encoder 把两段文本拼一起过模型,交互式打分,精度最高但每对都要跑一次(只用于小候选集)。

工程决策线:

  • 去重/纠错 → 编辑距离/Jaccard(毫秒级、可解释);
  • 搜索/推荐召回 → 向量余弦(ANN 索引支撑大规模);
  • 精排/高风险匹配 → Cross-Encoder rerank;
  • 别踩的坑:不同模型向量不可比(空间不同);余弦阈值要按模型校准(0.8 在 A 模型是高相似,B 模型可能只是中等);短文本相似度噪声大,加关键词/元数据条件过滤。