KNN分类算法

基本思想

近朱者赤 近墨者黑
如果一个样本的K个最相近的样本中,大多数都属于某一类,那这个样本也属于这一类

KNN原理

  1. K-Nearest Neighbors,它是有监督,分类算法,也可用于回归,思想简单,理论成熟
  2. 训练模型时,没有实际的训练过程,保存的模型只是将所有的训练样本集保存起来。
  3. 在预测未知样本时,计算其到训练样本集中每个样本的距离,然后对所有的距离从小到大排序,取距离最近的K个训练集样本,由这K个最近邻样本投票决定该未知样本的所属类别,解决回归问题时,则取这K个最近邻的标记值的平均值/加权平均值

KNN算法预测圆形样本的类别:
K=3
K=5
在这里插入图片描述
K值不同,预测结果不同,对K值敏感
小过拟合,大欠拟合

KNN的三要素

  1. K值选择,分类问题一般取奇数,且 K ≤ 20 或者 K ≤ m , m 为训练样本数 K\le20 或者 K\le \sqrt{m},m为训练样本数 K20或者Km ,m为训练样本数
  2. 距离的度量,一般采用欧式距离 (注意归一化)
  3. 近邻的决策方式
    分类问题–投票
    回归问题–>均值

KNN的复杂度

KNN分类的复杂度与训练样本数成正比–> O(m)

KNN问题点

训练集类别不平衡时,预测结果偏向于类别多的一方
例如:
类别为0 的样本数95
类别为1 的样本数5
取K=11,预测类别为1 的一个样本, 11个近邻中最多有
5个属于类别1,
6个属于类别0,
投票决策预测结果为0,显然这是不正确的

解决方案:不同的样本给予不同的权重 1 d 或者 1 d 2 \frac {1} {d}或者\frac {1} {d^2} d1或者d21

KNN优点

  1. 思想简单,理论成熟,既可以分类,也可以回归
  2. 可用于 非线性 非线性 非线性 的分类
  3. 训练时间复杂度较低,仅O(m)
  4. 和朴素贝叶斯相比,对数据没有假设,准确率高,对噪声数据不敏感

KNN 缺点

  1. 计算量大,尤其训练样本数多,维度大时
  2. 样本不平衡时,预测结果偏向于类别多的一类
  3. 大数据时,建立KD树,球树模型,需要大内存
  4. 训练模型,基本不学习,可解释性不强

sklearn库中KNN

#分类
from sklearn.neighbors import KNeighborsClassifier

#回归
from sklearn.neighbors import KNeighborsRegressor

#knn 扩展
from sklearn.neighbors import RadiusNeighborsClassifier
from sklearn.neighbors import RadiusNeighborsRegressor

以KNN分类为例,介绍常用的参数:

  • n_neighbors, K值,最近邻数,默认5, 一般取奇数,小于等于20
  • weights, K个近邻各自的权重,
    • ‘uniform’ ,权重相同
    • ‘distance’ ,权重跟距离成反比
    • 自定义函数,根据距离计算权重
  • algorithm,计算近邻的算法
    • ‘brute’,蛮力实现,适用于稀疏样本
    • ‘kd_tree’,大样本数,维度多,样本分布均匀,建立kd树
    • ‘ball_tree’,大样本数,维度多,样本分布不均匀,建立ball树
    • ‘auto’,自动选择算法
  • metric,距离度量方式,默认欧式距离

KNN小试牛刀

  1. 生成分类数据
from sklearn.datasets import make_classification
x,y = make_classification(n_samples=500,n_features=2,n_classes=3,n_redundant=0,n_clusters_per_class=1,class_sep=1.2)

#可视化样本点
from matplotlib import pyplot as plt
plt.figure()
plt.title("Sample points")

plt.scatter(x[y==0][:,0],x[y==0][:,1],s=100,c="r",marker="s",edgecolors=None,label="label 0")
plt.scatter(x[y==1][:,0],x[y==1][:,1],s=100,c="g",marker="^",edgecolors=None,label="label 1")
plt.scatter(x[y==2][:,0],x[y==2][:,1],s=100,c="b",marker="o",edgecolors=None,label="label 2")

plt.grid()
plt.legend(loc="best",frameon=True,framealpha=0.3)

plt.show()
  1. 训练模型
from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=15,weights="distance")
clf.fit(x,y)
  1. 画出KNN的分类边界
#分类边界
x_min,y_min = x.min(axis=0)
x_max,y_max = x.max(axis=0)
x_range = np.linspace(x_min-1,x_max+1,200)
y_range = np.linspace(y_min-1,y_max+1,200)
xx,yy = np.meshgrid(x_range,y_range)

#预测
z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
#画等高线
plt.contour(xx,yy,z.reshape(xx.shape),cmap="cool")
plt.show()

如下的分类边界
在这里插入图片描述

KNN 案例实战

KNN实战

KNN总结

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值