yywx001 发表于 2017-5-8 10:59:11

简单的相亲推荐应用——Python以及机器学习中K-邻近算法的应用

  好吧,已经3个月没碰博客了,今天打开发现里面已经积了一层灰了……今天重启博客是因为最近接触了一个新的领域,机器学习,而要实现机器学习又要使用Python语言,所以同时接触这两大块的新知识,不免会有些吃力,特别是要做出来一个应用(即使很简单),虽然做的时候里面的语句通过各种途径搞明白了,但是还是有些生疏,所以就先在这里记下,后面忘记了可以再回来看看。
  另外,预告一下下一篇博客的内容:手写识别的实现,也是使用与本次应用一样的K-邻近算法。
  我们先说一下里面的一些概念
  训练数据:就是一开始就准备的那些从记录里扒下来的男生的数据,专门用来训练这个程序的,训练的数据越多,程序预测的就越精确
  K-邻近算法:顾名思义,邻近,就是找最近的数据,至于K呢,就是要找K个最近的数据,怎么找呢,就是利用我们初中就会用的距离公式,已知两点或三点或…点的各轴坐标,求这两点间距离,这样计算待测数据和每一个训练数据之间的距离,就能找到距离最近的K个训练数据,这K个训练数据的结果就是带预测的数据被预测出的结果,看,是不是很简单呢~
  我们还需要理清这个应用的思路:
  应用很简单,通过分析一菇凉在相亲网站上的记录,得到她喜欢的和不喜欢的男生的属性数据,在这里我们使用的是三个属性:薪水、平时玩游戏的时间、每年吃多少冰激凌(这个有点无厘头的感觉……),得到足够多的数据后分析这些属性和对男生的好感度之间的关系,这样我们就可以按照这个菇凉的喜好来给他推荐相亲对象了~
  步骤如下:
  1、得到三个属性的值以及喜好程度(1代表不喜欢、2代表待考虑、3代表喜欢)的数据集
  2、将所有的数据导入到一个矩阵中便于计算
  3、将数据归一化,这是机器学习中常用的一种处理数据的方法,让数据变得易于处理
  4、测试,把训练数据中的一部分当做测试数据进行测试,看准确率是否达到预期效果
  5、利用K-邻近算法计算输入的数据与训练数据之间的举例,将之分到距离最近的一类当中
  6、大功告成~
  下面就是吧上面的步骤一一实现了,代码的解释都写在了后面的注释行里了
  1、数据
  已有现成数据(已传到附件中,如需要可以下载直接使用),其中一部分如下图所示
  

  
 第一列为半年的薪水,第二列为,游戏时间占所有时间的百分比,第三列为每年吃多少升(= =||)冰激凌
  第四列为喜好程度
  2,、导入数据
  代码如下:

def change(filename):                # 从文件中读取数据的方法
fl=open(filename)                   #打开文件
fllines=fl.readlines()
linenumber=len(fllines)         #计算文本行数
Mat=zeros((linenumber,3))   #创建矩阵Mat
labelVector=[]                         #创建空白向量
index=0
for line in fllines:                      #循环直到line等于fllines
line=line.strip()                  #除去数字间的空白格
lst=line.split('\t')                  
Mat=lst         #给矩阵Mat的第index行赋值
labelVector.append(int(lst[-1]))#把数据集的最后一列加到labelVector
index +=1
return Mat,labelVector
  3、归一化

def autoNorm(dataSet):         #归一化的方法、
maxV=dataSet.max(0)      #求最大值
minV=dataSet.min(0)         #最小值   
ranges=maxV-minV            #范围
normDataSet=zeros(shape(dataSet))#创建矩阵   
m=dataSet.shape          #数据大小
normDataSet=dataSet-tile(minV,)   #new=(old-min)/(max-min)
normDataSet=normDataSet/tile(ranges,)
return normDataSet,ranges,minV
  4、测试

def datingTest():
tst=0.01   #设置测试数据占总数据的百分比
datingMat,datingLabels=change('datingTestSet2.txt') #赋值并调用change函数,见上面的数据导入
normData,ranges,minV=autoNorm(datingMat) #赋值并调用autoNorm函数,见上面的归一化
m=datingMat.shape#计算datingMat的大小
tstnum=int(m*tst)    #计算测试数据的数量
errorCount=0.0      
for i in range (tstnum):      #循环,直到i=tstnum         tstresult=classify0(normData,normData,datingLabels,3)   #调用距离计算函数,见下面计算距离并分类      
print"the result I give is : %d,the real result is : %d" %(tstresult,datingLabels)    #输出预测值与实际值
if (tstresult!=datingLabels):errorCount+=1.0
print"the error rate is %f"%(errorCount/float(tstnum)) #计算并输出错误率

  进行测试所需操作:
  在python命令行中输入:
  程序名.datingTest(),例如程序名字为KNN,那么就输入KNN.datingTest()
  5、计算距离并分类

def classify0(inX,DataSet,labels,k):
DataSize=DataSet.shape                           #得到训练数据的长度
DiffDataSet=tile(inX,(DataSize,1))-DataSet            #将输入数据与训练数据各项相减
sqDiffDataSet=DiffDataSet**2                        #各项平方
sqDistance=sqDiffDataSet.sum(axis=1)                  #各项平方后相加
Distance=sqDistance**0.5                              #开方
sortedDistance=Distance.argsort()                     #将距离数据按升序排序
classCount={}                                       #新建字典
for i in range(k):                                    #循环,从0到k
sortedLabel=labels]             #将排好序的距离数据按顺序赋给sortedLabel
classCount=classCount.get(sortedLabel,0)+1      #加入字典
sortedclassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)    #将字典排序输出
return sortedclassCount                                             
  6、将代码总体展示如下

from numpy import *
import operator
def classify0(inX,DataSet,labels,k):
DataSize=DataSet.shape                           #得到训练数据的长度
DiffDataSet=tile(inX,(DataSize,1))-DataSet          #将输入数据与训练数据各项相减
sqDiffDataSet=DiffDataSet**2                        #各项平方
sqDistance=sqDiffDataSet.sum(axis=1)                #各项平方后相加
Distance=sqDistance**0.5                            #开方
sortedDistance=Distance.argsort()                   #将距离数据按升序排序
classCount={}                                       #新建字典
for i in range(k):                                  #循环,从0到k
sortedLabel=labels]         #将排好序的距离数据按顺序赋给sortedLabel
classCount=classCount.get(sortedLabel,0)+1   #加入字典
sortedclassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)   #将字典排序输出
return sortedclassCount                                             

def change(filename):         # 从文件中读取数据的方法
fl=open(filename)   #打开文件
fllines=fl.readlines()
linenumber=len(fllines)#计算文本行数
Mat=zeros((linenumber,3))   #创建矩阵
labelVector=[]   #创建空白向量
index=0
for line in fllines:
line=line.strip()
lst=line.split('\t')
Mat=lst
labelVector.append(int(lst[-1]))
index +=1
return Mat,labelVector
def autoNorm(dataSet):         #归一化的方法、
maxV=dataSet.max(0)      #求最大值
minV=dataSet.min(0)         #最小值   
ranges=maxV-minV            #范围
normDataSet=zeros(shape(dataSet))#创建矩阵   
m=dataSet.shape          #数据大小
normDataSet=dataSet-tile(minV,)      #new=(old-min)/(max-min)
normDataSet=normDataSet/tile(ranges,)
return normDataSet,ranges,minV

def datingTest():
tst=0.01
datingMat,datingLabels=change('datingTestSet2.txt')
normData,ranges,minV=autoNorm(datingMat)
m=datingMat.shape
tstnum=int(m*tst)
errorCount=0.0
for i in range (tstnum):
tstresult=classify0(normData,normData,datingLabels,3)
print"the result I give is : %d,the real result is : %d" %(tstresult,datingLabels)
if (tstresult!=datingLabels):errorCount+=1.0
print"the error rate is %f"%(errorCount/float(tstnum))

def Predict():
Preresult=("I'll never date with him",'Maybe I should know more about him','Please marry me!!!')
Salary=float(raw_input('How much money do you earn per half year?'))
Game=float(raw_input('How manny percent time do you spend on playing computer games?'))
iceCream=float(raw_input("How many liters(0~2) iceCream do you consumed per year?"))
datingMat,datingLabels=change('datingTestSet2.txt')
normMat,ranges,minV=autoNorm(datingMat)
resultArray=()
Result=classify0((resultArray-minV)/ranges,normMat,datingLabels,3)
print"Her opinion about this man :",Preresult

  好啦,大功告成啦,下面就是演示我们成果的时候了~见图片:
  在命令行输入程序名.Predict(),例如KNN.Predict(),之后按照他提示的输入内容就好啦~
  第一种结果:

  
 第二种结果:

   
  我就不再贴其他的结果了,大家有兴趣的话可以自己来搞,如果给加上界面就更好了~
页: [1]
查看完整版本: 简单的相亲推荐应用——Python以及机器学习中K-邻近算法的应用