python实现KNN分类算法


Posted in Python onOctober 16, 2019

一、KNN算法简介

邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。

kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。

python实现KNN分类算法

二、算法过程

1.读取数据集

2.处理数据集数据 清洗,采用留出法hold-out拆分数据集:训练集、测试集

3.实现KNN算法类:

   1)遍历训练数据集,离差平方和计算各点之间的距离

   2)对各点的距离数组进行排序,根据输入的k值取对应的k个点

   3)k个点中,统计每个点出现的次数,权重为距离的导数,得到最大的值,该值的索引就是我们计算出的判定类别

三、代码实现及数据分析

import numpy as np
import pandas as pd
 
# 读取鸢尾花数据集,header参数来指定标题的行。默认为0。如果没有标题,则使用None。
data = pd.read_csv("你的目录/Iris.csv",header=0)
# 显示前n行记录。默认n的值为5。
#data.head()
# 显示末尾的n行记录。默认n的值为5。
#data.tail()
# 随机抽取样本。默认抽取一条,我们可以通过参数进行指定抽取样本的数量。
# data.sample(10)
# 将类别文本映射成为数值类型
 
data["Species"] = data["Species"].map({"Iris-virginica": 0, "Iris-setosa": 1, "Iris-versicolor": 2})
# 删除不需要的Id列。
data.drop("Id", axis=1, inplace=True )
data.drop_duplicates(inplace=True)
## 查看各个类别的鸢尾花具有多少条记录。
data["Species"].value_counts()

分析:首先读取数据集,如下图

python实现KNN分类算法

最后一列为数据集的分类名称,但是在程序中,我们更倾向于使用如0、1、2数字来表示分类,所以对数据集进行处理,处理后的数据集如下:

python实现KNN分类算法

然后采用留出法对数据集进行拆分,一部分用作训练,一部分用作测试,如下图:

#构建训练集与测试集,用于对模型进行训练与测试。
# 提取出每个类比的鸢尾花数据
t0 = data[data["Species"] == 0]
t1 = data[data["Species"] == 1]
t2 = data[data["Species"] == 2]
# 对每个类别数据进行洗牌 random_state 每次以相同的方式洗牌 保证训练集与测试集数据取样方式相同
t0 = t0.sample(len(t0), random_state=0)
t1 = t1.sample(len(t1), random_state=0)
t2 = t2.sample(len(t2), random_state=0)
# 构建训练集与测试集。
train_X = pd.concat([t0.iloc[:40, :-1], t1.iloc[:40, :-1], t2.iloc[:40, :-1]] , axis=0)#截取前40行,除最后列外的列,因为最后一列是y
train_y = pd.concat([t0.iloc[:40, -1], t1.iloc[:40, -1], t2.iloc[:40, -1]], axis=0)
test_X = pd.concat([t0.iloc[40:, :-1], t1.iloc[40:, :-1], t2.iloc[40:, :-1]], axis=0)
test_y = pd.concat([t0.iloc[40:, -1], t1.iloc[40:, -1], t2.iloc[40:, -1]], axis=0)

实现KNN算法类:

#定义KNN类,用于分类,类中定义两个预测方法,分为考虑权重不考虑权重两种情况
class KNN:
 ''' 使用Python语言实现K近邻算法。(实现分类) '''
 def __init__(self, k):
  '''初始化方法 
   Parameters
   -----
   k:int 邻居的个数
  '''
  self.k = k
 
 def fit(self,X,y):
  '''训练方法
   Parameters
   ----
   X : 类数组类型,形状为:[样本数量, 特征数量]
   待训练的样本特征(属性)
  
  y : 类数组类型,形状为: [样本数量]
   每个样本的目标值(标签)。
  '''
  #将X转换成ndarray数组
  self.X = np.asarray(X)
  self.y = np.asarray(y)
  
 def predict(self,X):
  """根据参数传递的样本,对样本数据进行预测。
  
  Parameters
  -----
  X : 类数组类型,形状为:[样本数量, 特征数量]
   待训练的样本特征(属性) 
  
  Returns
  -----
  result : 数组类型
   预测的结果。
  """
  X = np.asarray(X)
  result = []
  # 对ndarray数组进行遍历,每次取数组中的一行。
  for x in X:
   # 对于测试集中的每一个样本,依次与训练集中的所有样本求距离。
   dis = np.sqrt(np.sum((x - self.X) ** 2, axis=1))
   ## 返回数组排序后,每个元素在原数组(排序之前的数组)中的索引。
   index = dis.argsort()
   # 进行截断,只取前k个元素。【取距离最近的k个元素的索引】
   index = index[:self.k]
   # 返回数组中每个元素出现的次数。元素必须是非负的整数。【使用weights考虑权重,权重为距离的倒数。】
   count = np.bincount(self.y[index], weights= 1 / dis[index])
   # 返回ndarray数组中,值最大的元素对应的索引。该索引就是我们判定的类别。
   # 最大元素索引,就是出现次数最多的元素。
   result.append(count.argmax())
  return np.asarray(result)
#创建KNN对象,进行训练与测试。
knn = KNN(k=3)
#进行训练
knn.fit(train_X,train_y)
#进行测试
result = knn.predict(test_X)
# display(result)
# display(test_y)
display(np.sum(result == test_y))
display(np.sum(result == test_y)/ len(result))

得出计算结果:

26
0.9629629629629629

得出该模型计算的结果中,有26条记录与测试集相等,准确率为96%

接下来绘制散点图:

#导入可视化所必须的库。
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"] = "SimHei"
mpl.rcParams["axes.unicode_minus"] = False
 
#绘制散点图。为了能够更方便的进行可视化,这里只选择了两个维度(分别是花萼长度与花瓣长度)。
# {"Iris-virginica": 0, "Iris-setosa": 1, "Iris-versicolor": 2})
# 设置画布的大小
plt.figure(figsize=(10, 10))
# 绘制训练集数据
plt.scatter(x=t0["SepalLengthCm"][:40], y=t0["PetalLengthCm"][:40], color="r", label="Iris-virginica")
plt.scatter(x=t1["SepalLengthCm"][:40], y=t1["PetalLengthCm"][:40], color="g", label="Iris-setosa")
plt.scatter(x=t2["SepalLengthCm"][:40], y=t2["PetalLengthCm"][:40], color="b", label="Iris-versicolor")
# 绘制测试集数据
right = test_X[result == test_y]
wrong = test_X[result != test_y]
plt.scatter(x=right["SepalLengthCm"], y=right["PetalLengthCm"], color="c", marker="x", label="right")
plt.scatter(x=wrong["SepalLengthCm"], y=wrong["PetalLengthCm"], color="m", marker=">", label="wrong")
plt.xlabel("花萼长度")
plt.ylabel("花瓣长度")
plt.title("KNN分类结果显示")
plt.legend(loc="best")
plt.show()

程序运行结果如下:

python实现KNN分类算法

四、思考与优化

①尝试去改变邻居的数量。

②在考虑权重的情况下,修改邻居的数量。

③对比查看结果上的差异。

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

Python 相关文章推荐
Python画图学习入门教程
Jul 01 Python
浅析Python中MySQLdb的事务处理功能
Sep 21 Python
Python连接PostgreSQL数据库的方法
Nov 28 Python
python实现多线程抓取知乎用户
Dec 12 Python
Python闭包之返回函数的函数用法示例
Jan 27 Python
pycharm安装和首次使用教程
Aug 27 Python
python3正则提取字符串里的中文实例
Jan 31 Python
基于python历史天气采集的分析
Feb 14 Python
python3.6+django2.0+mysql搭建网站过程详解
Jul 24 Python
基于Django框架的权限组件rbac实例讲解
Aug 31 Python
python下载的库包存放路径
Jul 27 Python
scrapy头部修改的方法详解
Dec 06 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
python 发送json数据操作实例分析
Oct 15 #Python
You might like
DOMXML函数笔记
2006/10/09 PHP
IP攻击升级,程序改进以对付新的攻击
2010/11/23 PHP
解析获取优酷视频真实下载地址的PHP源代码
2013/06/26 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
Google Suggest ;-) 基于js的动态下拉菜单
2006/10/11 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
jQuery中:reset选择器用法实例
2015/01/04 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
2015/03/09 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的方法
2016/11/29 Javascript
jquery中绑定事件的异同
2017/02/28 Javascript
JavaScript实现的冒泡排序法及统计相邻数交换次数示例
2017/04/26 Javascript
解决使用vue.js路由后失效的问题
2018/03/17 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
vue.js指令v-for使用以及下标索引的获取
2019/01/31 Javascript
layui上传图片到服务器的非项目目录下的方法
2019/09/26 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
2019/09/27 Javascript
vuex分模块后,实现获取state的值
2020/07/26 Javascript
vue中watch和computed的区别与使用方法
2020/08/23 Javascript
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
使用python实现BLAST
2018/02/12 Python
python在文本开头插入一行的实例
2018/05/02 Python
解决PyCharm import torch包失败的问题
2018/10/13 Python
Python父目录、子目录的相互调用方法
2019/02/16 Python
python sort、sort_index方法代码实例
2019/03/28 Python
python绘图模块matplotlib示例详解
2019/07/26 Python
详解python 破解网站反爬虫的两种简单方法
2020/02/09 Python
python实现图书馆抢座(自动预约)功能的示例代码
2020/09/29 Python
.NET初级开发工程师面试题(包括Javascript)
2012/08/22 面试题
安全生产管理合理化建议书
2014/03/12 职场文书
班干部竞选演讲稿
2014/04/24 职场文书
自查自纠工作总结
2014/10/15 职场文书
2019年公司快递收发管理制度模板
2019/11/20 职场文书
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
Python常遇到的错误和异常
2021/11/02 Python