Python的datasketch库中的MinHashLSH

1、简介

在工作中需要对海量数据进行相似性查找,即对微博全量用户进行关注相似度计算,计算得到每个用户关注相似度最高的TOP-N个用户,首先想到的是利用简单的协同过滤,先定义相似性度量(cos,Pearson,Jaccard),然后利用通过两两计算相似度,计算top-n进行筛选,这种方法的时间复杂度为O(n^2)(对于每个用户,都和其他任意一个用户进行了比较)。

但是在实际应用中,对于亿级的用户量,这个时间复杂度是无法忍受的。同时,对于高维稀疏数据,计算相似度同样很耗时,即O(n^2)的系数无法省略。这时,我们便需要一些近似算法,牺牲一些精度来提高计算效率,在这里简要介绍一下MinHashing,LSH。

假设您有很多集合。给出一个查询(也是一个集合),您想要在集合中查找Jaccard相似度高于特定阈值的集合,并希望对许多其他查询进行处理。为了有效地做到这一点,您可以为每个集合创建一个MinHash,当查询到来时,您可以计算查询MinHash与集合中所有MinHash之间的Jaccard相似度,并返回满足阈值的集合。

所述方法仍然是O(n^2)算法,这意味着查询成本相对于集合数量线性增加。一个流行的替代方法是使用本地敏感哈希(LSH:Locality Sensitive Hashing )索引。LSH可以与MinHash一起使用,以实现亚线性查询成本-这是一项巨大的改进。

LSH的属性保证了具有较高Jaccard相似度的集合总是比具有较低相似度的集合具有更高的返回概率。此外,可以对LSH进行优化,以使在阈值处出现概率“跳跃”,从而使合格的集比其他的更有可能获得返回。

LSH在海量高维稀疏数据中有很好的应用场景(文本,图片,结构数据均可以用),速度快,计算复杂度低。

1.1 MinHashing

1.2 LSH

上面的MinHashing解决了高维稀疏向量的运算,但是计算两两用户的相似度,其时间复杂度仍然是O(n^2),显然这个计算量还没有得到改善,这时我们如果能将用户分到不同的桶,只比较可能相似的用户,即相似用户以较大可能分到同一个桶内,这样不相似的用户基本不会发生比较,降低计算复杂度,LSH即为这样的方法。

LSH方法基于这样的思想:在原空间中很近(相似)的两个点,经过LSH哈希函数的映射后,有很大概率它们的哈希是一样的;而两个离的很远(不相似)的两个点,映射后,它们的哈希值相等的概率很小。

2、datasketch.MinHashLSH参数详解

http://ekzhu.com/datasketch/documentation.html#datasketch.MinHashLSH

3、案例

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 range(len(minhashes.keys())):
    result = lsh.query(minhashes[i])
    print("Candidates with Jaccard similarity > 0.5 for input", i,":", result)

结果打印

参考文献

http://ekzhu.com/datasketch/lsh.html

https://zhuanlan.zhihu.com/p/80638247

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值