1

我有两个数据集 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], [-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, dfB_transformed, 25.0, "distance")
.persist(MEMORY_AND_DISK)
.count() 
// 20741736,18820380,20772153


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

不过,我了解哈希冲突的随机性质:

  1. 在这里使用持久性有什么问题吗?
  2. 可以做些什么来提高approxSimilarityJoin的准确性?我看不到任何工具可以评估 BucketLength 的好坏。
  3. 如果我提前知道 A 和 B,我应该在 A 和 B 的联合上训练brp吗?
  4. 遍历 B 并按键查询每条记录是一种更稳定的方法吗?
4

0 回答 0