使用 Levenshtein 寻找彼此相似的字符串对
2019独角兽企业重金招聘Python工程师标准>>>
我们爬来了一些数据,接下来以豆瓣畅销书为例。
爬虫爬来的数据有
['艾伦•图灵传','深入理解计算机系统(原书第2版)','C++ Primer 中文版(第 5 版)','深入理解计算机系统','Web性能权威指南']
而我们系统中原有的数据有
['艾伦·图灵传','深入理解计算机系统(原书第2版)','C++ Primer 中文版(第 4 版)','深入理解计算机系统']
做前端的同志可能一眼就看出来了,两个数组中有三个元素是因为全半角的缘故,是不能全词匹配的,而前两本书事实上是同一本书。而《深入理解计算机系统》是可以全词匹配到的,《Web性能权威指南》一书是可以直接添加到数据库的。
解决方案一:
这个任务大可以交给编辑去做,但是时间复杂度为 N^2,连程序都吃不消跑,更别提让编辑做了。
解决方案二:
去除所有的标点符号,或者将所有全角符号转化为半角。 去掉所有空格。 然后进行全词匹配,这样做有些鲁莽,但是速度一点也不慢。
解决方案三:
我想到了用 jieba 进行中文分词,
import jieba
book = '艾伦·图灵传'
word = jieba.cut(book)
words = list(word)
# words = ['艾伦', '·', '图灵', '传']
对于每本书我们都可以进行这样一个分词操作,并可以考虑将标点符号去除。 然后看每两个数组的元素的重合情况,但要考虑归一化,原因如下:
- ‘Python 开发指南’ 和 ‘皇家 Python 开发指南’ 元素的重合数为 3 个单词。
- ‘Python 开发指南’ 和 ‘皇家 Python 超级无敌开发指南’ 元素的重合数为 3 个单词。
显然第 1 组看起来会比第 2 组相似一些,但是重合数是一样的。使用重合数显然不科学,我们可以通过除以分词后单词总数来计算它们的重合率。
解决方案四:
在想解决方案三的时候,我回忆起了以前做聚类算法的时候用的各种距离算法,对于实数的欧几里得距离,用在 k-modes 中的对于类型数据的相异度量算法,前者在这里显然不适用,后者又显得有点小题大做。然后我发现了一种叫做编辑距离 Edit Distance 的算法,又称 Levenshtein 距离。[1]
编辑距离是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。 维基上给出了一个例子: 'kitten' 和 'sitting' 的编辑距离为3:
- kitten → sitten (s 替换成 k)
- sitten → sittin (i 替换成 e)
- sittin → sitting (加上一个 g)
碰巧的是有一个开源的 python 包刚好可以计算 Levenshtein 距离,可以通过以下安装:
pip install python-Levenshtein
然后就可以计算编辑距离了:
import Levenshtein
texta = '艾伦·图灵传'
textb = '艾伦•图灵传'
print Levenshtein.distance(texta,textb)
# 3
很自然地会有这个疑问,为什么这里的编辑距离会是3,我们来看看具体进行的编辑操作。
Levenshtein.editops('艾伦·图灵传', '艾伦•图灵传')
[('insert', 6, 6), ('replace', 6, 7), ('replace', 7, 8)]
看起来只有一个字符的区别,但是这里做了三次编辑操作,为什么?我们来打印一下这两个字符串的具体表达:
In [4]: a='艾伦·图灵传'
In [5]: a
Out[5]: '\xe8\x89\xbe\xe4\xbc\xa6\xc2\xb7\xe5\x9b\xbe\xe7\x81\xb5\xe4\xbc\xa0'
In [6]: a='艾'
In [7]: a
Out[7]: '\xe8\x89\xbe'
看到这里就明白了,我们犯了一个错误,把这两个字符串存成了 string 类型,而在 string 类型中,默认的 utf-8 编码下,一个中文字符是用三个字节来表示的。于是这里又牵扯到了 Python 中的 string 和 unicode 的区别。然而在这个字节串中,我们的编辑距离,的的确确是3。
现在重新来计算距离。
print Levenshtein.distance(u'艾伦·图灵传',u'艾伦•图灵传')
# 1
现在就正确了,现在的编辑距离1就代表了两本书的名字的差别度量。这时候就要开始做归一化了,而巧的是,我们发现这个 Levenshtein 包中自带了一个相似度函数 jaro(),它可以接受两个字符串并给出从0到1范围内的相似度。下面所显示的0.888888888889便表示了这两个字符串的相似度。
print Levenshtein.jaro(u'艾伦·图灵传',u'艾伦•图灵传')
# 0.888888888889
然后我们可以写个嵌套的 for 循环,设置一个阈值 threshold,计算每一对书本的相似度,当他们超过某一阈值时,进行处理。这里要注意的就是,不要重复检验书本对,即检测(书本 A,书本 B)和(书本 B,书本 A),这样可以避免 N^2 的时间复杂度。
当然最后其实还是需要人工介入的,比如遇到第三本书这种情况,版次不一样并不算同一本书。再当然,我们是可以对所有版次有关的字符进行特殊处理,比如出现版次字符,而且两本书不相同的时候,把距离函数的输出值加上一个修正参数。不过,这种情况太多太多,还是用人工处理好了,此时的两本书为同一本书的机率是很高的。再不然,只能上机器学习了,但是也是要你有训练样本的。
参考文献: [1] wikipedia Levenshtein_distance [2] Levenshtein Document
转载于:https://my.oschina.net/shinedev/blog/494098
使用 Levenshtein 寻找彼此相似的字符串对相关推荐
- 通过正则寻找符合要求的字符串
一.findall是pd.Series.str所特有的(regex也有这个函数,字符串类没有这个函数): 二.字符串无论单独打印还是以series序列的形式打印,都没有定义时最外面的那个引号无论单双: ...
- 【C语言】(错题整理) 寻找完数、字符串中各类字符数的统计、最大公约数和最小公倍数、回文数计算 (循环、函数相关内容)
目录 一.循环 1.寻找完数(计算因子例题) 2.字符串中各类字符数的统计 3.最大公约数和最小公倍数 求最大公约数: 最小公倍数:最小公倍数=两整数的乘积÷最大公约数 二.函数 1.回文数计算 本篇 ...
- 计算字符串相似度算法—Levenshtein
什么是Levenshtein Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删 ...
- 寻找蛇形字符串python实现
输入一个字符串(不含空格),请寻找输入中包含的所有蛇形字符串. 1. 蛇形字符串的定义: 1.1 字符对定义:字符对有同一字母的大小组成(前大后小),如:Aa,Dd. 1.2 蛇形字符串中包含的字符对 ...
- c++ 模糊搜索 正则表达式_模糊搜索算法(近似字符串匹配算法)
考虑到您正在尝试对学校名称列表进行模糊搜索,因此我认为您不希望使用Levenshtein距离之类的传统字符串相似性. 我的假设是,您正在接受用户的输入(键盘输入或通过电话说出),并且想要快速找到匹配的 ...
- 2046幻想_寻找一个幻想足球的名字
2046幻想 Looking for a new fantasy football team name? I extracted over 500,000 fantasy football team ...
- Levenshtein distance 编辑距离算法
这几天再看 virtrual-dom,关于两个列表的对比,讲到了 Levenshtein distance 距离,周末抽空做一下总结. Levenshtein Distance 介绍 在信息理论和计算 ...
- 有条件截取字符串_Python小课堂之木辛老师特别讲解:再次深入浅出字符串的格式化...
我们已经学习了字符串和数字基础的处理方法和逻辑,大家有没有觉得使用起来很方便,编程的过程中也是很给力的呀!其实Python还有更多字符串处理的方法,大家今天就一起来体验一下吧 小朋友们可以先复习一下前 ...
- 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)
相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...
最新文章
- Windows Server 2012 从入门到精通系列之如何提高DC持续性?
- 现代中产男人必备的8种气质[zt] 来自9G群里发的,据说是BF推荐给9G的
- UNPIVOT的详细说明
- CSocketFile类
- python中的深浅拷贝
- 【BZOJ4562】食物链,拓扑DP
- 远程连接Ubuntu服务器
- 原生ajax接收json字符串(简单介绍)
- 并发数 = QPS*平均响应时间(转)
- MPU6050六轴传感器的原理及编程说明
- visio怎么画球_快速学习Visio 门球制图
- ,PLCSIM、SIMIT、Amesim、NX MCD、 Process Simulate、Plant Simulation,一文带你了解西门子整个虚拟调试与仿真软硬件体系
- 虚拟机使用本地服务器配置,虚拟机搭建本地云服务器配置
- 运行在网络处理器上的嵌入式Linux系统
- 买股不如买基?Python实现快速追踪基金的收益情况!谁还不是个买基高手?
- ftp 服务器 性能,Xlight FTP服务器网络性能测试
- 银行卡号- 查询银行卡信息
- 【计算机网络】计算机网络-分组发送相关计算
- 小程序团购商品CPS接入,实现达人分佣模式
- opencv人脸识别之让电脑分清吴彦祖和彭于晏 (LBPH)