python实现字符串模糊匹配

之前笔者写过一篇文章关于如何做搜索,但那篇文章的角度是从文本相似度角度写的。那种方式是目前发展的趋势,但是真正的搜索特别是网页搜索不可能在大范围的文本之间两两算相似度的。那样搜索引擎的效率会变得特别低下。本文将从字符串模糊匹配的角度介绍一下搜索引擎。

一般的搜索,要分为两个步骤:搜索排序。搜索的方法有很多,为了高效一般进行字符串或关键词匹配,而用户提供的一些关键词可能不是数据库中保存的,例如使用倒排的方法很难找到Head节点,此处需要使用模糊匹配的方式。这里简单列举一下Learning-to-Rank排序的方法:BM25算法、TF-IDF算相似度、SVD奇异值分解(主题模型)得到向量表示算相似度、再就是之前介绍的文本相似度计算的方法。如果是网页的排序,可能会涉及到网址质量好坏需要使用PageRank排序算法等。

本文主要从模糊匹配的角度,简单介绍下搜索。主要解决的问题类似,“刘得华演过的电影”与“刘德华演过的电影”表示的是同一个意思。

1. 编辑距离

首先给大家介绍一下编辑距离,编辑距离就是用于衡量两个字符串之间的差异。具体描述为:string1通过多少次最少操作(增添字符、删除字符、替换字符)得到string2,最少操作的次数就定义为编辑距离。例如句子刘得华演过的电影”与“刘德华演过的电影”只需要一次替换“得”为“德”,所以二者之间的距离为1。如果两个字符串S1和S2,长度分别为i,j。那么二者之间的距离D(i,j)可以表示为:

(1)min(i,j)==0,即S1,S2中存在空字符串

D(i,j)=max(i,j)

(2)min(i,j) != 0,

去掉S1或S2的最后一个字符进行比较,分别得到距离

D(i,j-1), D(i-1,j),D(i-1,j-1)

由动态规划的思想可以得到:

D(i,j) = min{D(i,j-1), D(i-1,j),D(i-1,j-1)+sigma(i,j)} 其中sigma(i,j)取值为0或 1,1表示S1和S2最后一个字符不相同,0表示相同。具体实现如下:

intLevenshteinDistance(constchar*s,intlen_s,constchar*t,intlen_t){intcost;if(len_s==)returnlen_t;if(len_t==)returnlen_s;if(s[len_s-1]==t[len_t-1])cost=;elsecost=1;returnminimum(LevenshteinDistance(s,len_s-1,t,len_t)+1,LevenshteinDistance(s,len_s,t,len_t-1)+1,LevenshteinDistance(s,len_s-1,t,len_t-1)+cost);}

2. fuzzywuzzy

Python提供fuzzywuzzy模块,不仅可用于计算两个字符串之间的相似度,而且还提供排序接口能从大量候选集中找到最相似的句子。

(1)安装

需要安装python-Levenshtein库用于计算上述讲解的编辑距离。

pip install python-Levenshtein

pip install fuzzywuzzy

(2)接口说明

两个模块:fuzz, process,fuzz主要用于两字符串之间匹配,process主要用于搜索排序。

fuzz.ratio(s1,s2)直接计算s2和s2之间的相似度,返回值为0-100,100表示完全相同;

fuzz.partial_ratio(S1,S2)部分匹配,如果S1是S2的子串依然返回100;

fuzz.token_sort_ratio(S1,S2)只比较S1,S2单词是否相同,不考虑词语之间的顺序;

fuzz.token_set_ratio(S1,S2)相比fuzz.token_sort_ratio不考虑词语出现的次数;

process.extract(S1, ListS,limit=n),表示从列表ListS中找出Top n与S1最相似的句子;

process.extractOne(S1,ListS),返回最相似的一个

(3)使用

运行结果:

说明str1和str2之间相似度是对称的。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180325G0J3OF00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券