11

Ich war für Word2Vec am example Spark Website suchen:Funken Word2vec Vektormathematik

val input = sc.textFile("text8").map(line => line.split(" ").toSeq) 

val word2vec = new Word2Vec() 

val model = word2vec.fit(input) 

val synonyms = model.findSynonyms("country name here", 40) 

Wie kann ich die interessante Vektor tun wie König - ein Mann + Frau = Königin. Ich kann model.getVectors verwenden, bin mir aber nicht sicher, wie ich weiter vorgehen soll.

+0

Können Sie die Antwort auch jetzt noch annehmen? Danke ... – desertnaut

Antwort

-2

Hier ist der Pseudocode. Für die vollständige Umsetzung, lesen Sie die Dokumentation: https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/mllib/feature/Word2VecModel.html

  1. w2v_map = model.getVectors() # this gives u a map {word:vec}
  2. my_vector = w2v_map.get('king') - w2v_map.get('man') + w2v_map.get('queen') # do vector algebra here
  3. most_similar_word_to_vector = model.findSynonyms(my_vector, 10) # they have an api to get synonyms for word, and one for vector

edit: https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/mllib/feature/Word2VecModel.html#findSynonyms(org.apache.spark.mllib.linalg.Vector,%20int)

+2

Nicht klar, wie die Vektorübereinstimmung zu tun ist. Breeze oder Spark Vektoren? Das ist eine Schlüsselkomponente der Frage .... – user3803714

+2

public scala.Tuple2 findSynonyms (Vektor vector, int num) Sie tun Vektor-Match mit dieser Methode, die ich aufgeführt: https: // spark. apache.org/docs/1.4.0/api/java/org/apache/spark/mllib/feature/Word2VecModel.html#findSynonyms (org.apache.spark.mllib.linalg.Vector,%20int) – jxieeducation

13

Hier ist ein Beispiel in pyspark, die ich schätze, ist einfach nach Scala zu portieren - der Schlüssel ist die Verwendung von model.transform.

Zunächst trainieren wir das Modell wie im Beispiel:

from pyspark import SparkContext 
from pyspark.mllib.feature import Word2Vec 

sc = SparkContext() 
inp = sc.textFile("text8_lines").map(lambda row: row.split(" ")) 

k = 220   # vector dimensionality 
word2vec = Word2Vec().setVectorSize(k) 
model = word2vec.fit(inp) 

k die Dimensionalität der Wortvektoren ist - je höher desto besser (Standardwert ist 100), aber Sie werden Speicher benötigen, und die höchste Zahl, die ich mit meiner Maschine gehen konnte, war 220. (BEARBEITEN: Typische Werte in den relevanten Publikationen sind zwischen 300 und 1000)

Nachdem wir das Modell trainiert haben, können wir eine einfache Funktion wie folgt definieren:

def getAnalogy(s, model): 
    qry = model.transform(s[0]) - model.transform(s[1]) - model.transform(s[2]) 
    res = model.findSynonyms((-1)*qry,5) # return 5 "synonyms" 
    res = [x[0] for x in res] 
    for k in range(0,3): 
     if s[k] in res: 
      res.remove(s[k]) 
    return res[0] 

Nun, hier sind einige Beispiele mit den Ländern und ihre Hauptstädte:

s = ('france', 'paris', 'portugal') 
getAnalogy(s, model) 
# u'lisbon' 

s = ('china', 'beijing', 'russia') 
getAnalogy(s, model) 
# u'moscow' 

s = ('spain', 'madrid', 'greece') 
getAnalogy(s, model) 
# u'athens' 

s = ('germany', 'berlin', 'portugal') 
getAnalogy(s, model) 
# u'lisbon' 

s = ('japan', 'tokyo', 'sweden') 
getAnalogy(s, model)  
# u'stockholm' 

s = ('finland', 'helsinki', 'iran') 
getAnalogy(s, model) 
# u'tehran' 

s = ('egypt', 'cairo', 'finland') 
getAnalogy(s, model) 
# u'helsinki' 

Die Ergebnisse sind nicht immer richtig - ich es Ihnen überlassen werden, zu experimentieren, aber sie besser mit mehr Training Daten und erhöhte Vektordimensionalität k.

Die for Schleife in der Funktion entfernt Einträge, die zu der Eingabeabfrage selbst gehören, da ich festgestellt habe, dass häufig die richtige Antwort die zweite in der zurückgegebenen Liste war, wobei die erste normalerweise einer der Eingabebegriffe ist.

+2

Können Sie bitte angeben warum du hier mit -1 multiplizierst: res = model.findSynonyms ((- 1) * qry, 5) # return 5 "Synonyme" Kannst du auch ein paar Kommentare über die for-Schleife in deiner getAnalogy-Funktion schreiben? – user3803714

+2

Das Beispiel mit demselben Datensatz hat nicht wie erwartet funktioniert. res = getAnalogy (s, model) print "Ergebnis ist:" + res o/p ist: Ergebnis ist: montpellier – user3803714

+3

1) '' -1'' ist nur für die Aufrechterhaltung der '' qry'' Reihenfolge intuitiv; Sie können diese Reihenfolge ändern und entfernen 2) Haben Sie bereits Kommentare in Bezug auf '' '' Schleife; versuche, es zu entfernen und alle 'res'' (anstatt nur' 'res [0]' 'zurückzugeben, um zu sehen, warum es notwendig ist 3) Bereits gesagt, dass die Ergebnisse nicht immer korrekt sind, aber sie werden mit steigendem' 'besser k'' (Papiere verwenden mindestens "k = 300"); genaue Ergebnisse hängen außerdem vom Zufallssamen ab. ** Alles in allem **, die Antwort bezieht sich genau auf die word2vec-Mathematik, worum es in der Frage ging. – desertnaut

1

val w2v_map = sameModel.getVectors // das gibt ua map {Wort: vec}

val (king, man, woman) = (w2v_map.get("king").get, w2v_map.get("man").get, w2v_map.get("women").get) 

    val n = king.length 

    //daxpy(n: Int, da: Double, dx: Array[Double], incx: Int, dy: Array[Double], incy: Int); 
    blas.saxpy(n,-1,man,1,king,1) 

    blas.saxpy(n,1,woman,1,king,1) 

    val vec = new DenseVector(king.map(_.toDouble)) 

    val most_similar_word_to_vector = sameModel.findSynonyms(vec, 10) //they have an api to get synonyms for word, and one for vector 
    for((synonym, cosineSimilarity) <- most_similar_word_to_vector) { 
    println(s"$synonym $cosineSimilarity") 
    } 

und das Laufergebnis als Schlag:

Frauen ,628454885964967 philip ,5539534290356802 henry ,5520055707837214 vii ,5455116413024774 elizabeth 0.5290994886254643 königin 0.5162519562606844 männer 0.5133851770249461 wenzeslaus 0,5127030522678778 viii 0,5104392579985102 ältestes 0.510425791249559