一个简单的python fuzzyset实现。
fuzzyset的Python项目详细描述
fuzzyset是一种执行类似于全文搜索的数据结构 根据数据确定可能的错配和近似字符串匹配。
用法
用法很简单。只需在集合中添加一个字符串,稍后再请求它 使用.get或[]:
>>> a = fuzzyset.FuzzySet() >>> a.add("michael axiak") >>> a.get("micael asiak") [(0.8461538461538461, u'michael axiak')]
结果将是一个(score, mached_value)元组的列表。 比分在0到1之间,1是完美的匹配。
对于大约15%的性能提升,还实现了一个cython 版本名为cfuzzyset。所以你可以写下面的,类似于 cStringIO和cPickle:
try: from cfuzzyset import cFuzzySet as FuzzySet except ImportError: from fuzzyset import FuzzySet
构造参数
- iterable: An iterable that yields strings to initialize the data structure with
- gram_size_lower: The lower bound of gram sizes to use, inclusive (see Theory of operation). Default: 2
- gram_size_upper: The upper bound of gram sizes to use, inclusive (see Theory of operation). Default: 3
- use_levenshtein: Whether or not to use the levenshtein distance to determine the match scoring. Default: True
操作理论
添加到数据结构
首先,让我们看看在一个空集合中添加一个字符串“michaelich”。我们首先把字符串分成n克(长度为 N)。所以“michaelich”的三联图看起来像:
'-mi' 'mic' 'ich' 'cha' 'hae' 'ael' 'eli' 'lic' 'ich' 'ch-'
注意,fuzzyset将首先通过删除除空格、逗号和force之外的非单词字符来规范化字符串。 一切都要小写。
接下来fuzzyset本质上在这些grams上创建一个反向索引。维护一本字典,上面写着:
'mic' -> (1, 0) 'ich' -> (2, 0) ...
还有一个列表如下:
[(3.31, 'michaelich')]
注意,我们在构造函数中为allgrams从gram_size_lower到gram_size_upper维护这个反向索引。 这在一秒钟内变得很重要。
检索
为了搜索数据结构,我们取查询字符串的n个grams并执行反向索引查找。为了说明, 让我们考虑在包含'michaelich'的虚拟集合中查找'michael',其中gram_size_upper 和gram_size_lower参数是默认值(分别为3和2)。
我们首先考虑所有三元组(值gram_size_upper)。这些克是:
'-mi' 'mic' 'ich' 'cha' 'el-'
然后,我们创建一个集合中任何元素的列表,其中至少有一个以上列出的trigram的出现。请注意 这只是查了5次字典。对于每个匹配的元素,我们计算 每个元素和查询字符串。然后我们排序得到最相似的匹配元素。
如果use_levenshtein为false,则返回具有相同余弦相似性的所有顶部匹配元素。
如果use_levenshtein为真,那么我们将可能的搜索空间截断为50,根据levenshtein计算得分 距离(以便我们处理换位),并基于此返回。
如果没有匹配的三元图,我们就用双元图重新尝试(注意,如果没有匹配的话, 不匹配会很快)。bigram搜索总是比较慢,因为要订购的集合要大得多。
安装
^{tt16}$
许可证
bsd