问题描述:一姑娘相亲无数,并且给相亲对象进行了评分123分别表示很喜欢的,一般般的和不喜欢的,这里也给出了被约过的1000位男士的个人信息包括飞行里数,玩游戏视频所耗时间比,和每周消费的冰激凌公升数。要求建立一个分类器使得一个新的男士出现时能以最大概率进行分类。这里我们用KNN算法。
一、准备数据
所给txt文档有1000行,大概长这样:
40920 8.326976 0.953952 3
14488 7.153469 1.673904 2
26052 1.441871 0.805124 1
75136 13.147394 0.428964 1
38344 1.669788 0.134296 1
...
先上代码:
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
我们最后将原数据的特征均放在returnMat中,对应类放在classLabelVector中。
注1:strip(‘chars’)的功能是移除收尾指定字符。如
str = "0000000this is string example....wow!!!0000000"
str.strip('0')
Out[11]: 'this is string example....wow!!!'
如果str.strip()则表示移除首尾空格。
注2:同样,后续使用时要时要将内参变为外参
datingDataMat,datingLabels=file2matrix('文件名.txt')
后面会加
二、分析数据
画图
import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(returnMat[:,1],returnMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show
即以数据中第二列第三列为坐标,datingLabels为颜色和大小标记标准
我们换第一列和第二列为坐标看看。即换成
ax.scatter(returnMat[:,0],returnMat[:,1],15.0*array(datingLabels),15.0*array(datingLabels))
三、数值归一化
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)) #差再除以max-min
return normDataSet, ranges, minVals
注1:min(0)是计算每列的最小值,min(1)的话是计算每行的最小值
注2:这里的\就是除法,不是矩阵除法,矩阵除法的话要linalg.solve(matA,matB)
注3:同样,内参变外参
normMat,range.minVals=autoNorm(datingDataMat)
后面会加
四、测试算法
def datingClassTest():
hoRatio = 0.10 #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)#取出10%的数据作为测试集
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
注1:
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
这行使用的是上一篇定义的功能,应该为classify0(测试集,特征集,类,k值),一般来说9:1分要随机,但这里本身给的顺序就是随机的,所以我们可以把1:100行作为测试集,101:1000行作为训练集。我们可以调节hoRatio来影响最后的错误率,最后我们选一个使错误率最低的比例估摸大概就是我们最终测试新数据可能会犯错的可能性。
五、使用算法
推广:电影推荐系统如何自动推荐你可能感兴趣的电影?按同样思路,可以把每部电影中含有的喜剧元素,动作元素,恐怖元素百分比等作为特征向量,但是这些数据又该如何得到,加入我们知道一群人分别很喜欢喜剧电影,动作电影,恐怖电影,并且知道他们给不同电影的评分,这样就可以推算出每部电影的不同元素百分比。
同样,可以根据用户今天或者上周在淘宝上的新增收藏数,加入购物车数,以及浏览时间等判断明天是否会下单疑问
def classifyperson(): resultList=['dislike','just so so','very like'] percentTats=float(raw_input("percentage of time spent playing video games?")) ffMiles=float(raw_input("frenquent flier miles earned per year?")) icecream=float(raw_input("liters of ice cream consumed per year?"))
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #load data setfrom file normMat, ranges, minVals = autoNorm(datingDataMat)#不重新写一遍就是内参了 inArr=array([ffMiles,percentTats,icecream])#合成 classifierRusult=classify0(inArr-minVals/ranges,normMat,datingLabels,3) print "reulitList[classifierRusult-1]"