KNN(python实现)

本文深入解析了kNN算法的工作流程,从数据收集到分类预测,详细介绍了如何使用Python实现kNN算法,包括计算欧式距离和曼哈顿距离,并通过一个分类器函数示例展示了kNN算法的具体应用。

kNN算法流程


一般情况下,kNN有如下流程: 
(1)收集数据:确定训练样本集合测试数据; 
(2)计算测试数据和训练样本集中每个样本数据的距离;

常用的距离计算公式: 
欧式距离公式:d(x,y)=∑ni=1(xi−yi)2−−−−−−−−−−−−√d(x,y)=∑i=1n(xi−yi)2 
曼哈顿距离公式:d(x,y)=∑ni=1|xi−yi|d(x,y)=∑i=1n|xi−yi|
(3)按照距离递增的顺序排序; 
(4)选取距离最近的k个点; 
(5)确定这k个点中分类信息的频率; 
(6)返回前k个点中出现频率最高的分类,作为当前测试数据的分类。

 

主要代码:

from numpy import *
import operator

#定义KNN算法分类器函数
#函数参数包括:(测试数据,训练数据,分类,k值)
def classify(inX,dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX,(dataSetSize,1))-dataSet
    sqDiffMat=diffMat**2
    sqDistances=sqDiffMat.sum(axis=1)
    distances=sqDistances**0.5 #计算欧式距离
    sortedDistIndicies=distances.argsort() #排序并返回index
    #选择距离最近的k个值
    classCount={}
    for i in range(k):
        voteIlabel=labels[sortedDistIndicies[i]]
        #D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #排序,降序
    sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

注:

  • 这里用到矩阵运算,计算测试样本和每个训练样本之间的L2距离
  • KNN存在的不足是,每次对一个样本进行预测时,都要对整个训练样本做一次测距,耗时严重;
  • 因此,对应的KD-Tree就能很好的解决这个问题,不用遍历所有样本,即可求得距离coor点最近的K个点的序号。详细过程可参考前面的文章 “KD-Tree的C++实现”

 

参考资料:https://blog.youkuaiyun.com/moxigandashu/article/details/71169991

KNN(K近邻算法)是一种简单且直观的分类算法,以下为你介绍其在Python中的实现。 ### 基本思路 KNN算法的核心思想是为了对新个体进行分类,查找训练集,找到与新个体最相似的那些个体,根据这些个体大多属于哪个类别,就把新个体分到哪个类别。在Python实现KNN算法通常包含以下步骤:引入数据、计算距离、排序选取最近的K个样本、统计类别频数并确定新个体的类别 [^1]。 ### 代码实现 ```python # 基本数据 x = [0, 1, 2, 3, 4, 5, 6, 7, 8] # 样本距离对应的类别 y = [0, 0, 0, 0, 1, 1, 1, 1, 1] # 待判断类型的新数据 x0 = 3.1 # 算出x0到其他所有值的距离,并将0,1表示的类别与之对应 data = [] for i in range(len(x)): dis = (x[i] - x0) ** 2 data.append((y[i], dis)) # 按元组第二个数据(距离)进行排序 data_one = sorted(data, key=lambda x: x[1]) # 超参数,只取距离最近的前k个来比较 k = 5 data_two = data_one[:k] # 统计各个类别的频数 c = {} for i in data_two: if i[0] in c.keys(): c[i[0]] = c[i[0]] + 1 else: c[i[0]] = 1 # 对类别频数进行排序 type_max = sorted(c.items(), key=lambda x: x[1]) print("如果 0,1,2,3 的类别是 0;\n4,5,6,7,8的类别是 1") print("则x0的类别是:", type_max[-1][0]) ``` ### 代码解释 1. **数据准备**:定义了基本数据`x`、对应的类别`y`以及待判断类型的新数据`x0`。 2. **计算距离**:通过遍历`x`,计算`x0`到每个样本的距离,并将类别和距离作为元组存入列表`data`中。 3. **排序**:使用`sorted`函数根据距离对`data`进行排序,得到`data_one`。 4. **选取最近的K个样本**:选取排序后前`k`个样本,存储在`data_two`中。 5. **统计类别频数**:遍历`data_two`,统计每个类别出现的频数,存储在字典`c`中。 6. **确定类别**:对字典`c`按频数排序,取频数最大的类别作为`x0`的类别。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值