机器学习第一篇——最近邻kNN
机器学习监督学习中,根据解决问题的连续性和离散型,分为分类问题和回归问题。最邻近算法kNN是一种最为直接和简便的分类方法。
kNN本质上,是计算目标到模型的欧式距离,从而判定目标所属的类别。
首先,在解决机器学习问题的时候,我们首先,其实面对这样一个问题:对数据的清洗。因为通常的,我们的程序设计语言,只能处理诸如数组,矩阵,字符,以及其他我们在程序设计中常见的一些数据类型。而通常的,我们手中的数据都是以文件的格式给出。比如.TXT格式的。
所以,首先第一步:完成数据类型的转换:
下面给出一段python 代码,旨在说明其中的思想:
def file2matrix(filename):
fr = open(filename) #打开文件
array0Lines = fr.readlines()#读取文件的内容(实际上,查看array0lines的内容时,发现文件的每一行,为一个字符串,且字符串中包含了“\t(制表位,就是对其的那个东西)”,“\n”)
number0fLines = len(array0Lines)#获取行数
returnMat = zeros((number0fLines,3))创造一个行数×3的矩阵
classLabelVector = []创建一个空的列表,注意这里只是列表
index = 0
for line in array0Lines: 开始完成数据清洗
line = line.strip()#去掉"\n",但此时制表位还在,数据格式仍然是我们处理不了的,如123 0.324 2.12(数据与数据的制表位仍然在)
listFromLine = line.split('\t')#去掉制表位(将每个数据转化为列表式数据),如['123', '0.324', '2.12'](很明显,变成了列表数据,列表数据是字符串,是我们可以处理的)
returnMat[index,:] = listFromLine[0:3]#将转化好的列表前三个数拷贝到矩阵每一行里面(主要疑问在于为什么字符串类型变成了浮点型(还是自己理解错误))
classLabelVector.append(int(listFromLine[-1]))#将listFromLine列表最后一个数据先转化为整型(请记住文件中数据为字符型),再存储到classLabelVector列表中
index +=1 return returnMat,classLabelVector
上述Python代码的输入文件是一个n乘以4的“矩阵”数据(在文件中看起来像矩阵,但是需要转化成真正能够处理的数据类型),前三列为一组数据,最后一列为另一组数据。很明显,我们将前三列数据转化成了矩阵,最后一列数据保存成了列表。
数据转化成了可以处理的数据,前三列的数据分别表示三个不同的参考指标。但是每个指标的量纲不一样,数量级不一样,比如第一列的数据范围是[0,1],第二列数据范围是[0,10000],第三列数据范围是[100,1000].前面说过,kNN本质上要计算欧式距离,那么这里为:sqrt((x-x1)2+(x-x2)2+(x-x3)2),但是面临这样一个问题:比如x2范围在[0,10000],很明显x2对结果的影响是很大的,从而降低了其他参考量的影响因子,但很多时候,我们需要这些影响因子具有相同的权重,甚至我们给定不同的参考因子一个不同的权重。因此,我们通常需要对数据进行归一化的处理。
下面给出Python代码:
def autoNorm(dataSet):
minvals = dataSet.min(0)#min(0)获取列最小值,min(1)获取行最小值
maxvals = dataSet.max(0)
ranges = maxvals-minvals
normDataSet = zeros(shape(dataSet))#shape()返回矩阵的行数和列数即(行,列)
m = dataSet.shape[0]#我们要理解这种打点的操作,对dataSet进行shape 操作取其第一个元素,即我们获取矩阵的行数信息(也可以用shape(dataSet)[0]这种用法)
normDataSet = dataSet-tile(minvals,(m,1))#tile的作用是复制,将minval数组复制成m行×1列的,这样是为了完成对应相减
normDataSet = normDataSet/tile(ranges,(m,1))#tile 的作用是相同的
return normDataSet,ranges,minvals #返回归一化后的数据矩阵,取值范围,最小值
上述两个过程,完成了对数据的基本清洗工作。
在完成数据分类之前,应该先构建一个数据分类器。这个分类器是分类的核心,Python代码如下:
def classify0(inx,dataSet,labels,k):#inx 是我们要进行分类的数据,dataSet是知道类别标签的数据,labels是dataSet的类别标签。k是选择最邻近的数目
dataSetSize = dataSet.shape[0]#获取行数
diffMat = tile(inx,(dataSetSize,1))-dataSet#将要分类的数据复制成dataSetSize行×1列,从而保证相减的时候维数相等
sqDiffMat = diffMat**2#平方运算
sqDistances = sqDiffMat.sum(axis=1).sum是numpy模块中的函数,sum(axis=1)表示二维数组按照行相加,sum(axis=0)表示按列相加,很明显这里是按照行相加
distances = sqDistances**0.5#开根运算
sortedDistIndicies = distances.argsort()#.argsort()将数组从小到大排列,并返回其索引。比如x=([3,1,2]),则返回[1,2,0]
classCout = {}#定义字典
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]#返回前K个比较小的索引对应的分类
classCout[voteIlabel] = classCout.get(voteIlabel,0)+1#?????????????????????????
sortedClassCout = sorted(classCout.items(),key = operator.itemgetter(1),reverse = True)#????????????????????/
return sortedClassCout[0][0]
完成分类器的构造之后,需要完成的是,对数据测试,即从数据中选出一定的数据建立模型,剩下的数据训练模型的出错率,Python代码如下:
def datingClassTest():
horatio = 0.1#选定10%的数据作为检测数据
datingDataMat,datingLables = file2matrix('datingTestSet2.txt')
normMat,ranges,minvals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*horatio)#得到检测数据的数目
errorcount = 0.0
for i in range(numTestVecs):
classifirerResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLables[numTestVecs:m],3)
print("the classifier came back with:%d,the real answer is: %d"%(classifirerResult,datingLables[i]))
if (classifirerResult != datingLables[i]):
errorcount +=1.0#如果分类出错,分类计数加1
print("the total error rate is: %f"%(errorcount/float(numTestVecs)))#计算分类错误率
以上过程,完成了对数据完成kNN最邻近方法分类模型训练的全部过程。
在这其中,强调这么几点:
1上述频繁使用矩阵计算,使得程序和计算变的更加简单,但矩阵并不是python自带的数据结构,因此numpy在数学计算中是一个十分重要的python库
2 列表是[],数组是([]),矩阵是([],[]),不要把列表当成了数组。
3 python 是解释性语言,因此比如我们在某一个程序文件中用到kNN.py文件中的函数。我们在开头处使用了import kNN。在kNN文件中我们使用from numpy import *,在kNN文件中导入了numpy库,假如我们想在当前文件中使用numpy中的矩阵运算,并不能因为当前文件包含了kNN文件,而kNN文件中导入了numpy库,我们就认为当前文件导入了numpy。因为python 是解释性语言,因此在运行某个矩阵运算的时候,并不能找到该矩阵运算的来源,因此,我们除了要写导入了kNN,也要写重新写一句from numpy import *
机器学习第一篇——最近邻kNN的更多相关文章
- sklearn学习 第一篇:knn分类
K临近分类是一种监督式的分类方法,首先根据已标记的数据对模型进行训练,然后根据模型对新的数据点进行预测,预测新数据点的标签(label),也就是该数据所属的分类. 一,kNN算法的逻辑 kNN算法的核 ...
- K最近邻(KNN,k-Nearest Neighbor)准确理解
K最近邻(KNN,k-Nearest Neighbor)准确理解 用了之后,发现我用的都是1NN,所以查阅了一下相关文献,才对KNN理解正确了,真是丢人了. 下图中,绿色圆要被决定赋予哪个类,是红色三 ...
- kNN算法:K最近邻(kNN,k-NearestNeighbor)分类算法
一.KNN算法概述 邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它 ...
- Python学习第一篇
好久没有来博客园了,今天开始写自己学习Python和Hadoop的学习笔记吧.今天写第一篇,Python学习,其他的环境部署都不说了,可以参考其他的博客. 今天根据MachineLearning里面的 ...
- Flink入门-第一篇:Flink基础概念以及竞品对比
Flink入门-第一篇:Flink基础概念以及竞品对比 Flink介绍 截止2021年10月Flink最新的稳定版本已经发展到1.14.0 Flink起源于一个名为Stratosphere的研究项目主 ...
- 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)
从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...
- Python爬虫小白入门(四)PhatomJS+Selenium第一篇
一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...
- Three.js 第一篇:绘制一个静态的3D球体
第一篇就画一个球体吧 首先我们知道Three.js其实是一个3D的JS引擎,其中的强大之处就在于这个JS框架并不是依托于JQUERY来写的.那么,我们在写这一篇绘制3D球体的文章的时候,应该注意哪些地 ...
- 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器
× 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...
随机推荐
- c/c++ 标准库 map set 大锅炖
标准库 map set 大锅炖 一,关联容器有哪些 按关键字有序保存元素 map 保存key和value set 只保存key mulutimap key可以重复出现 multiset key可以重复 ...
- Linux 中数组的使用
Linux中数组本人可能用的相对较少,但是会经常遇见,也容易忘记,就顺便记录下来吧 数值类型的数组:一对括号表示数组,数组中元素之间使用“空格”来隔开 arr=(1 2 3 4 5) 字符串类型数组: ...
- vscode中配置php的xdebug
vscode中配置php的xdebug vscode配置php的xdebug,步骤如下: 1. 安装phpdebug插件: PHP Debug 2.网上下载php的xdebug扩展(注意根据自己的ph ...
- CSipIm断网重连崩溃原因分析
断网重连之后的操作流程 拨打电话 ->调用SipService.makeCallOptions(),先重启一遍SipService保证PjSipService的各参数正常,尤其是create参数 ...
- html + js 实现图片上传,压缩,预览及图片压缩后得到Blob对象继续上传问题
先上效果 上传图片后(设置了最多上传3张图片,三张后上传按钮消失) 点击图片放大,可以使用删除和旋转按钮 (旋转功能主要是因为ios手机拍照后上传会有写图片被自动旋转,通过旋转功能可以调正) html ...
- TOPWAY智能彩色TFT液晶显示模块
TOPWAY 20年来专注工业显示, 以为全球工业用户提供稳定可靠和容易使用的液晶显示模块为己任, 智能彩色TFT液晶显示模块(以下简称智能模块), 就是我们在容易使用TFT 彩色液晶显示方向上为广大 ...
- Why do Kafka consumers connect to zookeeper, and producers get metadata from brokers?
Why do Kafka consumers connect to zookeeper, and producers get metadata from brokers? Ask Question u ...
- centos7下kubernetes(8.kubernetes Failover)
上一节我们运行的3个容器 其中有两个是运行在node2上一个运行在node1上,现在我们关闭node1,观察node1上的容器会发生什么变化 目前node1已经处于notready状态 现在我们查看一 ...
- vue快速入门
Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使 ...
- 为了下载和使用最新的git,只好安装了迅雷
一 安装迅雷时总感觉它的图标像是灰鸽子,让人不放心. 从https://git-scm.com/downloads上找到64-bit Git for Windows Setup的地址: https: ...