Как рассчитать сигнатуру Minhash для заданной матрицы характеристик с помощью Spark

У меня есть 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, который содержит элемент a а также dпоэтому у него есть вектор (5,[0,2],[1.0,1.0]) (вектор является столбцом под doc0, Обратите внимание, что сама матрица характеристик не содержит element столбец и первый ряд, они есть только для облегчения чтения.

Теперь моя цель - использовать N хэш-функции для получения сигнатуры Minhash этой характеристической матрицы.

Например, пусть N = 2другими словами, используются две хеш-функции, и давайте также скажем, что эти две хеш-функции приведены ниже:

(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.01119548E8]]   |
|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? у меня есть контроль над этими функциями? Как я могу затем хэшировать результат в разные группы, чтобы документы в одних и тех же группах были "одинаковыми"? В конце концов, мы не хотим делать парное сравнение...

0 ответов

Другие вопросы по тегам