2015-08-29 22 views
9

Utworzyłem Term Frequency using HashingTF w Spark. Mam termin częstotliwości przy użyciu tf.transform dla każdego słowa.Jak uzyskać szczegółowe informacje o słowie z TF Vector RDD w Spark ML Lib?

Jednak wyniki są wyświetlane w tym formacie.

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

np

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

jestem w stanie uzyskać indeks mieszania wiadra, używając tf.indexOf("word").

Ale jak uzyskać słowo przy użyciu indeksu?

Odpowiedz

20

Cóż, nie możesz. Ponieważ mieszanie nie jest iniekcyjne, nie ma funkcji odwrotnej. Innymi słowy, nieskończona liczba żetonów może zostać odwzorowana na pojedyncze wiadro, więc nie można stwierdzić, który z nich istnieje.

Jeśli używasz dużego skrótu, a liczba unikalnych tokenów jest stosunkowo niska, możesz spróbować utworzyć tabelę odnośników z segmentu do możliwych tokenów z zestawu danych. Jest to mapowanie jeden do wielu, ale jeśli warunki są powyżej, liczba konfliktów powinna być stosunkowo niska.

Jeśli potrzebujesz odwracalnej transformacji, możesz użyć kombajnów Tokenizer i StringIndexer i ręcznie zbudować rzadki wektor funkcji.

Zobacz także: What hashing function does Spark use for HashingTF and how do I duplicate it?

Edit:

W Spark 1.5+ (PySpark 1.6 +) można użyć CountVectorizer która dotyczy odwracalny transformacji i zapisuje słownictwo.

Pythonie

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) 

gdzie elementem w położeniu 0th odpowiada indeksie 0, element 1 w stanie indeksie 1 i tak dalej.

+1

Chciałbym tylko dodać, że jak widać w [docs] (https://spark.apache.org/docs/1.6.0/api/python/pyspark.mllib.html) od 1.2.0 możesz zadzwonić do indexOf (termin) – Matt