原生python实现knn分类算法


Posted in Python onOctober 24, 2019

一、题目要求

用原生Python实现knn分类算法。

二、题目分析

数据来源:鸢尾花数据集(见附录Iris.txt)

数据集包含150个数据集,分为3类,分别是:Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾)和Iris Virginica(维吉尼亚鸢尾)。每类有50个数据,每个数据包含四个属性,分别是:Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)和Petal.Width(花瓣宽度)。

将得到的数据集按照7:3的比例划分,其中7为训练集,3为测试集。编写算法实现:学习训练集的数据特征来预测测试集鸢尾花的种类,并且计算出预测的准确性。

KNN是通过测量不同特征值之间的距离进行分类。它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其中K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

三、算法设计

1)将文本文件按行分割,写入列表datas中

def data_read(filepath): # 读取txt文件,将读出的内容存入datas列表中
  fp = open(filepath, "r")
  datas = [] # 存储处理后的数据
  lines = fp.readlines() # 读取整个文件数据
  for line in lines:
    row = line.strip('\n').split(',') # 去除两头的换行符,按空格分割
    datas.append(row)
  fp.close()
  return datas

2)划分数据集与测试集,将数据集的数据存入labeldata_list列表,标签存入label_list列表,测试集数据存入text_list列表,标签存入textlabel_list列表。

3)对得到的两个数据集的数据和标签列表进行处理。将labeldata_list列表数据转换为元组labeldata_tuple,构造形入{labeldata_tuple: label_list}的字典mydict。这样不仅可以去掉重复数据,而且可唯一的标识各个数据所对应的鸢尾花种类。

for i in range(0, 105): # 数据集按照3:7的比例划分,其中105行为训练集,45行为测试集
  labeldata_list.append([datas[i][0], datas[i][1], datas[i][2], datas[i][3]])
  label_list.append(datas[i][4])

for i in range(105, 150): # 测试集的数据
  text_list.append([datas[i][0], datas[i][1], datas[i][2], datas[i][3]])
  textlabel_list.append(datas[i][4])

j = 0
for i in labeldata_list:
  labeldata_tuple = tuple(i)
  mydict.update({labeldata_tuple: label_list[j]})
  j = j + 1

4)计算测试集数据与各个训练集数据之间的距离,得到distance_list列表,外层循环进行一次,都会有一个该测试数据所对应的与训练数据最短距离。标记出该距离对应的训练集,在一个近邻的条件下,这个训练集的种类,就是该测试集的种类。
在计算距离时,使用绝对距离来计算。将每个训练集对应数据的属性值相减后求和add,得到一个测试数据与每个样本的距离,add的最小值就是距离最小值。

for i in range(len(text_list)):
  count += 1
  for j in range(len(train_list)):
    add1 = abs(float(train_list[j][0]) - float(text_list[i][0])) + abs(float(train_list[j][1])
                                      - float(text_list[i][1])) + abs(
      float(train_list[j][2]) - float(text_list[i][2])) + abs(float(train_list[j][3])
                                  - float(text_list[i][3]))
    distance_list.append(add1)
    if add > add1:
      add = add1
      index = train_list[j]
  print("预测", text_list[i], "的标签是:", mydict.get(index))

5)判断预测结果的准确性:将预测的测试数据种类与原始数据对比,若相同,则分子加一。

right = 0 # 分子
count = 0 # 分母
for i in range(len(text_list)):
  count += 1
  for j in range(len(train_list)):
    add1 = abs(float(train_list[j][0]) - float(text_list[i][0])) + abs(float(train_list[j][1])
                                      - float(text_list[i][1])) + abs(
      float(train_list[j][2]) - float(text_list[i][2])) + abs(float(train_list[j][3])
                                  - float(text_list[i][3]))
    distance_list.append(add1)
    if add > add1:
      add = add1
      index = train_list[j]
  print("预测", text_list[i], "的标签是:", mydict.get(index))
  if mydict.get(index) == textlabel_list[i]: # 当计算出来的1个近邻与测试集正确的标签相同时,分子加一
    right = right + 1
print('预测准确性:{:.2f}'.format(right / count))

6)举例,绘图

以测试集7.6,3.0,6.6,2.1,Iris-virginica为例:
首先运用anaconda绘制出数据集的散点图,其次,将需要测试的数据于数据集绘制在同一张图上,在一个近邻的前提下,距离测试数据最近的点的标签即为测试数据的的标签。如下图,黑色的测试点距离红点最近,所以,测试数据的标签就为virginica。

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import load_iris  #导入数据集iris
 
#载入数据集 
iris = load_iris() 
#获取花卉两列数据集 
DD = iris.data 
X = [x[0] for x in DD] 
Y = [x[1] for x in DD] 
#plt.scatter(7.6,3.0, color='black', marker='o')
plt.scatter(X[:50], Y[:50], color='red', marker='o', label='setosa') #前50个样本
plt.scatter(X[50:100], Y[50:100], color='blue', marker='x', label='versicolor') #中间50个
plt.scatter(X[100:], Y[100:],color='green', marker='+', label='Virginica') #后50个样本
plt.legend(loc=2) #左上角
plt.show()

算法数据流图:

原生python实现knn分类算法

计算各个测试数据与训练集间距离详细流程图:

原生python实现knn分类算法

五、测试

导入数据集

原生python实现knn分类算法

划分数据集

训练集:

原生python实现knn分类算法

测试集:

原生python实现knn分类算法

对得到的两个数据集的数据和标签列表进行处理

原生python实现knn分类算法

计算测试集数据与各个训练集数据之间的距离

原生python实现knn分类算法

判断预测结果的准确性

原生python实现knn分类算法

绘图举例

原生python实现knn分类算法

五、运行结果

1.对测试集所有数据进行预测,得到预测测试集的标签与预测准确性

原生python实现knn分类算法

绘出散点图:7.6,3.0,6.6,2.1,Iris-virginica作为测试集的举例

原生python实现knn分类算法

六、总结

学习了关于绘图的函数与库
发现在绘图方面anaconde比pycharm要方便的多

对向量之间的距离公式进行了复习
除了这次作业中使用到的绝对距离之外,还有:
a)欧氏距离
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离:
原生python实现knn分类算法
b)曼哈顿距离
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的曼哈顿距离
原生python实现knn分类算法
c)闵可夫斯基距离
两个n维变量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的闵可夫斯基距离定义为:
原生python实现knn分类算法

对文件的读操作进行使用

算法缺点:用了许多for循环,会降低效率,增加算法的时间复杂度;只是一个近邻的判断依据

七、源代码

def data_read(filepath): # 读取txt文件,将读出的内容存入datas列表中
  fp = open(filepath, "r")
  datas = [] # 存储处理后的数据
  lines = fp.readlines() # 读取整个文件数据
  for line in lines:
    row = line.strip('\n').split(',') # 去除两头的换行符,按空格分割
    datas.append(row)
  fp.close()
  return datas


datas = data_read("iris .txt")

labeldata_list = [] # 训练集的数据
label_list = [] # 训练集的标签
text_list = [] # 测试集数据
textlabel_list = [] # 测试集标签
labeldata_tuple = () # 转换列表为元组
mydict = {} # 以四维数据为键,以鸢尾花的特征为值。这样便可唯一标识

'''
划分数据集与测试集,将数据集的数据存入labeldata_list列表,标签存入label_list列表,
测试集数据存入text_list列表,标签存入textlabel_list列表。
'''
for i in range(0, 105): # 数据集按照3:7的比例划分,其中105行为训练集,45行为测试集
  labeldata_list.append([datas[i][0], datas[i][1], datas[i][2], datas[i][3]])
  label_list.append(datas[i][4])

for i in range(105, 150): # 测试集的数据
  text_list.append([datas[i][0], datas[i][1], datas[i][2], datas[i][3]])
  textlabel_list.append(datas[i][4])

j = 0
for i in labeldata_list:
  labeldata_tuple = tuple(i)
  mydict.update({labeldata_tuple: label_list[j]})
  j = j + 1


add = 100
index = 0
distance_list = []
train_list = []
for key, value in mydict.items():
  train_list.append(key)

right = 0 # 分子
count = 0 # 分母
'''
在计算距离时,使用绝对距离来计算。
将每个训练集对应数据的属性值相减后求和add,
得到一个测试数据与每个样本的距离,add的最小值就是距离最小值。
'''
for i in range(len(text_list)):
  count += 1
  for j in range(len(train_list)):
    add1 = abs(float(train_list[j][0]) - float(text_list[i][0])) + abs(float(train_list[j][1])
                                      - float(text_list[i][1])) + abs(
      float(train_list[j][2]) - float(text_list[i][2])) + abs(float(train_list[j][3])
                                  - float(text_list[i][3]))
    distance_list.append(add1)
    if add > add1:
      add = add1
      index = train_list[j]
  print("预测", text_list[i], "的标签是:", mydict.get(index))
  if mydict.get(index) == textlabel_list[i]: # 当计算出来的1个近邻与测试集正确的标签相同时,分子加一
    right = right + 1
print('预测准确性:{:.2f}'.format(right / count))

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

Python 相关文章推荐
python实现搜索本地文件信息写入文件的方法
Feb 22 Python
分享一下如何编写高效且优雅的 Python 代码
Sep 07 Python
python模仿网页版微信发送消息功能
Feb 24 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
Aug 02 Python
Python Pandas批量读取csv文件到dataframe的方法
Oct 08 Python
python reverse反转部分数组的实例
Dec 13 Python
tensorflow之自定义神经网络层实例
Feb 07 Python
python框架flask入门之路由及简单实现方法
Jun 07 Python
python 制作python包,封装成可用模块教程
Jul 13 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 Python
python re模块常见用法例举
Mar 01 Python
pytorch 两个GPU同时训练的解决方案
Jun 01 Python
python KNN算法实现鸢尾花数据集分类
Oct 24 #Python
python爬虫爬取幽默笑话网站
Oct 24 #Python
python栈的基本定义与使用方法示例【初始化、赋值、入栈、出栈等】
Oct 24 #Python
python 队列基本定义与使用方法【初始化、赋值、判断等】
Oct 24 #Python
python单向链表的基本实现与使用方法【定义、遍历、添加、删除、查找等】
Oct 24 #Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
Oct 24 #Python
python实现获取单向链表倒数第k个结点的值示例
Oct 24 #Python
You might like
PHP利用COM对象访问SQLServer、Access
2006/10/09 PHP
php利用iframe实现无刷新文件上传功能的代码
2011/09/29 PHP
smarty模板局部缓存方法使用示例
2014/06/17 PHP
PHP引用返回用法示例
2016/05/28 PHP
简单的代码实现jquery定时器
2013/11/17 Javascript
js中回调函数的学习笔记
2014/07/31 Javascript
JavaScript控制网页平滑滚动到指定元素位置的方法
2015/04/17 Javascript
jQuery.Callbacks()回调函数队列用法详解
2016/06/14 Javascript
微信开发 微信授权详解
2016/10/21 Javascript
echarts实现词云自定义形状的示例代码
2019/02/20 Javascript
vue router 传参获取不到的解决方式
2019/11/13 Javascript
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
CentOS 6.5下安装Python 3.5.2(与Python2并存)
2017/06/05 Python
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
python 读取视频,处理后,实时计算帧数fps的方法
2018/07/10 Python
将python图片转为二进制文本的实例
2019/01/24 Python
python读取Excel表格文件的方法
2019/09/02 Python
基于python3监控服务器状态进行邮件报警
2019/10/19 Python
Pytorch实现LSTM和GRU示例
2020/01/14 Python
Django nginx配置实现过程详解
2020/09/10 Python
HTML5 Notification(桌面提醒)功能使用实例
2014/03/17 HTML / CSS
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
Forever 21美国官网:美国标志性快时尚品牌
2017/02/20 全球购物
美国奢侈品购物平台:Orchard Mile
2018/05/02 全球购物
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
微软巴西官方网站:Microsoft Brasil
2019/09/26 全球购物
泰国最新活动和优惠:Megatix
2020/05/07 全球购物
报社实习生自荐信
2014/01/24 职场文书
护士岗位求职应聘自荐书范文
2014/02/12 职场文书
cf战队收人广告词
2014/03/14 职场文书
活动倡议书范文
2014/05/13 职场文书
组织鉴定材料
2014/06/02 职场文书
国家奖学金获奖感言
2014/08/16 职场文书
住房租房协议书
2014/08/20 职场文书
面试通知单大全
2015/04/20 职场文书
JavaScript执行机制详细介绍
2021/12/06 Javascript