KNN算法即近邻算法(Nearest neighbour algorithm),它通过预测点周围邻居点的信息来对该点进行分析,它在给定数据集中找到与新数据点最接近的K个邻居,并基于这些邻居的属性来预测新数据点的类别或值。
应用任务:
分类,回归
原理及步骤
- 数据预处理(标准化),由于KNN使用了距离计算,因此通常需要标准化将所有特征缩放到0-1之间,来保证数值较大的特征不会主导预测。
- 确定邻居的数量K,即通过多少个邻居点来估计给定点的标签。
- 计算距离,对于每个需要预测的数据点,计算它与训练集中所有点之间的距离。通常使用欧几里得距离。
- 找出最近的K个邻居,根据计算的距离,找出与待预测点距离最近的K个训练数据点。
- 进行预测:(1)分类:使用多数投票法(Majority voting),即待预测点的类别是其K个最近邻居中多数类别。(2)回归:取K个邻居的目标值的平均或加权平均作为预测值。
优点
- 简单易操作:KNN算法概念上简单直观,易于理解和实现。
- 无需训练:KNN是非参数模型(non-parametric model),在使用前不需要进行训练,所有的计算都是在预测阶段进行。
- 自适应:不需要预先假设数据的分布,即使分布未知,也能有良好的效果。
- 应用范围广:可以用于分类和回归任务。
- 高鲁棒性:通过选取适当的K值,KNN可以抵抗噪声和异常值的影响。
缺点
- 对K值敏感:KNN的性能高度依赖于选择的邻居数(K值)和距离度量方式。
- 计算量大:对于大数据集,KNN需要计算每个测试实例与所有训练实例之间的距离,这会导致较高的计算成本。
- 内存占用高:由于KNN是基于实例的学习,需要存储整个训练数据集,因此在数据集很大时会消耗大量内存。
- 对不均衡数据敏感:在类别分布不均衡的数据集中,KNN可能会偏向于数量较多的类别。
- 维度灾难:在高维数据中,由于“维度的诅咒”,距离计算可能变得不再准确,从而影响KNN的性能。
- 需要标准化:KNN对数据的尺度非常敏感,不同的特征尺度会导致不同的距离度量结果,一些值较大的特征可能主导预测,因此通常需要对数据进行标准化处理。
代码实现
这里我们可以使用sklearn来实现KNN,具体详情可查询官网:
KNN分类:https://scikit-learn.org.cn/view/695.html
KNN回归:https://scikit-learn.org.cn/view/695.html
这里我们主要介绍KNN分类的实现,对于KNeighborsClassifier中的参数,可见下图:
在下面的例子中,对于基础的KNN算法实现,我们将只设定K值,数据集选择iris数据集。
- 加载所需包
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score
# 加载KNN所需包
from sklearn.neighbors import KNeighborsClassifier
- 数据选择及标准化
# 加载数据集
iris_dataset = load_iris()
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
iris_dataset['data'], iris_dataset['target'], random_state=0)
# 数据标准化
scaler = MinMaxScaler()
scaler.fit(X_train)
X_train_norm = scaler.transform(X_train)
X_test_norm = scaler.transform(X_test)
- 初始化KNN分类器,设置K = 1
knn = KNeighborsClassifier(n_neighbors=1)
- 拟合训练集
knn.fit(X_train_norm, y_train)
- 预测测试集结果
y_pred = knn.predict(X_test_norm)
- 评估模型性能
print("Accuracy: {:.2f}".format(accuracy_score(y_pred, y_test)))
### Accuracy: 0.97