尝试编写最近邻算法 - 欧几里得距离函数只计算测试集的一行的距离 - 为啥?
Posted
技术标签:
【中文标题】尝试编写最近邻算法 - 欧几里得距离函数只计算测试集的一行的距离 - 为啥?【英文标题】:Trying to code the nearest neighbours algorithm - euclidean distance function only calculates the distances for one row of the test set - why?尝试编写最近邻算法 - 欧几里得距离函数只计算测试集的一行的距离 - 为什么? 【发布时间】:2021-12-03 04:29:57 【问题描述】:我正在尝试从头开始编写最近邻算法,但遇到了一个问题 - 我的算法只为训练集的一行/点提供最近邻的索引/分类。我浏览了代码的每一部分,并意识到问题出在我的欧几里得距离函数上。它只给出一行的结果。
这是我为欧几里得距离写的代码:
def euclidean_dist(r1, r2):
dist = 0
for j in range(0, len(r2)-1):
dist = dist + (r2[j] - r1[j])**2
return dist**0.5
在我的最近邻算法中,这是欧几里得距离函数的实现:
for i in range(len(x_test)):
dist1 = []
dist2 = []
for j in range(len(x_train)):
distances = euclidean_dist(x_test[i], x_train[j,:])
dist1.append(distances)
dist2.append(distances)
dist1 = np.array(dist1)
sorting(dist1) #separate sorting function to sort the distances from lowest to highest,
#the aim was to get one array, dist1, with the euclidean distances for each row sorted
#and one array with the unsorted euclidean distances, dist2, (to be able to search for index later in the code)
我在使用 iris 数据集并尝试使用它的这部分功能时注意到了这个问题。我将数据集分为测试和训练(X_test
、X_train
和 y_test
)。
当使用数据集实现这一点时,我得到了dist2
的以下数组:
[0.3741657386773946,
1.643167672515499,
3.389690251335658,
2.085665361461421,
1.284523257866513,
3.9572717874818752,
0.9539392014169458,
3.5805027579936315,
0.7211102550927979,
...
0.8062257748298555,
0.4242640687119287,
0.5196152422706631]
它的长度是 112,与X_train
的长度相同,但这些只是X_test
集合的第一行或第一点的欧几里得距离。 dist1
数组是相同的,只是它是排序的。
为什么我没有得到测试集每一行/点的欧几里得距离?我以为我用 for 循环正确地迭代了,但显然有些地方不太对劲。任何建议或帮助将不胜感激。
【问题讨论】:
x_test 上的每次迭代,都会重置 dist1 和 dist2。因此,您只有最后一个。顺便说一句,你真的应该为这种计算切换做 numpy 数组。 我怎样才能做到每次迭代都不会重置 dist1 和 dist2?我将如何使用 numpy 数组来改进这一点? 【参考方案1】:将 numpy 用于速度、内置距离和代码长度:
x_test_array = np.array(x_test)
x_train_array = np.array(x_train)
distance_matrix = np.linalg.norm(x_test[:,np.newaxis,:]-x_train[np.newaxis,:,:], axis=2)
矩阵中的单元格 i,j 对应于 x_train[i] 和 x_test[j] 之间的距离。 然后就可以进行排序了。
编辑:如何在没有 numpy 的情况下创建距离矩阵:
matrix = []
for i in range(len(x_test)):
dist1 = []
for j in range(len(x_train)):
distances = euclidean_dist(x_test[i], x_train[j,:])
dist1.append(distances)
matrix.append(dist1)
【讨论】:
嗨 - 有没有办法使用我的欧几里得距离代码而不是 np.linalg.norm 来做到这一点,并且仍然创建一个矩阵?我认为我不应该在这项任务中使用它。除了这个 - 在您提供的 np.linalg.norm 代码中,为什么 x_test 不包含在其中? 那是错字对不起修复它。如果没有 numpu,您可以创建列表列表。在第一个 for 循环之前创建一个列表并将其称为矩阵。然后在 i 上的每个循环结束时,将 dist 附加到矩阵。 我尝试将原始代码中的列表附加到一个空列表中,但显然我没有正确实现它。还有另一种我不知道的附加方法吗?感谢您的帮助!以上是关于尝试编写最近邻算法 - 欧几里得距离函数只计算测试集的一行的距离 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章