一、准备数据:从文本文件中解析数据
1.将特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式。在kNN.py 中创建名为file2matrix的函数,以此来处理输入格式的问题。该函数的输入为文件名字符串,输出为训练样本矩阵和类标签向量。将下面代码加到kNN.py中(将文本记录到转换Numpy的解析程序);
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.输入reload(kNN)然后回车,reload(kNN)是重新加载kNN模块,确保更新的内容可以生效,否则Python将使用旧的kNN模块;然后提示错误了,说是reload未定义,查阅资料发现这个语法是python2才能使用,python3版本要先引入库;引入库有两种方法:第一种:输入from imp import reload;第二种:from importlib import reload;第一种方法系统会提示不建议使用,所以使用第二种方法,回车之后再输入reload(kNN);
4.然后输入datingDataMat,datingLabels = kNN.file2matrix(‘datingTestSet.txt’),使用函数fileMatrix读取文件数据,必须确保文件datingTestSet.txt存储在我们的工作目录;不知道工作目录是啥,然后就把文件放在了和python.exe同一目录下,结果报错了;
5.最后发现文件datingTestSet.txt不在工作目录中,输入import os,回车输入os.getcwd()查看工作目录,然后将文件datingTestSet2.txt复制粘贴到对应工作目录中(注意:这里将datingTestSet.txt文件换成datingTestSet2.txt文件,因为datingTestSet.txt文件中末尾有字符串,int只能识别整形而出错),或者通过os.chdir(“f:\xxxxx”)修改工作目录路径,但是修改的路径在退出python后会自动修改到原路径;然后分别输入datingDataMat和datingLabels[0:20]回车得到如图结果。
二、分析数据:使用Matplotlib创建散点图
1.先通过在python中输入from numpy import array导入Numpy数组;
2.使用Matplolib制作原始数据的散点图,在python环境中输入以下命令:
>>>import matplotlib
>>>import matplotlib.pyplot as plt
>>>fig = plt.figure()
>>>ax = fig.add_subplot(111)
>>>ax.scatter(datingDataMat[:,1],datingDataMat[:,2])
>>>plt.show()
输出结果如图;散点图使用datingDataMat矩阵的第二、第三列数据,分别表示特征值“玩视频游戏所耗时间比”和“每周所消费的冰淇淋公升数”。
3.采用色彩来标记不同样本分类,以便更好理解数据信息。重新输入代码:
>>>import matplotlib
>>>import matplotlib.pyplot as plt
>>>fig = plt.figure()
>>>ax = fig.add_subplot(111)
>>>ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0array(datingLabels),15.0array(datingLabels))
>>>plt.show()
输出结果如图:
4.在kNN.py文件中增加新函数autoNorm(),该函数可以自动将数字特征值转化为0到1的区间。代码如下:
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
5.在python命令提示符下,重新加载kNN模块,执行autoNorm函数,检测函数执行结果,输入:
>>>from importlib import reload
>>>reload (kNN)
>>>normMat,ranges,minVals = kNN.autoNorm(datingDataMat)
>>>normMat
>>>ranges
>>>minVals
输出结果如图:
三、测试算法:作为完整程序验证分类器
1.在kNN.py文件中添加以下代码测试:
def datingClassTest():
hoRatio = 0.80 #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)
2.命令提示符下重新加载kNN模块,输入kNN.datingClassTest(),输出如图;得出分类器处理约会数据集的错误率是5.6%,可以改变函数daingClassTest内变量hoRatio和变量k的值,检测错误率是否随着变量的变化而变化。
四、使用算法:构建完整可用系统
1.将下列代码加入到kNN.py文件并重新载入kNN;其中新增的raw_input()函数是允许用户输入文本行命令并返回用户所输入的命令;
def classifyPerson():
resultList = ['not at all','in small doses','in large doses']
percentTats = float (raw_input("percentage of time spent playing video games?"))
ffMiles = float (raw_input("frequent flier miles earned per year?"))
iceCream = float(raw_input("liters of ice cream consumed per year?"))
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat,ranges,minVals = autoNorm(datingDataMat)
inArr = array([ffMiles,percentTats,iceCream])
classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
print ("You will probably like this person:",resultList[classifierResult - 1])
2.又发现一处错误,上述代码块中的raw_input()函数只能用于python2版本,python3版本使用input()即可,即把classifyPerson函数中的三处raw_input()换成input();然后输入:kNN.classifyPerson();然后输入你想要的对应问题的数字,最后输出结果如图: