通过本篇博文,你可以学习到:
- 环境搭建,主要为python,numpy,以及matplotlib库的搭建等;
- k-近邻算法;
- k-近邻算法实战练习,使用k-近邻算法判断某个同学是不是你喜欢的类型。
理论与实战的结合,赶快打起精神,一起来学习吧!吼吼吼~~~
环境搭建
- python:开发语言,使用广泛, 简单易学
- NumPy:科学计算库文件,它实现了大量的向量和矩阵操作,在python中我们可以像在matlab里面一样编写非常简单易读矩阵操作代码。
- matplotlib:绘图库文件,在python中我们可以像在matlab里面一样,方便的实现绘图功能。
python###
下载python安装文件
在https://www.python.org/downloads/ 上下载相应平台的python安装文件,本文采用的python版本为windows平台的python 2.7。下载后,点击安装,一路next。添加环境变量
右键“我的电脑”——属性——系统高级设置——高级——环境变量,在系统变量中找到Path,编辑此变量在后面追加 ;C:\Python27\ (python安装位置,每个人都可能不一样哦,注意前面的分号)。如何证明python安装成功?
打开命令提示符,输入python,能看到所安装python的版本信息即证明安装成功,如下图所示:
numpy及matplotlib等库文件安装###
一个一个安装比较麻烦,如果想省事儿的话,建议使用Anaconda进行安装,Anaconda针对的痛点就是一个一个安装这些库会比较麻烦,那么他就帮大家一起集成了。
下载Anaconda安装文件
在https://www.continuum.io/downloads 下载相应版本的安装文件,双击安装即可,一路next。环境变量设置
Anaconda安装的过程中,会自动在path下面添加相关的环境变量,所以这步跳过。如何证明Anaconda已经安装成功?
在cmd里面,输入conda list可以查看Anaconda已经帮大家安装的库,如下图所示。
可以自己看下我们所需要用到的numpy及matplotlib库文件也在包含在里面。
4.如何证明numpy及matplotlib已经安装成功?
如上图所示,就表示能够正常的使用numpy及matplotlib。
爬过的坑###
- 单独下载numpy包,然后cd到相应的路径,使用python setup.py install安装numpy,报错“failed with exit status 1120”,如下图所示:
产生问题的原因及解决办法:版本原因,python版本为2.7,numpy下载的版本为1.11,后来使用Anaconda下载的匹配的版本是1.10。解决方法是使用Anaconda安装。
2.安装完Anaconda之后,import matplotlib的时候,提示"no module named matplotlib"。
产生问题的原因:猜想是python无法使用Anaconda安装的库。
解决办法:
在python安装目录下的lib\site-packages下面,新建一个文件anaconda.pth,文件的内容是Anaconda安装目录下的site-packages路径。
3.import matplotlib.pyplot as plt报错“from PyQt4 import QtCore, QtGui ImportError: DLL load failed:找不到指定的程序“,如下图所示
产生问题的原因:没有安装PyQt4
解决办法:安装PyQt4,下载链接https://riverbankcomputing.com/software/pyqt/download
OK!到这一步为止环境就算搭建好了,下面就开始这篇文章的正题,k-近邻算法。
k-近邻(kNN)算法概述
- kNN算法原理
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似(最邻近)的分类标签。一般来说我们只选择数据集中前k个最相似的数据,这就是k-近邻算法的k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。
上面写的太复杂了,其实很简单,就是计算距离,根据距离进行分类。举个栗子,吼吼,如下图所示,已知右上角的两个点属于A类,左下角的两个点属于B类,那么给定一个点如图中的小红点,那么他是属于A点还是B点呢?
kNN算法给出的解决方案是,分别计算小红点与每个点的距离,然后将距离从小到大排序,取前k位,如取前2位,如果发现这2位都是B类,那么说明这个小红点也是属于B类。
- kNN算法实现
算法流程
- 计算待分类点与已知类别数据集中每个点的距离;
- 按照距离递增次序排序;
- 选取与待分类点距离最小的k个点;
- 确定前k个点类别出现的频率;
- 返回前k个点出现频率最高的类别作为当前点的预测分类。
python代码实现
from numpy import *
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
四不四很简单?吼吼吼~~~
使用k-近邻算法快速判定她是不是你喜欢的类型?
问题描述
比如你的朋友经常上约会网站寻找自己的约会对象,你的朋友选定约会对象的时候主要看重三点“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”,你阅人无数的朋友已经约会过很多个对象了,并且把这些对象分为三类“她是我喜欢的类型”、“一般喜欢”,“她不是我喜欢的类型”,经过无数次的约会之后,你的朋友心已经很累了,他想能否输入某人的“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”这三项数据,就能判断她是不是他喜欢的类型呢?-
已有资源
为了简化问题,我们假设你的朋友,已经整理了一份数据,如下图所示:
其中前三列分别表示“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”,第四列表示分类。其中“1”表示“她不是我喜欢的类型”、“2”表示“一般喜欢”,“3”表示“她是我喜欢的类型”。 如何使用kNN算法?
在前一篇博文机器学习实战入门篇之一:机器学习中必会的基础概念!中,我们介绍了使用机器学习算法解决问题的一般步骤,我们再一次回顾一遍流程图。
下面我们将一步一步来完成。
收集数据
为简单起见,已经提供txt文本数据。数据预处理
数据预处理中,我们得将txt文本中提供的数据放到矩阵或矢量中进行存储,然后还需要将数据进行归一化。
(1) 把txt文本中的数据转换成矩阵或矢量进行存储
#函数名:file2matrix
#输入:文件名
#输出:returnMat为txt文本数据的前三列构成的二维数组
# classLabelVector为txt文本数据第四列的分类信息的一维矢量
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines()) #get the number of lines in the file
returnMat = zeros((numberOfLines,3)) #prepare matrix to return
classLabelVector = [] #prepare labels return
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector
(2) 数据归一化
为什么要进行数据归一化?分析下数据可以看出,飞行距离相对于其他两个特征的数据来说通常要大的多,如果不进行数据归一化,那么在计算距离的时候飞行距离对结果的影响占绝对主导性,这显然是不合理的,所以需要进行数据归一化,归一化的python代码如下所示:
#函数名:autoNorm
#输入:dataSet为原始数据二维数组
#输出:normDataSet归一化之后的二维数组,ranges为每一列最大值减去最小值的范围,minVals为每一列的最小值。
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m,1))
normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide
return normDataSet, ranges, minVals
分析输入数据
可以将数据用二维散点图画出来,直观感受一下。训练算法
此步骤不适用于kNN算法测试算法
通常来说,我们使用数据的90%作为训练数据,10%的数据作为测试数据。测试的指标为出错率,当预测的分类和实际的分类结果不一致时,记录一个错误,错误的总数/测试的样本数即为出错率。
python代码:
#函数名:datingClassTest
#输入:无
#输出:无,但是会打印出错个数及错误率。
def datingClassTest():
hoRatio = 0.50 #hold out 10%
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])
if (classifierResult != datingLabels[i]): errorCount += 1.0
print "the total error rate is: %f" % (errorCount/float(numTestVecs))
print errorCount
运行结果:
可以看出,错误率为6.4%,大家可以改变参数值k,观察下出错率的变化。
- 应用算法
测试出错率达到满意结果之后,我们就可以拿来用了,应用程序如下:
def classifyPerson():
resultList = ['not like','so so','very like']
gamePercent = float(raw_input("gaming time percent:"))
flyMiles = float(raw_input("flying miles per year:"))
bookNum = float(raw_input("reading books per month:"))
datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")
normMat, ranges, minVals = autoNorm(datingDataMat)
inArray = array([flyMiles, gamePercent, bookNum])
classifyResult = classify0((inArray - minVals)/ranges, normMat, datingLabels, 3)
print "prediction result is: ", resultList[classifyResult - 1]
运行结果:
可以看出,具有这些特征数据的她对你吸引力一般般啦,你可以自己测试看看,看到底什么样的她才是你喜欢的类型呢?
kNN算法总结
- 优点:简单有效
- 缺点:经过前面的介绍可以看出,kNN算法必须保存全部的数据集,如果训练数据集很大,那么就需要耗费大量的存储空间。此外,由于必须对待分类数据计算与每一个训练数据的距离,非常耗时。
终于写好了,码字好累,欢迎志同道合的朋友留言交流,有什么写的不对的地方敬请指出!