机器学习作业二之KNN算法

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

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

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

——百度百科

一、算法思想:

已经有的样本,均有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值。

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

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

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

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

相关文章

Arduino IDE工程代码多文件编程和中文设置

一、esp8266模块信息 二、中英文切换 点击文件( File )–选择首选项( Preference )—选择语言( Language )—选择中文–点击确定( OK ) 三、多文件编程 在Arduino编程中,将代码分割成多个文件是一种很好的做法,特别是项目变得越来越大和复杂时。这样…

【微服务】Eureka(服务注册,服务发现)

文章目录 1.基本介绍1.学前说明2.当前架构分析1.示意图2.问题分析 3.引出Eureka1.项目架构分析2.上图解读 2.创建单机版的Eureka1.创建 e-commerce-eureka-server-9001 子模块2.检查父子pom.xml1.子 pom.xml2.父 pom.xml 3.pom.xml 引入依赖4.application.yml 配置eureka服务5.…

【牛客】SQL142 对试卷得分做min-max归一化

描述 现有试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间): idexam_idtagdifficultydurationrelease_time19001SQLhard602020-01-01 10:00:0029002Chard802020-01-0…

huawei 华为 交换机 配置 LACP 模式的链路聚合示例 (交换机之间直连)

组网需求 如 图 3-22 所示, SwitchA 和 SwitchB 通过以太链路分别都连接 VLAN10 和 VLAN20 的网络,且SwitchA 和 SwitchB 之间有较大的数据流量。用户希望 SwitchA 和 SwitchB 之间能够提供较大的链路带宽来使相同VLAN 间互相通信。在两台 Switch 设备上…

【SpringBoot】实现一个简单的图片上传

前端上传表单 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form enctype"multipart/form-data" method"post" action&q…

纯前端调用本机原生Office实现Web在线编辑Word/Excel/PPT,支持私有化部署

在日常协同办公过程中&#xff0c;一份文件可能需要多次重复修改才能确定&#xff0c;如果你发送给多个人修改后再汇总&#xff0c;这样既效率低又容易出错&#xff0c;这就用到网页版协同办公软件了&#xff0c;不仅方便文件流转还保证不会出错。 但是目前一些在线协同Office…

【考研数学】张宇最新全年学习包

考研数学冲高分必备&#xff0c;张宇老师肯定榜上有名&#xff01; 考研数学&#xff0c;其实就像一场没有硝烟的战斗。基础题是常规武器&#xff0c;中难题就是重型火炮&#xff0c;而压轴题呢&#xff0c;那就是核弹级别的存在&#xff01;考研的战场&#xff0c;关键就在那…

Vulnhub:DR4G0N B4LL: 1

目录 信息收集 1、arp 2、nmap WEB web信息收集 gobuster 隐藏目录发现 图片隐写 ssh登录 提权 get user 系统信息收集 get root 信息收集 1、arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l …

iOS - Runtime-isa详解(位域、union(共用体)、位运算)

文章目录 iOS - Runtime-isa详解&#xff08;位域、union&#xff08;共用体&#xff09;、位运算&#xff09;前言1. 位域介绍1.1 思路1.2 示例 - 结构体1.3 示例 - union&#xff08;共用体&#xff09;1.3.1 说明 1.4 结构体 对比 union&#xff08;共用体&#xff09; 2. a…

Github多账号共存

在开发阶段&#xff0c;如果同时拥有多个开源代码托管平台的账户&#xff0c;在代码的管理上非常麻烦。那么&#xff0c;如果同一台机器上需要配置多个账户&#xff0c;怎样才能确保不冲突&#xff0c;不同账户独立下载独立提交呢&#xff1f; 我们以两个github账号进行演示 …

LiteFlow简单使用

LiteFlow是什么 LiteFlow是一个非常强大的现代化的规则引擎框架&#xff0c;融合了编排特性和规则引擎的所有特性&#xff0c;具体介绍查看官网 官网&#xff1a;https://liteflow.cc/ github: https://github.com/dromara/liteflow gitee: https://gitee.com/dromara/lite…

网络七层模型:理解网络通信的架构(〇)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

生物信息—数据库

文章目录 核酸数据库1 一级核酸数据库&#xff1a;GenBank1.1 原核生物核酸序列1.2 真核生物成熟mRNA1.3 真核生物DNA序列 2 一级核酸数据库&#xff1a;基因组数据库&#xff1a;Ensemble3 一级核酸数据库&#xff1a;微生物宏基因组数据库&#xff1a;JCVI4 二级核酸数据库 蛋…

数据可视化基础与应用-04-seaborn库从入门到精通01-02

总结 本系列是数据可视化基础与应用的第04篇seaborn&#xff0c;是seaborn从入门到精通系列第1-2篇。本系列的目的是可以完整的完成seaborn从入门到精通。主要介绍基于seaborn实现数据可视化。 参考 参考:数据可视化-seaborn seaborn从入门到精通01-seaborn介绍与load_datas…

【AI科学小品文】AI之梦:未来探索之旅

引子&#xff1a;AI初识 在未来的某个城市&#xff0c;高耸的摩天大楼间&#xff0c;闪烁着无数LED屏幕的广告牌&#xff0c;在黄昏的余晖中显得格外耀眼。无人驾驶的磁悬浮车辆穿梭在街道上&#xff0c;几乎听不到任何声音。智能机器人在街头忙碌着&#xff0c;为行人提供着各…

数据挖掘终篇!一文学习模型融合!从加权融合到stacking, boosting

模型融合&#xff1a;通过融合多个不同的模型&#xff0c;可能提升机器学习的性能。这一方法在各种机器学习比赛中广泛应用&#xff0c; 也是在比赛的攻坚时刻冲刺Top的关键。而融合模型往往又可以从模型结果&#xff0c;模型自身&#xff0c;样本集等不同的角度进行融合。 数据…

Unity 视频组件 VideoPlayer

组件添加&#xff1a; 在自己定义的组件下&#xff08;例如&#xff1a;Panel&#xff09; 点击 Inspector 面板中的 AddComponent &#xff0c;输入“VideoPlayer”。 资源 这里 视频资源有两种形式&#xff0c;第一种是 VideoClip &#xff0c;需要将视频文件拖拽到该属性字段…

【Linux中vim系列】如何在vim中检索字符串

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

重构销售话术和知识库,容联云找到了大模型的“钉子”

科技云报道原创。 从ChatGPT诞生起&#xff0c;大模型在营销、客服等场景的落地就被予以众望。然而在经历了一年多的“百模大战”洗礼之后&#xff0c;人们发现无论是算力成本还是内容生成的安全合规问题&#xff0c;都让大模型很难直接应用于机器与人对话的实际业务中。 这其…

Java后端项目性能优化实战-群发通知

背景 公司群发通知模块性能存在问题&#xff0c;我进行全面的系统调优&#xff0c;系统处理能力大幅提升。 原发送流程 优化后的发送流程 优化的点 说明&#xff1a;以下问题基本都是压测过程遇到的&#xff0c;有些问题普通的功能测试暴露不了。优化目标&#xff1a;保证高…