【数据挖掘01】相似度算法大全(万字讲解)
一.文本相似度算法
主要用于字符串、段落、文档之间的相似度计算。
1.基于编辑距离
1.1 Levenshtein Distance(编辑距离)
定义
莱文斯坦distance距离 英 /ˈlevənʃtaɪn ˈdɪstəns/
用来衡量两个字符串之间有多像:通过计算把字符串 A 变成字符串 B,最少需要多少次基本编辑操作()
| 操作 | 含义 | 示例 |
|---|---|---|
| 插入 Insert | 插入一个字符 | cat → cart,插入 r |
| 删除 Delete | 删除一个字符 | cart → cat,删除 r |
| 替换 Replace | 替换一个字符 | cat → cut,a 替换成 u |
它的核心思想是:
把一个字符串变成另一个字符串,需要的最少增删改次数。
它的动态规划定义是:
dp[i][j] = word1 前 i 个字符变成 word2 前 j 个字符的最少操作数
转换为相似度
编辑距离越小,两个字符串越相似,但是原始距离不方便直接比较不同长度的字符串
例如:
"cat" 和 "cut" 距离是 1 "internationalization" 和 "internationalisation" 距离也是 1二者距离都是 1,但相似程度并不完全一样。
通常可以先进行归一化(一般使用最大长度归一化相似度,把编辑距离映射到0-1之间)
s i m i l a r i t y = 1 − d i s t a n c e max ( l e n ( s 1 ) , l e n ( s 2 ) ) similarity = 1 - \frac{distance}{\max(len(s_1),len(s_2))} similarity=1−max(len(s1),len(s2))distance
- 距离越大,相似度越低
- 距离为0完全相同,距离为最长串长度,相似度为0
例如:
cat 和 cut distance = 1 max_len = 3 similarity = 1 - 1/3 = 0.667 internationalization 和 internationalisation distance = 1 max_len = 20 similarity = 1 - 1/20 = 0.95
常见优化
在计算编辑距离前,通常先处理
- 大小写统一
- 去除首尾空格
- 去除特殊符号
- 全角半角转换
- 繁简转换
- 中文数字归一化
- 停用词处理
例如:
"IPhone-15 Pro Max" "iphone 15 pro max"标准化后:
iphone15promax iphone15promax编辑距离更可靠。
应用场景
-
拼写纠错
这是最经典的应用之一。
例如用户输入:
appel词典里有:
apple apply ape计算编辑距离:
appel → apple 距离 2 appel → apply 距离 2 appel → ape 距离 3系统可以推荐:
apple尤其适合处理:
少打一个字母 多打一个字母 字母打错例如:
recieve → receive definately → definitely googel → google原因是这些错误通常可以通过少量增删改修正。
-
搜索建议与模糊匹配
用户在搜索框输入:
iphnoe商品库里有:
iphone ipad phone caseiphnoe和iphone的编辑距离较小,因此可以猜测用户想搜的是:iphone适合场景:
站内搜索 商品搜索 联系人搜索 地址搜索 文件名搜索原因是这些场景中,用户输入经常会有小错别字。
-
DNA / 生物序列比对的简单场景:原因是DNA序列可以看错字符串,但在严肃的生物信息学场景里,通常会使用更复杂的算法,比如 Needleman-Wunsch、Smith-Waterman 等,因为它们支持更精细的 gap penalty 和匹配评分。
-
OCR 或 ASR 结果评估
OCR 是图片文字识别,ASR 是语音识别。
例如真实文本是:
hello world识别结果是:
helo world编辑距离为 1,因为少了一个
l。在语音识别中,常见指标 WER,即 Word Error Rate,也和编辑距离思想密切相关,只不过单位从字符变成了词。
适合原因:
识别系统的错误通常表现为漏字、错字、多字。 -
数据清洗与去重
比如数据库里有两条客户名称:
Alibaba Group Alibabba Group编辑距离很小,可能是录入错误。
再如:
Tencent Holdings Tencnet Holdings也可能是同一实体。
适合用来发现:
重复用户 重复公司名 重复地址 拼写不一致的字段但通常不应该单独依赖编辑距离做最终判断,而应该结合其他字段,例如手机号、邮箱、地址、统一社会信用代码等。
不适合场景
- 不适合判断语义相似度(又可能两个词语义很接近,但编辑距离很大。),Levenshtein 关注“字面像不像”,不关注“意思像不像”。
- 不适合长文本相似度比较(长文本中稍微调整段落顺序,编辑距离可能会很大,但文章内容其实很相似。)Levenshtein 对顺序非常敏感,不理解段落结构和语义结构。
- 不适合处理词序变化
- 不适合处理拼音、同音字、中文语义近似
1.2 Damerau–Levenshtein Distance
定义
达梅罗 - 莱文斯坦距离 英 /ˈdæmərəʊ ˈlevənʃtaɪn ˈdɪstəns/
Damerau–Levenshtein Distance 是 Levenshtein Distance 的扩展版本。
Levenshtein Distance 支持三种操作:
| 操作 | 含义 |
|---|---|
| 插入 | 插入一个字符 |
| 删除 | 删除一个字符 |
| 替换 | 将一个字符替换成另一个字符 |
而 Damerau–Levenshtein Distance 在此基础上增加了第四种操作:
| 新增操作 | 含义 |
|---|---|
| 交换相邻字符 | 将两个相邻字符的位置互换 |
也就是说,它计算的是:
将字符串 A 转换成字符串 B 所需要的最少编辑次数,其中允许插入、删除、替换、交换相邻字符。
核心思想仍然使用动态规划
定义:
dp[i][j]
表示:
将字符串
s1的前i个字符转换成字符串s2的前j个字符所需要的最少操作数。
与 Levenshtein Distance 相同,它需要考虑:
删除
插入
替换
同时额外考虑:
相邻字符交换
转换为相似度
Damerau–Levenshtein Distance 是距离,值越小越相似。
为了更方便比较,可以转成相似度:
similarity = 1 - distance / max(len(s1), len(s2))
例如:
s1 = "form"
s2 = "from"
distance = 1
max_len = 4
similarity = 1 - 1 / 4 = 0.75
应用场景
Damerau–Levenshtein 仍然是字符级算法,只判断字符编辑成本,不理解语义,应用场景与Levenshtein 一致
Damerau–Levenshtein Distance 适合解决“字符写得像不像,尤其是不是相邻字符写反了”的问题,不适合解决“语义是不是一样”的问题。
1.3 Hamming Distance
定义
汉明距离,英 /ˈhæmɪŋ ˈdɪstəns/
Hamming Distance,汉明距离,用于衡量两个等长字符串之间的差异。(必须等长)
它的定义是:
对两个长度相同的字符串,逐位比较,统计对应位置上字符不同的个数。
例如:
1011101
1001001
逐位比较:
| 位置 | 字符串 A | 字符串 B | 是否不同 |
|---|---|---|---|
| 1 | 1 | 1 | 否 |
| 2 | 0 | 0 | 否 |
| 3 | 1 | 0 | 是 |
| 4 | 1 | 1 | 否 |
| 5 | 1 | 0 | 是 |
| 6 | 0 | 0 | 否 |
| 7 | 1 | 1 | 否 |
不同的位置有 2 个。
所以:
Hamming Distance = 2
| 特点 | 说明 |
|---|---|
| 只能比较等长字符串 | 两个字符串长度必须一致 |
| 按位置逐个比较 | 不考虑插入、删除、错位 |
| 结果是不同位置的数量 | 距离越小,越相似 |
转换为相似度
Hamming Distance 转相似度最常用公式是:
s i m i l a r i t y = 1 − H a m m i n g D i s t a n c e / n similarity = 1 - HammingDistance / n similarity=1−HammingDistance/n
其中:n = 字符串长度
因为 Hamming Distance 越小越相似,所以用 1 - 差异比例 得到相似度
例子
两个等长字符串:
s1 = 10101 s2 = 11100逐位比较:
10101 11100不同位置有 2 个,所以:
HammingDistance = 2 n = 5相似度:
similarity = 1 - 2 / 5 = 0.6也就是:
相似度 = 60%
应用场景
-
固定长度编码比较
固定长度编码中,每一位通常都有明确含义。Hamming Distance 可以快速统计有多少位置不同。
示例:
编码 A:A101X9 编码 B:A101Y9只有第 5 位不同。
Hamming Distance = 1适用于:
状态码 错误码 设备编码 固定长度标签 基因编码 二进制编码 -
二进制向量比较:二进制向量中,每一位通常表示一个特征是否存在。
例如用户画像:
用户 A:101101 用户 B:100111每一位表示某个兴趣标签:
位 含义 1 喜欢数码 2 喜欢运动 3 喜欢美妆 4 喜欢游戏 5 喜欢汽车 6 喜欢旅游 逐位比较:
101101 100111不同位有 2 个。
说明两个用户在 2 个标签上不同。
-
哈希指纹比较
很多哈希或指纹算法会生成固定长度的二进制串。比较两个指纹的差异时,可以用 Hamming Distance。
例如图片相似度中的感知哈希:
image_hash_A = 110101101001 image_hash_B = 110101001001Hamming Distance 越小,图片越相似。
常见场景:
图片去重 音频指纹 视频帧相似度 SimHash 文本去重 恶意样本指纹比较示例:
图片 A hash 图片 B hash Hamming 距离 判断 110101101001 110101001001 1 非常相似 110101101001 001010010110 12 差异很大 -
通信错误检测
-
纠错码
-
等长 DNA 片段差异统计
-
固定长度 OCR 候选比较
不适合
- 长度不同的字符串
- 存在插入、删除、错位的文本
- 拼写纠错中的复杂错误
- 语义相似度判断
- 长文本相似度
- 公司名、商品名、人名等非固定格式文本匹配
- 业务主键的相似合并
1.4 Jaro Distance
定义
英 /ˈjɑːrəʊ ˈdɪstəns/,雅罗距离
Jaro Distance 也是一种用于衡量两个字符串相似程度的算法,常用于短字符串模糊匹配。
它最早常用于姓名匹配、记录链接、实体去重等任务。
严格来说,很多资料中会同时提到:
Jaro Similarity
Jaro Distance
二者关系通常是:
Jaro Distance = 1 - Jaro Similarity
也就是说:
| 指标 | 含义 | 值越大表示 |
|---|---|---|
| Jaro Similarity | 相似度 | 越相似 |
| Jaro Distance | 距离 | 越不相似 |
在实际业务中,我们更常用的是 Jaro Similarity,因为它的结果在 0 ~ 1 之间,越接近 1 表示越相似。
Levenshtein、Damerau-Levenshtein、Hamming 等方法主要关注“编辑成本”。
而 Jaro 更关注:
两个字符串中有多少字符能够在相近位置上匹配,以及匹配字符的顺序是否一致。
它特别适合处理这类情况:
MARTHA
MARHTA
这两个字符串中字符基本相同,只是 T 和 H 的位置发生了轻微交换。
Jaro 会认为它们非常相似。
计算相似度
Jaro Similarity 主要考虑三个因素:
| 因素 | 含义 |
|---|---|
| 匹配字符数 m | 两个字符串中有多少字符可以匹配 |
| 字符位置 | 字符必须在一定范围内才算匹配 |
| 转置数 t | 匹配字符的相对顺序有多少不一致 |
J a r o ( s 1 , s 2 ) = 1 / 3 × ( m / l e n ( s 1 ) + m / l e n ( s 2 ) + ( m − t ) / m ) Jaro(s1, s2) = 1/3 × (m / len(s1) + m / len(s2) + (m - t) / m) Jaro(s1,s2)=1/3×(m/len(s1)+m/len(s2)+(m−t)/m)
m如何计算?
Jaro 并不是只看同一位置字符是否相等,而是允许字符在一定窗口范围内匹配。
匹配窗口大小为:
m a t c h d i s t a n c e = f l o o r ( m a x ( l e n ( s 1 ) , l e n ( s 2 ) ) / 2 ) − 1 match_distance = floor(max(len(s1), len(s2)) / 2) - 1 matchdistance=floor(max(len(s1),len(s2))/2)−1
这里的floor是向上取整
也就是说,字符串 s1 中的某个字符 s1[i],可以和 s2 中位置范围内的字符匹配:
[ i − m a t c h d i s t a n c e , i + m a t c h d i s t a n c e ] [i - match_distance, i + match_distance] [i−matchdistance,i+matchdistance]
只要字符相同,并且对方字符还没有被匹配过,就算一个匹配字符。
s1 = MARTHA s2 = MARHTA两个字符串长度都是 6。
匹配窗口:
match_distance = floor(6 / 2) - 1 = 2这表示每个字符可以在当前位置前后 2 个位置内寻找匹配。
逐字符观察:
s1 位置 s1 字符 s2 可匹配范围 是否匹配 0 M 0~2 匹配 M 1 A 0~3 匹配 A 2 R 0~4 匹配 R 3 T 1~5 匹配 T 4 H 2~5 匹配 H 5 A 3~5 匹配 A 所以:
m = 6两个字符串的所有字符都匹配上了。
转置数t如何计算
匹配字符找出来以后,分别按它们在原字符串中的顺序排列。
对于:
s1 = MARTHA
s2 = MARHTA
匹配字符序列分别是:
s1 匹配序列:M A R T H A
s2 匹配序列:M A R H T A
逐位比较:
| 位置 | s1 匹配字符 | s2 匹配字符 | 是否不同 |
|---|---|---|---|
| 1 | M | M | 否 |
| 2 | A | A | 否 |
| 3 | R | R | 否 |
| 4 | T | H | 是 |
| 5 | H | T | 是 |
| 6 | A | A | 否 |
不同位置有 2 个。
Jaro 中的转置数通常定义为:
t = 不同位置数量 / 2
所以:
t = 2 / 2 = 1
仍然使用:
s1 = MARTHA s2 = MARHTA已知:
len(s1) = 6 len(s2) = 6 m = 6 t = 1代入公式:
Jaro = 1/3 × (m / len(s1) + m / len(s2) + (m - t) / m)即:
Jaro = 1/3 × (6/6 + 6/6 + (6-1)/6) Jaro = 1/3 × (1 + 1 + 5/6) Jaro = 1/3 × 2.8333 Jaro ≈ 0.9444所以:
Jaro Similarity("MARTHA", "MARHTA") ≈ 0.9444对应的 Jaro Distance:
Jaro Distance = 1 - 0.9444 = 0.0556
结果解释
| Jaro Similarity | 解释 |
|---|---|
| 1.0 | 完全相同 |
| 0.9 ~ 1.0 | 高度相似 |
| 0.8 ~ 0.9 | 较相似 |
| 0.7 ~ 0.8 | 有一定相似性 |
| 0.5 ~ 0.7 | 相似性较弱 |
| 0 ~ 0.5 | 差异较大 |
应用场景
Jaro Distance / Jaro Similarity 适合衡量“短字符串中字符是否大体相同,并且位置是否接近”,尤其适合姓名、字段名、公司名等模糊匹配;不适合语义相似、长文本匹配、跨语言匹配和强唯一标识字段的同一性判断。
1.5 Jaro–Winkler Distance
定义
雅罗 - 温克勒距离 英 /ˈjɑːrəʊ ˈwɪŋklə ˈdɪstəns/
Jaro–Winkler Similarity 是在 Jaro Similarity 基础上的增强版本。
它的核心思想是:
如果两个字符串开头部分相同,那么它们更可能是相似字符串,因此给相同前缀额外加分。
所以,Jaro–Winkler 特别适合:
姓名匹配
人名去重
公司名匹配
短字符串模糊匹配
拼写纠错
记录链接
严格来说:
| 名称 | 含义 | 越大表示 |
|---|---|---|
| Jaro–Winkler Similarity | 相似度 | 越相似 |
| Jaro–Winkler Distance | 距离 | 越不相似 |
二者关系通常是:
Jaro–Winkler Distance = 1 - Jaro–Winkler Similarity
Jaro 主要考虑:
匹配字符数量
字符位置是否接近
匹配字符顺序是否一致
Jaro–Winkler 在 Jaro 基础上额外考虑:
两个字符串开头是否相同
例如:
MARTHA
MARHTA
这两个字符串前缀都是:
MAR
所以 Jaro–Winkler 会认为它们比普通 Jaro 计算出的结果还要更相似。
计算相似度
aro–Winkler 的计算分两步:
第一步:计算 Jaro Similarity
第二步:根据公共前缀长度,对 Jaro Similarity 加权提升
公式为:
J W = J a r o + l × p × ( 1 − J a r o ) JW = Jaro + l × p × (1 - Jaro) JW=Jaro+l×p×(1−Jaro)
| 符号 | 含义 |
|---|---|
JW |
Jaro–Winkler Similarity |
Jaro |
Jaro Similarity |
l |
两个字符串共同前缀长度,通常最多取 4 |
p |
前缀缩放因子,通常取 0.1 |
p 是前缀奖励系数,通常取:
p = 0.1
它控制前缀奖励的强度。
如果 p 太大,前缀相同会被过度放大,容易误判。
常见约束是:
p ≤ 0.25
因为 l 通常最多为 4,保证:
l × p ≤ 1
避免相似度超过合理范围。
Jaro–Winkler Distance 是在 Jaro 的基础上加入“公共前缀奖励”的字符串距离算法,特别适合姓名、公司名、字段名等短字符串模糊匹配;但不适合语义相似、长文本匹配、跨语言匹配,以及订单号、SKU、身份证号等大量共享前缀的强唯一标识字段。
2.基于字符/词集合
2.1 Jaccard Similarity
集合交集 / 并集的比例。
Jaccard Similarity,中文常叫 Jaccard 相似度 / 杰卡德相似系数,用于衡量两个集合之间的相似程度。
它的核心思想是:
两个集合越多元素相同,它们越相似;共同元素占总体元素的比例越高,相似度越高。
J a c c a r d ( A , B ) = ∣ A ∩ B ∣ / ∣ A ∪ B ∣ Jaccard(A, B) = |A ∩ B| / |A ∪ B| Jaccard(A,B)=∣A∩B∣/∣A∪B∣
accard 不关心元素出现顺序,也不关心元素出现次数。
它只关心:
两个集合有多少共同元素
两个集合总共有多少不同元素
因此它适合处理:
标签集合
词集合
商品集合
用户行为集合
权限集合
兴趣集合
不适合直接处理:
字符顺序
文本语义
词频权重
句子结构
长文本深层语义
Jaccard 不关心顺序,适合词集合相似;Levenshtein 关心字符顺序,适合拼写纠错。
文本场景中,建议去除:
停用词
标点
空白
无意义高频词
HTML 标签
特殊符号
例如:
的、了、和、是、在
否则这些高频词会虚高相似度。
应用场景
适合选择 Jaccard 的情况:
对象可以自然表示为集合
元素顺序不重要
只关心是否共同出现
希望结果简单可解释
需要快速做候选召回
例如:
用户标签相似
商品标签相似
文章关键词重合
权限集合比较
购买商品集合比较
浏览行为集合比较
不建议选择 Jaccard 的情况:
字符顺序很重要
语义理解很重要
元素出现次数很重要
输入存在大量拼写错误
字段是订单号、身份证号等强唯一标识
2.2 Cosine Similarity
定义
Cosine Similarity,余弦相似度,用于衡量两个向量方向是否相似。
它的核心思想是:
两个向量夹角越小,方向越接近,相似度越高;夹角越大,方向越不同,相似度越低。
向量夹角的余弦值。
c o s i n e s i m i l a r i t y ( A , B ) = A ⋅ B / ( ∣ ∣ A ∣ ∣ × ∣ ∣ B ∣ ∣ ) cosine_similarity(A, B) = A · B / (||A|| × ||B||) cosinesimilarity(A,B)=A⋅B/(∣∣A∣∣×∣∣B∣∣)
假设有两个句子:
文本 A:机器学习 数据挖掘 算法 文本 B:机器学习 数据挖掘 模型构造词表:
[机器学习, 数据挖掘, 算法, 模型]转成词频向量:
词 文本 A 文本 B 机器学习 1 1 数据挖掘 1 1 算法 1 0 模型 0 1 所以:
A = [1, 1, 1, 0] B = [1, 1, 0, 1]点积:
A · B = 1×1 + 1×1 + 1×0 + 0×1 = 2向量长度:
||A|| = sqrt(1² + 1² + 1² + 0²) = sqrt(3) ||B|| = sqrt(1² + 1² + 0² + 1²) = sqrt(3)余弦相似度:
cosine = 2 / (sqrt(3) × sqrt(3)) = 2 / 3 ≈ 0.6667说明两个文本有一定相似度。
核心特点:只关注方向,不关注长度
应用场景
适合高维稀疏向量
文本向量通常非常高维,例如词表有10万个词。但是一篇文章中只出现其中几百个词汇,所以向量大部分位置是0,余弦相似度很适合这种高维稀疏向量
可以结合TF-IDF使用
TF-IDF核心思想:一个词在某篇文章中出现次数越多,他越重要;但如果这个词在很多文章中都出现,他的区分度就很低
文本中有些词出现频率高但区分度低,例如:
的、了、是、and、the、of如果只用词频,这些词会影响相似度。
TF-IDF 可以降低常见词权重,提高关键词权重。
常见组合:
TF-IDF + Cosine Similarity这是传统文本检索、文档相似度中的经典方法。
-
文档相似度识别:文档可以表示为词频向量、TF-IDF向量或者语义向量
-
TF-IDF 文本检索
非常适合。
经典流程:
文本集合 ↓ 分词 ↓ 构建词表 ↓ 计算 TF-IDF 向量 ↓ 计算查询与文档的 Cosine Similarity ↓ 排序返回结果示例:
查询:机器学习 算法 文档 A:机器学习常用算法包括决策树和随机森林 文档 B:今天东京天气晴朗文档 A 和查询的 Cosine Similarity 会明显高于文档 B。
-
推荐系统:可用于相似用户/商品推荐、用户画像匹配等等
-
聚类和近邻搜索:在高维向量空间中,可以使用余弦相似度算法做KNN最近邻搜索、文本聚类、用户聚类、商品聚类、向量数据库检索
Cosine Similarity 适合解决“两个对象的向量方向是否相似”的问题,尤其适合文本向量、TF-IDF、Embedding、用户画像和推荐系统;但它不适合直接解决短字符串拼写纠错、字符编辑解释、强唯一标识匹配,以及需要比较绝对规模差异的问题。
2.3 Overlap Coefficient
欧沃莱普 扣伊菲申特 重叠系数 英 /ˌəʊvəˈlæp ˌkəʊɪˈfɪʃnt/
用于衡量两个集合之间的包含或重叠程度
O v e r l a p ( A , B ) = ∣ A ∩ B ∣ / m i n ( ∣ A ∣ , ∣ B ∣ ) Overlap(A, B) = |A ∩ B| / min(|A|, |B|) Overlap(A,B)=∣A∩B∣/min(∣A∣,∣B∣)
| 值 | 含义 |
|---|---|
| 1 | 较小集合完全被较大集合包含 |
| 0 | 两个集合没有任何交集 |
| 越接近 1 | 两个集合重叠程度越高 |
Overlap Coefficient 衡量的是:较小集合有多大比例被较大集合覆盖。不要求两个集合大小接近,更关心的是小集合是否包含在大集合中
所以它非常适合处理
- 查询词与文档关键词匹配
- 短文本与长文本匹配
- 用户少量兴趣与商品标签匹配
- 权限子集判断
- 技能要求覆盖判断
例如用户搜索:
查询 = {机器学习, 算法}文档标题:
文档 = {机器学习, 算法, 特征工程, 模型训练, 数据挖掘}查询词都在文档里,Overlap 为 1。
这对搜索召回很有用。
适合选择 Overlap 的情况:
你关心的是包含关系
较小集合被较大集合覆盖很重要
一个对象明显比另一个对象短
查询词、必备技能、核心标签需要被覆盖
希望指标简单可解释
例如:
查询词是否被文档覆盖
岗位技能是否被候选人技能覆盖
用户兴趣是否被商品标签覆盖
权限集合是否被另一个权限集合包含
短文本是否被长文本覆盖
不建议选择 Overlap 的情况:
你关心两个集合整体是否相似
较小集合非常小
元素频率和权重很重要
需要语义理解
需要字符顺序或拼写纠错
字段是订单号、身份证号等唯一标识
Overlap Coefficient 适合解决“较小集合是否被较大集合覆盖”的问题,尤其适合短查询匹配长文档、标签覆盖、技能覆盖、权限包含等场景;但它不适合单独判断两个集合整体是否相似,也容易在小集合过小时产生虚高相似度。
2.4 Dice Coefficient/Sørensen–Dice Index
戴斯 扣伊菲申特
索伦森 - 戴斯 因戴克斯
Dice Coefficient,也叫 Sørensen–Dice Index,中文常称为 Dice 系数 或 Dice 相似系数。
它用于衡量两个集合之间的相似程度。
D i c e ( A , B ) = 2 × ∣ A ∩ B ∣ / ( ∣ A ∣ + ∣ B ∣ ) Dice(A, B) = 2 × |A ∩ B| / (|A| + |B|) Dice(A,B)=2×∣A∩B∣/(∣A∣+∣B∣)
乘 2 的原因是:
交集元素同时属于 A 和 B,等于在两个集合中都贡献了一次,因此用
2 × 交集表示共同部分在两个集合中的双向重合程度。
适合选择 Dice 的情况:
对象可以表示为集合
关心两个集合的共同元素比例
希望比 Jaccard 稍微宽松一些
短文本可以切成 n-gram
标签、权限、技能、商品集合需要比较
需要简单、快速、可解释的相似度
不建议选择 Dice 的情况:
你需要语义理解
你需要精确编辑路径
你需要考虑词频或权重但又只用普通 Dice
文本顺序会改变含义
字段是订单号、身份证号等强唯一标识
Dice Coefficient 适合解决“两个集合或文本片段有多少共同元素”的问题,比 Jaccard 更偏向奖励交集,常用于标签相似、短文本 n-gram 相似、文档近重复和图像分割评估;但它不理解语义、不考虑标准词频,也不适合强唯一标识字段或需要精确编辑解释的场景。
3.基于向量化文本
3.1 TF-IDF + Cosine Similarity
经典文本相似度计算方法,核心思想是:先用TF-IDF吧文本转换为向量,再用余弦相似度算法计算两个文本向量的相似程度
TF-IDF作用
在文本中·,有些词出现次数很多,但并不重要
如中文文本中的:
的、了、是、在、和、一个、我们
英文文本中的:
the, is, of, and, to, in
这些词出现频率很高,但区分文本主题的能力很弱。
TF-IDF作用:降低常见词的权重,提高能区分文本主题的关键词权重
TF-IDF 组成
TF-IDF由两部分组成
TF - IDF = TF × IDF
其中
| 指标 | 全称 | 含义 |
|---|---|---|
| TF | Term Frequency 词频 | 某个词在当前文档中出现得多不多 |
| IDF | Inverse Document Frequency 逆文档频率 | 某个词在所有文档中稀不稀有 |
一个词若是在当前文档中出现次数多,并且在其他文档中出现次数少,那么他对当前文档越重要
T F ( t , d ) = 词 t 在文档 d 中出现次数 / 文档 d 的总词数 TF(t, d) = 词 t 在文档 d 中出现次数 / 文档 d 的总词数 TF(t,d)=词t在文档d中出现次数/文档d的总词数
I D F ( t ) = l o g ( N / D F ( t ) ) IDF(t) = log(N / DF(t)) IDF(t)=log(N/DF(t))
- N:总文档数
- DF(t):包含词t的文档数量
实际工程中,为了避免除零或极端值,常使用平滑公式:
I D F ( t ) = l o g ( ( N + 1 ) / ( D F ( t ) + 1 ) ) + 1 IDF(t) = log((N + 1) / (DF(t) + 1)) + 1 IDF(t)=log((N+1)/(DF(t)+1))+1
这样即使某个词只出现很少,也不会导致权重过于极端。
完整流程
原始文本
↓
文本清洗
↓
分词
↓
去停用词
↓
构建词表
↓
计算 TF
↓
计算 IDF
↓
得到 TF-IDF 向量
↓
计算 Cosine Similarity
↓
得到文本相似度
实践建议:文本预处理很重要
大小写统一
全角半角统一
繁简转换
去 HTML 标签
去标点
去停用词
分词
词形还原
同义词归一
数字归一
单位归一
可以使得相似度更稳定
应用场景
更适用于:
文档相似度
关键词搜索
文章推荐
文本聚类
文本去重
FAQ 关键词召回
商品标题匹配
简历和岗位初筛
中长文本主题相似
原因:
TF-IDF 能突出关键词
Cosine 能比较向量方向
方法简单、快速、可解释
无需标注数据
适合高维稀疏文本向量
不适合:
短字符串拼写纠错
强语义相似但词面不同
同义词、缩写、别名匹配
跨语言匹配
否定和逻辑关系判断
订单号、身份证号等唯一标识匹配
非常短的文本直接匹配
原因:
TF-IDF 主要依赖词面重合
不理解深层语义
不自动识别同义词
不适合字符编辑错误
不适合强业务主键
TF-IDF + Cosine Similarity 是经典的关键词权重相似度方法,适合文本检索、文档相似、文章去重、内容推荐和文本聚类;它的优势是简单、快速、可解释,但它主要依赖词面重合,不适合深层语义理解、短字符串拼写纠错、同义词别名匹配和强唯一标识字段匹配
3.2 BM25
定义
BM25 可以看作 TF-IDF 的增强版本。
BM25是信息检索领域非常经典的文本相关性排序算法,常用于搜索引擎、站内搜索、文档检索、问答召回等场景,用来衡量
一个文档和一个查询词之间有多相关
更关心:当用户输入一个查询时,那些文档应该排在前面
核心思想
BM25 可以理解为 TF-IDF 的改进版。
它综合考虑三个因素:
1. 查询词是否出现在文档中
2. 查询词在文档中出现了多少次
3. 查询词是否足够稀有
4. 文档长度是否过长
其中最重要的是:
| 因素 | 含义 |
|---|---|
| TF | 查询词在文档中出现的频率 |
| IDF | 查询词在整个语料库中的稀有程度 |
| 文档长度归一化 | 避免长文档天然占便宜 |
S c o r e ( D , Q ) ≡ ∑ q i ∈ Q I D F ( q i ) ⋅ f ( q i , D ) ⋅ ( k 1 + 1 ) f ( q i , D ) + k 1 ⋅ ( 1 − b + b ⋅ ∣ D ∣ a v g d l ) Score(D, Q) \equiv \sum_{q_i \in Q} IDF(q_i) \cdot \frac{f(q_i, D) \cdot (k_1 + 1)}{f(q_i, D) + k_1 \cdot \left(1 - b + b \cdot \frac{|D|}{avgdl}\right)} Score(D,Q)≡qi∈Q∑IDF(qi)⋅f(qi,D)+k1⋅(1−b+b⋅avgdl∣D∣)f(qi,D)⋅(k1+1)
- Q:查询文本
- D:某篇文档
- qi:查询中的第 i 个词
- f(qi,D):查询词qi在文档D中出现的次数
- avgdl:所有文档的平均长度
- k1:控制词频饱和程度
- b:控制文档长度归一化程度
- IDF(qi):查询词的重要性权重
在普通 TF-IDF 中,一个词出现越多,TF 越高。
但是 BM25 认为:
一个词出现次数增加,相关性会上升,但不会无限上升。
例如用户搜索:
机器学习
两篇文档:
文档 A:机器学习 是 人工智能 的重要方向
文档 B:机器学习 机器学习 机器学习 机器学习 机器学习
如果只看词频,B 会非常高。
但实际上,B 不一定更有价值,甚至可能是关键词堆砌。
所以 BM25 引入了 词频饱和机制。
词频饱和机制
f ⋅ ( k 1 + 1 ) f + k 1 \frac{f \cdot (k_1 + 1)}{f + k_1} f+k1f⋅(k1+1)
假设 k1=1.5:
| 词频 f | BM25 词频贡献 |
|---|---|
| 1 | 1.00 |
| 2 | 1.43 |
| 3 | 1.67 |
| 5 | 1.92 |
| 10 | 2.17 |
| 100 | 2.46 |
可以看到:
从 1 次到 2 次,提升明显
从 10 次到 100 次,提升很小
这就是 BM25 的优势:
它不会让重复堆砌关键词的文档无限加分。
文档长度归一化
搜索排序中,长文档有一个天然问题:
文档越长,包含用户查询词的概率越高。
例如:
文档 A:短文,只有 100 个词,但主题高度集中
文档 B:长文,有 10000 个词,什么内容都有一点
用户搜索:
推荐系统
长文档 B 很可能也出现了“推荐系统”,但它未必比 A 更相关。
所以 BM25 引入文档长度惩罚:
1 − b + b ⋅ ∣ D ∣ a v g d l 1 - b + b \cdot \frac{|D|}{avgdl} 1−b+b⋅avgdl∣D∣
| b 值 | 含义 |
|---|---|
| 0 | 不考虑文档长度 |
| 0.75 | 默认常用值 |
| 1 | 完全按文档长度归一化 |
k1 控制词频增长的饱和速度。
| k1 值 | 效果 |
|---|---|
| 较小 | 词频很快饱和,多出现几次提升不大 |
| 较大 | 词频影响更强,多出现几次还能继续加分 |
| 常用范围 | 1.2 ~ 2.0 |
计算实例
实际使用 BM25 一般流程如下:
1. 准备文档集合
2. 对文档进行分词
3. 去除停用词,可选
4. 统计每篇文档的词频
5. 统计每个词出现在多少篇文档中
6. 计算每个词的 IDF
7. 计算所有文档的平均长度 avgdl
8. 输入用户查询
9. 对查询分词
10. 对每篇文档计算 BM25 得分
11. 按得分从高到低排序
适用场景
| 场景 | 是否适合 BM25 | 原因 |
|---|---|---|
| 搜索引擎排序 | 适合 | 查询词匹配是核心 |
| 站内搜索 | 适合 | 商品、文章、文档通常关键词明确 |
| 企业知识库检索 | 适合 | 文档多,关键词检索需求强 |
| 法律文档检索 | 适合 | 专业术语非常关键 |
| 论文检索 | 适合 | 关键词、术语、标题摘要匹配重要 |
| RAG 初始召回 | 适合 | 快速、可解释、成本低 |
| 语义改写匹配 | 不适合 | 不理解同义表达 |
| 情感分析 | 不适合 | BM25 不是分类模型 |
| 文本聚类 | 不适合 | 不是全局语义表示 |
| 跨语言匹配 | 不适合 | 词面无法直接对应 |
| 复杂推理问答 | 不适合 | 不能推理,只能检索 |
3.3 Word2Vec / FastText / GloVe + 余弦相似度
定义
这一类方法的核心思想是:把词表示成向量,再用向量之间的距离或夹角衡量语义相似度
例如:
“国王” -> [0.21, -0.35, 0.82, ...]
“王后” -> [0.19, -0.31, 0.79, ...]
“苹果” -> [-0.44, 0.12, 0.06, ...]
如果两个词语语义相近,它们的向量在空间中也应该更接近。
比如:
cosine(国王, 王后) > cosine(国王, 苹果)
这就是词向量相似度的基本思想。
词向量
为什么需要词向量?
传统文本处理中,词通常被表示为 one-hot向量
假设词表是:
[苹果, 香蕉, 汽车, 手机, 国王, 王后]
那么:
苹果 = [1, 0, 0, 0, 0, 0]
香蕉 = [0, 1, 0, 0, 0, 0]
汽车 = [0, 0, 1, 0, 0, 0]
这种表示有两个严重问题:
- **向量太过稀疏:**如果词表有100万个词,每个词的向量就是100万维,但每个向量只有一个位置是1,其他都是0,这会造成存储浪费、计算效率低、无法表达语义关系
- **无法表达词语之间的相似性:**在 one-hot表示法中,任意两个不同词之间的余弦相似度都为0
分布式假设:词向量的理论基础
词向量的核心理论来自分布式假设:一个词的含义,可以通过它周围出现的词来理解
也就是说,上下文相似的词,语义往往相似
例如:
我喜欢吃苹果
我喜欢吃香蕉
我喜欢吃葡萄
“苹果”“香蕉”“葡萄”经常出现在类似上下文中:
我 / 喜欢 / 吃 / ...
所以它们的词向量会比较接近。
再比如:
他开着汽车去上班
他开着卡车去上班
他开着摩托车去上班
“汽车”“卡车”“摩托车”上下文相似,所以向量也会接近。
基于词向量的语义相似度流程
- 准备语料
- 分词
- 训练或加载词向量
- 把词、句子或文档转换为向量
- 使用余弦相似度计算相似度
如果是词语相似度:
词 A -> 向量 A 词 B -> 向量 B cosine(A, B)如果是句子相似度:
句子 A -> 多个词向量 -> 聚合成句向量 句子 B -> 多个词向量 -> 聚合成句向量 cosine(句向量 A, 句向量 B)
Word2Vec
Word2Vec是非常经典的词向量模型,不是一个单一算法,而是一组训练词向量的方法,主要包括:CBOW、Skip-gram
Word2Vec的目标是:通过上下文预测关系,让语义相近的词在向量空间中靠近
Word2Vec的两种训练方式
-
CBOW(Continuous Bag of Words):用上下文预测中心词
训练任务是:根据一个词周围的上下文,预测中间这个词
例如句子:
我 喜欢 吃 苹果如果窗口大小为 2,中心词是“吃”,上下文可能是:
我 / 喜欢 / 苹果CBOW 要做的是:
输入:我、喜欢、苹果 预测:吃再比如:
北京 是 中国 的 首都中心词是“中国”:
输入:北京、是、的、首都 预测:中国特点 说明 训练速度快 因为多个上下文词共同预测一个中心词 对高频词效果较好 高频词训练样本多 对低频词稍弱 低频词出现次数少,学习不充分 适合大规模语料快速训练 速度优势明显 -
Skip-gram:用中心词预测上下文
例如:
我 喜欢 吃 苹果中心词是“吃”,窗口大小为 2:
输入:吃 预测:我、喜欢、苹果再比如:
机器 学习 是 人工智能 的 分支中心词是“机器学习”:
输入:机器学习 预测:人工智能、分支、是特点 说明 对低频词更友好 一个中心词可以生成多个训练样本 训练相对较慢 预测多个上下文词 语义表示通常更细致 尤其在大语料中表现好 适合专业领域词向量 低频专业术语也能学到一些信息
优化技巧
Word2Vec 原始训练需要在整个词表上做分类。
如果词表有 100 万个词,每次预测都要计算 100 万个词的概率,代价很高。
所以 Word2Vec 常用两种优化方法:
Hierarchical Softmax
Negative Sampling
-
Negative Sampling负采样
不再每次预测整个词表,而是只区分"真实上下文词"和少量"随机负样本词"
-
Hierarchical Softmax 层次Softmax
层次Softmax把词表组织成一颗二叉树,每个词是树上的叶子节点,预测一个词时,不再对所有词计算概率,而是沿着树路径做二分类
优点
- 能捕捉语义相似性
- 能捕捉一定的类比关系
- 训练速度快
缺点
- 无法很好地处理训练集中没出现过的词汇(OOV)
- 无法区分一词多义:Word2Vec给每个词一个固定向量
- 对语序不敏感
Doc2Vec
是 Word2Vec 的增强版。
Word2Vec 学的是:
词的向量表示
Doc2Vec 学的是:
句子、段落、文章、文档的向量表示
也就是说,Doc2Vec 可以把一整篇文档表示成一个固定长度的向量,然后用余弦相似度比较两个文档是否相似。
Doc2Vec 是 Word2Vec 的文档级扩展,它通过为每篇文档学习一个独立向量,把长文档映射到低维语义空间,再用余弦相似度比较文档相似性;它适合长文档主题比较、文档推荐、新闻聚类、论文聚类和相似案例初步召回,但不适合短文本高精度匹配、精确关键词检索、小语料训练、复杂推理和多主题长文档的整体比较。
FastText
FastText 可以理解为 Word2Vec 的增强版。
它最大的特点是:
不仅学习整个词的向量,还学习词内部的字符 n-gram 向量。
这使它在处理:
低频词
未登录词
拼写变化
形态变化
时比 Word2Vec 更强
Word2Vec 把一个词当作整体。
例如:
learning
Word2Vec 会直接学习:
learning -> 一个词向量
FastText 会把它拆成多个字符 n-gram。
例如 n=3 时:
<learning>
可以拆成:
<le
lea
ear
arn
rni
nin
ing
ng>
然后:
learning 的向量 = 这些子词向量的组合
优点
- 可以处理未登录词
- 对低频词更友好
- 对拼写变化更鲁棒
缺点
- 子词相似不一定等于语义相似
- 对短词的帮助有限
- 仍然不能真正理解上下文:FastText 虽然比 Word2Vec 更好处理词形和未登录词,但它仍然是静态词向量。
Glove
GloVe 全称是:
Global Vectors for Word Representation
它的核心思想是:
利用全局词共现统计信息学习词向量。
Word2Vec 更偏向局部上下文窗口预测。
GloVe 更强调整个语料中的全局共现矩阵
假设有一个词共现矩阵:
| 词 | ice | steam | fashion | king |
|---|---|---|---|---|
| solid | 100 | 2 | 1 | 1 |
| gas | 1 | 90 | 1 | 1 |
| queen | 0 | 0 | 2 | 80 |
矩阵中的值表示两个词在上下文窗口中共同出现的次数。
GloVe 会学习词向量,使得:两个词向量的点积 ≈ 它们共现次数的某种函数
更准确地说,GloVe 希望:
w i T w ~ j + b i + b ~ j ≈ log ( X i j ) w_i^T \tilde{w}_j + b_i + \tilde{b}_j \approx \log(X_{ij}) wiTw~j+bi+b~j≈log(Xij)
| 符号 | 含义 |
|---|---|
| wi | 词 i 的主词向量 |
| wj | 词 j 的上下文词向量 |
| Xij | 词 i 和词 j 的共现次数 |
| bi,bj | 偏置项 |
| 对比项 | Word2Vec | GloVe |
|---|---|---|
| 核心思想 | 局部上下文预测 | 全局共现矩阵分解 |
| 训练目标 | 预测中心词或上下文词 | 拟合词共现统计 |
| 关注信息 | 局部窗口 | 全局共现 |
| 常见优势 | 训练快、工程成熟 | 全局统计信息利用较充分 |
| 对大语料 | 表现好 | 表现也很好 |
| OOV 支持 | 弱 | 弱 |
| 一词多义 | 弱 | 弱 |
Glove优点
- 利用了全局统计信息,而不是只看单个局部窗口
- 在大规模语料上,GloVe通常能学习到质量较好的通用词向量
- 适合离线批处理场景(一次性把所有数据都加载进来,先做完整的全局统计,再基于统计结果训练模型。)
缺点
- 共现矩阵规模较大,内存压力大
- 不适合动态更新
- 不能处理上下文一词多意
3.4 BERT / RoBERTa / SBERT
定义
BERT全称是Bidirectional Encoder Representations from Transformers,基于Transforme Encoder 的双向上下文语言模型
关键点有三个
- Transformer Encoder
- 双向上下文训练
- 预训练 + 微调范式
前面提到的Word2Vec、FastText、GloVe都属于静态词向量,特点是:一个词只能有一个固定向量
而现在的BERT/RoBERTa/SBERT都属于上下文语义向量模型
核心特点是:同一个词在不同上下文中,可以得到不同的向量表示
也就是说:
“苹果”在水果语境中 ≈ 水果
“苹果”在科技语境中 ≈ 公司 / 手机品牌
双向
传统语言模型常见的是从左到右预测:
我 喜欢 吃 [MASK]
根据前文预测后面的词。
但 BERT 同时看左边和右边上下文。
例如:
我喜欢吃 [MASK],因为它很甜。
BERT 可以同时利用:
左边:我喜欢吃
右边:因为它很甜
来判断 [MASK] 更可能是:
苹果 / 香蕉 / 蛋糕
这种双向上下文建模能力,使 BERT 比传统词向量更能理解语义。
BERT的预训练任务
预训练任务就是让模型在没有人工标注任务数据的情况下,先通过大量文本“自学语言规律”,学会词义、语法、上下文关系、句子关系等通用能力。
先用海量通用文本,比如百科、书籍、新闻等,让模型学习语言本身。
这个阶段不需要人工给每条数据打标签,而是通过设计一些“自监督任务”让模型自己产生训练信号。
比如:
我喜欢吃苹果。
我们可以把它改成:
我喜欢吃 [MASK]。
然后让模型预测
[MASK]原来是什么。答案是:
苹果
这就是一种预训练任务。
预训练完成后,BERT 已经有了比较强的语言理解能力。
然后我们再拿它去做具体任务,比如:
下游任务 输入示例 输出 情感分类 这家店太好吃了 正面 文本匹配 A: 今天天气怎么样? B: 今天会下雨吗? 是否相似 问答任务 文章 + 问题 答案位置 命名实体识别 马云创办了阿里巴巴 人名、组织名 所以,预训练任务的作用就是给 BERT 打基础,微调任务才是让它完成具体业务目标。
1.MLM遮盖语言模型
MLM的做法是随机遮盖句子中的一些词,让模型根据上下文预测被遮盖住的词语
2.NSP下一句预测
NSP的任务是判断两个句子是否前后相邻
BERT + 余弦相似度流程
整体流程如下:
1. 输入两个句子
2. 使用 tokenizer 分词
3. 送入 BERT / RoBERTa 模型
4. 获取 token 输出向量
5. 用 [CLS] 或 Mean Pooling 得到句向量
6. 对两个句向量计算 cosine similarity
tokenizer 可以理解为:
文本进入模型前的“切词 + 编码器”。
它主要做两件事:
第一,把句子切成一个个 token。
第二,把每个 token 转换成词表里的数字 ID。例如:
我喜欢机器学习经过 tokenizer 之后,可能变成:
我 / 喜 / 欢 / 机 / 器 / 学 / 习然后每个 token 会被映射成数字:
[2769, 1599, 3614, 3322, 1690, 2110, 739]这些数字才是 BERT 真正接收的输入。
RoBERTa
采用动态Mask + 无NSP
| 对比项 | BERT | RoBERTa |
|---|---|---|
| 模型结构 | Transformer Encoder | 基本相同 |
| 预训练任务 | MLM + NSP | MLM,无 NSP |
| Mask 策略 | 静态 Mask | 动态 Mask |
| 训练数据 | 相对较少 | 更大规模 |
| 训练时间 | 相对较短 | 更充分 |
| 通常效果 | 强 | 通常更强 |
| 使用方式 | 编码文本 | 编码文本 |
动态Mask
BERT 在预处理阶段就确定哪些词被遮盖。
比如句子:
机器学习是人工智能的重要方向
可能一直是:
机器学习是[MASK]的重要方向
RoBERTa 使用动态 Mask。
也就是说,同一句话在不同训练轮次中,可能遮盖不同位置:
第 1 次:机器学习是[MASK]的重要方向
第 2 次:机器学习是人工智能的[MASK]
第 3 次:[MASK]是人工智能的重要方向
这样模型能从同一句话中学到更多信息。
SBERT
SBERT 全称是:
Sentence-BERT
它是对 BERT / RoBERTa 的改造,专门用于生成句子向量。
SBERT 的目标是:
让语义相似的句子在向量空间中更接近。
例如:
A:我想买一台便宜的手机
B:有没有性价比高的智能机推荐
C:今天晚上可能会下雨
SBERT 希望:
cosine(A, B) 高
cosine(A, C) 低
BERT / RoBERTa / SBERT 向量相似度通过上下文语义编码,把句子或文本映射到深度语义向量空间,再用余弦相似度衡量语义接近程度;其中原始 BERT / RoBERTa 更适合语言理解和下游微调,SBERT 更适合句向量、语义搜索、FAQ 匹配、文本去重、聚类和 RAG 召回,但它不适合单独承担精确编号检索、复杂推理、长文档整体理解和高风险最终决策。
二.数值与向量相似度算法
数值与向量相似度算法常用于特征工程、机器学习、高维向量比较
1.皮尔逊相关系数(Pearson correlation coefficient)
定义与公式
皮尔逊相关系数是衡量两个连续变量之间线性相关程度的统计指标
她回答的问题是:当变量X增大时,变量Y是否也倾向于增大或者减小?这种变化关系有多强?
例如:
身高 和 体重 是否相关?
广告投入 和 销售额 是否相关?
学习时间 和 考试成绩 是否相关?
房屋面积 和 房价 是否相关?
皮尔逊相关系数衡量的是:
两个变量是否沿着一条直线方向共同变化
如果 X 增大时,Y 也增大:
正相关
如果 X 增大时,Y 减小:
负相关
如果 X 和 Y 没有明显线性关系:
相关性接近 0
| r 值 | 含义 |
|---|---|
| 1 | 完全正线性相关 |
| 0.8 ~ 1 | 强正相关 |
| 0.5 ~ 0.8 | 中等偏强正相关 |
| 0.3 ~ 0.5 | 弱到中等正相关 |
| 0 ~ 0.3 | 很弱正相关 |
| 0 | 无线性相关 |
| -0.3 ~ 0 | 很弱负相关 |
| -0.5 ~ -0.3 | 弱到中等负相关 |
| -0.8 ~ -0.5 | 中等偏强负相关 |
| -1 ~ -0.8 | 强负相关 |
| -1 | 完全负线性相关 |
公式为
r = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) ∑ i = 1 n ( x i − x ˉ ) 2 ∑ i = 1 n ( y i − y ˉ ) 2 r = \frac{\sum_{i=1}^{n} (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n} (x_i - \bar{x})^2} \sqrt{\sum_{i=1}^{n} (y_i - \bar{y})^2}} r=∑i=1n(xi−xˉ)2∑i=1n(yi−yˉ)2∑i=1n(xi−xˉ)(yi−yˉ)
应用场景
适合使用皮尔逊相关系数的场景:
- 连续变量之间的线性关系分析
- 特征相关性分析
- 多重共线性初步检查
- 推荐系统中的用户相似度
- 金融数据中的相关性分析
不适合使用皮尔逊相关系数的场景
-
非线性关系
不适合原因:
Pearson 只衡量线性关系 非线性关系可能被误判为低相关更适合:
Spearman 相关 Kendall 相关 互信息 非线性模型 散点图观察 -
有明显异常值的数据
不适合原因:
Pearson 对异常值敏感 极端点可能大幅改变相关系数更适合:
Spearman 相关 Kendall 相关 稳健相关系数 先做异常值处理 -
分类型变量:不是连续型变量,直接计算Pearson通常没有意义
不适合原因:
类别编码的数字大小没有真实连续含义 例如 北京=1,上海=2,广州=3,并不代表上海比北京大更适合:
卡方检验 Cramér's V 点二列相关 ANOVA 互信息
卡方检验用于判断:
两个分类变量是否相互独立。
例如:
性别 和 是否购买 是否有关?假设有数据:
性别 购买 未购买 男 80 120 女 130 70 直觉上:
女性购买比例更高 男性未购买比例更高卡方检验可以判断这种差异是否显著。
-
等级变量但间隔不确定
例如满意度:
1 = 很不满意 2 = 不满意 3 = 一般 4 = 满意 5 = 很满意虽然可以用数字表示,但 1 到 2 的差距未必等于 4 到 5 的差距。
不适合原因:
Pearson 默认变量间隔有意义 等级变量更适合按排序关系处理更适合:
Spearman 相关 Kendall 相关
显著性p值
p 值用来判断你算出来的 Pearson 相关系数 r,是否可能只是随机巧合。
当我们计算样本相关系数时,还可以做显著性检验。
原假设:
H0:总体相关系数 ρ = 0
备择假设:
H1:总体相关系数 ρ ≠ 0
p 值表示:
如果总体实际上没有线性相关,那么观察到当前相关系数或更极端结果的概率。
| 指标 | 回答的问题 |
|---|---|
| r 值 | 两个变量线性相关有多强、方向是什么 |
| p 值 | 这个相关关系在统计上是否显著,是否可能只是随机波动 |
常见判断标准是:
| p 值 | 常见解释 |
|---|---|
p < 0.001 |
极显著 |
p < 0.01 |
非常显著 |
p < 0.05 |
显著 |
p ≥ 0.05 |
不显著 |
例如:
r = 0.42, p = 0.03
通常可以说:
在 0.05 显著性水平下,两个变量存在显著线性相关。
但如果是:
r = 0.42, p = 0.18
就不能说它们显著相关,只能说:
当前样本没有足够证据证明总体中存在线性相关。
注意这里不是说“完全没有关系”,而是说证据不够。
在数据分析中的典型流程
- 确认变量类型是否为连续数值型
- 画散点图观察关系形态
- 检查异常值
- 计算Pearson相关系数
- 计算p值
- 结合业务解释
- 但不把相关直接当作因果
可视化建议
1.散点图
- 是否线性
- 是否有异常值
- 是否存在分组
- 是否有非线性关系
2.相关性热力图
适合多个数值变量一起分析
例如:
特征 A、B、C、D 与目标 Y 的相关性
特征之间是否存在高度相关
2.Spearman’s Rank Correlation
定义与公式
斯皮尔曼秩相关系数
Spearman相关系数是一种基于"排序的相关性指标",用来衡量两个变量之间是否存在单调关系
不是直接比较原始数值,而是先把数据转换成排名,在计算排名之间的相关性
Spearman关注的是:一个变量增大时,另一个变量是否总体也增大,或者总体减小
衡量的是单调关系,而不是严格的线性关系
| Spearman 值 | 含义 |
|---|---|
| 1 | 完全单调递增 |
| 0.7 ~ 1 | 强正单调相关 |
| 0.4 ~ 0.7 | 中等正单调相关 |
| 0.2 ~ 0.4 | 弱正单调相关 |
| 接近 0 | 几乎没有单调关系 |
| -0.2 ~ -0.4 | 弱负单调相关 |
| -0.4 ~ -0.7 | 中等负单调相关 |
| -0.7 ~ -1 | 强负单调相关 |
| -1 | 完全单调递减 |
原始数据:
| 用户 | 消费金额 X | 活跃天数 Y |
|---|---|---|
| A | 100 | 3 |
| B | 200 | 5 |
| C | 300 | 4 |
| D | 400 | 8 |
| E | 500 | 10 |
转换成排名:
| 用户 | X 排名 | Y 排名 |
|---|---|---|
| A | 1 | 1 |
| B | 2 | 3 |
| C | 3 | 2 |
| D | 4 | 4 |
| E | 5 | 5 |
然后计算这两个排名序列之间的 Pearson 相关系数。
所以可以理解为:
Spearman = 对两个变量分别排序后,再计算 Pearson 相关系数。
ρ = 1 − 6 ∑ d i 2 n ( n 2 − 1 ) \rho = 1 - \frac{6 \sum d_i^2}{n(n^2 - 1)} ρ=1−n(n2−1)6∑di2
- ρ:Spearman 秩相关系数
- n:样本数量
- di:第i个样本在两个变量之间的排名差
应用场景
-
变量之间是单调但非线性关系
-
数据中存在异常值:Spearman只关注排名,因此受异常值影响较小
-
有序分类变量:对于有顺序的变量可进行排名编码
-
评分、等级、排名类数据
-
数据筛选中的初步相关性分析
在机器学习建模前,可以先用Spearman观察
- 特征与目标变量是否存在单调关系
- 特征之间是否存在荣誉关系
- 是否存在高度相关变量
不适应场景
- 关系不是单调关系
- 名义行分类变量,无法进行顺序排名
- 不能结束具体数值变化幅度
- 大量重复执导之排名信息不足
- 样本量很小
数据分析流程
-
明确分析目标
-
判断变量类型
Spearman适合:
- 连续变量 VS 连续变量
- 连续变脸 VS 有序变量
- 有序变量 VS 有序变量
-
数据清洗
处理
- 缺失值处理
- 异常值处理
- 重复值处理
-
处理有序分类变量
例如用户等级:
青铜 < 白银 < 黄金 < 铂金 < 钻石可以编码为:
用户等级 编码 青铜 1 白银 2 黄金 3 铂金 4 钻石 5 注意:
编码必须符合真实业务顺序。
不能把城市、职业、商品类别这类无序变量随便编码后计算 Spearman。
-
计算Spearman相关系数
-
结合p-value判断显著性
Spearman 通常会输出两个结果:
rho: 相关系数 p-value: 显著性水平一般解释:
p-value 含义 < 0.01 极显著 < 0.05 显著 ≥ 0.05 暂无统计显著证据 但是要注意:
p-value 受样本量影响很大。
样本量很大时,即使相关系数很小,也可能显著。
例如:
rho = 0.05, p-value < 0.001这说明统计上显著,但业务上可能很弱。
所以要同时看:
相关系数大小 p-value 样本量 业务意义 可视化结果 -
构建相关矩阵:多个变量时,可以计算Spearman相关矩阵
-
解释结果
可视化
- 散点图
- 排名散点图
- 热力图:Spearman相关性热力图
- 分箱趋势图
- 箱线图:当一个变量是有序等级,另一个变量是连续值时,可以用箱线图。
3.Euclidean Distance(欧几里得距离)
定义与公式
欧几里得距离就是两个点之间的“直线距离”。
在二维平面中,它就是我们熟悉的:
两点之间,线段最短
核心思想
欧几里得距离衡量的是:
两个样本在特征空间中的几何距离。
如果两个样本的距离越小,说明它们在特征空间中越相似。
如果距离越大,说明它们越不相似
n维空间计算公式
在机器学习中,一个样本通常有很多特征。
例如用户画像:
年龄、收入、活跃天数、购买次数、浏览次数、评分……
假设两个样本分别为:
X = ( x 1 , x 2 , … , x n ) Y = ( y 1 , y 2 , … , y n ) X = (x_1, x_2, \dots, x_n) \\ Y = (y_1, y_2, \dots, y_n) X=(x1,x2,…,xn)Y=(y1,y2,…,yn)
那么欧几里得距离为
d ( X , Y ) = ∑ i = 1 n ( x i − y i ) 2 d(X,Y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2} d(X,Y)=i=1∑n(xi−yi)2
标准化
欧几里得距离必须进行标准化,因为特征量纲会影响距离,常见做法是使用Z-score进行标准化
欧几里得相似度计算
有三种常见的转换方式
s i m i l a r i t y = 1 1 + d similarity = \frac{1}{1 + d} similarity=1+d1
其中 d是欧几里得距离。优点是简单,结果在0到1之间
s i m i l a r i t y = e − d similarity = e^{-d} similarity=e−d
距离越大,相似度下降越快
$$
\text{similarity} = e^{-\gamma d^2}
$$
这就是 RBF 核函数的思想之一。
其中 γ 控制距离衰减速度。
应用场景
适用场景
- 连续数值特征之间的距离衡量
- KNN最近邻算法
- K-means聚类
不适用场景
- 特征尺度很大但未标准化
- 存在大量异常值
- 高维稀疏文本数据
- 只关心方向相似,不关心数值大小
三.灰色关联
1. 定义
Grey Relational Analysis, GRA
灰色关联分析是一种基于序列几何形状接近程度的关联度分析算法,也可用于衡量序列之间的相似程度
更关心:一个变量的变化曲线,与参考变量的变化曲线,在形状和走势上是否接近
灰色关联分析来自灰色系统理论,常用于样本较少、信息不完全、变量之间关系不容易用传统统计模型刻画的场景。灰色关联分析的核心是比较参考序列和比较序列之间的几何形状相似程度。
1.1 灰色
灰色系统理论中,通常把信息状态分为三类:
| 类型 | 含义 |
|---|---|
| 白色系统 | 信息完全清楚 |
| 黑色系统 | 信息完全未知 |
| 灰色系统 | 信息部分已知、部分未知 |
现实业务数据往往不是完全清楚的。
例如:
影响销售额的因素很多,但不可能全部观测到;
宏观经济、竞争对手、天气、促销、价格都可能影响销售;
样本量可能不大,变量关系也不一定满足正态分布或线性假设。
这类“信息不完全但又不是完全未知”的系统,就可以看作灰色系统。
灰色关联分析正是用于这种场景下的多因素关系分析方法。
1.2 用途
灰色关联分析主要回答:多个因素中,哪些因素与目标变量的变化趋势最接近?
目标序列:
销售额比较序列:
广告投放金额 商品价格 促销力度 用户访问量 客服响应速度灰色关联分析可以判断:
哪个因素的变化趋势与销售额最接近? 哪个因素可能与销售额关系更密切?
| 方法 | 关注点 | 适合变量 | 主要用途 |
|---|---|---|---|
| Pearson 相关系数 | 线性关系 | 连续变量 | 判断线性相关 |
| Spearman 相关系数 | 单调关系 | 连续 / 有序变量 | 判断排名是否同向变化 |
| 卡方检验 | 分类变量是否独立 | 分类变量 | 判断分类变量关联显著性 |
| 灰色关联分析 | 曲线走势相似程度 | 序列型指标 | 多因素趋势关联和排序 |
1.3 序列性指标
序列型指标指的是:
某个指标不是一个单独数值,而是一组按顺序排列的数据序列。
如:
| 年份 | 参考序列:销售额 | 因素A:广告投入 | 因素B:价格 |
|---|---|---|---|
| 2020 | 100 | 20 | 50 |
| 2021 | 130 | 25 | 48 |
| 2022 | 160 | 31 | 45 |
| 2023 | 200 | 40 | 43 |
这里“销售额”“广告投入”“价格”都可以看作序列型指标,因为每个指标都有一串按年份排列的数据。
灰色关联分析会比较:
广告投入这条曲线的走势是否和销售额相似,
价格这条曲线的走势是否和销售额相似。
相似度越高,说明该因素与参考指标的关联程度越强,然后就可以进行多因素排序。
所以,简单说:
序列型指标 = 由多个有顺序的数据点组成的指标,用来反映某个因素随时间、阶段或样本顺序变化的趋势。
1.4 灰色关联系数与灰色关联度
灰色关联系数表示:
在某一个时间点或某一个样本点上,比较序列与参考序列的接近程度。
取值通常在 0 到 1 之间。
越接近 1,表示该点越接近。
灰色关联度是把各个点上的关联系数汇总起来,通常取平均值或加权平均值。
它表示:
整个序列层面上,某个因素与参考序列的总体关联程度。
灰色关联度越大,说明该比较序列和参考序列的走势越接近。
2.计算步骤
- 确定参考序列
- 确定比较序列
- 数据无量纲化
- 计算差值序列
- 找全局最大差和最小差
- 计算灰色关联系数
- 计算灰色关联度
- 按关联度排序
- 结合业务解释
假设输出结果为:
| 因素 | 灰色关联度 |
|---|---|
| visits | 0.756 |
| ad_cost | 0.656 |
| price | 0.532 |
可以写成:
以销售额作为参考序列,对广告费、访问量和商品价格进行灰色关联分析。
结果显示,访问量与销售额的灰色关联度最高,为 0.756,说明访问量的变化趋势与销售额最接近。
广告费的灰色关联度为 0.656,排第二。
商品价格的灰色关联度为 0.532,说明其走势与销售额的接近程度相对较低。
但要补一句:
灰色关联度反映的是走势接近程度,不代表因果关系。
3.应用场景
3.1 小样本,多指标分析
灰色关联分析常用于样本较少但指标较多的系统分析。
例如:
10 个城市
8 个经济指标
希望判断哪些指标与综合发展水平最接近
传统统计模型可能样本不足,而灰色关联分析仍可做趋势或评价排序。
灰色关联分析的一个常见优势是对样本量和分布假设要求较低,可用于大样本或小样本,并且计算较简便。
3.2 时间序列趋势关联
例如:
销售额 vs 广告费
故障率 vs 温度
利润 vs 原材料价格
客流量 vs 搜索指数
如果关心的是:
变化趋势是否一致
灰色关联分析比较适合。
3.2 多指标综合评价
例如评价多个供应商:
| 供应商 | 成本 | 质量 | 交付时间 | 服务评分 |
|---|---|---|---|---|
| A | 低 | 高 | 快 | 高 |
| B | 中 | 中 | 稳定 | 中 |
| C | 高 | 高 | 快 | 高 |
可以构造理想参考序列:
成本最低
质量最高
交付最快
服务最高
然后计算每个供应商与理想方案的灰色关联度。
关联度越高,说明越接近理想方案。
不适合场景
- 需要严格统计显著性检验:
灰色关联分析通常不给出传统意义上的 p-value。
如果你的问题是:
两个变量的关联是否统计显著?
更适合:
Pearson 相关检验
Spearman 相关检验
卡方检验
回归模型显著性检验
灰色关联分析更偏向:
关联程度排序
走势接近度分析
综合评价
- 需要解释因果关系:灰色关联度高,只能说明走势接近
- 数据噪声极大且没有平滑处理:
如果时间序列噪声很大,灰色关联度可能被短期波动影响。
例如:
每天销售额受随机活动、库存、天气、竞品价格影响很大直接做灰色关联分析可能不稳定。
可以先做:
移动平均 趋势分解 异常点处理 按周或按月聚合
- 序列没有可比顺序
灰色关联分析适合有顺序的数据,例如:
时间顺序 空间顺序 评价指标顺序 样本排列有业务含义如果样本顺序完全随机,曲线形状相似性就不容易解释。
例如随机排列的用户样本:
用户 年龄 收入 是否购买 U1 20 3000 0 U2 45 20000 1 U3 23 5000 0 如果用户排列没有意义,用灰色关联分析解释“曲线走势”就比较牵强。
- 特征关系是明显非同步滞后关系
4.可视化图像
- 标准化后的趋势折线图
- 观察各序列走势是否接近
- 检查是否有明显滞后
- 检查异常点
- 辅助解释灰色关联度
- 灰色关联度柱状图:展示因素关联度排序
- 灰色关联系数热力图
- 差值序列折线图
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)