我试图寻找一个最小哈希开源实现,我可以利用我的工作。
我需要的功能很简单,给定一组输入,执行应返回其最小哈希。
一个Python或C的实现将是首选,以防万一我需要破解它为我工作。
任何指针将有很大的帮助。
问候。
我试图寻找一个最小哈希开源实现,我可以利用我的工作。
我需要的功能很简单,给定一组输入,执行应返回其最小哈希。
一个Python或C的实现将是首选,以防万一我需要破解它为我工作。
任何指针将有很大的帮助。
问候。
你应该看看下面的开源库,为了。 他们都是在Python,并展示如何使用LSH /最小哈希计算文档相似性:
LSH
LSHHDC:局部性敏感哈希基于高维聚类
最小哈希
看看在datasketch库 。 它支持序列化和合并。 它是纯Python实现的,没有外部的依赖。 在围棋版本具有完全相同的功能。
如果你有兴趣在研究最小哈希算法,这里是一个非常简单的实现了一些讨论。
要生成一组最小哈希签名,我们创建长的矢量$N$
其中所有的值设置为正无穷大。 我们还创建了$N$
接受某个输入整数和置换该值的功能。 的$i^{th}$
功能将用于更新单独负责$i^{th}$
在矢量值。 鉴于这些值,我们可以计算的的最小哈希签名由一组传递的每个值通过每个的设置$N$
置换函数。 如果输出$i^{th}$
置换函数小于下$i^{th}$
矢量的值,我们用来自置换函数的输出替换值(这就是为什么该散列被称为“ 最小 -hash”)。 让我们实现这个在Python:
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
这里的所有都是它的! 为了展示我们如何使用这个实现,让我们只是一个简单的例子:
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) )
这将返回〜0.9,因为这些矢量之间的相似性的测量。
虽然我们比较上面只有两个最小哈希载体,我们可以通过使用“局部敏感哈希”更简单地进行比较。 要做到这一点,我们可以构建$ W $最小哈希矢量分量的每个序列映射到从中构建了最小哈希向量组的唯一标识符的字典。 例如,如果W = 4
,我们有一组S1
从中我们导出最小哈希矢量[111,512,736,927,817...]
我们将在添加S1
标识符的该矢量4个最小哈希值中的每个序列:
d[111-512-736-927].append('S1')
d[512-736-927-817].append('S1')
...
一旦我们做到这一点对所有套组,我们可以检查字典中的每个键,如果该键有多个不同的集ID的,我们有理由相信,这些集是相似的。 实际上,次数越大的一对组ID的的字典中的一个单一的值内发生,这两个集合之间的相似性越大。 以这种方式处理我们的数据,我们可以减少查明所有对类似的套大致线性时间的复杂性!
我建议你这个库 ,特别是如果你需要持久性。 在这里,你可以使用Redis的存储/检索您的所有数据。
你必须选择一个Redis的数据库,或者简单地使用内置的内存Python字典的选项。
使用Redis的,至少如果Redis的服务器在本地机器上运行的性能,都几乎相同通过标准的Python字典实现。
你只需要指定一个配置字典,如
config = {"redis": {"host": 'localhost', "port": '6739', "db": 0}}
并把它作为参数传递给LSHash
类的构造函数。