首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >寻找k近邻

寻找k近邻
EN

Stack Overflow用户
提问于 2021-06-05 13:07:04
回答 1查看 81关注 0票数 1

我正在自学数据科学的python,偶然发现了一章,我已经看了好几个小时了,但我不明白。我希望你能帮我理解它。在示例中,他们希望编码k-最近的邻居。代码如下所示:

代码语言:javascript
复制
X = np.random.rand(10,2)
dist_sq = np.sum((X[:, np.newaxis,:] - X[np.newaxis,:,:])** 2, axis = -1)

nearest = np.argsort(dist_sq, axis=1)

K = 2
nearest_partition = np.argpartition(dist_sq, K + 1, axis=1)

 plt.scatter(X[:, 0], X[:, 1], s=100)
# draw lines from each point to its two nearest neighbors
K=2
for i in range(X.shape[0]):
    for j in nearest_partition[i, :K+1]:
    plt.plot(*zip(X[j], X[i]), color='black')

我确实理解计算原子核距离的前提,但是对我来说,理解3D数组等是非常抽象的。谢谢你们为我简化了它。我感谢你的每一个回答!谢谢!

fyi:我正在学习的书是python数据科学手册,第89页。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-05 14:32:08

阵列广播在三维是相当棘手的包装你的头。

让我们从两个维度开始:

代码语言:javascript
复制
X = np.arange(5)
X[np.newaxis,:] + 10*X[:,np.newaxis]

array([[ 0,  1,  2,  3,  4],                                                                                                   
       [10, 11, 12, 13, 14],                                                                                                   
       [20, 21, 22, 23, 24],                                                                                                   
       [30, 31, 32, 33, 34],                                                                                                   
       [40, 41, 42, 43, 44]])

正如您所看到的,当我们将(1xN)行向量添加到(Nx1)列向量时,我们得到了一个( can )矩阵。在添加之前,行向量变成( N )矩阵,其中每一行都是相同的。类似地,列向量成为( N )矩阵,其中每个列都是相同的。在某种意义上,这是执行以下操作的一种速记方式。

代码语言:javascript
复制
X1 = np.array([[0., 1., 2., 3., 4.],
               [0., 1., 2., 3., 4.],
               [0., 1., 2., 3., 4.],
               [0., 1., 2., 3., 4.],
               [0., 1., 2., 3., 4.]])
                                                                                                          
X2 = np.array([[ 0.,  0.,  0.,  0.,  0.],                                                                                              
               [10., 10., 10., 10., 10.],                                                                                              
               [20., 20., 20., 20., 20.],                                                                                              
               [30., 30., 30., 30., 30.],                                                                                              
               [40., 40., 40., 40., 40.]])

很明显,X1 + X2会给我们一个和以前一样的答案。

那么这在三维中是如何工作的呢?完全一样。在我们重复第一次穿越第二维度之前(反之亦然)。

代码语言:javascript
复制
X1 = X[:, np.newaxis,:]
X2 = X[np.newaxis,:,:]
difference = X1 - X2

在减去之前,X1的第1维和第3维对第2维中的每一片重复。每1维切片重复X2的第2和第3维。让我们用一些容易读懂的材料来观察。

代码语言:javascript
复制
X1 = np.array([[1.,2.],
               [3.,4.],
               [5.,6.]])

X2 = np.array([[10.,20.],
               [30.,40.],
               [50.,60.]])

X1[:,np.newaxis,:] + X2[np.newaxis,:,:] 

array([[[11., 22.],
        [31., 42.],
        [51., 62.]],

       [[13., 24.],
        [33., 44.],
        [53., 64.]],

       [[15., 26.],
        [35., 46.],
        [55., 66.]]])

最容易在视觉上看到X2在第1维(块)重复。在每个块中,我们看到10s数字是相同的。也许将其理解为2D广播的for循环比较容易。

代码语言:javascript
复制
first_dimension = []
for i_row in X1.shape[0]:
    first_dimension.append(X2 + X1[i_row,:])

希望现在很清楚

代码语言:javascript
复制
X1 = X[:, np.newaxis,:]
X2 = X[np.newaxis,:,:]
difference = X1 - X2
sq_diff = difference ** 2

sq_diff是一个三维张量,其中三维的每个切片是X2的一列和X1的一列之间的平方差。

代码语言:javascript
复制
ssq_diff = np.sum(sq_diff, axis = -1)

然后在第3维(axis = -1只是表示数组中的最后一个维度)求和。现在,ssq_diff是一个2D矩阵,其中每个元素都是两个数据点之间的欧几里德距离。对于行i和列jssq_diff[i,j]Xith和jth行之间的欧几里德距离。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67849903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档