Apache spark Spark Word2vec向量数学
我正在查看Word2Vec的Spark站点:Apache spark Spark Word2vec向量数学,apache-spark,machine-learning,apache-spark-mllib,word2vec,Apache Spark,Machine Learning,Apache Spark Mllib,Word2vec,我正在查看Word2Vec的Spark站点: val input=sc.textFile(“text8”).map(line=>line.split(“”.toSeq) val word2vec=新的word2vec() val模型=word2vec.fit(输入) val synonyms=model.findSynonyms(“此处为国家名称”,40) 我如何做有趣的向量,比如国王-男人+女人=女王。我可以使用model.getVectors,但不确定如何继续 这是伪代码。有关完整实施,请
val input=sc.textFile(“text8”).map(line=>line.split(“”.toSeq)
val word2vec=新的word2vec()
val模型=word2vec.fit(输入)
val synonyms=model.findSynonyms(“此处为国家名称”,40)
我如何做有趣的向量,比如国王-男人+女人=女王。我可以使用model.getVectors,但不确定如何继续 这是伪代码。有关完整实施,请阅读文档:
w2v_map=model.getVectors()#这会给你一个映射{word:vec}
my_vector=w2v_map.get('king')-w2v_map.get('man')+w2v_map.get('queen')#在这里做向量代数
most_-simple_-word_-to_-vector=model.findSynonyms(my_-vector,10)#它们有一个api来获取单词的同义词,还有一个api用于向量
编辑:这里是
pyspark
中的一个示例,我想它很容易移植到Scala-关键是使用model.transform
首先,我们训练模型,如示例所示:
从pyspark导入SparkContext
从pyspark.mllib.feature导入Word2Vec
sc=SparkContext()
inp=sc.textFile(“text8_行”).map(lambda行:row.split(“”))
k=220#向量维数
word2vec=word2vec()。设置向量大小(k)
模型=字2向量拟合(inp)
k
是单词向量的维数-越高越好(默认值为100),但您需要内存,我的机器可以使用的最大值是220。(编辑:相关出版物中的典型值介于300和1000之间)
在对模型进行培训后,我们可以定义一个简单的函数,如下所示:
def getsimulation(s,model):
qry=model.transform(s[0])-model.transform(s[1])-model.transform(s[2])
res=model.findSynonyms(-1)*qry,5)#返回5个“同义词”
res=[x[0]表示以res表示的x]
对于范围(0,3)内的k:
如果s[k]在res中:
res.remove(s[k])
返回res[0]
下面是一些国家及其首都的例子:
s=(‘法国’、‘巴黎’、‘葡萄牙’)
GetSimulation(s,模型)
#里斯本
s=(‘中国’、‘北京’、‘俄罗斯’)
GetSimulation(s,模型)
#“莫斯科”
s=(‘西班牙’、‘马德里’、‘希腊’)
GetSimulation(s,模型)
#u'athens'
s=(‘德国’、‘柏林’、‘葡萄牙’)
GetSimulation(s,模型)
#里斯本
s=(‘日本’、‘东京’、‘瑞典’)
GetSimulation(s,模型)
#斯德哥尔摩大学
s=(‘芬兰’、‘赫尔辛基’、‘伊朗’)
GetSimulation(s,模型)
#u'tehran'
s=(‘埃及’、‘开罗’、‘芬兰’)
GetSimulation(s,模型)
#赫尔辛基
结果并不总是正确的-我将把它留给你去实验,但是随着训练数据的增加和向量维数的增加,结果会变得更好
函数中的
for
循环删除属于输入查询本身的条目,因为我注意到,正确答案通常是返回列表中的第二个,第一个通常是输入项之一。不清楚如何进行向量匹配。微风还是火花?这是问题的一个关键部分……public scala.Tuple2 findSynonyms(Vector Vector,int num)您使用我列出的方法进行向量匹配:您可以指定为什么在这里乘以-1:res=model.findSynonyms((-1)*qry,5)#还返回5个“同义词”,你能在GetSimulation函数中写一些关于for循环的注释吗?使用相同数据集的示例没有按预期工作。res=getsimulation(s,model)print“结果是:“+res o/p是:结果是:montpellier1)-1
只是为了保持qry
顺序的直观性;您可以更改此顺序并将其删除2)已经提供了有关for
循环的注释;尝试删除它并返回所有的res
(而不仅仅是res[0]
,看看为什么有必要3)已经说过,结果并不总是正确的,但随着k
的增加,结果会变好(论文至少使用k=300
);此外,精确结果取决于随机种子。总之,答案完全是关于word2vec数学的,这就是问题所在。@user3803714还请记住,出版物和演示中显示的结果总是手工挑选的,即错误的结果根本不显示(尽管它们确实存在)。
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")
}
women 0.628454885964967
philip 0.5539534290356802
henry 0.5520055707837214
vii 0.5455116413024774
elizabeth 0.5290994886254643
**queen 0.5162519562606844**
men 0.5133851770249461
wenceslaus 0.5127030522678778
viii 0.5104392579985102
eldest 0.510425791249559