自然语言处理NLP:姓名相似度
大家好,自然语言处理会涉及到一致性验证特征。英文的姓名相似度包含用户自己填写的姓名、身份证上ocr识别的姓名、征信报告中用户姓名,可以作为模型特征使用、也可以作为业务的个人信息验证规则使用,本文简单介绍其计算逻辑。
1.原理
编辑距离,又叫Levenshtein距离。对于两个字符串文本序列,根据 Levenshtein 计算将一个序列更改为另一个序列所需的最小插入、删除和替换次数,以及插入、删除和替换的自定义成本。
如 "lewenstein"、"levenshtein"的编辑距离为2,"lewenstein" 需要通过一次替换(第三位字符"w"替换为"v")、一次插入("s"字符后插入"t"),即可变为"levenshtein"。
编辑距离越小,一个字符串变更为另一个字符串的变更次数越小,两个字符串的相似度也就越高。可以看出编辑距离非常适合用于计算英文的姓名相似度,在客户自己填写个人信息时,可能会有部分缩写,如"Travor Noah"缩写为"Noah, T.",也可能将"levenshtein"错误拼写为"lewenstein"(ocr识别出姓名的此类问题更是常见),而编辑距离能够很好地减缓这种问题所造成的姓名不一致。
2.工具包
编辑距离的计算可以直接调用levenshtein包,不仅实现了编辑距离及归一化的相似度,还实现了hamming距离和jaro距离计算。
pip install levenshtein https://pypi.tuna.tsinghua.edu.cn/simple your_package
3.参数解释
3.1 编辑距离
Levenshtein.distance(s1, s2, *, weights=(1, 1, 1), processor=None, score_cutoff=None)
s1 ( Sequence [ Hashable ] ) :要比较的第一个字符串。
s2 ( Sequence [ Hashable ] ) :要比较的第二个字符串。
weights ( Tuple [ int , int , int ] or None , optional ):三种操作的权重(插入、删除、替换)。默认值为 (1, 1, 1),即插入1次、删除1次、替换1次,计算的编辑距离均为1,可自定义。
processor ( callable , optional ):可选参数,用于在比较字符串之前对其进行预处理,默认不使用。
score_cutoff ( int , optional ):设定s1 和 s2 之间的最大距离限制,如果编辑距离大于score_cutoff,则返回 score_cutoff + 1。默认为无,不使用最大距离限制。
3.2 编辑距离相似度
归一化的编辑距离:将编辑距离归一化,使得相似度取值范围在[0,1]内,越接近于1、相似度越高。注意此处字符的插入、删除、替换权重为(1, 1, 2)。
Levenshtein.ratio(s1, s2, *, processor=None, score_cutoff=None)
processor ( callable , optional ):可选参数,用于在比较字符串之前对其进行预处理,默认不使用。
score_cutoff ( float , optional ):分数阈值的可选参数,作为 0 到 1.0 之间的浮点数。对于norm_sim < score_cutoff返回0,否则返回1。默认值为 0、不使用cutoff。
3.3 Hamming距离
汉明距离的计算要求比较的两个字符串长度相同,逻辑为两个字符串对应位置上不同的字符个数。
Levenshtein.hamming(s1, s2, *, processor=None, score_cutoff=None)
processor ( callable , optional ):可选参数,用于在比较字符串之前对其进行预处理。默认不使用。
score_cutoff ( int or None , optional ):设置 s1 和 s2 之间的最大距离限制。如果距离大于 score_cutoff,则返回 score_cutoff + 1。默认为无,不使用cutoff。
4.姓名相似度
有了编辑距离归一化的相似度,可以用于计算英文名的姓名相似度,但是需要注意的是经常会有名字顺序颠倒的情况,这时候直接套用Levenshtein.ratio是有明显问题的。
import Levenshtein
Levenshtein.distance("lewenstein", "levenshtein")
# 2
Levenshtein.ratio("lewenstein", "levenshtein")
# 0.8571428571428572
Levenshtein.ratio("steven zhou", "zhou steven")
# 0.5454545454545454
针对姓名first、median、last name顺序错乱颠倒的问题,可以把两个姓名的first、median、last name进行排序处理:按照空格分割、对分割结果的list进行升序排序、再拼接为字符串,这样就可以避免,然后再进行比较就可以了。
def split_sort(string):
result=' '.join(sorted(string.split()))
return result
print(split_sort('zhou steven'))
print(split_sort('steven zhou'))
# steven zhou
# steven zhou
Levenshtein.ratio("steven zhou", "zhou steven")
# 0.5454545454545454
Levenshtein.ratio(split_sort("steven zhou"), split_sort("zhou steven"))
# 1.0
原文地址:https://blog.csdn.net/csdn1561168266/article/details/136716060
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!