Python 3.x 如何使用spotify';python中的恼人库?
我想知道烦恼图书馆是如何运作的。我从github获得了这个测试代码,但我对编码还不熟悉,所以很难理解Python 3.x 如何使用spotify';python中的恼人库?,python-3.x,computer-vision,annoy,Python 3.x,Computer Vision,Annoy,我想知道烦恼图书馆是如何运作的。我从github获得了这个测试代码,但我对编码还不熟悉,所以很难理解 from annoy import AnnoyIndex import random f = 40 t = AnnoyIndex(f, 'angular') #Length of item vector that will be indexed for i in range(1000): v = [random.gauss(0, 1) for z in range(f)] t
from annoy import AnnoyIndex
import random
f = 40
t = AnnoyIndex(f, 'angular') #Length of item vector that will be indexed
for i in range(1000):
v = [random.gauss(0, 1) for z in range(f)]
t.add_item(i, v)
t.build(10) # 10 trees
t.save('test.ann')
u = AnnoyIndex(f, 'angular')
u.load('test.ann') # super fast, will just mmap the file
print(u.get_nns_by_item(0, 1000)) # will find the 1000 nearest neighbors
烦恼库基本上用于解决欧几里德距离、曼哈顿距离、余弦距离、汉明距离或点(内积)距离的最近邻布尔搜索(NNS)问题。使用“烦恼”,你将在n维空间中构建一个由点或向量组成的网络,然后要求它给出这个给定网络的不同属性。使用此库的优点之一是,它在内存存储方面特别有效。你可以用它做很多事情,事情变得复杂到你想要的程度,但这里有一个简单的例子可能会有所帮助
a = AnnoyIndex(3, 'euclidean')
b = AnnoyIndex(3 ,'angular')
在这里,您首先创建对象,烦恼包将在其上运行。第一种情况是具有欧几里德距离的三维空间。第二个是有角度的
a.add_item(0,[1,0,0])
a.add_item(1,[0,1,0])
a.add_item(2,[2,0,0])
a.add_item(3,[2.5,0,0])
a.add_item(4,[1,0,0.5])
b.add_item(0,[1,0,0])
b.add_item(1,[0,1,0])
b.add_item(2,[2,0,0])
b.add_item(3,[2.5,0,0])
b.add_item(4,[1,0,0.5])
a.build(1)
b.build(1)
在这里,我分别在对象a和b的相同位置添加相同的五个项目,然后使用a/b.build(n)构建网络,其中n是使用的“树”的数量。树木越多,执行操作时,网络越精确,速度越快。在这种情况下,我们使用n=1,因为网络非常简单
print(a.get_nns_by_item(0, 4))
print(b.get_nns_by_item(0, 4))
现在我要求网络给我网络中0到4之间的所有元素,从离项目0较近的地方到较远的地方列出,使用其各自的距离,分别获得0,4,1,2,3和0,2,3,4,1。现在让我们来看看为什么我们会得到这样的结果。在下面的几行中,我计算项目0与其他项目之间的距离,然后将它们从小到大排序
对象a,使用欧几里德距离的距离(d((x,y,z),(x',y',z'))=sqrt{(x-x')^2+(y-y')^2+(z-z')^2}): 从小到大排序:d0-0、d0-4、d0-1、d0-2、d0-3(或{0,4,1,2,3})
对象b,使用角度距离的距离(两个矢量之间的角度,单位为度): 在这种情况下,如果两个元素具有相同的角度,排序将优先于较小的项:{0,2,3,4,1}
到目前为止还不错。现在让我们看看你的代码
from annoy import AnnoyIndex
import random
f = 40
t = AnnoyIndex(f, 'angular') #Length of item vector that will be indexed
for i in range(1000):
v = [random.gauss(0, 1) for z in range(f)]
t.add_item(i, v)
t.build(10) # 10 trees
t.save('test.ann')
在第一部分中,我们将网络空间的维数设置为40,并选择使用角距离。然后,在下一步中,我们创建一千个项目,每个项目都有对应的四十维向量,也可以理解为四十维空间中的一个点。然后,计算每个维度的值
由random.gauss(0,1)设置,它随机返回高斯分布中的一个点,由
e^{x}^2/2}/sqrt{2\pi}。然后,我们使用10棵树构建相应的网络,并将其保存为“test.ann”
u = AnnoyIndex(f, 'angular')
u.load('test.ann') # super fast, will just mmap the file
现在我们可以下载它并将其用于我们想要的任何目的,它的优点是网络已经建成,因此速度更快
print(u.get_nns_by_item(0, 1000))
现在,我们要得到千个元素,它们按照相对于第0项的角度距离排序。请注意,如果我们不输入1000,而是输入一个较小的数字,则大于此数字的项目将自动被划分
有关最近的Neightbour搜索的详细信息:
Github恼怒包
这与VPTree相比如何?计算的欧几里德距离是否不正确?您已经提到:
树越多,网络在执行操作时就越精确和快速。
这不是错吗?当我增加树的数量时,执行搜索需要更长的时间。
u = AnnoyIndex(f, 'angular')
u.load('test.ann') # super fast, will just mmap the file
print(u.get_nns_by_item(0, 1000))