Реализация minhash LSH с использованием Spark (Java)
Это довольно долго, и я сожалею об этом.
Я пытался реализовать алгоритм Minhash LSH, рассмотренный в главе 3, используя Spark (Java). Я использую игрушку, как это:
+--------+------+------+------+------+
|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.
С другой стороны, model.approxSimilarityJoin(...)
требует, чтобы мы объединили два набора данных, и у меня есть только один набор данных, который имеет 4 документа, и я хотел бы выяснить, какие из этих четырех похожи друг на друга, поэтому у меня нет второго набора данных для присоединения... Просто чтобы попробовать это, я фактически соединил свой единственный набор данных с собой. Исходя из результата, похоже, model.approxSimilarityJoin(...)
Я выполнил парное вычисление Jaccard, и я не вижу никакого влияния, меняя число хэш-функций и т. д., что заставляет меня задуматься о том, где именно была вычислена сигнатура minhash и где произошло разделение на группы / ряды...
Другой звонок, model.approxNearestNeighbors(...)
, фактически запрашивает точку сравнения, и затем модель будет определять ближайшего соседа (ей) к данной точке... Очевидно, это тоже не то, что я хотел, так как у меня есть четыре игрушечных документа, и у меня нет дополнительная контрольная точка.
У меня заканчиваются идеи, поэтому я реализовал свою собственную версию алгоритма, используя API-интерфейсы Spark, но не получил большой поддержки от MinHashLSHModel model
, который действительно заставил меня чувствовать себя плохо. Я думаю, что я что-то упустил...??
Я хотел бы услышать любые мысли, действительно хочу раскрыть тайну.
Спасибо, ребята, заранее!
1 ответ
- Расчет сигнатур minHash происходит в
model.approxSimilarityJoin(...)
сам гдеmodel.transform(...)
Функция вызывается для каждого из входных наборов данных, и хеш-сигнатуры вычисляются перед их соединением и выполнением парного вычисления расстояния по jaccard. Таким образом, влияние изменения количества хеш-функций можно увидеть здесь. - В
model.approxNearestNeighbors(...)
, влияние того же можно увидеть при создании модели с использованиемminHash.fit(...)
функция, в которойtransform(...)
вызывается во входном наборе данных.