web-dev-qa-db-ja.com

Spark MLLibのTFVector RDDからWordの詳細を取得する方法は?

SparkでHashingTFを使用して用語頻度を作成しました。各単語に_tf.transform_を使用して頻度という用語を取得しました。

しかし、結果はこの形式で表示されています。

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

例えば:

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

tf.indexOf("Word")を使用して、ハッシュバケット内のインデックスを取得できます。

しかし、インデックスを使用してWordを取得するにはどうすればよいですか?

17
Srini

まあ、できません。ハッシュは単射ではないため、逆関数はありません。つまり、無限の数のトークンを1つのバケットにマップできるため、実際にどのトークンが存在するかを判断することはできません。

大きなハッシュを使用していて、一意のトークンの数が比較的少ない場合は、バケットからデータセットの可能なトークンへのルックアップテーブルを作成してみてください。これは1対多のマッピングですが、上記の条件が満たされている場合、競合の数は比較的少ないはずです。

可逆変換が必要な場合は、combine TokenizerStringIndexer を使用して、スパース特徴ベクトルを手動で作成できます。

参照: どのハッシュ関数がSpark HashingTFに使用し、それを複製するにはどうすればよいですか?

編集

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に対応します。

26
zero323