机器学习笔记1(K-近邻算法)

人生苦短,我用Python

K-近邻算法:简单来说,K-近邻算法就是采用测量不同特征值之间的距离方法进行分类

  • 优点:精度高、对异常值不敏感、无数据输入假定
  • 缺点:计算复杂度高、空间复杂度高
  • 适用范围:数值型、标称型

工作原理:

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似的数据(最近邻)的分类标签。一般来说,我们只选择样本集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。最后,选择K个最相似数据中出现次数最多的分类,作为新数据的分类。

K-近邻算法的一般流程:

  1. 收集数据:可以使用任何方法。
  2. 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
  3. 分析数据:可以使用任何方法。
  4. 训练算法:此步骤不适用于K-近邻算法。
  5. 测试算法:计算错误率。
  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行K-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

实施KNN分类算法--伪代码

对未知类别属性的数据集中的每个点依次执行以下操作:

  1. 计算已知类别数据集中的点与当前点之间的距离;
  2. 按照距离递增次序排序;
  3. 选取与当前点距离最小的K个点;
  4. 确定前K个点所在类别的出现频率;
  5. 返回前K个点出现频率最高的类别作为当前点的预测分类;

计算两个向量点之间的距离公式--欧式距离公式:

例如:点(0,0)与(1,2)之间的距离计算为:

sqrt((1-0)**2+(2-0)**2)

代码实现:

import numpy as np
import operator
"""
def CreateDataSet():group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels=['A','A','B','B']return group,labels
print(CreateDataSet())
"""
"""
inX--用于分类的输入向量
dataSet--输入的训练样本集
labels--标签向量
k--用于选择最近邻居的数目
其中标签向量的元素数目和矩阵dataSet的行数相同
"""
def classify(inX,dataSet,labels,k):dataSetSize=dataSet.shape[0]    #获得训练样本集的行数#将输入向量在列方向重复一次,在行方向上dataSize次,并与训练样本集dataSet相减diffMat=np.tile(inX,(dataSetSize,1))-dataSetprint("diffMat:")print(diffMat)#将相减后的集合进行平方运算sqDiffMat=diffMat**2print("sqDiffMat:")print(sqDiffMat)#对平方后的集合进行相加运算--按行相加sqDistances=sqDiffMat.sum(axis=1)print("sqDistances:")print(sqDistances)#对相加后的数据开平方,得到输入向量与每个训练样本集之间的距离值distances=np.sqrt(sqDistances)print("distances")print(distances)#返回数组从小到大的索引值--排序sortedDistIndicies=np.argsort(distances)print("sortedDistIndicies")print(sortedDistIndicies)classCount={}for i in range(k):voteIlabel=labels[sortedDistIndicies[i]]print("voteIlabel"+str(i))print(voteIlabel)classCount[voteIlabel]=classCount.get(voteIlabel,0)+1print("classCount"+str(i))print(classCount)sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)print("sortedClassCount:")print(sortedClassCount)return sortedClassCount[0][0]if __name__=='__main__':#训练样本集group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])#标签向量labels = ['A', 'A', 'B', 'B']#输入向量inX=[0,0]#用于选择最近邻居的数目k=3result=classify(inX,group,labels,k)print(result)"""
输出值:
diffMat:
[[-1.  -1.1][-1.  -1. ][ 0.   0. ][ 0.  -0.1]]
sqDiffMat:
[[ 1.    1.21][ 1.    1.  ][ 0.    0.  ][ 0.    0.01]]
sqDistances:
[ 2.21  2.    0.    0.01]
distances
[ 1.48660687  1.41421356  0.          0.1       ]
sortedDistIndicies
[2 3 1 0]
voteIlabel0
B
classCount0
{'B': 1}
voteIlabel1
B
classCount1
{'B': 2}
voteIlabel2
A
classCount2
{'B': 2, 'A': 1}
sortedClassCount:
[('B', 2), ('A', 1)]
BProcess finished with exit code 0
"""复制代码

测试结果:

输入[0,0],经过测试后,返回的结果是B,也就是说[0,0]这个输入向量通过K-近邻算法分类后归为B类


示例:使用K-近邻算法改进约会网站的配对效果

  1. 收集数据:提供文本文件
  2. 准备数据:使用Python解析文本文件
  3. 分析数据:使用Matplotlib画二维扩散图
  4. 训练算法:此步骤不适用与K-近邻算法
  5. 测试算法:使用海伦提供的部分数据作为测试样本
  6. 测试样本和非测试的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
  7. 使用算法:产生简单的命令行程序,然后可以输入一些特征数据以判断对方是否是自己喜欢的类型

准备数据:从文本文件中解析数据

文本样本数据特征:

  • 每年获得的飞行常客里程数
  • 玩视频游戏所耗时间的百分比
  • 每周消费的冰淇淋公升数

将文本记录转换为numpy数据的解析程序:

def file2matrix(filename):# 打开文件fr = open(filename, 'r', encoding='utf-8')# 按行读取数据arrayOLines = fr.readlines()# 获取数据的行数numberOfLines = len(arrayOLines)# 创建以0填充的矩阵returnMat = np.zeros((numberOfLines, 3))print(returnMat)classLabelVector = []index = 0for line in arrayOLines:print(line)# 截取掉所有回车字符line = line.strip()print(line)# 以'\t'将line分割成一个元素列表listFromLine = line.split('\t')# 选取前三个元素,存储到特征矩阵中returnMat[index, :] = listFromLine[0:3]# 选取最后一个元素存储到标签向量中classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector
datingDataMat,datingLabels=file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')
fig=plt.figure()
plt.title('K-')
plt.xlabel('fly')
plt.ylabel('consume')
ax=fig.add_subplot(111)ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*np.array(datingLabels),15.0*np.array(datingLabels))
plt.show()复制代码

特别说明:代码中的资源文件可以在此处下载:LiuGuoJiang/machinelearninginaction

解析文本数据并用散点图展示:


准备数据:归一化数值

任选样本数据中一行数据,计算距离时,因为飞行常客里程数比较大,所以对最后计算结果影响过大,所以需要对数据做归一化处理。如将取值范围处理为0~1或者-1~1之间。下面的公式可以将任意取值范围的特征值转化为0~1区间内的值:

newValue=(oldValue-min)/(max-min)

  • 其中min和max分别是数据集中的最小特征值和最大特征值。

归一化特征值函数:

def autoNorm(dataSet):#选取列的最小值minVals=dataSet.min(0)#选取列的最大值maxVals=dataSet.max(0)#列的最大值与最小值做减法ranges=maxVals-minVals#normDataSet=np.zeros([dataSet.shape[0],dataSet.shape[1]])print(normDataSet)#取出dataSet的行数m=dataSet.shape[0]#np.tile(minVals,(m,1))将minVals在 列上重复一次,在行上重复m次normDataSet=dataSet-np.tile(minVals,(m,1))  #(oldValue-min)normDataSet=normDataSet/np.tile(ranges,(m,1))   #(oldValue-min)/(max-min)return normDataSet,ranges,minValsnormDataSet,ranges,minVals=autoNorm(datingDataMat)
print(normDataSet)复制代码

测试算法:机器学习算法一个很重要的工作就是评估算法的正确率,通常我们只提供已有数据的90%作为训练样本来训练分类器,而使用其余的10%数据去测试分类器,检测分类器的正确率。10%数据应该是随机选择的。

分类器的测试代码:

def datingClassUnitTest():hoRatio=0.10datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')print(datingDataMat)normDataSet, ranges, minVals = autoNorm(datingDataMat)print(normDataSet)m=normDataSet.shape[0]numTestVecs=int(m*hoRatio)print("numTestVecs")print(numTestVecs)errorCount=0.0for i in range(numTestVecs):classifierResult=classify(normDataSet[i,:],normDataSet[numTestVecs:m,:],datingLabels[numTestVecs:m],3)print("the classfier came back with:{},the real answer is:{}".format(classifierResult,datingLabels[i]))if (classifierResult!=datingLabels[i]):errorCount+=1.0print("the total error rate is:{}".format(errorCount/float(numTestVecs)))the classfier came back with:3,the real answer is:3
the classfier came back with:2,the real answer is:2
the classfier came back with:1,the real answer is:1
.........
the classfier came back with:1,the real answer is:1
the classfier came back with:3,the real answer is:3
the classfier came back with:3,the real answer is:3
the classfier came back with:2,the real answer is:2
the classfier came back with:1,the real answer is:1
the classfier came back with:3,the real answer is:1
the total error rate is:0.05复制代码

分类器处理数据集的错误率是5%,即代表此分类器可以帮助对象判定分类。

编写可以让用户输入自己需要判断的输入向量,通过该分类器帮助用户判断属于哪一分类:

def classifyPerson():resultList = ['not at all', 'in small doses', 'in large doses']percentTats = float(input( \"percentage of time spent playing video games?"))ffMiles = float(input("frequent flier miles earned per year?"))iceCream = float(input("liters of ice cream consumed per year?"))datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')normDataSet, ranges, minVals = autoNorm(datingDataMat)inArr = np.array([ffMiles, percentTats, iceCream, ])classifierResult = classify((inArr - \minVals) / ranges, normDataSet, datingLabels, 3)print("You will probably like this person: {}".format(resultList[classifierResult - 1]))
if __name__=='__main__':classifyPerson()"""
return:
percentage of time spent playing video games?10
frequent flier miles earned per year?10000
liters of ice cream consumed per year?0.5
You will probably like this person: in small doses
"""复制代码

总结:

  1. 定义K-近邻算法程序。
  2. 定义将文本数据集处理成二维数组的函数,便于处理。
  3. 为消除某一特征数值过大对结果判定的影响,定义归一化数值函数,公式:(oldValue-min)/(max-min)
  4. 定义测试算法函数,用于测试分类器的错误率是否满足使用要求。
  5. 定义可以让用户输入的代码,输入输入向量,用于判定分类


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

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

相关文章

C# 格式化字符串

原文地址:http://www.cnblogs.com/zyh-nhy/archive/2007/10/11/921240.html 1 前言如果你熟悉Microsoft Foundation Classes(MFC)的CString,Windows Template Library(WTL)的CString或者Standard Template …

【数据库学习笔记】——操作sqlite(增删改查)以及cursor的方法介绍

目录 1、sqlite数据库介绍 1)常见的数据库操作 2)数据操作常见步骤 2、向数据表中增加数据(insert into) 1)向数据表中添加一条记录 2)向数据表中一次性添加多条记录 ​ 3、修改数据表中已有的数据 1)…

springMVC分析-2

springMVC的请求映射 上一次分析了一下springMVC的大致流程,这次细分一下,对请求映射进行分析。 先从DispatcherServlet中的getHandler()方法分析 protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {for (Hand…

简单消息协议

简单消息协议:定义了ROS与工业机器人之间简单的消息协议。额外的处理程序和管理器类包含用于处理有限连接的系统。这个包是ROS-Industrial计划的一部分。 简单消息协议定义了ROS驱动层与机器人控制器层通信的消息结构。该消息结构符合下列要求: 1、结构足…

Centos安装Vmware-Tools工具

1、打开指定的Centos虚拟机&#xff0c;点击清单-->虚拟机-->客户机-->安装/升级VMware-Tools&#xff08;<u>W</u>&#xff09;&#xff1b; 2、登录Centos会话台&#xff0c;Applications-->Systme Tools-->Terminal&#xff1b; 3、使用“su -”…

【sqlite常用操作SQL语句】

目录 1、创建一个新的数据表 2、在已有的数据表中增加一个新的字段&#xff08;列&#xff09; 3、 在已有的数据表中增加一条新的记录&#xff08;行&#xff09; 1、创建一个新的数据表 "create table user(id int(11) primary key, name varchar(20))" 含义&…

perl-基础

1、Perl 语法入门&#xff1a; 1、print 语句&#xff1a; print "Hello, world\n"; print("Hello, world\n"); 2、引号&#xff1a; Perl双引号和单引号的区别: 双引号可以正常解析一些转义字符与变量&#xff0c;而单引号无法解析会原样输出。 3、perl数…

wdk1703+vs2015编译的诡异问题

wdk1703vs2015编译的诡异问题 最近将wdk升级到1703&#xff08;10.0.15063.0&#xff09;版本&#xff0c;编译一个新建的minifiter项目居然出现了失败 提示错误为 WindowsDriver.common.targets(460,5): error MSB6004: The specified task executable location "\stampi…

centos6虚拟机复制后修改网卡

方法1&#xff1a; 使用vmware创建centos6.4虚拟机&#xff0c; 创建完成后复制该虚拟机&#xff0c; 打开复制的虚拟机发现网卡名字是eth1&#xff0c;而网卡配置文件为eth0&#xff0c;mac地址变了 这时修改网卡配置文件&#xff0c; 删除uuid&#xff0c;修改deivce为eth1&a…

【pyinstaller打包pyqt5编写的项目为exe(脱离环境可运行)】

目录 下载pyinstaller库 0、pyinstaller语句介绍 1、单个py文件打包成exe 1)只有py文件 假设只有一个py文件&#xff1a;pyinstaller -F xxx.py 加上图标&#xff1a;pyinstaller -F xxx.py -i xxx.ico 取消命令行窗口:pyinstaller -F -w xxx.py -i xxx.ico 2) 不但有py…

熔化极气体保护电弧焊简介

1概述 熔化极气体保护电弧焊&#xff08;英文简称GMAW&#xff09;是采用连续等速送进可熔化的焊丝与被焊工件之间的电弧作为热源来熔化焊丝和母材金属&#xff0c;形成熔池和焊缝的焊接方法&#xff0c;如图1所示。为了得到良好的焊缝应利用外加气体作为电弧介质并保护熔滴、熔…

python 中cPickle学习二

写入&#xff1a; import cPickle as p shoplistfile data.data shoplist [meili,[current_account,[100000,1222],basis_account,[5555555,888]],qinshan,[current_account,[1089000,12292],basis_account,[55555955,888]],jiayou,[current_account,[10000,12292],basis_acc…

4.0 多线程基础篇

本文并非最终版本&#xff0c;如有更新或更正会第一时间置顶&#xff0c;联系方式详见文末如果觉得本文内容过长&#xff0c;请前往本人 “简书”4.0-1.1 进程 概念 : 进程是指在系统中正在运行的一个应用程序 (操作系统中每一个 APP 就是一个进程)  性质 : 每个进程之间是独…

【python pandas excel操作】

目录 1、打开Excel&#xff0c;获取不同sheet的名称 2、获取不同sheet的内容 3、 获取行数以及表头 4、对某一列的信息进行筛选 5、根据列号和索引号提取一行或者一列的数据 6、其他panda对Excel的操作 摘自&#xff1a;python对excel操作获取某一列&#xff0c;某一行的值…

焊接机器人应用现状及发展趋势

据不完全统计&#xff0c;全世界在役的工业机器人中大约有将近一半的工业机器人用于各种形式的焊接加工领域&#xff0c;焊接机器人应用中最普遍的主要有两种方式&#xff0c;即点焊和电弧焊。图4所示是这两种焊接机器人在工业机器人中所占的大致比例。我们所说的焊接机器人其实…

线性期望(BUPT2015校赛.F)

将整体期望分成部分期望来做。 F. network 时间限制 3000 ms 内存限制 65536 KB题目描述 A social network is a social structure made up of a set of social actors (such as individuals or organizations) and a set of the relationships between these actors. In simp…

【pyqt5学习】——进度条progressBar

# 进度条 self.progressBar.setValue(0) # 设置进度条的最小值 self.progressBar.setMaximum(100) # 设置进度条的最大值 # 设置进度条当前值 self.progressBar.setValue((int(curindex/excelNum)*100)) 常用方法 方法值说明setRangeQProgressBar.setRange(min, Max)通过 setR…

弧焊 不同气体对焊缝的影响 100二氧化碳 15%氩气CO2混合

Ar含量提高后&#xff0c;相比原来的100%CO2成本会提高很多。 Ar的密度比CO2小&#xff0c;焊接的焊枪必须压的很低&#xff0c;如果焊接结构中有一些狭小区域&#xff0c;焊枪则无法到达。纯CO2气体保护焊&#xff0c;焊丝可伸出较长。 Ar属于惰性气体&#xff0c;焊接时…

Windows和Linux如何使用Java代码实现关闭进程

在用selenium做自动化测试时&#xff0c;由于各种不明原因&#xff0c;有时Chrome浏览器会出现假死的情况&#xff0c;也就是整个浏览器响应超时&#xff0c;本人脚本主要部署在Windows机器上&#xff0c;所以主要以Windows为主&#xff0c;浏览器为Chrome,即如下图所示 或者由…