上一个part1的例子比较简单,很适合入门
这次的例子也比较简单,但是涉及的是从文本文件中解析数据、matplotlib可视化数据、数据归一化、分类测试,算是机器学习的入门知识实现了
原理不多赘述了,都是些基础的东西。
注:文章中的代码(注释除外)大多来自《机器学习实战》,请多支持正版书籍!
=====================================================================
file2matrix函数用于将文本文件转化为简单的数组
- 数据转换:
def file2matrix(filename):
fr=open(filename)
arrayOlines=fr.readlines()
#read()将文件内容放到一个字符串变量中
#readline()每只读去一行
#readlines()每次安航读取一整个文件内容,放到一个列表里,返回List
numberofLines=len(arrayOlines)
returnMat=zeros((numberofLines,3))
#3是由于本例中特征为三维
classLabelVector=[]
index=0
for line in arrayOlines:
line=line.strip()
#去掉所有回车字符
listFromLine=line.split('\t')
#将行内容按tab字符分割成元素列表
returnMat[index,:]=listFromLine[0:3]
classLabelVector.append(int(listFromLine[-1]))
#classLabelVector加入listFromLine的最后一个元素,该数据集中最后一列为类别标签
index+=1
return returnMat,classLabelVector
- 结果可视化化:
returnMat,classlabel=KNN.file2matrix('datingTestSet.txt')
fig=plt.figure()
#创建图表
ax=fig.add_subplot(111)
#fig.add_subplot是matplotlib的函数,在图表中创建子图
#参数表示1行1列第1个
#fig没有直接的scatter函数
ax.scatter(returnMat[:,1],returnMat[:,2],15.0*np.asarray(classlabel),15.0*np.asarray(classlabel))
#scatter用于画散点图,后两位参数是对图表样式进行设置
plt.show()
跟书上一个地方不一样的是,书中scatter函数参数是:
ax.scatter(returnMat[:,1],returnMat[:,2],15.0*array(classlabel),15.0*array(classlabel))
这样的话,会报“array not define”的错误,我是3.4版本的py
故引入:
import numpy as np
然后改为:
ax.scatter(returnMat[:,1],returnMat[:,2],15.0*np.asarray(classlabel),15.0*np.asarray(classlabel))
- 数据归一化:
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))
return normDataSet,ranges,minVals
哈哈,这段归一化的原理和代码都比较简单,就没注释了
- 结果测试
下面是一个将上述几个小步骤(包括上一篇文章的KNN分类函数)整合起来,用于统计分类错误率
def datingClassTest():
hoRatio=0.10
#转换数据格式
datingDataMat,datingLabels=file2matrix('datingTestSet.txt')
#数据归一化
normMat,ranges,minval=autoNorm(datingDataMat)
m=normMat.shape[0]
numTestVecs=int(m*hoRatio)
#numTestVecs表示从数据集中选择hoRatio比例的数据来做测试集
errorCount=0.0
for i in range(numTestVecs):
classifierResult=classify(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函数调用的方式,原书方法会报错。
运行结果
错误率只有5%,比我自己的研究结果好多了()
最后用一个完整的函数,根据用户的输入来完成检测功能。
def classifyPerson():
resultList=['not at all','in small doses','in large doses']
percentTats=float(input("percentage of time spent playing video game?"))
ffMiles=float(input("frequent flier miles earned per year?"))
iceCream=float(input("liters of ice cream consumed per year?"))
datingDataMat,datingLabels=file2matrix('datingTestSet.txt')
normMat,ranges,minval=autoNorm(datingDataMat)
inArr=array([ffMiles,percentTats,iceCream])
classifierResult=classify((inArr-minval)/ranges,normMat,datingLabels,3)
print("You will probably like this person:",resultList[classifierResult-1])
与书中不一样的就是,raw_input在3.4版本中直接被Input替代咯。
输出的结果:
KNN还有最后一小部分,放在part3中。
=====================================================================
小插曲:想在IDE里头自己写个二维数组试一下MIN函数
被自己蠢哭……
>>> a=[1,2,3;4,5,6;7,8,9]
SyntaxError: invalid syntax
>>> a=[[1 2 3],[4 5 6],[7 8 9]]
SyntaxError: invalid syntax
>>> a=[[1 2 3][4 5 6][7 8 9]]
SyntaxError: invalid syntax
>>> a={[1 2 3],[4 5 6],[7 8 9]}
SyntaxError: invalid syntax
>>> a=[[1,2,3],[4,5,6],[7,8,9]]
>>> min(a)]
SyntaxError: invalid syntax
>>> min(a)
[1, 2, 3]
不要告诉我未来老板~~~~~~~~~~~~~~~~~~~~~~~
=======================================================================
实验中所需数据集,可以从这里下载: