我有一个大小为(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笔记本中的相应代码。