原生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中str is not callable问题详解及解决办法
Feb 10 Python
python中模块的__all__属性详解
Oct 26 Python
python2.7实现FTP文件下载功能
Apr 15 Python
django 解决自定义序列化返回处理数据为null的问题
May 20 Python
keras的三种模型实现与区别说明
Jul 03 Python
Python3爬虫关于识别检验滑动验证码的实例
Jul 30 Python
Python连接mysql方法及常用参数
Sep 01 Python
详解python命令提示符窗口下如何运行python脚本
Sep 11 Python
深入浅析pycharm中 Make available to all projects的含义
Sep 15 Python
Python根据字典的值查询出对应的键的方法
Sep 30 Python
Python3 用matplotlib绘制sigmoid函数的案例
Dec 11 Python
Python带你从浅入深探究Tuple(基础篇)
May 15 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
在字符串中把网址改成超级链接
2006/10/09 PHP
php 小乘法表实现代码
2009/07/16 PHP
php日历制作代码分享
2014/01/20 PHP
PHP连接数据库实现注册页面的增删改查操作
2016/03/27 PHP
PHP内存缓存功能memcached示例
2016/10/19 PHP
PHP xpath()函数讲解
2019/02/11 PHP
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
基于jQuery的弹出框插件
2012/03/18 Javascript
网页右下角弹出窗体实现代码
2014/06/05 Javascript
setTimeout()递归调用不加引号出错的解决方法
2014/09/05 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
浅谈JS使用[ ]来访问对象属性
2016/09/21 Javascript
有趣的bootstrap走动进度条
2016/12/01 Javascript
Angular搜索 过滤 批量删除 添加 表单验证功能集锦(实例代码)
2017/10/25 Javascript
如何封装了一个vue移动端下拉加载下一页数据的组件
2019/01/06 Javascript
9102了,你还不会移动端真机调试吗
2019/03/25 Javascript
node.js文件操作系统实例详解
2019/11/05 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
2020/09/11 Javascript
通过python下载FTP上的文件夹的实现代码
2013/02/10 Python
Python学习笔记之常用函数及说明
2014/05/23 Python
常见的在Python中实现单例模式的三种方法
2015/04/08 Python
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
2018/05/16 Python
Python基础学习之基本数据结构详解【数字、字符串、列表、元组、集合、字典】
2019/06/18 Python
python使用minimax算法实现五子棋
2019/07/29 Python
python做接口测试的必要性
2019/11/20 Python
Python unittest基本使用方法代码实例
2020/06/29 Python
如何用css3实现switch组件开关的方法
2018/02/09 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
高三英语教学反思
2014/01/13 职场文书
项目施工员岗位职责
2014/03/09 职场文书
音乐节策划方案
2014/06/09 职场文书
2014年网络管理员工作总结
2014/12/01 职场文书
2015年个人剖析材料范文
2014/12/29 职场文书
2015年乡镇统计工作总结
2015/04/22 职场文书
大学生青年志愿者活动总结
2015/05/06 职场文书
CSS浮动引起的高度塌陷问题
2022/08/05 HTML / CSS