kNN之改进约会网站配对效果(附源码)

时间:2022-05-07
本文章向大家介绍kNN之改进约会网站配对效果(附源码),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

kNN实战之改进约会网站配对效果

本篇文章紧接上一篇(),在()中我们首先简单的介绍了一下KNN算法的基本原理,然后以约会网站的配对为实战背景,使用python编程实现了从文本文件中解析数据,并使用matplotlib创建散点图实现数据的分析。本文我们将在此基础上构建完整可用的匹配系统(文末附有本例程中所使用的数据以及python的实现代码)

3. 准备数据:归一化

在本实例中,样本中的每年获取的飞行里程数属性对于计算结果的影响远远大于其他两个属性(玩游戏所占的时间比以及每周消耗的冰激凌公斤数)的影响。产生这种原因的唯一原因是因为个属性之间的数量级不同所致。在同样考虑三个属性重要程度的情况下,每年获得的飞行里程数不应该如此严重的影响计算结果。

在处理这种不同取值范围的属性时,归一化是我们最常用的方法,如将取值范围压缩/扩展至[0, 1]或者[-1, 1]。下面的公式可以讲任意取值范围的属性值转化为[0, 1] :

newValue = (oldValue-Min)/(Max - Min)

其中,Min和Max分别为数据集中最小属性值以及最大属性值。虽然改变数值的范围一定程度上增加了算法的时空复杂度,但是为了更好地利用数据间的信息,这么做是必须的。为此,我们新建一个名为autoNorm的函数,该函数将属性值压缩至[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

在python命令行下,加载kNN.py模块,执行autoNorm函数,如下所示。

这儿我们可以只把normMat作为函数返回值。

4. 测试算法

本文中我们采用数据集的10%作为测试数据集,90%作为训练数据集(注意:训练数据集以及测试数据集的产生应该随机选取)。

创建名为classify0的函数作为kNN分类器,代码如下。

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()     
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.iteritems(),     key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

为了测试分类器的效果,我们需要创建名为datingClassTest的函数,代码如下。

def datingClassTest():
    hoRatio = 0.50      #hold out 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):
        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

本函数总使用了之前定义的函数,file2matrix函数将从文本文件中解析数据,autoNorm将读进内存的数据进行归一化。在python命令行中输入以下代码,如下所示。

如图所示,处理约会数据集的错误率为6.4%,这是一个相当不错的结果。我们可以调试datingClassTest中的变量hoR安提哦你和变量k的值来降低错误率。为此,二丫完全可以输入未知对象的属性信息,有分类软件帮助她判定该队形属于哪一类(讨厌,一般喜欢以及非常喜欢)。

5. 使用算法:构建完整可用系统

实现的代码如下。

def classifyPerson():
    resultList = ['not at all', 'in small does', 'in large does']
    percentTats = float(raw_input("percentage of time spend playing video games?"))
    ffMiles = float(raw_input("frequent filter miles earns per years?"))
    iceCream = float(raw_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]

在python命令行下输入下图所示。

至此,我们就完成了kNN在约会网站配对率改善的应用。

本文中使用的数据集以及完整的python实现代码请点解百度云链接:http://pan.baidu.com/s/1boPnSBH