使用min-hash实现局部敏感哈希

时间:2013-01-07 21:11:59

标签: algorithm locality-sensitive-hash minhash

我已经阅读了许多使用min-hash实现LSH(局部敏感哈希)的教程,文档和代码片段。

LSH试图通过散列随机子集并聚合这些子集来找到两组的Jaccard系数。我查看了code.google.com中的实现,但也无法理解他们的方法。我理解论文Google news personalization: scalable online collaborative filtering,但我无法理解其中的任何实现。

有人可以用简单的话来解释我如何用MinHash实现LSH吗?

2 个答案:

答案 0 :(得分:7)

您希望实现min-hash算法,但 LSH本身。最小散列 LSH技术。因此,LSH通常不接近Jaccard系数,min-hashing的特定方法确实如此。

Mining of Massive Datasets, Chapter 3 by Anand Rajaraman and Jeff Ullman中给出了介绍。

答案 1 :(得分:0)

集合的最小哈希表示是估计Jaccard相似性的有效方法,给定为两个最小哈希集之间的共享哈希的相对数量:

import random



def minhash():
    d1 = set(random.randint(0, 2000) for _ in range(1000))
    d2 = set(random.randint(0, 2000) for _ in range(1000))
    jacc_sim = len(d1.intersection(d2)) / len(d1.union(d2))
    print("jaccard similarity: {}".format(jacc_sim))

    N_HASHES = 200
    hash_funcs = []
    for i in range(N_HASHES):
        hash_funcs.append(universal_hashing())

    m1 = [min([h(e) for e in d1]) for h in hash_funcs]
    m2 = [min([h(e) for e in d2]) for h in hash_funcs]
    minhash_sim = sum(int(m1[i] == m2[i]) for i in range(N_HASHES)) / N_HASHES
    print("min-hash similarity: {}".format(minhash_sim))



def universal_hashing():
    def rand_prime():
        while True:
            p = random.randrange(2 ** 32, 2 ** 34, 2)
            if all(p % n != 0 for n in range(3, int((p ** 0.5) + 1), 2)):
                return p
    m = 2 ** 32 - 1
    p = rand_prime()
    a = random.randint(0, p)
    if a % 2 == 0:
        a += 1
    b = random.randint(0, p)
    def h(x):
        return ((a * x + b) % p) % m
    return h




if __name__ == "__main__":
    minhash()
相关问题