Beh, non è possibile. Poiché l'hashing non è iniettivo, non esiste una funzione inversa. In altre parole, il numero infinito di token può essere mappato su un singolo bucket, quindi è impossibile stabilire quale sia effettivamente lì.
Se si utilizza un hash di grandi dimensioni e il numero di token unici è relativamente basso, è possibile provare a creare una tabella di ricerca da bucket a possibili token dal set di dati. È una mappatura uno-a-molti, ma se le condizioni di cui sopra sono soddisfatte, il numero di conflitti dovrebbe essere relativamente basso.
Se è necessaria una trasformazione reversibile è possibile utilizzare Combina Tokenizer
e StringIndexer
e creare manualmente un vettore di funzionalità sparse.
Consulta anche: What hashing function does Spark use for HashingTF and how do I duplicate it?
Edit:
In Spark 1.5 + (PySpark 1.6+) è possibile utilizzare CountVectorizer
che si applica trasformazione reversibile e memorizza il vocabolario.
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)
dove elemento nella posizione 0th corrisponde all'indice 0, elemento alla 1a posizione di indice 1 e così via.
Vorrei solo aggiungere che come si può vedere nella [documenti] (https://spark.apache.org/docs/1.6.0/api/python/pyspark.mllib.html) dalla versione 1.2.0 , puoi chiamare indexOf (term) – Matt