微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 BucketedRandomProjectionLSH

如何解决如何使用 BucketedRandomProjectionLSH

我有两个数据集 dfA (5M) 和 dfB (6K)。 我在 spark 2.2 上训练 LSH

val brp = new BucketedRandomProjectionLSH()
  .setBucketLength(2.0)
  .setNumHashTables(3)
  .setInputCol("features")
  .setoutputCol("hashes")

val brp_model = brp.fit(dfA)

val dfA_transformed = brp_model.transform(dfA)
val dfB_transformed = brp_model.transform(dfB)

我跟踪一对距离为 17.59 的记录:

val uidB = 601295446577L

val key_s = dfB_transformed
    .filter(col("uid") === lit(uidB))
    .select("features")
    .as[String].collect()(0)

val key = Vectors.parse(key_s).asML

brp_model
.approxNearestNeighbors(dfA_transformed,key,2,"distance")
.drop("features")
.show(5,false)

+-------------+-----------------------+------------------+
|uid          |hashes                 |distance          |
+-------------+-----------------------+------------------+
|1194000912899|[[0.0],[-1.0],[-1.0]]|17.592033410506907|
|163208761881 |[[0.0],[-1.0]]|19.912395647390348|
+-------------+-----------------------+------------------+

到目前为止,一切都很好。但是当我使用 approxSimilarityJoin 时,我没有得到我的一对 17.59,而是来自 A 的距离远得多的其他人。

.approxSimilarityJoin(dfA_transformed,dfB_transformed,25.0,"distance")
.persist(MEMORY_AND_disK)
.filter(col("datasetB.uid") === lit(uidB))
+-------------+------------+------------------+
|         uidA|        uidB|          distance|
+-------------+------------+------------------+
| 128849023798|601295446577|20.977834057053013|
|1005022360587|601295446577|21.919213729270727|
| 463856471960|601295446577|22.595725081515273|
| 670014905945|601295446577|23.396613579631136|
|1262720389581|601295446577| 24.03850371925476|
|1073741843710|601295446577|24.095447353196946|
+-------------+------------+------------------+

更准确地说,如果我使用 persist 我永远不会得到那对,而没有 persist 我总是看到它存在。

每次运行生成的数据集都显示出大小的剧烈波动:

brp_model
.approxSimilarityJoin(dfA_transformed,"distance")
.persist(MEMORY_AND_disK)
.count() 
// 20741736,18820380,20772153


brp_model
.approxSimilarityJoin(dfA_transformed,"distance")
.count() 
// 19371911,17323851,20074502

我理解散列冲突的随机性,但是:

  1. 在这里使用 persist 有什么问题吗?
  2. 可以采取哪些措施来提高 approxSimilarityJoin 的准确性?我看不到任何工具可以评估 BucketLength 的好坏。
  3. 如果我提前知道 A 和 B,我应该就 A 和 B 的并集训练 brp 吗?
  4. 迭代 B 并按键查询每条记录是否更稳定?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。