如何从Spark ML Lib中的TF Vector RDD获取单词详细信息?

时间:2015-08-29 11:46:35

标签: apache-spark apache-spark-mllib tf-idf apache-spark-ml

我在Spark中使用HashingTF创建了术语频率。我为每个单词使用tf.transform获得了术语频率。

但结果以这种格式显示。

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

例如:

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

我可以使用tf.indexOf("word")在哈希桶中获取索引。

但是,我怎样才能使用索引得到这个词?

1 个答案:

答案 0 :(得分:25)

嗯,你不能。由于散列是非单射的,因此没有反函数。换句话说,无限数量的令牌可以映射到一个桶,因此无法确定哪一个实际存在。

如果您使用大型哈希并且唯一令牌的数量相对较低,那么您可以尝试从数据集中创建从存储桶到可能令牌的查找表。它是一对多映射,但如果满足上述条件,则冲突的数量应相对较低。

如果您需要可逆转换,可以使用合并TokenizerStringIndexer并手动构建稀疏特征向量。

另请参阅:What hashing function does Spark use for HashingTF and how do I duplicate it?

修改

在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,依此类推。