更快地实施LSH(AND-OR)

时间:2018-11-17 06:27:51

标签: python locality-sensitive-hash minhash

我有一个大小为(160000,3200)的数据集,其中所有元素都是零或一。我想找到类似的候选人。我使用Minhash使用一个for循环将其哈希到(160000,200),花了大约两分钟,对此我感到满意。我使用从“大量数据集的挖掘”第3章中学到的AND-OR模式实现了局部敏感哈希(LSH),以在for循环中使用for循环查找候选对。我想减少这个时间。有没有更快的方法?

  

这是我完成LSH的方式-Minhash签名长度(n)= 200,   子签名长度(r)= 5,频段数(b)= 40。

bucket-of-ids = 'empty list of dictionaries of 
                 length 40'
for each-user in 160000:
  for each-band in 40:
    r_signature = string(jth 5 elements)
    if r_signature in bucket-of-ids[band]:
       'add id of user to dictionary of band 
        using r_signature as key'
    else :
       'create r_signature as new key and then 
        add user id to it as list of values'

大小为(160000,200)的Minhash签名矩阵是一个numpy数组。我的想法是,如果我可以廉价地将其转换为(160000,40)数组,其中新数组的每个元素由minhash数组的5个元素组成,那么也许我可以使用numpy.unique()获得每列的唯一r_signature用作候选ID字典的键。我是python以及编码的新手。我想不出一种优化它以使其运行更快的方法。

以下是代码和数据的链接: https://colab.research.google.com/drive/1HetBrWFRYqwUxn0v7wIwS7COBaNmusfD

注意:我观察到Minhash部分花费的时间随数据线性增加(在这种情况下为用户数),而LSH部分花费的时间则呈非线性增加(前6.25%花费了20.15秒而最后6.25%则花费了132.3秒)。我认为,如果可能的话,有必要对这部分进行优化以正确地缩放数据。我相信检查字典中是否已经存在密钥是对此负责的代码的一部分。

更新:尽管我最终在for循环中两次使用for循环,但通过避免检查dict中是否存在键来解决此问题。现在,对于160000个候选对象,需要310秒,并且所花费的时间与数据呈线性比例关系。我已经更新了Google-colab笔记本中的相应代码。

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用datasketch library?它具有Minhash和LSH算法的实现。