【KNN算法详解(用法,优缺点,适用场景)及应用】

简介: 【KNN算法详解(用法,优缺点,适用场景)及应用】

KNN算法介绍

KNN(K Near Neighbor):k个最近的邻居,即每个样本都可以用它最接近的k个邻居来代表。KNN算法属于监督学习方式的分类算法,我的理解就是计算某给点到每个点的距离作为相似度的反馈。

简单来讲,KNN就是“近朱者赤,近墨者黑”的一种分类算法。

KNN是一种基于实例的学习,属于懒惰学习,即没有显式学习过程。

要区分一下聚类(如Kmeans等),KNN是监督学习分类,而Kmeans是无监督学习的聚类,聚类将无标签的数据分成不同的簇。

KNN算法三要素

距离度量

特征连续:距离函数选用曼哈顿距离(L1距离)/欧氏距离(L2距离)

当p=1 的时候,它是曼哈顿距离

当p=2的时候,它是欧式距离

当p不选择的时候,它是切比雪夫

特征离散:汉明距离

举最简单的例子来说明欧式/曼哈顿距离公式是什么样的。

K取值

在scikit-learn重KNN算法的K值是通过n_neighbors参数来调节的,默认值是5。


参考李航博士一书统计学习方法中写道的K值选择:


K值小,相当于用较小的领域中的训练实例进行预测,只要与输入实例相近的实例才会对预测结果,模型变得复杂,只要改变一点点就可能导致分类结果出错,泛化性不佳。(学习近似误差小,但是估计误差增大,过拟合)

K值大,相当于用较大的领域中的训练实例进行预测,与输入实例较远的实例也会对预测结果产生影响,模型变得简单,可能预测出错。(学习近似误差大,但是估计误差小,欠拟合)

极端情况:K=0,没有可以类比的邻居;K=N,模型太简单,输出的分类就是所有类中数量最多的,距离都没有产生作用。

什么是近似误差和估计误差:

近似误差:训练集上的误差

估计误差:测试集上的误差

分类规则

knn使用的分类决策规则是多数表决,如果损失函数为0-1损失函数,那么要使误分类率最小即使经验风险最小,多数表决规则实际上就等同于经验风险最小化。

KNN实际应用

案例引入

我们先看一个案例,这样可以更直观的理解KNN算法。数据如下表,其中包括10个人的身高、体重和年龄数据,然后预测第十一个人的体重。

为了更清晰地了解数据间的关系,我们用坐标轴将身高和年龄表示出来,其中横坐标为年龄(age)、纵坐标为身高(Height)。

通过上图可以看到,11点的值是需要求解的,那么怎么求呢?我们可以看到在图中11点更接近于5点和1点,所以其体重应该更接近于5点和1点的值,就是在72-77之间,这样我们就可以大致得到11点的体重值。下面我们用算法来实现这一过程。

KNN算法工作


如上所述,KNN可以用于分类和回归问题,通过样本间的某些相似特征来进行预测未知元素的值,即“物以类聚”:相同或相似的事物之间具有一些相似的特征。


在分类问题中,我们可以直接将其最近的样本值作为预测结果,那么在回归问题中怎么计算最终的预测结果呢?就像上面的例子,11点取值介于72-77之间,最终结果应该取多少合适呢?一般来说,我们将其平均值作为最终的预测结果。


1、计算待测点到已知点的距离

2、选择距离待测点最近的K个点,k值为人工设置的,至于k值如何设置合适在后边讨论。在这个例子中,我们假设k=3,即点1、5、6被选择。

3、将点1、5、6的值取平均值作为最终的预测结果。即11点的Weight=(77+72+60)/3 = 69.66 kg

K值选择

K值代表最近邻的个数,k值的选择对预测结果有较大影响

在上面的例子中,我们选择k=3时

最终的预测结果为

ID11 = (77+72+60)/3

ID11 = 69.66 kg

当我们选择k=5时

最终的预测结果为

ID 11 = (77+59+72+60+58)/5

ID 11 = 65.2 kg

我们可以看到k值不同结果也将不同,因此我们需要选择一个合适的k值来获得最佳的预测结果。我们的目标就是获得预测值与真实值之间最小的误差。

下面我们看一下k值与误差的关系曲线

由曲线可得,如果K值太小,则会发生过拟合;如果k值太大,则会发生欠拟合。因此我们根据误差曲线选择最佳k值为9,你也可以使用其他方法寻找最佳k值。

python实现代码

1、读取数据

import pandas as pd
df = pd.read_csv('train.csv')
df.head()

2、处理缺失值

df.isnull().sum()
#missing values in Item_weight and Outlet_size needs to be imputed
mean = df['Item_Weight'].mean() #imputing item_weight with mean
df['Item_Weight'].fillna(mean, inplace =True)
mode = df['Outlet_Size'].mode() #imputing outlet size with mode
df['Outlet_Size'].fillna(mode[0], inplace =True)

3、处理分类变量并删除ID列

df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)
df = pd.get_dummies(df)

4、划分训练集与测试

df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)from sklearn.model_selection import train_test_split
train , test = train_test_split(df, test_size = 0.3)
x_train = train.drop('Item_Outlet_Sales', axis=1)
y_train = train['Item_Outlet_Sales']
x_test = test.drop('Item_Outlet_Sales', axis = 1)
y_test = test['Item_Outlet_Sales']
df = pd.get_dummies(df)

5、特征标准化

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
x_train_scaled = scaler.fit_transform(x_train)
x_train = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(x_test)
x_test = pd.DataFrame(x_test_scaled)

6、查看误差曲线

from sklearn import neighbors
from sklearn.metrics import mean_squared_error 
from math import sqrt
import matplotlib.pyplot as plt
%matplotlib inline
rmse_val = [] #to store rmse values for different k
for K in range(20):
    K = K+1
    model = neighbors.KNeighborsRegressor(n_neighbors = K)
    model.fit(x_train, y_train)  #fit the model
    pred=model.predict(x_test) #make prediction on test set
    error = sqrt(mean_squared_error(y_test,pred)) #calculate rmse
    rmse_val.append(error) #store rmse values
    print('RMSE value for k= ' , K , 'is:', error)
curve = pd.DataFrame(rmse_val) #elbow curve 
curve.plot()

输出

由误差曲线可得我们选择k=7可以获得最优结果

预测结果

test = pd.read_csv('test.csv')
submission = pd.read_csv('SampleSubmission.csv')
submission['Item_Identifier'] = test['Item_Identifier']
submission['Outlet_Identifier'] = test['Outlet_Identifier']
#preprocessing test dataset
test.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)
test['Item_Weight'].fillna(mean, inplace =True)
test = pd.get_dummies(test)
test_scaled = scaler.fit_transform(test)
test = pd.DataFrame(test_scaled)
#predicting on the test set and creating submission file
predict = model.predict(test)
submission['Item_Outlet_Sales'] = predict
submission.to_csv('submit_file.csv',index=False)

KNN算法优点,缺点,适用场景

优点

流程简单明了,易于实现

方便进行多分类任务,效果优于SVM

适合对稀有事件进行分类

缺点


计算量大,T = O ( n ) T=O(n)T=O(n),需要计算到每个点的距离

样本不平衡时(一些分类数量少,一些多),前K个样本中大容量类别占据多数,这种情况会影响到分类结果

K太小过拟合,K太大欠拟合,K较难决定得完美,通过交叉验证确定K

适用场景


多分类问题

稀有事件分类问题

文本分类问题

模式识别

聚类分析

样本数量较少的分类问题



相关文章
|
1天前
|
机器学习/深度学习 算法
基于鲸鱼优化的knn分类特征选择算法matlab仿真
**基于WOA的KNN特征选择算法摘要** 该研究提出了一种融合鲸鱼优化算法(WOA)与K近邻(KNN)分类器的特征选择方法,旨在提升KNN的分类精度。在MATLAB2022a中实现,WOA负责优化特征子集,通过模拟鲸鱼捕食行为的螺旋式和包围策略搜索最佳特征。KNN则用于评估特征子集的性能。算法流程包括WOA参数初始化、特征二进制编码、适应度函数定义(以分类准确率为基准)、WOA迭代搜索及最优解输出。该方法有效地结合了启发式搜索与机器学习,优化特征选择,提高分类性能。
|
3天前
|
机器学习/深度学习 数据采集 算法
KNN算法原理及应用(一)
**KNN算法**是一种监督学习的分类算法,适用于解决分类问题。它基于实例学习,无需训练过程,当新样本到来时,通过计算新样本与已有训练样本之间的距离,找到最近的K个邻居,然后根据邻居的类别进行多数表决(或加权表决)来预测新样本的类别。K值的选择、距离度量方式和分类决策规则是KNN的关键要素。KNN简单易懂,但计算复杂度随样本量增加而增加,适用于小规模数据集。在鸢尾花数据集等经典问题上表现良好,同时能处理多分类任务,并可应用于回归和数据预处理中的缺失值填充。
KNN算法原理及应用(一)
|
3天前
|
算法 索引
DFS算法及应用(二)
回溯:回溯就是DFS的一种,在搜索探索过程中寻找问题的解,当发现不满足求解条件时,就回溯返回,尝试其他路径。
|
3天前
|
算法
DFS算法及应用(一)
DFS(深度优先搜索)是一种图遍历算法,常用于解决穷举问题,如全排列、迷宫问题、图的连通性等。它沿着树的深度分支进行探索,直至达到叶子节点,若无法继续则回溯。例如,将数字6拆分为3个正整数的递增序列问题可以通过DFS实现,类似地,分糖果问题和买瓜问题同样可以用DFS求解。DFS通常涉及递归或栈结构,通过标记已访问节点避免重复。在编程中,会定义递归函数,设定结束条件,然后枚举可能的情况,并处理下一层节点。
|
3天前
|
算法
KNN算法原理及应用(二)
不能将所有数据集全部用于训练,为了能够评估模型的泛化能力,可以通过实验测试对学习器的泛化能力进行评估,进而做出选择。因此需要使用一个测试集来测试学习器对新样本的判别能力。
|
3天前
|
算法
基于蝗虫优化的KNN分类特征选择算法的matlab仿真
摘要: - 功能:使用蝗虫优化算法增强KNN分类器的特征选择,提高分类准确性 - 软件版本:MATLAB2022a - 核心算法:通过GOA选择KNN的最优特征以改善性能 - 算法原理: - KNN基于最近邻原则进行分类 - 特征选择能去除冗余,提高效率 - GOA模仿蝗虫行为寻找最佳特征子集,以最大化KNN的验证集准确率 - 运行流程:初始化、评估、更新,直到达到停止标准,输出最佳特征组合
|
2天前
|
机器学习/深度学习 算法 数据可视化
基于BP神经网络的64QAM解调算法matlab性能仿真
**算法预览图省略** MATLAB 2022A版中,运用BP神经网络进行64QAM解调。64QAM通过6比特映射至64复数符号,提高数据速率。BP网络作为非线性解调器,学习失真信号到比特的映射,对抗信道噪声和多径效应。网络在处理非线性失真和复杂情况时展现高适应性和鲁棒性。核心代码部分未显示。
|
4天前
|
机器学习/深度学习 算法 数据可视化
m基于PSO-LSTM粒子群优化长短记忆网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,应用PSO优化的LSTM模型提升了电力负荷预测效果。优化前预测波动大,优化后预测更稳定。PSO借鉴群体智能,寻找LSTM超参数(如学习率、隐藏层大小)的最优组合,以最小化误差。LSTM通过门控机制处理序列数据。代码显示了模型训练、预测及误差可视化过程。经过优化,模型性能得到改善。
21 6
|
2天前
|
缓存 算法
基于机会网络编码(COPE)的卫星网络路由算法matlab仿真
**摘要:** 该程序实现了一个基于机会网络编码(COPE)的卫星网络路由算法,旨在提升无线网络的传输效率和吞吐量。在MATLAB2022a中测试,结果显示了不同数据流个数下的网络吞吐量。算法通过Dijkstra函数寻找路径,计算编码机会(Nab和Nx),并根据编码机会减少传输次数。当有编码机会时,中间节点执行编码和解码操作,优化传输路径。结果以图表形式展示,显示数据流与吞吐量的关系,并保存为`R0.mat`。COPE算法预测和利用编码机会,适应卫星网络的动态特性,提高数据传输的可靠性和效率。
|
4天前
|
算法 调度
基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图
**摘要:** 实现变异混合蛙跳算法的MATLAB2022a版车间调度优化程序,支持动态调整工件和机器数,输出甘特图。核心算法结合SFLA与变异策略,解决Job-Shop Scheduling Problem,最小化总完成时间。SFLA模拟蛙群行为,分组进行局部搜索和全局信息交换。变异策略增强全局探索,避免局部最优。程序初始化随机解,按规则更新,经多次迭代和信息交换后终止。