2

我有一个DataSet如下:

+----+---------+-------------------------+
|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])|
+----+---------+-------------------------+

这个数据集的vector一部分就是所谓的“特征矩阵”,它表示“哪个文档包含哪个元素”。让我用一种更容易理解的格式写出特征矩阵:

+--------+------+------+------+------+
|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   |  
+--------+------+------+------+------+

如果你仔细看,你可以看到key0映射到doc0,其中包含元素ad,这就是为什么它有一个由给出的(5,[0,2],[1.0,1.0])向量(向量是 下的列doc0。注意特征矩阵本身不包含element列和第一行,它们只是为了让阅读更容易。

现在,我的目标是使用N哈希函数来获得这个特征矩阵的Minhash 签名

例如 let N = 2,换句话说,使用了两个 Hash 函数,我们也说这两个 Hash 函数如下所示:

(x + 1) % 5
(3x + 1) % 5

是特征矩阵中x的行号。使用这两个哈希函数后,我期待“minhash 签名矩阵”如下所示:

+--------+------+------+------+------+
|        | doc0 | doc1 | doc2 | doc3 |
+--------+------+------+------+------+
|   h1   |   1  |  3   |  0   |  1   |
|   h2   |   0  |  2   |  0   |  0   |
+--------+------+------+------+------+

现在,使用 Spark Java,我如何指定我想使用的这两个哈希函数,然后如何从给定的数据集生成上述 RDD(在这个问题的乞求时)?在实际测试用例中,我可能会使用大约 1000 个哈希函数,但现在了解如何使用 2 就足够了。

我一直在搜索和阅读 Spark 文档,但似乎很难找到一个处理程序。任何提示/指导都会对我有很大帮助。

先感谢您!

现在,我确实查看了文档,并且我有以下代码:

<pre>
    List<Tuple2<String, String[]>> data  = Arrays.asList(
            new Tuple2<>("key0", new String [] {"a", "d"}),
            new Tuple2<>("key1", new String [] {"c"}),
            new Tuple2<>("key2", new String [] {"b", "d", "e"}),
            new Tuple2<>("key3", new String [] {"a", "c", "d"})
    );
    JavaPairRDD<String, String[]> rdd = JavaPairRDD.fromJavaRDD(jsc.parallelize(data));
    rdd.values().foreach(new VoidFunction<String[]>() {
        public void call(String[] rows) throws Exception {
            for ( int i = 0; i < rows.length; i ++ ) {
                System.out.print(rows[i] + "|");                    
            }
            System.out.println();
        }
    });

    StructType schema = StructType.fromDDL("key string, value array<String>");
    Dataset<Row> df = spark.createDataFrame(
            rdd.map((Function<Tuple2<String, String[]>, Row>) value -> RowFactory.create(value._1(), value._2())),
            schema
    );
    df.show(false);

    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);
    model.transform(matrixDoc).show(false);

这是我得到的:
+----+----------+-------------+-------- -------------------------------------------------- ---------------------------------------------+
|键 |值 |向量 |哈希 |
+----+----------+-------------+-------- -------------------------------------------------- ---------------------------------------------+
|key0|[a, d] |(5,[0,1],[1.0,1.0]) |[[7.57939931E8], [-1.974869772E9], [-1.974047307E9], [4.95314097E8], [7.01119548 E8]] |
|key1|[c] |(5,[2],[1.0]) |[[-2.031299587E9], [-1.758749518E9], [-4.86208737E8], [1.247220523E9], [1.702128832E9]]|
|key2|[b, d, e]|(5,[0,3,4],[1.0,1.0,1.0])|[[-1.278435698E9], [-1.542629264E9], [-1.974047307E9], [4.95314097E8],[-1.59182918E9]]|
|key3|[a, c, d]|(5,[0,1,2],[1.0,1.0,1.0])|[[-2.031299587E9], [-1.974869772E9], [-1.974047307E9], [4.95314097E8],[7.01119548E8]] |
+----+----------+-------------+-------- -------------------------------------------------- ---------------------------------------------+

现在,我不知道如何解释结果...... Spark 使用了哪些哈希函数?我可以控制这些功能是什么吗?然后如何将结果散列到不同的存储桶中,以便相同存储桶中的文档是“相同”文档?毕竟,我们不想进行成对比较......

4

0 回答 0