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 排列组合之itertools
Mar 20 Python
python简单实现基数排序算法
May 16 Python
使用python实现接口的方法
Jul 07 Python
Python数据结构之栈、队列的实现代码分享
Dec 04 Python
TensorFlow入门使用 tf.train.Saver()保存模型
Apr 24 Python
Python3.4 tkinter,PIL图片转换
Jun 21 Python
Python字典中的键映射多个值的方法(列表或者集合)
Oct 17 Python
python实现将汉字保存成文本的方法
Nov 16 Python
Django JWT Token RestfulAPI用户认证详解
Jan 23 Python
对Python 检查文件名是否规范的实例详解
Jun 10 Python
Cython编译python为so 代码加密示例
Dec 23 Python
Python 操作pdf pdfplumber读取PDF写入Exce
Aug 14 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如何得到当前页和上一页的地址?
2006/11/27 PHP
测试您的 PHP 水平的题目
2007/05/30 PHP
PHP编码规范之注释和文件结构说明
2010/07/09 PHP
将PHP从5.3.28升级到5.3.29时Nginx出现502错误
2015/05/09 PHP
PHP实现判断数组是一维、二维或几维的方法
2017/02/06 PHP
JavaScript获取GridView中用户点击控件的行号,列号
2009/04/14 Javascript
比Jquery的document.ready更快的方法
2010/04/28 Javascript
jQuery ajax cache缓存问题
2010/07/01 Javascript
JS+ACTIVEX实现网页选择本地目录路径对话框
2013/03/18 Javascript
node.js中的fs.rmdirSync方法使用说明
2014/12/16 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
js实现复选框的全选和取消全选效果
2017/01/03 Javascript
canvas实现探照灯效果
2017/02/07 Javascript
基于zepto.js实现手机相册功能
2017/07/11 Javascript
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
跟老齐学Python之用Python计算
2014/09/12 Python
用python做游戏的细节详解
2019/06/25 Python
python通过TimedRotatingFileHandler按时间切割日志
2019/07/17 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
Django REST Swagger实现指定api参数
2020/07/07 Python
python实现最短路径的实例方法
2020/07/19 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
罗马尼亚购物网站:Vivantis.ro
2019/07/20 全球购物
工地门卫岗位职责
2013/12/30 职场文书
上课迟到检讨书
2014/01/19 职场文书
工程专业求职自荐书范文
2014/02/08 职场文书
工程质量承诺书
2014/03/27 职场文书
大学生党员承诺书
2014/05/20 职场文书
装饰施工员岗位职责
2015/04/11 职场文书
2015年医院护理部工作总结
2015/04/23 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书