机器学习第一篇——最近邻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 ...
随机推荐
- AspNet mvc的一个bug
[HttpPost] public ActionResult updateLoan(TuWenMilitaryRank entity) 使用mvc绑定表单 每次绑定的对象都为null,查看Reques ...
- c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)
二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: ...
- MySQL常用命令(二)
1.索引分类 1.普通索引 2.唯一索引 3.主键索引 4.外键索引2.普通索引(index) 1.使用规则 1.一个表中可以有多个index字段 2.字段的值可以有重复,也可以为NULL值 3.经常 ...
- Cs231n课堂内容记录-Lecture2-Part1 图像分类
Lecture 2 课程内容记录:(上)https://zhuanlan.zhihu.com/p/20894041?refer=intelligentunit (下)https://zhuanlan. ...
- python3+beautifulsoup4爬取汽车信息
import requests from bs4 import BeautifulSoup response = requests.get("https://www.autohome.com ...
- Call to a member function display() on a non-object问题的解决
在使用ThinkPHP做项目的时候,出现了如下 的报错: 报错是Call to a member function display() on a non-object.我的代码是: 查看了ThinkP ...
- PATH_SEPARATOR
PATH_SEPARATOR是一个常量,在Linux系统中是一个" : "号,Windows上是一个";"号.所以编写程序时最好用常量 PATH_SEPARAT ...
- 【算法】LeetCode算法题-Reverse Integer
这是悦乐书的第143次更新,第145篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第2题(顺位题号是7),给定32位有符号整数,然后将其反转输出.例如: 输入: 123 ...
- Object类(根类)
Object中的方法是所有类都有的方法,每个类默认继承了Object类. boolean equals(Object obj) : Object中默认是比较地址,可以重写equals(Object ...
- Servlet中的request与response
了解这方面的知识可以查看以下博客 https://www.cnblogs.com/zhangyinhua/p/7629221.html https://www.cnblogs.com/zhaojian ...