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爬虫教程之爬取百度贴吧并下载的示例
Mar 07 Python
python删除指定类型(或非指定)的文件实例详解
Jul 06 Python
Python中文竖排显示的方法
Jul 28 Python
python3+PyQt5实现使用剪贴板做复制与粘帖示例
Jan 24 Python
浅谈python socket函数中,send与sendall的区别与使用方法
May 09 Python
python得到一个excel的全部sheet标签值方法
Dec 10 Python
python实现处理mysql结果输出方式
Apr 09 Python
Pyecharts地图显示不完成问题解决方案
May 11 Python
Python日志处理模块logging用法解析
May 19 Python
Django多个app urls配置代码实例
Nov 26 Python
python解压zip包中文乱码解决方法
Nov 27 Python
python数字转对应中文的方法总结
Aug 02 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
php中修改浏览器的User-Agent来伪装你的浏览器和操作系统
2011/07/29 PHP
php上传图片之时间戳命名(保存路径)
2014/08/15 PHP
php利用cookies实现购物车的方法
2014/12/10 PHP
PHP对XML内容进行修改和删除实例代码
2016/10/26 PHP
PHP读取XML格式文件的方法总结
2017/02/27 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
2019/12/12 PHP
JavaScript 对象的属性和方法4种不同的类型
2010/03/19 Javascript
javascript学习笔记(九) js对象 设计模式
2012/06/19 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
js计算精度问题小结
2013/04/22 Javascript
浅析document.createDocumentFragment()与js效率
2013/07/08 Javascript
Javascript 函数parseInt()转换时出现bug问题
2014/05/20 Javascript
JavaScript中for循环的使用详解
2015/06/03 Javascript
jQuery通用的全局遍历方法$.each()用法实例
2016/07/04 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
js实现百度搜索提示框
2017/02/05 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
nodejs读取并去重excel文件
2018/04/22 NodeJs
前后端如何实现登录token拦截校验详解
2018/09/03 Javascript
解决vue-cli输入命令vue ui没效果的问题
2020/11/17 Javascript
Python获取脚本所在目录的正确方法
2014/04/15 Python
Python的requests网络编程包使用教程
2016/07/11 Python
Python 操作文件的基本方法总结
2017/08/10 Python
python爬虫之urllib库常用方法用法总结大全
2018/11/14 Python
Python功能点实现:函数级/代码块级计时器
2019/01/02 Python
python中嵌套函数的实操步骤
2019/02/27 Python
利用Node实现HTML5离线存储的方法
2020/10/16 HTML / CSS
美国知名的摄影器材销售网站:Adorama
2017/02/01 全球购物
印刷工程专业应届生求职信
2013/09/29 职场文书
大学生职业生涯规划书范文
2014/01/14 职场文书
公司领导九九重阳节发言稿2014
2014/09/25 职场文书
工作保证书怎么写
2015/02/28 职场文书
Vertica集成Apache Hudi重磅使用指南
2022/03/31 Servers
Spring Boot 底层原理基础深度解析
2022/04/03 Java/Android