摘要:项目介绍某用户一直使用在线约会软件寻找适合自己的约会对象。尽管约会网站会推荐不同的人选但她并不是喜欢每一个人。
某APP用户一直使用在线约会软件寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她并不是喜欢每一个人。经过一番总结,她发现曾交往过三种类型的人:
不喜欢的人(3)
魅力一般的人(2)
极具魅力的人(1)
某APP用户希望分类软件可以更好地帮助她将匹配对象划分到确切的分类中。此外还可以收集了约会软件未曾记录的数据信息,她认为这些数据更有助于匹配对象的归类。收集的部分信息如下图所示:数据集下载样本主要包含以下3种特征:
每年获得的飞行常客里程数
每周消费的冰淇淋公升数
在将上述特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式。
使用Matplotlib库图形化清晰地标识了三个不同的样本分类区域,具有不同爱好的人其类别区域也不同。
defdraw_pic(datingDataMat,datingLabels):"""每年获取的飞行常客里程数与每周所消费的冰淇淋公升数”构成的散点图。:paramdatingDataMat::paramdatingLabels::return:"""#中文显示乱码问题;myfont=font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc",size=12)#创建画布fig=plt.figure()ax=fig.add_subplot(111)ax.scatter(datingDataMat[:,0],datingDataMat[:,2],15*datingLabels,datingLabels)plt.xlabel("每年的飞行里程数",fontproperties=myfont)plt.ylabel("每周消费的冰淇淋公升数",fontproperties=myfont)plt.grid(alpha=0.5)plt.show()效果展示
计算样本3和样本4之间的距离:
问题:飞行常客里程数对于计算结果的影响将远远大于其他两个特征的影响
解决方式:处理不同取值范围的特征值时,通常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。
归一化公式:newValue=oldValue/max
defautoNorm(dataSet):"""归一化数值,:paramdataSet:用户提供的每行数据信息,三列;:return:normDataSet:归一化的特征信息;maxVals:每个特征数据的最大值;"""#获取每个特征数据的最大值;maxVals=dataSet.max(0)#获取样本个数;m=dataSet.shape[0]#根据公式生成归一化的特征信息;normDataSet=dataSet/np.tile(maxVals,(m,1))returnnormDataSet,maxVals4实施kNN算法对未知类别属性的数据集中的每个点依次执行以下操作,与上一个案例代码相同:(1)计算已知类别数据集中的点与当前点之间的距离;(2)按照距离递增次序排序;(3)选取与当前点距离最小的k个点;(4)确定前k个点所在类别的出现频率;(5)返回前k个点出现频率最高的类别作为当前点的预测分类。
defdatingClassTest():"""分类器针对约会网站的测试代码,获取错误率;:return:"""hoRatio=0.10datingDataMat,datingLabels=file2matrix("data/datingTestSet2")normDataSet,maxVals=autoNorm(datingDataMat)#样本个数m=normDataSet.shape[0]#测试集个数;numTestVecs=int(m*hoRatio)errorCount=0.0foriinrange(numTestVecs):classiferResult=classify(normDataSet[i,:],normDataSet[numTestVecs:m,:],datingLabels[numTestVecs:m],3)#print(classiferResult)ifclassiferResult!=datingLabels[i]:errorCount+=1print("正确结果:",datingLabels[i])print("预测结果:",classiferResult)#print("错误个数:",errorCount)returnerrorCount