21

我想使用局部敏感哈希来近似匹配字符串。我有许多字符串> 10M,可能包含拼写错误。对于每个字符串,我想与所有其他字符串进行比较,并根据某个阈值选择具有编辑距离的字符串。

也就是说,简单的解决方案需要 O(n^2) 比较。为了避免这个问题,我正在考虑使用Locality Sensitive Hashing。然后接近相似的字符串会导致相同的桶,我只需要在桶内搜索。所以它是 O(n*C),其中 C 是桶大小。

但是,我不明白如何表示字符串。如果是文本,我会在向量空间中表示。我的主要问题是这是否可以使用 LSH 以及字符串的适当向量表示来处理。

我可以使用已经实现的库来完成这项任务吗?还是取决于我的问题,所以我必须自己实施?有没有这样做的python包?

4

1 回答 1

28

我在该主题上找到的最好的学术资源是《海量数据集挖掘》的第 3 章,它对局部敏感散列和 minhashing 进行了很棒的概述。

非常简单地说,这个想法是获取几个字符串,将这些字符串向量化,然后在结果向量上传递一个滑动窗口。如果两个向量在相同的窗口位置具有相同的值,则将它们标记为更细粒度的相似性分析的候选。

Python 数据草图库 ( pip install datasketch) 中有一个很棒的实现。这是一个示例,显示您可以捕获模糊字符串相似性:

from datasketch import MinHash, MinHashLSH
from nltk import ngrams

data = ['minhash is a probabilistic data structure for estimating the similarity between datasets',
  'finhash dis fa frobabilistic fata ftructure for festimating the fimilarity fetween fatasets',
  'weights controls the relative importance between minizing false positive',
  'wfights cfntrols the rflative ifportance befween minizing fflse posftive',
]

# Create an MinHashLSH index optimized for Jaccard threshold 0.5,
# that accepts MinHash objects with 128 permutations functions
lsh = MinHashLSH(threshold=0.4, num_perm=128)

# Create MinHash objects
minhashes = {}
for c, i in enumerate(data):
  minhash = MinHash(num_perm=128)
  for d in ngrams(i, 3):
    minhash.update("".join(d).encode('utf-8'))
  lsh.insert(c, minhash)
  minhashes[c] = minhash

for i in xrange(len(minhashes.keys())):
  result = lsh.query(minhashes[i])
  print "Candidates with Jaccard similarity > 0.4 for input", i, ":", result

这将返回:

Candidates with Jaccard similarity > 0.4 for input 0 : [0, 1]
Candidates with Jaccard similarity > 0.4 for input 1 : [0, 1]
Candidates with Jaccard similarity > 0.4 for input 2 : [2, 3]
Candidates with Jaccard similarity > 0.4 for input 3 : [2, 3]
于 2017-01-22T15:52:21.247 回答