手动实现最近邻算法时欧氏距离仅计算测试集单行距离的原因求解
问题原因及修复方案
核心问题定位
你遇到的问题根源是距离存储数组的初始化位置错误:
dist1 = []、dist2 = []被写在了遍历测试集的外层for i循环内部,每处理一个测试样本,就会清空两个列表的历史内容,之前计算的其他测试样本距离会被直接覆盖。等外层循环全部执行完毕,你能拿到的只有最后一个测试样本对应的距离数组,长度自然和训练集(112条)一致。- 你当前用的是一维列表存储结果,无法承载「每个测试样本对应一组训练集距离」的二维数据结构。
其他潜在问题
- 欧氏距离计算可能缺特征:你当前距离函数的循环范围是
range(0, len(r2)-1),如果你的x_train/x_test是纯特征数组(不含标签列),这个写法会漏掉最后一维特征的计算,导致距离结果错误。 - 排序后丢失索引映射:你直接对距离数组排序,但没有保留距离对应的训练集索引,后续就算拿到最小距离,也无法匹配对应训练样本的标签,得不到正确分类结果。
dist1和dist2完全冗余:你内层循环给两个列表追加的是完全相同的距离值,没有额外存储索引的话两个数组内容没有差异。
修复后的代码示例
import numpy as np # 修正后的欧氏距离函数,默认r1/r2都是纯特征向量 def euclidean_dist(r1, r2): dist = 0 # 去掉减1,遍历所有特征维度 for j in range(len(r2)): dist += (r2[j] - r1[j]) ** 2 return dist ** 0.5 # ------------- 距离计算逻辑 ------------- # 外层存储结构:每个元素对应一个测试样本的距离结果 all_unsorted_dist = [] all_sorted_dist = [] # 额外存储带索引的排序结果,方便后续取标签 all_sorted_with_idx = [] for i in range(len(x_test)): # 单个测试样本对应的距离列表,仅存当前样本的计算结果 current_dist = [] current_dist_with_idx = [] for j in range(len(x_train)): dist = euclidean_dist(x_test[i], x_train[j,:]) current_dist.append(dist) # 存储(距离, 训练集索引)元组,方便排序后溯源 current_dist_with_idx.append( (dist, j) ) # 存入未排序总列表 all_unsorted_dist.append(current_dist) # 存入排序后纯距离总列表 all_sorted_dist.append(sorted(current_dist)) # 存入带索引的排序结果 current_dist_with_idx.sort() all_sorted_with_idx.append(current_dist_with_idx) # 转numpy数组后形状为 (测试集样本数, 训练集样本数),符合你的预期 all_unsorted_dist = np.array(all_unsorted_dist) all_sorted_dist = np.array(all_sorted_dist)
内容的提问来源于stack exchange,提问作者uniha2021
相关产品推荐
相关产品推荐

