首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >你能推荐一个好的minhash实现吗?

你能推荐一个好的minhash实现吗?
EN

Stack Overflow用户
提问于 2013-01-26 11:01:44
回答 4查看 20.5K关注 0票数 19

我正在努力寻找一个可以在我的工作中使用的minhash开源实现。

我需要的功能非常简单,给定一个set作为输入,实现应该返回它的minhash。

最好是python或C实现,以防我需要修改它才能为我工作。

任何提示都会有很大的帮助。

致以问候。

EN

回答 4

Stack Overflow用户

发布于 2013-05-11 05:07:13

您应该按顺序查看以下开源库。它们都是用Python编写的,向您展示了如何使用LSH/MinHash计算文档相似度:

lsh

LSHHDC : Locality-Sensitive Hashing based High Dimensional Clustering

MinHash

票数 13
EN

Stack Overflow用户

发布于 2015-04-04 21:03:08

看一看datasketch library。它支持序列化和合并。它是用纯python实现的,没有外部依赖。Go version具有完全相同的功能。

票数 12
EN

Stack Overflow用户

发布于 2018-09-27 18:14:16

如果您对学习minhash算法感兴趣,这里有一个非常简单的实现,并进行了一些讨论。

为了为集合生成MinHash签名,我们创建一个长度为$N$的向量,其中所有值都设置为正无穷大。我们还创建了接受输入整数并对该值进行置换的$N$函数。$i^{th}$函数将单独负责更新向量中的$i^{th}$值。给定这些值,我们可以通过将集合中的每个值传递给每个$N$置换函数来计算集合的最小散列签名。如果$i^{th}$置换函数的输出低于向量的最小哈希值,我们就用置换函数的输出替换该值(这就是为什么哈希值被称为“$i^{th}$ -hash值”)。让我们用Python实现这一点:

代码语言:javascript
复制
from scipy.spatial.distance import cosine
from random import randint
import numpy as np

# specify the length of each minhash vector
N = 128
max_val = (2**32)-1

# create N tuples that will serve as permutation functions
# these permutation values are used to hash all input sets
perms = [ (randint(0,max_val), randint(0,max_val)) for i in range(N)]

# initialize a sample minhash vector of length N
# each record will be represented by its own vec
vec = [float('inf') for i in range(N)]

def minhash(s, prime=4294967311):
  '''
  Given a set `s`, pass each member of the set through all permutation
  functions, and set the `ith` position of `vec` to the `ith` permutation
  function's output if that output is smaller than `vec[i]`.
  '''
  # initialize a minhash of length N with positive infinity values
  vec = [float('inf') for i in range(N)]

  for val in s:

    # ensure s is composed of integers
    if not isinstance(val, int): val = hash(val)

    # loop over each "permutation function"
    for perm_idx, perm_vals in enumerate(perms):
      a, b = perm_vals

      # pass `val` through the `ith` permutation function
      output = (a * val + b) % prime

      # conditionally update the `ith` value of vec
      if vec[perm_idx] > output:
        vec[perm_idx] = output

  # the returned vector represents the minimum hash of the set s
  return vec

非那样做不行!为了演示如何使用此实现,让我们仅举一个简单的示例:

代码语言:javascript
复制
import numpy as np

# specify some input sets
data1 = set(['minhash', 'is', 'a', 'probabilistic', 'data', 'structure', 'for',
        'estimating', 'the', 'similarity', 'between', 'datasets'])
data2 = set(['minhash', 'is', 'a', 'probability', 'data', 'structure', 'for',
        'estimating', 'the', 'similarity', 'between', 'documents'])

# get the minhash vectors for each input set
vec1 = minhash(data1)
vec2 = minhash(data2)

# divide both vectors by their max values to scale values {0:1}
vec1 = np.array(vec1) / max(vec1)
vec2 = np.array(vec2) / max(vec2)

# measure the similarity between the vectors using cosine similarity
print( ' * similarity:', 1 - cosine(vec1, vec2) )

这将返回~.9作为这些向量之间相似性的度量。

虽然我们只比较上面的两个minhash向量,但我们可以通过使用“位置敏感散列”来更简单地比较它们。为此,我们可以构建一个字典,将每个$W$ MinHash矢量分量序列映射到构造MinHash矢量的集合的唯一标识符。例如,如果W = 4和我们有一个集合S1,我们从它导出一个MinHash向量[111,512,736,927,817...],我们会将S1标识符添加到该向量中四个MinHash值的每个序列中:

代码语言:javascript
复制
d[111-512-736-927].append('S1')
d[512-736-927-817].append('S1')
...

一旦我们对所有的集合都这样做了,我们就可以检查字典中的每个键,如果这个键有多个不同的集合id,我们就有理由相信这些集合是相似的。事实上,一对集合id在字典中的单个值内出现的次数越多,两个集合之间的相似性就越大。以这种方式处理我们的数据,我们可以将识别所有相似集对的复杂性降低到大致线性的时间!

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14533420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档