机器学习作业二之KNN算法

KNN(K- Nearest Neighbor)法即K最邻近法,最初由 Cover和Hart于1968年提出,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路非常简单直观:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别 。

该方法的不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最邻近点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。另外还有一种 Reverse KNN法,它能降低KNN算法的计算复杂度,提高分类的效率 。

KNN算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分 。

——百度百科

一、算法思想:

(算法名字中含有Nearest Neighbor,最近的邻居,可以想想一下一个人刚到一片陌生的地方,想要熟悉这个地方的一种方法就是找几个最近的邻居来了解这块地方。)

个人概括的正式一点的解释:

已经有的样本,均有n个特征值,可以用n个坐标轴表示出这个样本点的位置。

而测试集中的元素,也均有n个特征值,也可以用n个坐标轴表示出这个样本点的位置。

对于每个测试集中的元素,找到距离其最近的k个点(距离可使用欧氏距离d(x, y) = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2}),在这k个点中选出数量最多的一个种类,将这个种类作为其结果。

需要注意的是,由于每个坐标的相对大小不同, 需要将数值做归一化处理。


二、代码

思想不难,代码:

(代码下方有各个函数的解释)

import csv
import math
import operatorfrom matplotlib import pyplot as pltdef guiyihua(train, input):maxval1 = 0minval1 = 101maxval2 = 0minval2 = 101for i in range( len(train) ):train[i][0] = float(train[i][0])train[i][1] = float(train[i][1])maxval1 = max(maxval1, train[i][0])minval1 = min(minval1, train[i][0])maxval2 = max(maxval2, train[i][1])minval2 = min(minval2, train[i][1])for i in range( len(input) ):input[i][0] = float(input[i][0])input[i][1] = float(input[i][1])maxval1 = max(maxval1, input[i][0])minval1 = min(minval1, input[i][0])maxval2 = max(maxval2, input[i][1])minval2 = min(minval2, input[i][1])for i in range( len(train)):train[i][0] = (train[i][0]-minval1)/(maxval1-minval1)train[i][1] = (train[i][1]-minval2)/(maxval2-minval2)for i in range( len(input) ):input[i][0] = (input[i][0]-minval1)/(maxval1-minval1)input[i][1] = (input[i][1]-minval2)/(maxval2-minval2)def load(fname):with open(fname, 'rt') as csvfile:lists = csv.reader(csvfile)data = list(lists)return datadef euclideanDistance(atrain, ainput, needcal):re2 = 0for i in range(needcal):re2 += (atrain[i] - ainput[i])**2return math.sqrt(re2)def jg(train, ainput, k):alldis = []needcal = len(ainput)-1 #需要计算的维度for i in range(len(train)):nowdis = euclideanDistance(train[i], ainput, needcal)alldis.append((train[i], nowdis))alldis.sort(key=operator.itemgetter(1))vote = {}for i in range(k):type = alldis[i][0][-1]if type in vote:vote[type] += 1else:vote[type] = 1sortvote = sorted(vote.items(), key=operator.itemgetter(1), reverse=True)#items()将字典转为列表,这样可以对第二个值进行排序return sortvote[0][0]def showright(train, input):plt.subplot(2, 5, 1)plt.title("right")for i in range(len(train)):if train[i][-1] == "第一种" :  plt.scatter(train[i][0], train[i][1], c = '#0066FF', s = 10, label = "第一种")else :plt.scatter(train[i][0], train[i][1], c = '#CC0000', s = 10, label = "第二种")for i in range(len(input)):if input[i][-1] == "第一种" :plt.scatter(input[i][0], input[i][1], c = '#0066FF', s = 50, label = "cs第一种")#plt.scatter(input[i][0], input[i][1], c = '#FF3333', s = 30, label = "cs第一种")else :plt.scatter(input[i][0], input[i][1], c = '#CC0000', s = 50, label = "cs第一种")#plt.scatter(input[i][0], input[i][1], c = '#FF33FF', s = 30, label = "cs第二种")def showtest(train, input, re, ki, cnt):plt.subplot(2, 5, ki+1)plt.title("k = "+ repr(ki)+" acc: "+repr(1.0*cnt/(1.0*len(input))*100 )+ '%')for i in range(len(train)):if train[i][-1] == "第一种" :plt.scatter(train[i][0], train[i][1], c = '#0066FF', s = 10, label = "第一种")else :plt.scatter(train[i][0], train[i][1], c = '#CC0000', s = 10, label = "第二种")for i in range(len(input)):if re[i] == "第一种" :plt.scatter(input[i][0], input[i][1], c = '#0066FF', s = 50, label = "cs第一种")#plt.scatter(input[i][0], input[i][1], c = '#00FF33', s = 30, label = "cs第一种")else :plt.scatter(input[i][0], input[i][1], c = '#CC0000', s = 50, label = "cs第二种")#plt.scatter(input[i][0], input[i][1], c = '#00FFFF', s = 30, label = "cs第二种")
def main():train = load("C:\\Users\\T.HLQ12\\Desktop\\wdnmd\\python\\jiqixuexi\\train.csv")input = load("C:\\Users\\T.HLQ12\\Desktop\\wdnmd\\python\\jiqixuexi\\test.csv")guiyihua(train, input)# print(train)# print(input)showright(train, input)for ki in range (1, 10):re = []k = kicnt = 0for i in range(len(input)):type = jg(train, input[i], k)if(type == input[i][-1]):cnt += 1re.append(type)print("预测:" + type + ",实际上: " + input[i][-1])print("准确率: " + repr(1.0*cnt/(1.0*len(input))*100) + '%')showtest(train, input, re, ki, cnt)plt.show()
main()

逐个解释一下:

guiyihua:

不会归一化的英文,就写拼音了,从训练集和测试集中找出一个最大值和最小值。然后把训练集和测试集的数据都减去最小值,再除以最大值减最小值即可。

load:

使用with open可以不用人为关闭文件。其中csv.reader会返回一个迭代器,配合list将data赋值为二维数组。

euclideanDistance:

欧式距离,就是把所有维度平方下相加,然后再返回开根号的值。

jg:

这个是judge的缩写,判断输入的测试集中的一个元素的种类。函数的参数有训练集,一个输入的值和一个k。遍历训练集中的所有元素,算出距离测试点的欧式距离,然后添加到alldis数组里。最后对数组进行排序(参数中意味按照元组中第一个值排序,默认从大到小)。然后创建一个vote字典。这个字点的第一个值是种类,第二个值是种类的个数。循环遍历距离数组,每次碰到一个种类,就把这个种类的数量加一。循环结束后,对这个字典的第二个值进行排序(排序中参数:第一个item:将字典vote转换为一个包含键值对的列表, 第二个:对下标1进行排序,第三个:从大到小排序),选出最大数量的种类作为这个测试元素的结果。

shoright 与showtest:

这两个函数是用于绘制散点图的。Subplot中第一个参数是行数,第二个参数是列数。第三个参数是第几个部分。Title中可以设置这张图的标题。训练集中每个种类的颜色都不一样,点是使用scatter打上去的,其中第一个参数是这个点在第一条坐标轴上对应的值。第二个点是第二个坐标轴上对应的值,c是颜色。S是点的大小。 label是这个点的标签。循环遍历训练集和测试的每个点,就可以绘制出一张散点图。

三、实际问题

一、

如图所示,这个报错是因为vote中不存在vote括号中的值,修改为:

即可。

二、

这个问题不知道发生的原因是什么,查询资料本来以为是scatter可以使用切分,但是实际上没有办法使用,最后就替换成了循环遍历每个点来绘制散点图的方式。

四、实验结论

结果:(第一张图为对的。对于每张图,大的是测试集,小的是训练集,颜色相同的是一个种类)

数据:

从结果分析上来看,K在1~9范围内,不能很好的确定最优值,需要多次取值,反复确认才能锁定k值。

尽管KNN算法有着计算量大,维度灾难等缺点,但是可以不用训练,容易理解,对于新手来说很友好。

(纯手打,求老师轻点批改)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/778924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字化运维实战手册:构建高效运维体系的方法与实践

一本书掌握数字化运维方法,构建数字化运维体系 数字化转型已经成为大势所趋,各行各业正朝着数字化方向转型,利用数字化转型方法论和前沿科学技术实现降本、提质、增效,从而提升竞争力。 数字化转型是一项长期工作,包含…

Mybatis中QueryWrapper的复杂查询SQL

最近在使用QueryWrapper编写查询语句时发现复杂的SQL不会写。在网上找了半天,终于得到了点启示。在此做个记录以备忘。 我要实现的SQL是这样的: -- 实现这个复杂查询 -- 查询设备表 select * from oa_device where ((dev_code BSD1003 and dev_status…

[flume$1]记录一个启动flume配置的错误

先总结:Flume配置文件后面,不能跟注释 报错代码: [ERROR - org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:158)] Unable to deliver event. Exception follows. org.apache.flume.EventDeliveryException: Failed to open…

Termius for Mac/Win:多协议远程管理利器,你的工作效率提升神器

在数字化飞速发展的今天,远程管理已成为企业运营和个人工作不可或缺的一部分。而Termius,作为一款多协议远程管理软件,正以其卓越的性能和便捷的操作,成为广大用户的心头好。 Termius支持多种协议,无论是SSH、RDP还是…

查询优化-提升子查询-UNION类型

瀚高数据库 目录 文档用途 详细信息 文档用途 剖析UNION类型子查询提升的条件和过程 详细信息 注:图片较大,可在浏览器新标签页打开。 SQL: SELECT * FROM score sc, LATERAL(SELECT * FROM student WHERE sno 1 UNION ALL SELECT * FROM student…

企业微信知识库:从了解到搭建的全流程

你是否也有这样的疑惑:为什么现在的企业都爱创建企业微信知识库?企业微信知识库到底有什么用?如果想要使用企业微信知识库企业应该如何创建?这就是我今天要探讨的问题,感兴趣的话一起往下看吧! | 为什么企业…

网站业务对接DDoS高防

准备需要接入的网站域名清单,包含网站的源站服务器IP(仅支持公网IP的防护)、端口信息等。所接入的网站域名必须已完成ICP备案。如果您的网站支持HTTPS协议访问,您需要准备相应的证书和私钥信息,一般包含格式为.crt的公…

游戏赛道新机会:善用数据分析,把握游戏赛道广告变现良机 | TOPON变现干货

12月10日,由罗斯基联合TopOn、钛动科技共同主办的《游戏赛道新机会》主题系列沙龙在武汉举办。活动邀请了国内外多家业内知名公司的负责人到场分享,现场嘉宾分别从自己擅长的领域出发,通过数据分析,案例复盘等多个维度方向进行讲解…

C++超市商品管理系统

一、简要介绍 1.本项目为面向对象程序设计的大作业,基于Qt creator进行开发,Qt框架版本6.4.1,编译环境MINGW 11.2.0。 2.项目结构简介:关于系统逻辑部分的代码的头文件在head文件夹中,源文件在s文件夹中。与图形界面…

基于Java仓库管理系统设计与实现(源码+部署文档+论文)

博主介绍: ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精彩专栏 推荐订阅 👇🏻 不然下次找不到 Java项目精品实…

剑指Offer题目笔记20(在数组范围内二分查找)

面试题72: 问题: ​ 输入一个非负整数,计算它的平方根。 解决方案: 使用二分查找。一个数x的平方根一定小于或等于x,同时,除了0之外的所有非负整数的平方根都大于等于1,故该数的平方根在1到x…

数据库中的约束纯干货——主键约束

目录 (一)特点: (二)添加主键约束 2.1格式: 2.2举例: 2.3建立表级约束: 2.4建立表后增加主键约束 (三)复合主键 3.1格式: 3.2举例&#…

每日一题 --- 快乐数[力扣][Go]

快乐数 题目:202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到…

Pocket 2荧光拍摄的几个有趣玩法

荧光是现象,当某种常温物质经某种波长的入射光(通常是或)照射,吸收光能后进入,并且立即退激发并发出出射光(通常波长比入射光的波长,原先看不见的短波长紫外线,变成在可见光波段的可…

JAVA的NIO和BIO底层原理分析

文章目录 一、操作系统底层IO原理1. 简介2. 操作系统进行IO的流程 二、BIO底层原理1. 什么是Socket2. JDK原生编程的BIO 三、Java原生编程的NIO1. 简介2. NIO和BIO的主要区别3. Reactor模式4. NIO的三大核心组件5. NIO核心源码分析 一、操作系统底层IO原理 1. 简介 IO&#x…

font-spider压缩文字

FZLanTingHei-DB-GBK是我引入的字体包名字 1.安装依赖 建议全局安装但是要注意npm配置 我配成了_globel 真是沙雕 npm install font-spider -g2. 在static文件夹新增一个文件夹font-spider 同时在font-spider文件夹里面新增index.css和index.html index.css font-face {f…

产品推荐 | 基于华为海思ARM+Xilinx FPGA双核的8路SDI高清视频图像处理平台

一、板卡概述 PCIE703 是我司自主研制的一款基于 PCIE 总线架构的高性能综 合视频图像处理平台,该平台采用 Xilinx 的高性能 Kintex UltraScale 系列 FPGA 加上华为海思的高性能视频处理器来实现。 华为海思的 HI3531DV200 是一款集成了 ARM A53 四核处理 器性能强…

Java设计模式—备忘录模式(快照模式)

定义 备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原,很多软件都提供了撤销(Undo)操作&#…

什么是DevOps?如何使用DevOps?

无论您是在维持公司基础设施的正常运行,还是在为客户的IT问题管理提供支持,抑或是在构建、测试或修复软件,还是在保护同事免受安全威胁,您都可能接触过 DevOps。 毕竟,这个术语已经出现了 15 年,其采用率也…

基于单片机的二维码LCD显示控制设计

**单片机设计介绍,基于单片机的二维码LCD显示控制设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的二维码LCD显示控制设计是一个集硬件、软件与通信于一体的综合性项目。此设计的主要目标是实现单片机…