由于Spark的mllib没有最近邻功能,因此我正在尝试使用Annoy进行近似最近邻。我尝试广播Annoy对象并将其传递给工作节点,但它没有按预期运行。
下面是用于复现问题的代码(在PySpark中运行)。问题在于使用Annoy时与不使用Spark时看到的差异。
from annoy import AnnoyIndex
import random
random.seed(42)
f = 40
t = AnnoyIndex(f) # Length of item vector that will be indexed
allvectors = []
for i in xrange(20):
v = [random.gauss(0, 1) for z in xrange(f)]
t.add_item(i, v)
allvectors.append((i, v))
t.build(10) # 10 trees
# Use Annoy with Spark
sparkvectors = sc.parallelize(allvectors)
bct = sc.broadcast(t)
x = sparkvectors.map(lambda x: bct.value.get_nns_by_vector(vector=x[1], n=5))
print "Five closest neighbors for first vector with Spark:",
print x.first()
# Use Annoy without Spark
print "Five closest neighbors for first vector without Spark:",
print(t.get_nns_by_vector(vector=allvectors[0][1], n=5))
输出结果如下:
使用Spark得到第一个向量的五个最近邻居:无
不使用Spark得到第一个向量的五个最近邻居:[0, 13, 12, 6, 4]