自行实现的K=1近邻分类函数与scikit-learn结果不一致原因排查
KNN实现结果与scikit-learn差异原因分析
- 核心差异来自两种实现的验证逻辑不统一
你自己编写的PPV函数用的是留一交叉验证逻辑:每次预测第i个样本前,都会把第i个样本从训练集中移除,仅用剩余的149个样本计算最近邻,这种场景下得到96%的准确率是K=1近邻在鸢尾花数据集上的正常结果。
你调用KNeighborsClassifier得到100%准确率,是因为测试逻辑不严谨:你大概率是直接把整个鸢尾花数据集同时用作训练集和测试集。K=1场景下,模型预测训练集内的样本时,距离最近的样本永远是样本本身,自然能得到100%的准确率,这不是公平的参数对齐对比。
- 次要差异为平局处理规则不同
当出现多个样本和待预测样本的欧氏距离完全相等的平局场景时,np.argmin只会返回第一个出现的最小距离对应的类别,而scikit-learn的默认规则是选择类别编号更小的类别,这种差异可能在个别样本上导致预测结果不同,但不会造成4%这么大的准确率差距。
你可以运行以下代码用scikit-learn实现相同的留一交叉验证逻辑,会得到和你自己实现完全一致的96%准确率:
from sklearn.model_selection import LeaveOneOut from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score from sklearn import datasets import numpy as np iris = datasets.load_iris() X = iris.data Y = iris.target loo = LeaveOneOut() y_true, y_pred = [], [] for train_idx, test_idx in loo.split(X): knn = KNeighborsClassifier(n_neighbors=1) knn.fit(X[train_idx], Y[train_idx]) y_pred.append(knn.predict(X[test_idx])[0]) y_true.append(Y[test_idx][0]) print(f"sklearn 留一法K=1准确率: {accuracy_score(y_true, y_pred)*100}%")
内容的提问来源于stack exchange,提问作者Mavil
相关产品推荐
相关产品推荐

