Как получить информацию о словах из TF Vector RDD в Spark ML Lib?

Я создал временную частоту, используя HashingTF в Spark. У меня есть термин частоты с использованием tf.transform для каждого слова.

Но результаты отображаются в этом формате.

[<hashIndexofHashBucketofWord1>,<hashIndexofHashBucketofWord2> ...]
,[termFrequencyofWord1, termFrequencyOfWord2 ....]

например:

(1048576,[105,3116],[1.0,2.0])

Я могу получить индекс в хэш-ведре, используя tf.indexOf("word").

Но как я могу получить слово, используя индекс?

Ответ 1

Ну, ты не можешь. Поскольку хеширование не является инъективным, нет обратной функции. Другими словами, бесконечное количество токенов может отображаться в одном ведре, поэтому невозможно определить, какой из них действительно существует.

Если вы используете большой хеш, а количество уникальных токенов относительно невелико, вы можете попытаться создать таблицу поиска из ведра в возможные маркеры из вашего набора данных. Это сопоставление "один ко многим", но если соблюдены приведенные выше условия, количество конфликтов должно быть относительно низким.

Если вам нужно обратимое преобразование, вы можете использовать комбинацию Tokenizer и StringIndexer и создайте разреженный вектор функции вручную.

Смотрите также: Какая функция хэширования использует Spark для HashingTF и как ее дублировать?

Edit

В Spark 1.5+ (PySpark 1.6+) вы можете использовать CountVectorizer, который применяет обратимое преобразование и сохраняет словарь.

Python:

from pyspark.ml.feature import CountVectorizer

df = sc.parallelize([
    (1, ["foo", "bar"]), (2, ["foo", "foobar", "baz"])
]).toDF(["id", "tokens"])

vectorizer = CountVectorizer(inputCol="tokens", outputCol="features").fit(df)
vectorizer.vocabulary
## ('foo', 'baz', 'bar', 'foobar')

Scala:

import org.apache.spark.ml.feature.{CountVectorizer, CountVectorizerModel}

val df = sc.parallelize(Seq(
    (1, Seq("foo", "bar")), (2, Seq("foo", "foobar", "baz"))
)).toDF("id", "tokens")

val model: CountVectorizerModel = new CountVectorizer()
  .setInputCol("tokens")
  .setOutputCol("features")
  .fit(df)

model.vocabulary
// Array[String] = Array(foo, baz, bar, foobar)

где элемент в 0-й позиции соответствует индексу 0, элемент в 1-й позиции индексирует 1 и т.д.