侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python可视化实现KNN算法

Python  /  管理员 发布于 7年前   198

简介

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

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

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

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

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

KNN――最近邻算法python代码

代码实现:

import numpy as npimport matplotlib as mplimport matplotlib.pyplot as pltdef 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 npimport matplotlib as mplimport 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 npimport matplotlib as mplimport 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 = 5nums = np.random.randint(50,100,classnum) #示例 array([56, 69, 60, 92, 95]),每个数字在50~100范围内dataSet = makeKNNData(3,classnum,nums)showFigure(dataSet,classnum)

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

完整代码

import numpy as npimport matplotlib as mplimport 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]=0showFigure(predData,classnum)k = 10KNNData = KNNClassify(labelData,predData,k)showFigure(KNNData,classnum)

运行程序,结果如下:

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

 

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

 

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

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


  • 上一条:
    Python生成验证码、计算具体日期是一年中的第几天实例代码详解
    下一条:
    python实现KNN分类算法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客