这很长,我很抱歉。
我一直在尝试使用Spark(Java)实现chapter 3中讨论的Minhash LSH算法。我正在使用这样的玩具问题:
+--------+------+------+------+------+
|element | doc0 | doc1 | doc2 | doc3 |
+--------+------+------+------+------+
| d | 1 | 0 | 1 | 1 |
| c | 0 | 1 | 0 | 1 |
| a | 1 | 0 | 0 | 1 |
| b | 0 | 0 | 1 | 0 |
| e | 0 | 0 | 1 | 0 |
+--------+------+------+------+------+
目标是在这四个文档(doc0
,doc1
,doc2
和doc3
)中识别哪些文档彼此相似。显然,唯一可能的候选对是doc0
和doc3
。
使用Spark的支持,生成以下"特征矩阵"就此而言,我可以达到:
+----+---------+-------------------------+
|key |value |vector |
+----+---------+-------------------------+
|key0|[a, d] |(5,[0,2],[1.0,1.0]) |
|key1|[c] |(5,[1],[1.0]) |
|key2|[b, d, e]|(5,[0,3,4],[1.0,1.0,1.0])|
|key3|[a, c, d]|(5,[0,1,2],[1.0,1.0,1.0])|
+----+---------+-------------------------+
以下是代码片段:
CountVectorizer vectorizer = new CountVectorizer().setInputCol("value").setOutputCol("vector").setBinary(false);
Dataset<Row> matrixDoc = vectorizer.fit(df).transform(df);
MinHashLSH mh = new MinHashLSH()
.setNumHashTables(5)
.setInputCol("vector")
.setOutputCol("hashes");
MinHashLSHModel model = mh.fit(matrixDoc);
现在,MinHashLSHModel model
似乎有两个可以使用的主要调用:model.approxSimilarityJoin(...)
和model.approxNearestNeighbors(...)
。有关使用这两个调用的示例,请访问:https://spark.apache.org/docs/latest/ml-features.html#lsh-algorithms
另一方面,model.approxSimilarityJoin(...)
要求我们加入两个数据集,而我只有一个数据集有4个文档,我想弄清楚这四个文档中哪些是相似的,所以我没有第二个数据集可以加入...只是试一试,我实际上加入了我唯一的数据集。基于结果,似乎model.approxSimilarityJoin(...)
只做了一对配对的Jaccard计算,并且我没有通过改变Hash函数的数量等来看到任何影响,让我想知道minhash签名的确切位置在哪里计算出带/行分区的位置......
另一个调用model.approxNearestNeighbors(...)
实际上要求一个比较点,然后模型会识别到这个给定点的最近邻居......显然,这不是我想要的,因为我有四个玩具文件,我没有额外的参考点。
我的想法已经用完了,所以我继续使用Spark API实现了我自己的算法版本,但没有来自MinHashLSHModel model
的大量支持,这让我感觉很糟糕。我想我一定错过了什么...... ??
我很想听到任何想法,真的希望解开这个谜。
提前谢谢你们!
答案 0 :(得分:1)
model.approxSimilarityJoin(...)
本身model.transform(...)
在每个输入数据集和散列签名上调用函数
在加入它们并做成对的jaccard之前计算
距离计算。那么,改变哈希数的影响
功能可以在这里看到。 model.approxNearestNeighbors(...)
中,
使用时创建模型可以看到相同的影响
调用minHash.fit(...)
的{{1}}函数
输入数据集。