python可视化实现KNN算法


Posted in Python onOctober 16, 2019

简介

这里通过python的绘图工具Matplotlib包可视化实现机器学习中的KNN算法。

需要提前安装python的Numpy和Matplotlib包。

KNN?最近邻分类算法,算法逻辑比较简单,思路如下:

1.设一待分类数据iData,先计算其到已标记数据集中每个数据的距离,例如欧拉距离sqrt((x1-x2)^2+(y1-y2)^2);

2.然后根据离iData最近的k个数据的分类,出现次数最多的类别定为iData的分类。

KNN——最近邻算法python代码

代码实现:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

def KNNClassify(labelData,predData,k): #数据集包含分类属性
#labelData 是已经标记分类的数据集
#predData 未分类的待预测数据集
 labShape = labelData.shape
 for i in range(predData.shape[0]): #以predData的每行数据进行遍历
 iData = predData[i]
 iDset = np.tile(iData,(labShape[0],1)) #将iData重复,扩展成与labelData同形的矩阵
 #这里用欧拉距离sqrt((x1-x2)^2+(y1-y2)^2)
 diff = iDset[...,:-1] - labelData[...,:-1]
 diff = diff**2
 distance = np.sum(diff,axis=1)
 distance = distance ** 0.5 #开根号
 sortedIND = np.argsort(distance) #排序,以序号返回。
 classCount = { }
 for j in range(k): #计算距离最近的前k个标记数据的类别
 voteLabel = labelData[sortedIND[j],-1]
 classCount[voteLabel] = classCount.get(voteLabel,0)+1

 maxcls = max(classCount,key=classCount.get) #类别最多的,返回键名(类别名)
 predData[i][...,-1] = maxcls

 return predData

为了测试这个算法,需要现成的已分类数据集,由于手动输入很有限,数据量少,耗时。作为学习我们这里用代码模拟生成数据来进行测试。下面是生成已分类数据集的代码:

生成模拟数据的函数

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

#模拟生成分类数据
#目标是产生二维坐标中的几堆数据集,每堆为一个类
#函数逻辑:
#将x轴分段,每个段设一个中心的,所有的中心点用cores存储。
#设置每个数据中心点core的类别,由中心点在一定范围内随机产生数据,并将这些数据设为和core一样的类别
#所以每类的数据会简单的被X轴的每段大致分开

def makeKNNData(colnum,clsnum,nums,cores = []):
#colnum单个数据拥有特征数量(包括数据的分类);
# clsnum表示共有多少种分类;
# nums是一个元组,表示每个类别希望产生多少数据样本,如colnum为5,nums为[56, 69, 60, 92, 95];
#cores非必要参数,手动给出只是用于测试,cores提供每类的中心点,以中心点为依据产生该类数据。

 dataSet = np.zeros((sum(nums),colnum)) #初始化数据集,用于存放随后生成的所有数据
 n=0 #记录生成数据的下标
 step = 20/clsnum #假定X坐标轴只显示0~20的范围,step为X轴分段后的段长
 for j in range(clsnum): #循环生成各个类数据
 try:
 core = cores[j] #如果cores没有给出则,则出错,跳至except执行
 except IndexError :
 core = np.random.rand(1,3) #中心点为array([[x1,x2,c]]),c用于表示类别,这里产生的是1*3的二维数组
 core[0][0] =j*step + core[0][0]*step #将x1限制在各段中
 core[0][1] *=15 #将x2即y轴限制在0~15范围内
 core[0][2] = j #设置类别
 cores.append(core)
 for i in range(nums[j]): #按nums中指定了每类数据的数量,用循环生成。
 point= core[0][:2] + np.random.rand(1,2)*step -step/2 #产生点point(x,y),x以中心点在(core_x - step/2, core_x + step/2)范围随机波动,y同理。
 row = np.column_stack((point,core[0][2])) #加上类别成为一个数据
 dataSet[n] = row
 n +=1
 i +=1

 j +=1

 #print("print cores:",cores)
 return dataSet

有了数据集之后,我们可以用Matplotlib将数据可视化,以直观显示出来

数据可视化函数

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

#绘图展示数据,每类数据点以不同的颜色显示
def showFigure(dataSet,clsnum):
 fig = plt.figure()
 ax = fig.add_subplot(1,1,1) #界面只需显示一个视图
 ax.set_title('KNN separable data set') #视图名称,这里简单统一定这个名称吧
 plt.xlabel('X') #坐标轴名称
 plt.ylabel('Y')

 colors = ['r','g','b','y','k'] #定义显示的颜色b为blue,k为black
 for i in range(clsnum):
 idx = np.where(dataSet[:,2] == i) #查询每类的索引号
 ax.scatter(dataSet[idx,0], dataSet[idx,1], marker='o', color=colors[i%5], label=1, s=10) #在视图中的显示方式

 plt.legend(loc = 'upper right') #图例显示位置
 plt.show()


#测试一下
#需要结合模拟生成数据的函数
classnum = 5
nums = np.random.randint(50,100,classnum) #示例 array([56, 69, 60, 92, 95]),每个数字在50~100范围内
dataSet = makeKNNData(3,classnum,nums)
showFigure(dataSet,classnum)

生成的模拟数据展示结果如下:

python可视化实现KNN算法

完整代码

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

#模拟生成分类数据
#目标是产生二维坐标中的几堆数据集,每堆为一个类
#函数逻辑:
#将x轴分段,每个段设一个中心的,所有的中心点用cores存储。
#设置每个数据中心点core的类别,由中心点在一定范围内随机产生数据,并将这些数据设为和core一样的类别
#所以每类的数据会简单的被X轴的每段大致分开

def makeKNNData(colnum,clsnum,nums,cores = []):
#colnum单个数据拥有特征数量(包括数据的分类);
# clsnum表示共有多少种分类;
# nums是一个元组,表示每个类别希望产生多少数据样本;
#cores非必要参数,手动给出只是用于测试,cores提供每类的中心点,以中心点为依据产生该类数据。

 dataSet = np.zeros((sum(nums),colnum)) #初始化数据集,用于存放随后生成的所有数据
 n=0 #记录生成数据的下标
 step = 20/clsnum #假定X坐标轴只显示0~20的范围,step为X轴分段后的段长
 for j in range(clsnum): #循环生成各个类数据
 try:
 core = cores[j] #如果cores没有给出则,则出错,跳至except执行
 except IndexError :
 core = np.random.rand(1,3) #中心点为array([[x1,x2,c]]),c用于表示类别,这里产生的是1*3的二维数组
 core[0][0] =j*step + core[0][0]*step #将x1限制在各段中
 core[0][1] *=15 #将x2即y轴限制在0~15范围内
 core[0][2] = j #设置类别
 cores.append(core)
 for i in range(nums[j]): #按nums中指定了每类数据的数量,用循环生成。
 point= core[0][:2] + np.random.rand(1,2)*step -step/2 #产生点point(x,y),x以中心点在(core_x - step/2, core_x + step/2)范围随机波动,y同理。
 row = np.column_stack((point,core[0][2])) #加上类别成为一个数据
 dataSet[n] = row
 n +=1
 i +=1

 j +=1

 #print("print cores:",cores)
 return dataSet

#绘图展示数据,每类数据点以不同的颜色显示
def showFigure(dataSet,clsnum):
 fig = plt.figure()
 ax = fig.add_subplot(1,1,1) #界面只需显示一个视图
 ax.set_title('KNN separable data set') #视图名称,这里简单统一定这个名称吧
 plt.xlabel('X') #坐标轴名称
 plt.ylabel('Y')

 colors = ['r','g','b','y','k'] #定义显示的颜色b为blue,k为black
 for i in range(clsnum):
 idx = np.where(dataSet[:,2] == i) #查询每类的索引号
 ax.scatter(dataSet[idx,0], dataSet[idx,1], marker='o', color=colors[i%5], label=1, s=10) #在视图中的显示方式

 plt.legend(loc = 'upper right') #图例显示位置
 plt.show()


#分类算法:
#待分类数据iData,先计算其到已标记数据集中每个数据的距离
#然后根据离iData最近的k个数据的分类,出现次数最多的类别定为iData的分类。

def KNNClassify(labelData,predData,k): #数据集包含分类属性
#labelData 是已经标记分类的数据集
#predData 待预测数据集
 labShape = labelData.shape
 for i in range(predData.shape[0]): #以predData的每行数据进行遍历
 iData = predData[i]
 iDset = np.tile(iData,(labShape[0],1)) #将iData重复,扩展成与labelData同形的矩阵
 #这里用欧拉距离sqrt((x1-x2)^2+(y1-y2)^2)
 diff = iDset[...,:-1] - labelData[...,:-1]
 diff = diff**2
 distance = np.sum(diff,axis=1)
 distance = distance ** 0.5 #开根号
 sortedIND = np.argsort(distance) #排序,以序号返回。
 classCount = { }
 for j in range(k): #计算距离最近的前k个标记数据的类别
 voteLabel = labelData[sortedIND[j],-1]
 classCount[voteLabel] = classCount.get(voteLabel,0)+1

 maxcls = max(classCount,key=classCount.get) #类别最多的,返回键名(类别名)
 predData[i][...,-1] = maxcls

 return predData

#测试
labNums = np.random.randint(50,200,classnum)
predNums = np.random.randint(10,80,classnum)
#cores = [np.array([[ 0.08321641, 12.22596938, 0. ]]), np.array([[9.99891798, 4.24009775, 1. ]]), np.array([[14.98097374, 9.80120399, 2. ]])]

labelData = makeKNNData(3,classnum,labNums)
showFigure(labelData,classnum)
predData = makeKNNData(3,classnum,predNums) #这里为了方便,不在写产生待分类数据的代码,只需用之前的函数并忽略其类别就好。
predData[...,-1]=0
showFigure(predData,classnum)

k = 10
KNNData = KNNClassify(labelData,predData,k)
showFigure(KNNData,classnum)

运行程序,结果如下:

1.labelData的数据(已知分类的数据) 

 python可视化实现KNN算法

2.predData的数据(未标记的数据) 

 python可视化实现KNN算法

3KNNData的数据(用KNN算法进行分类后的数据)

python可视化实现KNN算法

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

Python 相关文章推荐
Web服务器框架 Tornado简介
Jul 16 Python
python实现从web抓取文档的方法
Sep 26 Python
Python使用自带的ConfigParser模块读写ini配置文件
Jun 26 Python
python 实现调用子文件下的模块方法
Dec 07 Python
mac系统下Redis安装和使用步骤详解
Jul 09 Python
Python 读取用户指令和格式化打印实现解析
Sep 02 Python
python计算n的阶乘的方法代码
Oct 25 Python
python zip()函数使用方法解析
Oct 31 Python
节日快乐! Python画一棵圣诞树送给你
Dec 24 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
Feb 04 Python
Python如何把多个PDF文件合并代码实例
Feb 13 Python
python中lower函数实现方法及用法讲解
Dec 23 Python
python实现KNN分类算法
Oct 16 #Python
python子线程退出及线程退出控制的代码
Oct 16 #Python
python Pillow图像处理方法汇总
Oct 16 #Python
win10环境下配置vscode python开发环境的教程详解
Oct 16 #Python
500行代码使用python写个微信小游戏飞机大战游戏
Oct 16 #Python
python提取xml里面的链接源码详解
Oct 15 #Python
python yield关键词案例测试
Oct 15 #Python
You might like
一个自定义位数的php多用户计数器代码
2007/03/11 PHP
PHP中spl_autoload_register函数的用法总结
2013/11/07 PHP
Yii框架创建cronjob定时任务的方法分析
2017/05/23 PHP
PHP使用phpunit进行单元测试示例
2019/09/23 PHP
JQuery 国际象棋棋盘 实现代码
2009/06/26 Javascript
基于jQuery的烟花效果(运动相关)点击屏幕出烟花
2012/06/14 Javascript
jQuery实现简单二级下拉菜单
2015/04/12 Javascript
Javascript BOM学习小结(六)
2015/11/26 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
基于js文件加载优化(详解)
2018/01/03 Javascript
详解使用element-ui table组件的筛选功能的一个小坑
2018/11/02 Javascript
详解javascript对数组和json数组的操作
2019/04/15 Javascript
详解滑动穿透(锁body)终极探索
2019/04/16 Javascript
vue项目中引入Sass实例方法
2019/08/27 Javascript
JS实现图片幻灯片效果代码实例
2020/05/21 Javascript
小程序实现多个选项卡切换
2020/06/19 Javascript
在Python中使用dict和set方法的教程
2015/04/27 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
python实现log日志的示例代码
2018/04/28 Python
如何优雅地处理Django中的favicon.ico图标详解
2018/07/05 Python
Python 比较文本相似性的方法(difflib,Levenshtein)
2018/10/15 Python
Windows系统下PhantomJS的安装和基本用法
2018/10/21 Python
一文带你了解Python中的字符串是什么
2018/11/20 Python
用Python实现将一张图片分成9宫格的示例
2019/07/05 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
python 创建一维的0向量实例
2019/12/02 Python
pytorch制作自己的LMDB数据操作示例
2019/12/18 Python
python使用openCV遍历文件夹里所有视频文件并保存成图片
2020/01/14 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
2020/05/13 Python
Django celery异步任务实现代码示例
2020/11/26 Python
使用html2canvas.js实现页面截图并显示或上传的示例代码
2018/12/18 HTML / CSS
会计学自我鉴定
2014/02/06 职场文书
学习型家庭事迹材料
2014/12/20 职场文书
小班教师个人总结
2015/02/05 职场文书
2016大学生社会实践心得体会范文
2016/01/14 职场文书
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
2022/04/30 Vue.js