4. 相似度度量入门

在金融文本处理中,“相似”并不是一个单一概念。两份公告可能因为措辞几乎一致而相似,也可能因为共享大量关键词而相似,还可能因为向量方向一致而相似。若选错度量方法,去重结果就会出现漏判或误判。本节围绕四种最常用的相似度度量展开:编辑距离、Jaccard 相似度、余弦相似度和欧氏距离,重点讲清它们的计算逻辑、适用边界与金融场景中的取舍。

核心判断:相似度度量不是“哪个更高级就用哪个”,而是“文本以什么形态进入比较,就选与之匹配的度量”。字符序列比编辑距离,集合比 Jaccard,向量比余弦或欧氏。

一、核心原理:四种度量分别在“比什么”

编辑距离(Levenshtein Distance)衡量的是把一个字符串变成另一个字符串所需的最少单字符编辑次数,允许插入、删除、替换。它关注的是字符顺序和局部结构,因此对“字面几乎一样、只差几个字”的文本非常敏感。金融公告中常见的标题微调、日期替换、公司简称与全称混用,都适合先用编辑距离做粗筛。

Jaccard 相似度把文本看作词集合,计算两个集合的交集大小除以并集大小。它不关心词序,只关心“共同出现了哪些词”。当公告被改写、语序调整但关键词高度重合时,Jaccard 往往比编辑距离更稳健。其缺点是忽略词频,长文本中高频词会稀释区分度。

余弦相似度把文本表示为向量,计算两个向量夹角的余弦值。它关注方向而非长度,因此对文本长短不敏感,适合 TF-IDF、词向量或句向量场景。金融公告去重中,余弦相似度常用于“语义相近但表述不同”的判定。

欧氏距离计算两个向量端点之间的直线距离,关注绝对位置差异。它对向量长度敏感,适合特征已归一化、量纲一致的场景。若直接用于未归一化的词频向量,长文本会天然远离短文本,导致误判。

四种相似度度量的比较维度 编辑距离 比较对象:字符序列 敏感点:字序与拼写 输出:整数距离 优点:细粒度 缺点:怕改写 适用:标题、短句 近似重复检测 Jaccard 比较对象:词集合 敏感点:共现词汇 输出:0~1 比值 优点:抗语序调整 缺点:忽略词频 适用:关键词重合 短公告去重 余弦相似度 比较对象:向量方向 敏感点:语义分布 输出:-1~1 优点:抗长度差异 缺点:需向量化 适用:长文本语义 公告语义去重 欧氏距离 比较对象:向量位置 敏感点:绝对差异 输出:非负距离 优点:直观可解释 缺点:怕量纲不一 适用:归一化特征 聚类与分类

二、方法流程:从文本到相似度分数的四步链路

无论使用哪种度量,金融文本相似度计算通常遵循同一条链路:预处理、表示、度量、阈值判定。差别在于“表示”这一步决定了后续可用的度量集合。

  1. 预处理:去除 HTML 标签、页眉页脚、空白字符;对中文进行分词或按字切分;统一全半角、数字与日期格式。
  2. 文本表示:若保留字符序列,可直接算编辑距离;若转为词集合,可算 Jaccard;若转为 TF-IDF 或嵌入向量,可算余弦与欧氏。
  3. 计算相似度:按选定公式得到分数或距离,注意距离越小越相似,相似度越大越相似。
  4. 阈值判定:结合业务设定阈值,例如余弦相似度大于 0.92 判为重复,编辑距离小于 3 判为近似标题。
from difflib import SequenceMatcher
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import jieba

def edit_ratio(a, b):
    return SequenceMatcher(None, a, b).ratio()

def jaccard(a, b):
    sa, sb = set(jieba.lcut(a)), set(jieba.lcut(b))
    return len(sa & sb) / len(sa | sb)

def cosine_tfidf(texts):
    vec = TfidfVectorizer(tokenizer=jieba.lcut)
    mat = vec.fit_transform(texts)
    return cosine_similarity(mat)

t1 = "关于召开2024年第一次临时股东大会的通知"
t2 = "关于召开2024年度第一次临时股东大会的公告"
print("编辑距离相似度:", round(edit_ratio(t1, t2), 3))
print("Jaccard:", round(jaccard(t1, t2), 3))
print("余弦:", round(cosine_tfidf([t1, t2])[0][1], 3))

三、案例与场景:金融公告去重中的选择策略

假设某券商每天需要处理上千份公告,去重目标分为三层:标题级近似重复、正文级关键词重复、语义级改写重复。不同层级应使用不同度量。

场景推荐度量理由典型阈值
公告标题微调检测编辑距离标题短、字面差异小,字符级敏感度高距离 ≤ 3 或相似度 ≥ 0.9
短公告关键词去重Jaccard语序可变,关键词集合稳定≥ 0.75
长公告语义去重余弦相似度文本长、表述多样,需方向比较≥ 0.90
公告聚类与分类欧氏距离特征归一化后,距离可直接用于 KMeans按业务调参

组合策略:实际工程中很少只用一种度量。常见做法是先用 Jaccard 或编辑距离做快速粗筛,再用余弦相似度对候选集精排,最后人工复核边界样本。这样兼顾速度与准确率。

四、误区与复盘:四个最容易踩的坑

  • 误区一:用欧氏距离比较未归一化的词频向量。长公告的词频向量模长天然更大,距离被长度主导,导致相似公告被判为不相似。应先做 L2 归一化或改用余弦。
  • 误区二:用编辑距离比较长文本。长文本中任意插入一段话都会显著拉大距离,但语义可能完全一致。编辑距离更适合短文本或标题。
  • 误区三:Jaccard 忽略词频。“重大”“关于”“公告”等高频词会抬高 Jaccard,造成误判。应结合停用词表和 TF-IDF 权重。
  • 误区四:阈值一刀切。不同公告类型、不同长度分布的最优阈值不同。应分场景统计正负样本分布,再确定阈值。

复盘要点:相似度度量的选择本质是“文本表示”与“业务目标”的匹配问题。先明确你要抓的是字面重复、关键词重复还是语义重复,再决定用哪种度量。任何度量都只是工具,阈值和组合策略才是去重效果的关键。

掌握这四种度量后,你已具备金融文本去重的基础判断力。下一步需要做的,是把它们嵌入到完整的去重流水线中,结合分词、向量化和阈值调优,形成可落地的公告去重方案。