2016-08-08 59 views
4

Fragen Sie sich, ob es eine eingebaute Spark-Funktion gibt, um 1-, 2-, n-Gramm-Funktionen in einem einzigen Vokabular zu kombinieren. Einstellung n=2 in NGram gefolgt von Aufruf von CountVectorizer ergibt ein Wörterbuch mit nur 2-Gramm. Was ich wirklich will, ist, alle häufigen 1-Gramm, 2-Gramm, usw. in einem Wörterbuch für mein Korpus zu kombinieren.Wie kombiniere ich N-Gramm zu einem Vokabular in Spark?

Antwort

7

Sie können separate Modelle NGram und CountVectorizer trainieren und unter Verwendung von VectorAssembler zusammenführen.

from pyspark.ml.feature import NGram, CountVectorizer, VectorAssembler 
from pyspark.ml import Pipeline 


def build_ngrams(inputCol="tokens", n=3): 

    ngrams = [ 
     NGram(n=i, inputCol="tokens", outputCol="{0}_grams".format(i)) 
     for i in range(1, n + 1) 
    ] 

    vectorizers = [ 
     CountVectorizer(inputCol="{0}_grams".format(i), 
      outputCol="{0}_counts".format(i)) 
     for i in range(1, n + 1) 
    ] 

    assembler = [VectorAssembler(
     inputCols=["{0}_counts".format(i) for i in range(1, n + 1)], 
     outputCol="features" 
    )] 

    return Pipeline(stages=ngrams + vectorizers + assembler) 

Beispiel Nutzung:

df = spark.createDataFrame([ 
    (1, ["a", "b", "c", "d"]), 
    (2, ["d", "e", "d"]) 
], ("id", "tokens")) 

build_ngrams().fit(df).transform(df) 
+1

Danke, das durchaus Sinn macht. –

+0

Eine Alternative wäre, die Unigramme und Bigramme mit 'VectorAssembler' zu kombinieren und dann einen einzelnen Vektor dem' CountVectorizer' zuzuführen. Ich denke, das ist mehr im Einklang mit Scikit-lernen CountVectorizer. Nicht sicher, ob es wirklich einen Unterschied macht. –

+1

@danieln Wenn sich nichts geändert hat, kann 'VectorAssembler' keine Arrays von Strings erstellen. – zero323