将约会网站的人分为三种类型:不喜欢的,魅力一般的,极具魅力的,分别用数字1,2,3表示,这些是样本的标签。样本特征为,每年飞行里程,玩视频游戏占百分比,每周消费冰淇淋公升数。
文件格式如下:
首先要解析文本。代码如下:
def file2matrix(filename):
fr=open(filename)
arrayOLines=fr.readlines()
numberOfLines=len(arrayOLines)#文件的行数
returnMat=zeros((numberOfLines,3))
classLabelVector=[]
index=0
for line in arrayOLines:
line=line.strip()#截取回车字符
listFromLine=line.split('\t')#使用'\t'分割成元素列表
returnMat[index,:]=listFromLine[0:3] #第index行 为listfromline前3个元素
classLabelVector.append(int(listFromLine[-1])) #添加分类标签
index+=1
return returnMat,classLabelVector
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
fig=plt.figure() #创建一个图形示例
ax=fig.add_subplot(111)#将画布分成1行1列,并且画在从左往右从上往下的第一块
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels)) #描绘散点图
plt.show()
这么看来关系好像不大。。。
通过下表可以看出,飞行里程数对计算结果的影响远大于其他两个。但是我们认为这三个对结果的影响应该是一样的,那么就应该归一化数值。即把每个特征的最小值最大值求出,最小值赋值为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))
return normDataSet,ranges,minVals
归一化以后就可以使用k近邻算法了。
不过我们得留10%的数据进行测试,这些测试数据得是随机的。
def datingClassTest():
hoRatio=0.10 #10%测试
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt') #解析文本
normMat,ranges,minVals=autoNorm(datingDataMat)#归一化
m=normMat.shape[0] #文本行数
numTestVecs=int(m*hoRatio) #测试集的数量
errorCount=0.0 #初始化错误的数量
for i in range(numTestVecs):
#训练,四个参数分别为测试集,训练集,标签,k,第一个表示第i行全部数据,第二个为从测试集第一行到文本最后一行
#第三个为测试集的标签,k选取3
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 #如果错了,错误数量+1
print("the total error rate is:%f" %(errorCount/(float)(numTestVecs))) #计算错误率
运行结果:
构建完整可用系统:
#构建完整可用系统
def classifyPerson():
resultList=['not at all','in small doses','in large doses'] #与1,2,3分别对应
#输入三个参数
percentTats=float(input(\
"percentage of time spent playing video games?"))
ffMiles=float(input("frequent filer miles earned per year?"))
iceCream=float(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])
运行结果:
总而言之感觉这个算法好神奇的样子,但是原理又并不是很难理解。