赞
踩
本文主要整理一下经典的文本匹配/相似度计算算法,包括Jaccard相似度、Levenshtein编辑距离、Simhash、TF-IDF、BM25。
参考链接:https://en.wikipedia.org/wiki/Jaccard_index
Jaccard相似度,是用于比较有限样本集合的相似性的统计量,定义为两个集合的交集与并集的比例。
J
(
A
,
B
)
=
∣
A
∩
B
∣
∣
A
∪
B
∣
=
∣
A
∩
B
∣
∣
A
∣
+
∣
B
∣
−
∣
A
∩
B
∣
0
≤
J
(
A
,
B
)
≤
1
J(A,B)={{|A\cap B|} \over {|A\cup B|}}={{|A\cap B|} \over {|A|+|B|-|A\cap B|}}\\ 0 \le J(A,B) \le 1
J(A,B)=∣A∪B∣∣A∩B∣=∣A∣+∣B∣−∣A∩B∣∣A∩B∣0≤J(A,B)≤1
对应的Jaccard距离为:
d
J
(
A
,
B
)
=
1
−
J
(
A
,
B
)
=
∣
A
∪
B
∣
−
∣
A
∩
B
∣
∣
A
∪
B
∣
d_{J}(A,B)=1-J(A,B)={{|A\cup B|-|A\cap B|} \over |A\cup B|}
dJ(A,B)=1−J(A,B)=∣A∪B∣∣A∪B∣−∣A∩B∣
参考链接:
https://zh.wikipedia.org/wiki/%E8%90%8A%E6%96%87%E6%96%AF%E5%9D%A6%E8%B7%9D%E9%9B%A2
https://zhuanlan.zhihu.com/p/43009353
Levenshtein距离,是编辑距离的一种,指两个字符串之间,由一个转换成另一个所需的最少编辑次数。其中编辑操作包括:插入、删除、替换。编辑操作可以有不同权重,这里以等权为例。求解算法通常为动态规划。
定义a、b两个字符串,则其编辑距离如下:
其中, lev a , b ( i , j ) \text{lev}_{a,b}(i,j) leva,b(i,j)表示 a a a字符串的前 i i i个字符,与 b b b字符串的前 j j j个字符的编辑距离; 1 ( a i ≠ b j ) 1_{\left(a_{i} \neq b_{j}\right)} 1(ai=bj)是指示函数,当二者相同时为1,否则为0。 min \min min运算中的3个公式,分别表示对字符串 a a a执行删除、插入、替换操作。
具体求解编辑距离通常用动态规划算法,伪代码如下。首先构造一个距离矩阵,其中第一行第一列表示两个空串,每个交叉点表示对应的编辑距离,最右下角的编辑距离即是整个字符串的编辑距离。
pip install python-Levenshtein
import Levenshtein
参考链接:https://www.cnblogs.com/maybe2030/p/5203186.html
Simhash是一种将文本hash编码之后,仍然能保持一定的相似度计算能力的hash编码。基本思路是将词进行hash编码后,得到64位01串,对每个词中0改为-1并对整体加权,最后将所有词求和作为句子的表示。
具体流程包括:
1. 分词。有意义则分词,否则直接分到字
2. hash。将词转为01串,如10101111
3. 加权。如果有单词的权重信息,则加权,如2 -2 2 -2 2 2 2 2
4. 合并。将句子的所有词求和
5. 降维。对合并后的结果中,>0的设置为1,<0的设置为0
示例如下:
参考:
https://zhuanlan.zhihu.com/p/113017752
https://zh.wikipedia.org/wiki/Tf-idf
https://zhuanlan.zhihu.com/p/348412847
TF-IDF是衡量一个文档集中每个文档中每个词的重要性。TF,一个词在当前文档中出现的次数越多越重要;IDF,文档集中,一个词出现的文档数越少越重要。
t
f
×
i
d
f
(
i
,
j
)
=
t
f
i
j
×
i
d
f
i
=
n
i
j
∑
k
n
k
j
×
log
(
∣
D
∣
1
+
∣
D
i
∣
)
tf\times idf(i,j)=tf_{ij}\times idf_{i}=\frac{n_{ij}}{\sum_kn_{kj}}\times \log(\frac{|D|}{1+|D_i|})
tf×idf(i,j)=tfij×idfi=∑knkjnij×log(1+∣Di∣∣D∣)
在求文本相似度时,基本思路是找出字符串之间共现的词,并用tfidf做加权。即
S
c
o
r
e
t
f
i
d
f
(
Q
,
D
)
=
∑
i
n
I
D
F
i
∗
T
F
(
q
i
,
D
)
Score_{tfidf}(Q,D)=\sum^{n}_{i} IDF_i * TF(q_i,D)
Scoretfidf(Q,D)=i∑nIDFi∗TF(qi,D)
参考:
https://zhuanlan.zhihu.com/p/113224707
https://en.wikipedia.org/wiki/Okapi_BM25
BM25是搜索中的经典算法,与TFIDF做相似度类似,只是优化的每项的计算方式。
score
(
D
,
Q
)
=
∑
i
=
1
n
IDF
(
q
i
)
⋅
f
(
q
i
,
D
)
⋅
(
k
1
+
1
)
f
(
q
i
,
D
)
+
k
1
⋅
(
1
−
b
+
b
⋅
∣
D
∣
avgdl
)
{\displaystyle {\text{score}}(D,Q)=\sum _{i=1}^{n}{\text{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|}{\text{avgdl}}}\right)}}}
score(D,Q)=i=1∑nIDF(qi)⋅f(qi,D)+k1⋅(1−b+b⋅avgdl∣D∣)f(qi,D)⋅(k1+1)
其中
D
D
D表示候选句,
Q
Q
Q表示查询句,
Q
=
{
q
1
,
.
.
.
,
q
n
}
Q=\{q_1,...,q_n\}
Q={q1,...,qn}。
I
D
F
IDF
IDF表示词的权重或重要性,逆文档率的一种形式,如下所示
N
N
N表示总文档数,
n
(
q
i
)
n(q_i)
n(qi)表示包含改词的文档数
IDF
(
q
i
)
=
ln
(
N
−
n
(
q
i
)
+
0.5
n
(
q
i
)
+
0.5
+
1
)
{\displaystyle {\text{IDF}}(q_{i})=\ln({\frac {N-n(q_{i})+0.5}{n(q_{i})+0.5}}+1)}
IDF(qi)=ln(n(qi)+0.5N−n(qi)+0.5+1)
公式的右半部分表示词频信息,主要是查询词和候选句之间的关系。
f
(
q
i
,
D
)
f(q_i,D)
f(qi,D)表示改词在该文档中出现的次数,
∣
D
∣
|D|
∣D∣为该文档的总词数,
avgdl
\text{avgdl}
avgdl表示文档集中文档的平均词数,
k
1
,
b
k_1,b
k1,b是超参数,通常取值
k
1
∈
[
1.2
,
2.0
]
,
b
=
0.75
k_1 \in [1.2,2.0],b=0.75
k1∈[1.2,2.0],b=0.75。
其他还有如LCS(最长公共子序列)、SSK(字符串核)等。有机会在补上吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。