KNeighborsClassifier训练准确率恒为1交叉验证得分正常问题咨询
scaler = StandardScaler() knn_clf = KNeighborsClassifier(weights="distance") pipeline = make_pipeline(scaler, knn_clf) param_grid = {"kneighborsclassifier__n_neighbors": np.arange(1,11)} knn_gscv = GridSearchCV(pipeline, param_grid, cv=5, scoring="accuracy") knn_gscv.fit(X_train, y_train) knn_gscv.best_params_ knn_gscv.best_score_ print(knn_gscv.cv_results_) y_pred_test = knn_gscv.predict(X_test) y_pred_train = knn_gscv.predict(X_train) print("train accuracy :", metrics.accuracy_score(y_train, y_pred_train)) print("test accuracy :", metrics.accuracy_score(y_test, y_pred_test))
异常原因分析
- 核心诱因是KNN初始化时设置的
weights="distance"参数,结合KNN本身的预测逻辑,必然会导致训练集预测准确率为100%:
对于任意一个属于训练集的样本,用训练完成的模型预测其标签时,该样本本身一定会被检索为最近邻样本,二者的距离为0。基于距离的权重计算规则会给这个距离为0的样本赋予无穷大的权重,其余k-1个邻居的权重占比可完全忽略,最终预测结果必然和该样本的真实标签完全一致,所以训练集准确率固定为1。 knn_gscv.best_score_是5折交叉验证的平均验证得分,和全训练集准确率的计算逻辑有本质区别:交叉验证的每一轮都会将原始训练集拆分为训练子集和验证子集,验证子集的样本不会出现在对应轮的训练子集中,不会出现「自己预测自己」的情况,因此得分是正常的90%左右,和测试集准确率匹配,属于合理结果。
内容的提问来源于stack exchange,提问作者MK.
相关产品推荐
相关产品推荐

