KNN算法优缺点、原理及参数最优解

本文深入解析KNN算法,涵盖其工作原理、优缺点及应用场景,特别聚焦于电影分类的KNN分析,展示如何利用欧几里得距离进行数据点间的距离度量,以及通过实例解释KNN的分类过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. KNN算法简介

  • 1.1 简述

  • 简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类(k-Nearest Neighbor,KNN)

  • 1.2 优缺点

    • 优点:精度高、对异常值不敏感、无数据输入假定。

    • 缺点:时间复杂度高、空间复杂度高。

    1. 当样本不平衡时,比如一个类的样本容量很大,其他类的样本容量很小,输入一个样本的时候,K个临近值中大多数都是大样本容量的那个类,这时可能就会导致分类错误。改进方法是对K临近点进行加权,也就是距离近的点的权值大,距离远的点权值小。

    2. 计算量较大,每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点,改进方法是:先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

  • 1.3 适用数据范围

    • 标称型:标称型目标变量的结果只在有限目标集中取值,如真与假(标称型目标变量主要用于分类)

    • 数值型:数值型目标变量则可以从无限的数值集合中取值,如0.100,42.001等 (数值型目标变量主要用于回归分析)

2. 工作原理

2.1 训练样本集

  • 存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据 与所属分类的对应关系。

  • 输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。

  • 一般来说,我们 只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。 最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类。

2.2 电影类别的KNN分析

  • 如何进行电影分类

    • 众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 题。没有哪个电影人会说自己制作的电影和以前的某部电影类似,但我们确实知道每部电影在风格 上的确有可能会和同题材的电影相近。那么动作片具有哪些共有特征,使得动作片之间非常类似, 而与爱情片存在着明显的差别呢?动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们 不能单纯依靠是否存在打斗或者亲吻来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中 的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.3 欧几里得距离(Euclidean Distance)

  • 欧式距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离,公式如下:

d i s t ( X , Y ) = ∑ i = 0 n ( X i − Y i ) 2 = ( X 1 − Y 1 ) 2 + ( X 2 − Y 2 ) 2 + ( X 3 − Y 3 ) 2 + … … + ( X i − Y i ) dist(X,Y) = \sqrt{\sum_{i=0}^{n}(X_i - Y_i)^2} = \sqrt{(X_1-Y_1)^2 + (X_2-Y_2)^2+(X_3-Y_3)^2+……+(X_i-Y_i)} dist(X,Y)=i=0n(XiYi)2 =(X1Y1)2+(X2Y2)2+(X3Y3)2++XiYi

2.4 计算过程图

  • 在这里插入图片描述

2.5 kNN近邻分类算法的原理

在这里插入图片描述

  • 从上图中我们可以看到,图中的数据集都有了自己的标签,一类是蓝色的正方形,一类是红色的三角形,那个绿色的圆形是我们待分类的数据

  • 如果K=3,那么离绿色点最近的有2个红色三角形和1个蓝色的正方形,这3个点投票,于是绿色的这个待分类点属于红色的三角形.

  • 如果K=5,那么离绿色点最近的有2个红色三角形和3个蓝色的正方形,这5个点投票,于是绿色的这个待分类点属于蓝色的正方形

  • 我们可以看到,KNN本质是基于一种数据统计的方法!其实很多机器学习算法也是基于数据统计的

  • 总结:KNN是一种基于记忆的学习(memory-based learning),也是基于实例的学习(instance-based learning),属于惰性学习(lazy learning)。即它没有明显的前期训练过程,而是程序开始运行时,把数据集加载到内存后,不需要进行训练,就可以开始分类了。

3. K值最优解

  • 3.1 原因:

    • k值过大,非相似数据被包含较多,造成噪声增加而导致分类结果的降低。

    • k值过小,得到的邻近数过少,会降低分类精度,同时也会放大噪声数据的干扰。

  • 3.2 方法:

    • k一般低于训练样本数的平方根,通常采用交叉检验来确定。
  • 3.3 KNN算法参数的筛选代码

  ### 导包,加载数据

import numpy as np

from sklearn.neighbors import KNeighborsClassifier

from sklearn import datasets

# model_selection:模型选择
# cross_val_score  cross:交叉,validation:验证(测试)
# 交叉验证
from sklearn.model_selection import cross_val_score

# 通过训练样本数的开平方对k值进行参考
X,y = datasets.load_iris(True)
X.shape[0]**0.5

结果是:12.24744871391589,所以k值的取值范围是1到13

应用cross_val_score筛选最合适的邻居数量

erros = []
for k in range(1,14):
    knn = KNeighborsClassifier(n_neighbors=k)
    score = cross_val_score(knn,X,y,scoring='accuracy',cv = 6).mean()
#     误差越小,说明k选择越合适,越好
    erros.append(1 - score)
    
import matplotlib.pyplot as plt
%matplotlib inline
# k = 11时,误差最小,说明k = 11对鸢尾花来说,最合适的k值
plt.plot(np.arange(1,14),erros)

在这里插入图片描述

通过上面代码所得图,可以看出当k = 11时,误差最小,k值最好

多参数组合使用cross_val_score筛选最合适的参数组合

result = {}
weights = ['distance','uniform']
for k in range(1,14):
    for w in weights:
        knn = KNeighborsClassifier(n_neighbors=k,weights=w)
        sm = cross_val_score(knn,X,y,scoring='accuracy',cv = 6).mean()
        result[w + str(k)] = sm
result
{'uniform1': 0.9591049382716049,
 'distance1': 0.9591049382716049,
 'uniform2': 0.9390432098765431,
 'distance2': 0.9591049382716049,
 'uniform3': 0.9660493827160493,
 'distance3': 0.9660493827160493,
 'uniform4': 0.9660493827160493,
 'distance4': 0.9660493827160493,
 'uniform5': 0.9660493827160493,
 'distance5': 0.9660493827160493,
 'uniform6': 0.9729938271604938,
 'distance6': 0.9729938271604938,
 'uniform7': 0.9729938271604938,
 'distance7': 0.9729938271604938,
 'uniform8': 0.9591049382716049,
 'distance8': 0.9729938271604938,
 'uniform9': 0.9660493827160493,
 'distance9': 0.9729938271604938,
 'uniform10': 0.9729938271604938,
 'distance10': 0.9729938271604938,
 'uniform11': 0.98070987654321,
 'distance11': 0.9799382716049383,
 'uniform12': 0.9737654320987654,
 'distance12': 0.9799382716049383,
 'uniform13': 0.9737654320987654,
 'distance13': 0.9729938271604938}

通过输出结果可以看出,当weights=uniform,且k=11时,误差最小,是k和weights的最优解

如果需要得到其他参数的最优解,方法同上

<think>好的,我现在需要回答用户关于KNN算法中超参数选择与调优的问题。首先,我得回忆一下KNN的基本原理和常见的超参数有哪些。KNN是一种基于实例的学习算法,分类或回归时依赖于最近的k个邻居。主要的超参数包括k值、距离度量方法(如欧氏距离、曼哈顿距离等)、权重分配方式(统一权重或距离加权)以及是否考虑特征权重等。 接下来,我需要确定如何结构清晰地组织这些信息。用户可能想了解每个超参数的作用以及如何选择它们。同时,用户提到了调优方法,比如交叉验证和网格搜索,这需要结合引用中的内容来阐述。 首先,应该解释每个超参数的意义。例如,k值控制了邻居的数量,较小的k可能导致过拟合,较大的k可能欠拟合。距离度量的选择影响相似度的计算,不同的问题可能需要不同的距离函数。权重分配可以调整近邻的影响程度,距离加权的KNN可能在某些情况下表现更好。 然后,调优方法部分需要介绍交叉验证,尤其是k折交叉验证,以及网格搜索如何系统地遍历参数组合。引用中提到GridSearchCV这个API,应该具体说明其使用方法,比如参数网格的设定和交叉验证的折数。 还需要比较传统手工调参和自动调参的优缺点,如传统方法耗时且不一定找到最优解,而网格搜索结合交叉验证更高效可靠。此外,引用中的资料提到模型选择与调优的步骤,可能需要分点说明流程。 最后,生成相关的问题时,要确保问题覆盖用户可能进一步感兴趣的方面,比如不同距离度量的影响、交叉验证的具体步骤、实际应用中的例子,以及与其他算法的对比等。 需要注意的是,回答中所有数学表达式要用$...$格式,如欧氏距离公式$d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}$,独立公式用$$...$$。同时,引用标识要自然添加,比如在提到交叉验证时引用对应的文献。 现在,需要将这些思考整理成结构化的回答,确保每个部分清晰,并符合用户的要求。检查是否有遗漏的超参数或调优方法,以及是否引用了正确的来源。此外,代码示例部分可能需要展示如何使用GridSearchCV,这需要确保语法正确,并适当注释。</think>### KNN算法中的超参数选择与调优 #### 一、KNN的核心超参数及作用 1. **K值(邻居数量)** - 控制分类或回归时参考的最近邻数量。 - **过小**(如$k=1$)易受噪声影响导致过拟合;**过大**(如$k=50$)可能忽略局部特征导致欠拟合[^2]。 2. **距离度量(metric)** - 定义样本间相似度的计算方式,常见方法: - 欧氏距离:$$d(x,y) = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}$$ - 曼哈顿距离:$$d(x,y) = \sum_{i=1}^n |x_i - y_i|$$ - 不同度量对高维数据或稀疏数据的敏感度不同[^1]。 3. **权重分配(weights)** - 统一权重:所有邻居贡献相同。 - 距离加权:近邻权重更大,例如$\text{weight} = \frac{1}{d(x,y)}$,缓解噪声干扰[^3]。 4. **算法实现方式(algorithm)** - 可选暴力搜索(brute)、KD树(kd_tree)或球树(ball_tree),影响计算效率,尤其在大数据集上[^5]。 --- #### 二、超参数调优方法 1. **交叉验证(Cross-Validation)** - **原理**:将数据集划分为$k$个子集,轮流用$k-1$个子集训练,剩余1个验证,重复$k$次取平均性能。 - **作用**:减少过拟合风险,评估超参数泛化能力。 2. **网格搜索(Grid Search)** - **步骤**: 1. 定义超参数候选值(如$k \in \{3,5,7\}$,距离度量$\in \{\text{欧氏, 曼哈顿}\}$)。 2. 遍历所有组合,通过交叉验证选出最优组合。 - **API示例**(基于scikit-learn): ```python from sklearn.model_selection import GridSearchCV param_grid = {'n_neighbors': [3,5,7], 'metric': ['euclidean', 'manhattan']} grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, cv=5) grid_search.fit(X_train, y_train) print("最优参数:", grid_search.best_params_) ``` 3. **随机搜索(Random Search)** - 在超参数空间中随机采样,适用于参数范围较大时,比网格搜索更高效[^4]。 --- #### 三、实际应用建议 - **数据标准化**:KNN对特征尺度敏感,需先进行归一化或标准化。 - **维度灾难**:高维数据中距离计算可能失效,需结合特征选择或降维(如PCA)。 - **样本均衡性**:类别不平衡时,需调整权重或采用加权投票策略。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值