2015-10-12 9 views
12

Ich habe erfolgreich ein LDA-Modell in Funken über den Python API trainiert:Extract Dokument-Thema Matrix aus Pyspark LDA Modell

from pyspark.mllib.clustering import LDA 
model=LDA.train(corpus,k=10) 

Die komplett funktioniert gut, aber ich muß jetzt das Dokument -topic Matrix für das LDA-Modell, aber soweit ich sagen kann alles, was ich bekommen kann, ist das Wort -Thema, mit model.topicsMatrix().

Gibt es eine Möglichkeit, die Dokument-Thema-Matrix aus dem LDA-Modell zu erhalten, und wenn nicht, gibt es eine alternative Methode (außer LDA von Grund auf neu zu implementieren) in Spark ein LDA-Modell auszuführen, das mir das Ergebnis gibt Ich brauche?

EDIT:

um ein wenig Nach dem Graben, ich die Dokumentation für DistributedLDAModel in der Java api gefunden, das hat ein topicDistributions() dass ich denke, genau das, was ich hier brauchen (aber ich bin 100% sicher, ob die LDAModel in Pyspark ist in der Tat ein DistributedLDAModel unter der Haube ...).

Auf jedem Fall ich bin in der Lage, diese Methode indirekt zu nennen wie so, ohne offenkundiges Versagen:

In [127]: model.call('topicDistributions') 
Out[127]: MapPartitionsRDD[3156] at mapPartitions at PythonMLLibAPI.scala:1480 

Aber wenn ich die Ergebnisse betrachtet eigentlich alles, was ich bekommen ist, dass die Ergebnis-String mir zu sagen, ist eigentlich ein Scala Tupel (glaube ich):

In [128]: model.call('topicDistributions').take(5) 
Out[128]: 
[{u'__class__': u'scala.Tuple2'}, 
{u'__class__': u'scala.Tuple2'}, 
{u'__class__': u'scala.Tuple2'}, 
{u'__class__': u'scala.Tuple2'}, 
{u'__class__': u'scala.Tuple2'}] 

dies ist in der Regel der richtige Ansatz Vielleicht, aber gibt es, um die tatsächlichen Ergebnisse zu bekommen?

+1

Ich weiß, dass die LDA-Funktionalität in Funken noch in der Entwicklung ist, aber es scheint seltsam, dass es zu bekommen diese Informationen aus dem Modell keine einfache Art und Weise ist ... – moustachio

+0

Ich denke, es gibt ein anderes Problem hier. Wie von Jason Lenderman (http://stackoverflow.com/users/2480873/jason-lenderman) gezeigt, implementiert Spark LDA keine LSA, sondern eine Variante von PLSI. Es macht diese Matrizen direkt weniger nützlich. Siehe auch http://StackOverflow.com/a/32953813/1560062 – zero323

+0

Ich sehe, aber in diesem Fall wäre eine mehr oder weniger gleichwertige Lösung, Themen für die ursprünglichen Schulungsdokumente ähnlich der in der verknüpften Frage beschriebenen Methode vorherzusagen Soweit ich das beurteilen kann, sind die notwendigen Methoden in der Python-API nicht implementiert. Sind sie irgendwo versteckt oder gibt es eine andere Möglichkeit, dies in Pyspark zu erreichen? – moustachio

Antwort

4

Nach ausführlicher Recherche ist dies mit der Python API auf der aktuellen Version von Spark (1.5.1) definitiv nicht möglich. Aber in Scala, es ist ziemlich einfach (da ein RDD documents auf dem Zug):

import org.apache.spark.mllib.clustering.{LDA, DistributedLDAModel} 

// first generate RDD of documents... 

val numTopics = 10 
val lda = new LDA().setK(numTopics).setMaxIterations(10) 
val ldaModel = lda.run(documents) 

# then convert to distributed LDA model 
val distLDAModel = ldaModel.asInstanceOf[DistributedLDAModel] 

dann das Dokument Thema Verteilungen zu erhalten ist so einfach wie:

distLDAModel.topicDistributions 
2

Wie Spark 2.0 Sie verwenden können, transform() als eine Methode von pyspark.ml.clustering.DistributedLDAModel. Ich habe das gerade auf dem 20 Newsgroups-Datensatz von scikit-learn ausprobiert und es funktioniert. Sehen Sie sich die zurückgegebene vectors an, die eine Verteilung zu Themen für ein Dokument darstellt.

>>> test_results = ldaModel.transform(wordVecs) 
Row(filename='/home/jovyan/work/data/20news_home/20news-bydate-test/rec.autos/103343', target=7, text='I am a little confused on all of the models of the 88-89 bonnevilles.\nI have heard of the LE SE LSE SSE SSEI. Could someone tell me the\ndifferences are far as features or performance. I am also curious to\nknow what the book value is for prefereably the 89 model. And how much\nless than book value can you usually get them for. In other words how\nmuch are they in demand this time of year. I have heard that the mid-spring\nearly summer is the best time to buy.', tokens=['little', 'confused', 'models', 'bonnevilles', 'someone', 'differences', 'features', 'performance', 'curious', 'prefereably', 'usually', 'demand', 'spring', 'summer'], vectors=SparseVector(10977, {28: 1.0, 29: 1.0, 152: 1.0, 301: 1.0, 496: 1.0, 552: 1.0, 571: 1.0, 839: 1.0, 1114: 1.0, 1281: 1.0, 1288: 1.0, 1624: 1.0}), topicDistribution=DenseVector([0.0462, 0.0538, 0.045, 0.0473, 0.0545, 0.0487, 0.0529, 0.0535, 0.0467, 0.0549, 0.051, 0.0466, 0.045, 0.0487, 0.0482, 0.0509, 0.054, 0.0472, 0.0547, 0.0501])) 
+0

Hinweis für Moderatoren, ich habe einen anderen Beitrag gelöscht, den ich mit dieser Antwort erstellt habe. –

+1

Was ist WordVecs in Ihrem Beispiel? –

3

Im Folgenden wird die obige Antwort für PySpark und Spark 2.0 erweitert.

Ich hoffe, Sie entschuldigen mich dafür, dies als Antwort anstatt als Kommentar zu veröffentlichen, aber mir fehlt der Rep im Moment.

Ich gehe davon aus, dass Sie ein geschultes LDA-Modell aus einem Korpus wie so gemacht haben:

lda = LDA(k=NUM_TOPICS, optimizer="em") 
ldaModel = lda.fit(corpus) # Where corpus is a dataframe with 'features'. 

Um ein Dokument in ein Thema Verteilung zu konvertieren, erstellen wir einen Datenrahmen des Dokuments ID und einen Vektor (Sparse ist besser) der Wörter.

documents = spark.createDataFrame([ 
    [123myNumericId, Vectors.sparse(len(words_in_our_corpus), {index_of_word:count}], 
    [2, Vectors.sparse(len(words_in_our_corpus), {index_of_word:count, another:1.0}], 
], schema=["id", "features"] 
transformed = ldaModel.transform(documents) 
dist = transformed.take(1) 
# dist[0]['topicDistribution'] is now a dense vector of our topics. 
+1

können Sie den vollen Code, den Sie verwenden, teilen .. Ich habe Problem in Pyspark und Spark 2.0 ausgeführt, die transformierte Methode .. (es heißt, dass es nicht verfügbar ist) –

+0

Genau welche Arten von Daten zurückgegeben wird durch Umwandlung in die dist Objekt? Sind alle scala-API-Ausgaben dort, einschließlich topTopicsPerDocument usw.? Warum scheint es, als wären wir die ersten Menschen, die jemals versucht haben, Sparks LDA zu verwenden? Vielleicht ist es am besten zu vermeiden, diesen Code vollständig zu verwenden .... Es scheint so Alpha-Klasse. –

+0

Anscheinend funktioniert der obige Beispielcode über Spark 2+. Weitere Informationen finden Sie unter https://spark.apache.org/docs/2.1.0/api/python/pyspark.ml.html#pypark.ml.clustering.LDA. –