Математика векторной графики Spark Word2vec

Я смотрел пример сайта Spark для Word2Vec:

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)

Как сделать интересный вектор, такой как king-man + woman = queen. Я могу использовать model.getVectors, но не уверен, как двигаться дальше.

Ответ 1

Вот пример в pyspark, который, я думаю, прямо pyspark в Scala - ключевым является использование model.transform.

Во-первых, мы обучаем модель, как в примере:

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 - размерность векторов слов - чем выше, тем лучше (значение по умолчанию равно 100), но вам понадобится память, и наибольшее число, которое я мог бы использовать с моей машиной, было 220. (EDIT: Типичные значения в соответствующих публикациях находятся между 300 и 1000)

После того, как мы подготовили модель, мы можем определить простую функцию следующим образом:

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]

Вот несколько примеров со странами и их столицами:

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'

Результаты не всегда правильны - я оставлю это вам, чтобы экспериментировать, но они улучшаются с большим количеством данных обучения и увеличенной векторной размерностью k.

Цикл for в функции удаляет записи, принадлежащие самому входному запросу, поскольку я заметил, что часто правильный ответ был вторым в возвращенном списке, причем первый обычно является одним из входных условий.

Ответ 2

  val w2v_map = sameModel.getVectors//this gives u a map {word: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")
  }

и результат бега как удар:

женщины 0,628454885964967 филип 0,5539534290356802 генри 0,5520055707837214 vii 0,5455116413024774 элизабет 0,5290994886254643 королева 0,5162519562606844 мужчины 0,5133851770249461 венеслас 0,5 эл.

Ответ 3

Вы человек? Мы приносим извинения за путаницу, но мы не можем точно сказать, являетесь ли вы человеком или сценаристом.

Пожалуйста, не принимайте это на свой счет.

Боты и сценарии могут быть удивительно живыми в наши дни!

Поставьте галочку в поле CAPTCHA, и мы будем вне вашего пути.

Ответ 4

Вот псевдокод. Для полной реализации прочитайте документацию: https://spark.apache.org/docs/1.4.0/api/java/org/apache/spark/mllib/feature/Word2VecModel.html.

  1. w2v_map = model.getVectors() # this gives ua 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

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)