分类问题中的k近邻法


前言

k近邻(k-Nearest Neighbors,简称kNN)算法是一种简单且常用的分类算法。k近邻的输入是实例的特征向量,对应于特征空间的点,输出为实例的类别。


一、k近邻算法

我们用人话来讲,就是现在,二维平面上有一堆点,已经分好类别了,看图看图,现在图上的点是不是被分成A,B两类。

那现在橙色的点我们应该分在哪类呢,当然是它离哪类近就归类为哪类。那我们现在要做的就是确定选择几个参考点(k近邻中k值的选取),然后用什么算法计算点之间的距离(距离度量),最后采取什么分类策略(服从多数,即分类决策规则)

这其实就包含了k近邻法的三要素,距离度量,k值选择,分类度量规则。

二、k近邻算法实现

1.自然想法

这里关键是计算样本点的邻域,不妨设这个样本点为x,现在就是要确定,和x离得最近的k个点,还记得k吗?k就是上面k值。我可以计算x与特征空间(理解为平面)中,所有点的距离,储存在一个数组里面,然后对数组进行排序,然后选择前k个元素,即是我们要求的参考点,但是这个方法要计算x与所有参考点的距离,还要进行数组排序,但这个方法的时间复杂度很高,所以不是很理想。

2.kd树

kd树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。kd 树是二叉树,表示对k维空间的一个划分。构造 kd 树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。

我这里给一个简单的例子:

首先,我们将以x轴为标准,找到x坐标的中位数,即479,于是以点4为划分,将空间划分为两部分。同样的,先看左边,以y轴坐标为标准,找到y坐标的中位数,即721,于是以点1划分,将左边空间划分为两部分,同理,右边以点6划分,将右边空间划分为两部分。

构建出的kd树如下图:

现在来看如何使用kd树,现在有一个点x(471,449),先从根节点,由于471小于479,所以遍历到节点1,又449小于721,所以遍历到节点2上,故以x到节点2的距离为半径的邻域里,有最近的节点。

3.代码简单演示

这里哥们直接调库了嗷,从 scikit-learn 库中导入 k近邻分类器的语句。有兴趣的宝子可以自己用二叉树实现一下,哥们也不太会哈哈哈。

from sklearn.neighbors import KNeighborsClassifier
import numpy as np

# 样本数据和对应的类别标签
X_train = np.array([
    [70, 721],
    [207, 313],
    [343, 858],
    [479, 449],
    [615, 40],
    [751, 177],
    [888, 585]
])

y_train = np.array([0, 1, 0, 1, 1, 0, 0])

# 初始化k近邻分类器,选择k值为3
k = 3
knn = KNeighborsClassifier(n_neighbors=k)

# 训练模型
knn.fit(X_train, y_train)

# 预测新样本点的类别
X_new = np.array([[471, 449]])
y_pred = knn.predict(X_new)

print("预测类别:", y_pred)

代码运行结果:

其实是很直观的,我标注的数据,你可以很清楚得看出x离类别1比较近,有兴趣的可以自己计算一下()想起之前打数模计算欧式距离的噩梦了。。


总结

1.通俗介绍了一下什么是k近邻算法

2.讲解了k近邻算法的底层实现逻辑

3.用scikit-learn 库简单演示了一下例子

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值