用Python实现KNN分类算法


Posted in Python onDecember 22, 2017

本文实例为大家分享了Python KNN分类算法的具体代码,供大家参考,具体内容如下

KNN分类算法应该算得上是机器学习中最简单的分类算法了,所谓KNN即为K-NearestNeighbor(K个最邻近样本节点)。在进行分类之前KNN分类器会读取较多数量带有分类标签的样本数据作为分类的参照数据,当它对类别未知的样本进行分类时,会计算当前样本与所有参照样本的差异大小;该差异大小是通过数据点在样本特征的多维度空间中的距离来进行衡量的,也就是说,如果两个样本点在在其特征数据多维度空间中的距离越近,则这两个样本点之间的差异就越小,这两个样本点属于同一类别的可能性就越大。KNN分类算法利用这一基本的认知,通过计算待预测样本点与参照样本空间中所有的样本的距离,并找到K个距离该样本点最近的参照样本点,统计出这最邻近的K个样本点中占比数量最多的类别,并将该类别作为预测结果。

用Python实现KNN分类算法

KNN的模型十分简单,没有涉及到模型的训练,每一次预测都需要计算该点与所有已知点的距离,因此随着参照样本集的数量增加,KNN分类器的计算开销也会呈比例增加,并且KNN并不适合数量很少的样本集。并且KNN提出之后,后续很多人提出了很多改进的算法,分别从提高算法速率和提高算法准确率两个方向,但是都是基于“距离越近,相似的可能性越大”的原则。这里利用Python实现了KNN最原始版本的算法,数据集使用的是机器学习课程中使用得非常多的莺尾花数据集,同时我在原数据集的基础上向数据集中添加了少量的噪声数据,测试KNN算法的鲁棒性。

数据集用得是莺尾花数据集,下载地址。

用Python实现KNN分类算法

数据集包含90个数据(训练集),分为2类,每类45个数据,每个数据4个属性 

Sepal.Length(花萼长度),单位是cm;
Sepal.Width(花萼宽度),单位是cm;
Petal.Length(花瓣长度),单位是cm;
Petal.Width(花瓣宽度),单位是cm;

分类种类: Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾)
之前主打C++,近来才学的Python,今天想拿实现KNN来练练手,下面上代码:

#coding=utf-8
import math
#定义鸢尾花的数据类
class Iris:
 data=[]
 label=[]
 pass
#定义一个读取莺尾花数据集的函数
def load_dataset(filename="Iris_train.txt"):
 f=open(filename)
 line=f.readline().strip()
 propty=line.split(',')#属性名
 dataset=[]#保存每一个样本的数据信息
 label=[]#保存样本的标签
 while line:
 line=f.readline().strip()
 if(not line):
 break
 temp=line.split(',')
 content=[]
 for i in temp[0:-1]:
 content.append(float(i))
 dataset.append(content)
 label.append(temp[-1])
 total=Iris()
 total.data=dataset
 total.label=label
 return total#返回数据集
 
#定义一个Knn分类器类
class KnnClassifier:
 def __init__(self,k,type="Euler"):#初始化的时候定义正整数K和距离计算方式
 self.k=k
 self.type=type
 self.dataloaded=False
 def load_traindata(self,traindata):#加载数据集
 self.data=traindata.data
 self.label=traindata.label
 self.label_set=set(traindata.label)
 self.dataloaded=True#是否加载数据集的标记
 
 def Euler_dist(self,x,y):# 欧拉距离计算方法,x、y都是向量
 sum=0
 for i,j in zip(x,y):
 sum+=math.sqrt((i-j)**2)
 return sum
 def Manhattan_dist(self,x,y):#曼哈顿距离计算方法,x、y都是向量
 sum=0
 for i,j in zip(x,y):
 sum+=abs(i-j)
 return sum
 def predict(self,temp):#预测函数,读入一个预测样本的数据,temp是一个向量
 if(not self.dataloaded):#判断是否有训练数据
 print "No train_data load in"
 return
 distance_and_label=[]
 if(self.type=="Euler"):#判断距离计算方式,欧拉距离或者曼哈顿距离
 for i,j in zip(self.data,self.label):
 dist=self.Euler_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 if(self.type=="Manhattan"):
 for i,j in zip(self.data,self.label):
 dist=self.Manhattan_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 print "type choice error"
 #获取K个最邻近的样本的距离和类别标签
 neighborhood=sorted(distance_and_label,cmp=lambda x,y : cmp(x[0],y[0]))[0:self.k]
 neighborhood_class=[]
 for i in neighborhood:
 neighborhood_class.append(i[1])
 class_set=set(neighborhood_class)
 neighborhood_class_count=[]
 print "In k nearest neighborhoods:"
 #统计该K个最邻近点中各个类别的个数
 for i in class_set:
 a=neighborhood_class.count(i)
 neighborhood_class_count.append([i,a])
 print "class: ",i," count: ",a
 result=sorted(neighborhood_class_count,cmp=lambda x,y : cmp(x[1],y[1]))[-1][0]
 print "result: ",result
 return result#返回预测的类别
 
if __name__ == '__main__':
 traindata=load_dataset()#training data
 testdata=load_dataset("Iris_test.txt")#testing data
 #新建一个Knn分类器的K为20,默认为欧拉距离计算方式
 kc=KnnClassifier(20)
 kc.load_traindata(traindata)
 predict_result=[]
 #预测测试集testdata中所有待预测样本的结果
 for i,j in zip(testdata.data,testdata.label):
 predict_result.append([i,kc.predict(i),j])
 correct_count=0
 #将预测结果和正确结果进行比对,计算该次预测的准确率
 for i in predict_result:
 if(i[1]==i[2]):
 correct_count+=1
 ratio=float(correct_count)/len(predict_result)
 print "correct predicting ratio",ratio

测试集中11个待测样本点的分类结果:

In k nearest neighborhoods:
class: Iris-setosa count: 20
result: Iris-setosa
In k nearest neighborhoods:
class: Iris-setosa count: 20
result: Iris-setosa
In k nearest neighborhoods:
class: Iris-setosa count: 20
result: Iris-setosa
In k nearest neighborhoods:
class: Iris-setosa count: 20
result: Iris-setosa
In k nearest neighborhoods:
class: Iris-setosa count: 20
result: Iris-setosa
In k nearest neighborhoods:
class: Iris-versicolor count: 20
result: Iris-versicolor
In k nearest neighborhoods:
class: Iris-versicolor count: 20
result: Iris-versicolor
In k nearest neighborhoods:
class: Iris-versicolor count: 20
result: Iris-versicolor
In k nearest neighborhoods:
class: Iris-versicolor count: 20
result: Iris-versicolor
In k nearest neighborhoods:
class: Iris-versicolor count: 20
result: Iris-versicolor
In k nearest neighborhoods:
class: Iris-setosa count: 18
class: Iris-versicolor count: 2
result: Iris-setosa
correct predicting ratio 0.909090909091

KNN中对距离的计算有很多种方法,不同的方法适用于不同的数据集,该代码中只实现了欧拉距离和曼哈顿距离两种计算方式;测试集中的数据是从原数据集中抽离出来的,数据量不是很大,结果并不能很好地体现KNN的性能,所以程序运行结果仅供参考。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解在Python中处理异常的教程
May 24 Python
在Django的上下文中设置变量的方法
Jul 20 Python
Python数据操作方法封装类实例
Jun 23 Python
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
Jul 24 Python
python爬取拉勾网职位数据的方法
Jan 24 Python
Python装饰器模式定义与用法分析
Aug 06 Python
用python一行代码得到数组中某个元素的个数方法
Jan 28 Python
Python 转换RGB颜色值的示例代码
Oct 13 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
Jun 08 Python
pytorch VGG11识别cifar10数据集(训练+预测单张输入图片操作)
Jun 24 Python
python实现粒子群算法
Oct 15 Python
图神经网络GNN算法
May 11 Python
Python数据拟合与广义线性回归算法学习
Dec 22 #Python
python 动态加载的实现方法
Dec 22 #Python
Python决策树分类算法学习
Dec 22 #Python
Python之Scrapy爬虫框架安装及简单使用详解
Dec 22 #Python
Python2.7下安装Scrapy框架步骤教程
Dec 22 #Python
Python机器学习之决策树算法
Dec 22 #Python
python+selenium实现登录账户后自动点击的示例
Dec 22 #Python
You might like
这部好评如潮的动漫 知名梗频出 但是画风劝退很多人
2020/03/08 日漫
PHP syntax error, unexpected $end 错误的一种原因及解决
2008/10/25 PHP
Fine Uploader文件上传组件应用介绍
2013/01/06 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
详解ThinkPHP3.2.3验证码显示、刷新、校验
2016/12/29 PHP
PHP执行系统命令函数实例讲解
2021/03/03 PHP
JavaScript中void(0)的具体含义解释
2007/02/27 Javascript
javascript 树控件 比较好用
2009/06/11 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
onmouseover和onmouseout的一些问题思考
2013/08/14 Javascript
js中confirm实现执行操作前弹出确认框的方法
2014/11/01 Javascript
angularjs创建弹出框实现拖动效果
2020/08/25 Javascript
基于bootstrap插件实现autocomplete自动完成表单
2016/05/07 Javascript
switch语句的妙用(必看篇)
2016/10/03 Javascript
Angularjs上传图片实例详解
2017/08/06 Javascript
JavaScript数组,JSON对象实现动态添加、修改、删除功能示例
2018/05/26 Javascript
Vue组件中的data必须是一个function的原因浅析
2018/09/03 Javascript
简述Vue中容易被忽视的知识点
2019/12/09 Javascript
Vue仿Bibibili首页的问题
2021/01/21 Vue.js
JavaScript代码实现微博批量取消关注功能
2021/02/05 Javascript
[01:05:40]VG vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python实现一个简单的MySQL类
2015/01/07 Python
Python NumPy库安装使用笔记
2015/05/18 Python
在python中修改.properties文件的操作
2020/04/08 Python
AmazeUI 缩略图的实现示例
2020/08/18 HTML / CSS
移动端HTML5开发神器之vconsole详解
2020/12/15 HTML / CSS
PHP经典面试题
2016/09/03 面试题
机电一体化毕业生求职信
2013/11/02 职场文书
函授自我鉴定
2013/11/06 职场文书
外国人聘用意向书
2014/04/01 职场文书
团拜会策划方案
2014/06/07 职场文书
如何写贫困证明申请书
2014/10/29 职场文书
教师党员学习群众路线心得体会
2014/11/04 职场文书
合作意向书怎么写
2019/06/24 职场文书
SQL实现LeetCode(176.第二高薪水)
2021/08/04 MySQL
分析MySQL优化 index merge 后引起的死锁
2022/04/19 MySQL