2

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

这是我如何完成 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 循环两次。现在,160000 个候选人需要 310 秒,并且所花费的时间与数据呈线性关系。我已经更新了 google-colab notebook 中的相应代码。

4

1 回答 1

0

您是否尝试过使用数据草图库?它具有 Minhash 和 LSH 算法的实现。

于 2019-04-11T13:54:04.250 回答