机器学习实战——KNN算法改进约会网站配对效果

背景:

        将约会网站的人分为三种类型:不喜欢的,魅力一般的,极具魅力的,分别用数字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])

运行结果:


总而言之感觉这个算法好神奇的样子,但是原理又并不是很难理解。

猜你喜欢

转载自blog.csdn.net/qq_36718317/article/details/80430758