KNN 可能是最简单的机器学习算法,它不需要训练,直接根据邻近样本来判断。这个算法背后的想法很朴素——'近朱者赤'。在许多入门案例里,KNN 都能给出不错的结果,比如鸢尾花分类。在这篇文章里,我打算把它的原理、手动实现和调参过程完整走一遍。
算法原理
KNN 做什么?给定一个新样本,它在训练集里找 K 个最近的邻居,然后看这些邻居的标签,少数服从多数(分类),或者取平均值(回归)。所以,核心两件事:怎么定义'近',以及选多少个邻居。
距离度量最常用的是欧氏距离:
# 欧氏距离的直观计算
dist = np.sqrt(np.sum((x1 - x2)**2))
当然,曼哈顿距离(np.sum(np.abs(x1 - x2)))或余弦相似度也各有各的适用场景。流程很直白:
- 先归一化数据,避免量纲影响距离计算。
- 对每个测试样本,算到所有训练样本的距离。
- 排序后取前 K 个。
- 分类则多数投票,回归则均值或加权平均。
先跑一个 Scikit-learn 版本
加载鸢尾花数据集,只选前两个特征方便画边界。标准化后,用 KNeighborsClassifier 一跑,准确率就很高:
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print(f"Accuracy with K=5: {accuracy_score(y_test, y_pred):.2f}")
# 输出:0.98
自己动手实现一个 KNN
要想真的理解 KNN,还是得自己写一遍。下面这个 CustomKNN 就做两件事:fit 存住数据,predict 算欧氏距离、排序、投票:


