美文网首页
(二)k-邻近算法(约会网站配对效果)

(二)k-邻近算法(约会网站配对效果)

作者: 张潇_64df | 来源:发表于2018-01-09 15:32 被阅读0次
    机器学习实战.jpg

    机器学习之k-邻近算法

    本文主要根据2013年6月出版的《机器学习实战》中所讲述内容,使用python3.6实现了书中所写代码。

    • 主要有数据的文本输入处理
    • 算法的具体实现classify()方法
    • 对不同数据集进行归一化处理
    • 以及对matplotlib绘图的简单使用

    github地址:https://github.com/IBITM/Machine-Learning-in-Action


    代码实现如下
    # 手动实现knn算法
    __author__="ZhangXiao"
    # group -- array
    # labels -- list类型
    
    
    from numpy import *
    import operator
    import matplotlib
    import matplotlib.pyplot as plt
    
    
    # 创造数据集
    def createDataSet():  # labels
        group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 1.0]])
        labels = ['A', 'B', 'C', 'D']
        return group, labels
    
    
    # x是用于分类的输入向量
    def classify(x, dataSet, labels, k):
        # shape[0] 是返回第一维,也就是行数
        dataSetSize = dataSet.shape[0]  # shape方法:一个整型数字的元组,元组中的每个元素表示相应的数组每一维的长度
        diffMat = tile(x, (dataSetSize, 1)) - dataSet  # 见我简书博客的专门讲解
        sqDiffMat = diffMat ** 2
        sqDistances = sqDiffMat.sum(axis=1)  # 每一行,把所有的列的数加起来
        distances = sqDistances ** 0.5
        sortedDistances = distances.argsort()  # argsort函数返回的是数组值从小到大的索引值,并不是对数组进行排序
        classCount = {}
        # 选择距离最小的k个点
        for i in range(k):
            voteIabel = labels[sortedDistances[i]]
            classCount[voteIabel] = classCount.get(voteIabel, 0) + 1
        sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
        # 书本中所写的是classCOunt.iteritems() 这是python2.7的写法,我已经更换成python3.6的写法了
        return sortedClassCount[0][0]
    
    
    # 从文本中读取数据
    def filematrix(filename):
        fr = open(filename)
        arrayLines = fr.readlines()  # 把文件的每一行读入进来
        numberOfLines = len(arrayLines)
        returnMat = zeros((numberOfLines, 3))  # 构造一个n行3列的0数组
        classLabelVector = []
        index = 0
        for line in arrayLines:
            line = line.strip()  # 去掉所有的回车字符
            listFromLine = line.split('\t')  # 返回是一个list
            returnMat[index, :] = listFromLine[0:3]
            classLabelVector.append(int(listFromLine[-1]))  # 显示指出是int型
            index += 1
        return returnMat, classLabelVector
    
    
    # 进行数据归一化
    def autoNorm(dataSet):
        minValue = dataSet.min(0)  # axis=0; 每列的最小值
        maxValue = dataSet.max(0)
        ranges = maxValue - minValue
        normDataSet = zeros(shape(dataSet))
        m = dataSet.shape[0]
        normDataSet = dataSet - tile(minValue, (m, 1))
        normDataSet = normDataSet / tile(ranges, (m, 1))
        return normDataSet, ranges, minValue
    
    
    def datingClassTest():
        hoRatio = 0.10
        datingDataMat, datingLabels = filematrix("datingTestSet2.txt")
        normMat, ranges, minValue = autoNorm(datingDataMat)
        m = normMat.shape[0]  # 行数
        numTestVecs = int(m * hoRatio)  # 测试数量
        errorCount = 0.0
        for i in range(numTestVecs):
            classiFierResult = classify(normMat[i, :], normMat[numTestVecs:m, :], \
                                        datingLabels[numTestVecs:m], 3)
            print("分类器返回的结果为:%d, 实际的结果为:%d" \
                  % (classiFierResult, datingLabels[i]))
            if (classiFierResult != datingLabels[i]):
                errorCount += 1.0
        print("错误率为:%f" % (errorCount / float(numTestVecs)))
    
    
    def calssifyPerson():
        resultList = ["没兴趣", "稍微感兴趣", "非常感兴趣"]
        percentTats = float(input("玩视频游戏所占的时间比"))
        ffMiles = float(input("每年飞行时间历程数"))
        iceCream = float(input("每周消费的冰激凌公斤数"))
        datingDataMat, datingLabels = filematrix("datingTestSet2.txt")
        normMat, ranges, minValue = autoNorm(datingDataMat)
        inArr = array([ffMiles, percentTats, iceCream])
        classifierResult = classify((inArr - minValue) / ranges, normMat, datingLabels, 3)
        print("你对这个人的印象可能是:", resultList[classifierResult - 1])
    
    
    if __name__ == "__main__":
        # 开始数据的读入
        datingDataMat, datingLabels = filematrix("datingTestSet2.txt")
        # 进行绘图
        # fig = plt.figure() # 新建一个绘画窗口
        # ax = fig.add_subplot(111) # 设置子图的行数、列数、子图的个数
        # ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
        # plt.show()
        # datingClassTest()
        calssifyPerson()
    
    

    所用到数据和源码的下载地址:
    https://www.manning.com/MachineLearninginAction

    相关文章

      网友评论

          本文标题:(二)k-邻近算法(约会网站配对效果)

          本文链接:https://www.haomeiwen.com/subject/hfxgnxtx.html