KNN算法-学习笔记
2026/7/18 4:33:43 网站建设 项目流程

KNN(K-Nearest Neighbors)

K近邻算法,近朱者赤,近墨者黑:
对于一个待预测样本,在特征空间里找出距离它最近的 K 个邻居,通过这 K 个邻居的类别 / 取值来决定该样本的结果:

  1. 分类任务:K 个邻居投票,少数服从多数,票数最多的类别作为预测结果;
  2. 回归任务:取 K 个邻居标签的平均值作为预测值。

K 值选取:

  • K 太小:容易受噪声、异常点干扰,过拟合;
    例:K=1,完全跟着最近一个样本走,容错极差。
  • K 太大:会把距离很远、无关样本纳入,欠拟合;
    极端 K = 全部样本,预测结果永远是训练集最多类别的常量。
  • 常用选择:
    取奇数避免平票;一般用网格搜索 / 交叉验证遍历 1~30 左右选最优 K。

距离度量方式(衡量样本相似度):
距离度量方式(衡量样本相似度)设两个样本 (x=(x_1,x_2…x_n)),(y=(y_1,y_2…y_n))

  1. 欧式距离(最常用)

KNN分类任务

(标签不连续)投票

代码:

""" KNN(分类)代码实现思路 1.导包 2.准备数据集(测试集和训练集) 3.创建模型对象(KNN分类模型) 4.模型训练 5.模型测试 """# 1.导包(KNN分类模型包)fromsklearn.neighborsimportKNeighborsClassifier# 准备数据集x_train=[[0],[1],[2],[3]]# 训练集特征y_train=[0,0,1,1]# 训练集标签x_test=[[4]]# 测试集特征数据# 2.创建模型(KNN分类模型)# estimator 评估器estimator=KNeighborsClassifier(n_neighbors=3)#取k值# 3.模型训练# 填充训练集特征和标签数据estimator.fit(x_train,y_train)# 4.模型预测# 给测试集特征数据给出测试标签(预测结果)y_pre=estimator.predict(x_test)print(f"y_test的预测结果:{y_pre}")

数据:

计算过程:

KNN回归任务

(标签连续)平均值

代码:

# 1.导包fromsklearn.neighborsimportKNeighborsRegressor# 2.准备数据集(训练集和测试集)# 4个训练样本,每个样本3个特征x_train=[[2,4,1],[5,1,3],[3,3,2],[1,5,4]]# 对应训练标签 y_train 4个分类标签y_train=[0.2,0.3,0,0.5]# 测试样本 1个,3列特征x_test=[[4,2,2]]# 3.创建模型对象(KNN回归类型)estimator=KNeighborsRegressor(n_neighbors=3)# 4.模型训练estimator.fit(x_train,y_train)# 5.模型预测y_pre=estimator.predict(x_test)print(f"y_test的预测结果:{y_pre}")

数据:

计算过程:

常用距离度量方式

欧式距离

欧式距离 = 对应维度差值平方和,开平方根

曼哈顿距离

曼哈顿距离(城市街区距离) = 对应维度的差值的绝对值,求和

切比雪夫距离

切比雪夫距离 = 对应维度的差值的绝对值,找最大值

闵可夫斯基距离

统一封装了三种经典距离(欧式距离、曼哈顿距离、切比雪夫距离),参数可调,通用性极强。

或者

p=1时,(曼哈顿距离,一次根号可省略)
p=2时,(欧氏距离,二次根号)
p=∞时,切比雪夫距离

特征预处理

归一化

数据归一化通过对原始数据进行变化把数据映射到【 min,max】,默认为 0 到 1,可以设置最小值和最大值的范围

公式:

x’'公式:mi和mx可以设置范围:比如 3 到 5 之间

代码例子:

# 导包fromsklearn.preprocessingimportMinMaxScaler# 数据集x_train=[[90,2,10,40],[60,4,15,45],[75,3,13,46]]# 创建归一化transformer=MinMaxScaler(feature_range=(0,1))# feature_range的默认范围是0到1# 对原数据集进行归一化处理new_x_train=transformer.fit_transform(x_train)# 打印结果print(new_x_train)

标准化

数据标准化通过对原始数据进行标准化,转换为均值为0标准差为1的标准正态分布的数据

公式:
σ:标准差
σ2(sigma ):方差
μ(mu):平均值


代码:

# 导包fromsklearn.preprocessingimportStandardScaler# 数据集x_train=[[90,2,10,40],[60,4,15,45],[75,3,13,46]]# 创建标准化transformer=StandardScaler()# 对原数据集进行归一化处理new_x_train=transformer.fit_transform(x_train)print(new_x_train)

归一化和标准化区别

数据归一化:如果出现异常点,影响了最大值和最小值,那么结果就会显然发生改变。
数据标准化:如果出现异常点,由于具有一定数据量,少量的异常点对于平均值的影响不大。

交叉验证和网格搜索

  1. 交叉验证(CV)
    多次拆分数据集轮流训练、验证,取平均效果,避免单次划分数据带来的偶然误差,更真实衡量模型泛化能力,常用 5 折 / 10 折。
  2. 网格搜索
    提前列出多组超参数组合,暴力遍历所有参数搭配,筛选效果最好的一组超参数。
  3. 二者关系
    网格搜索选参数时,依靠交叉验证评判每组参数好坏,二者搭档用于自动调参 + 靠谱评估模型。
fromsklearn.datasetsimportload_iris# 加载鸢尾花测试集的.fromsklearn.model_selectionimporttrain_test_split,GridSearchCV# 分割训练集和测试集的, 网格搜索的fromsklearn.preprocessingimportStandardScaler# 数据标准化的fromsklearn.neighborsimportKNeighborsClassifier# KNN算法 分类对象# 1. 获取数据集.iris_data=load_iris()# 2. 数据基本处理-划分数据集.x_train,x_test,y_train,y_test=train_test_split(iris_data.data,iris_data.target,test_size=0.2,random_state=22)# 3. 数据集预处理-数据标准化.transfer=StandardScaler()x_train=transfer.fit_transform(x_train)x_test=transfer.transform(x_test)# 4.模型训练# 4.1.创建估计器对象estimator=KNeighborsClassifier()# 4.2.使用校验验证网格搜索,指定参数范围param_grid={'n_neighbors':range(1,10)}# 4.3. 具体的网格搜索过程和交叉验证# 参数1:估计器对象;参数2:参数范围;参数3:交叉验证的折数estimator=GridSearchCV(estimator=estimator,param_grid=param_grid,cv=5)# 模型训练estimator.fit(x_train,y_train)# 4.4交叉验证,网格搜索结果查看print(estimator.best_score_)# 模型在交叉验证中, 所有参数组合中的最高平均测试得分print(estimator.best_estimator_)# 最优的估计器对象.print(estimator.cv_results_)# 模型在交叉验证中的结果.print(estimator.best_params_)# 模型在交叉验证中的结果.# 5. 得到最优模型后, 对模型重新预测.estimator=KNeighborsClassifier(n_neighbors=6)estimator.fit(x_train,y_train)print(f'模型评估:{estimator.score(x_test,y_test)}')# 因为数据量和特征的问题, 该值可能小于上述的平均测试得分.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询