美文网首页开发技巧首页投稿(暂停使用,暂停投稿)程序员
机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?

作者: shareLin | 来源:发表于2016-04-26 21:33 被阅读2447次
    她是不是你喜欢的类型.jpg

    通过本篇博文,你可以学习到:

    1. 环境搭建,主要为python,numpy,以及matplotlib库的搭建等;
    2. k-近邻算法;
    3. k-近邻算法实战练习,使用k-近邻算法判断某个同学是不是你喜欢的类型。

    理论与实战的结合,赶快打起精神,一起来学习吧!吼吼吼~~~

    环境搭建

    • python:开发语言,使用广泛, 简单易学
    • NumPy:科学计算库文件,它实现了大量的向量和矩阵操作,在python中我们可以像在matlab里面一样编写非常简单易读矩阵操作代码。
    • matplotlib:绘图库文件,在python中我们可以像在matlab里面一样,方便的实现绘图功能。

    python###

    1. 下载python安装文件
      https://www.python.org/downloads/ 上下载相应平台的python安装文件,本文采用的python版本为windows平台的python 2.7。下载后,点击安装,一路next。

    2. 添加环境变量
      右键“我的电脑”——属性——系统高级设置——高级——环境变量,在系统变量中找到Path,编辑此变量在后面追加 ;C:\Python27\ (python安装位置,每个人都可能不一样哦,注意前面的分号)。

    3. 如何证明python安装成功?
      打开命令提示符,输入python,能看到所安装python的版本信息即证明安装成功,如下图所示:

    python安装成功示意图.png

    numpy及matplotlib等库文件安装###

    一个一个安装比较麻烦,如果想省事儿的话,建议使用Anaconda进行安装,Anaconda针对的痛点就是一个一个安装这些库会比较麻烦,那么他就帮大家一起集成了。

    1. 下载Anaconda安装文件
      https://www.continuum.io/downloads 下载相应版本的安装文件,双击安装即可,一路next。

    2. 环境变量设置
      Anaconda安装的过程中,会自动在path下面添加相关的环境变量,所以这步跳过。

    3. 如何证明Anaconda已经安装成功?
      在cmd里面,输入conda list可以查看Anaconda已经帮大家安装的库,如下图所示。

    Anaconda安装成功示意图.png

    可以自己看下我们所需要用到的numpy及matplotlib库文件也在包含在里面。

    4.如何证明numpy及matplotlib已经安装成功?

    numpy正常使用示意图.png matplotlib正确安装示意图_代码.png 使用matplotlib画图.png

    如上图所示,就表示能够正常的使用numpy及matplotlib。

    爬过的坑###

    1. 单独下载numpy包,然后cd到相应的路径,使用python setup.py install安装numpy,报错“failed with exit status 1120”,如下图所示:
      爬过的坑1.png

    产生问题的原因及解决办法:版本原因,python版本为2.7,numpy下载的版本为1.11,后来使用Anaconda下载的匹配的版本是1.10。解决方法是使用Anaconda安装。

    2.安装完Anaconda之后,import matplotlib的时候,提示"no module named matplotlib"。

    产生问题的原因:猜想是python无法使用Anaconda安装的库。

    解决办法
    在python安装目录下的lib\site-packages下面,新建一个文件anaconda.pth,文件的内容是Anaconda安装目录下的site-packages路径。

    爬过的坑2.png

    3.import matplotlib.pyplot as plt报错“from PyQt4 import QtCore, QtGui ImportError: DLL load failed:找不到指定的程序“,如下图所示

    爬过的坑3.png

    产生问题的原因:没有安装PyQt4

    解决办法:安装PyQt4,下载链接https://riverbankcomputing.com/software/pyqt/download

    OK!到这一步为止环境就算搭建好了,下面就开始这篇文章的正题,k-近邻算法。

    k-近邻(kNN)算法概述

    • kNN算法原理

    存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似(最邻近)的分类标签。一般来说我们只选择数据集中前k个最相似的数据,这就是k-近邻算法的k的出处,通常k是不大于20的整数。最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

    上面写的太复杂了,其实很简单,就是计算距离,根据距离进行分类。举个栗子,吼吼,如下图所示,已知右上角的两个点属于A类,左下角的两个点属于B类,那么给定一个点如图中的小红点,那么他是属于A点还是B点呢?

    kNN算法给出的解决方案是,分别计算小红点与每个点的距离,然后将距离从小到大排序,取前k位,如取前2位,如果发现这2位都是B类,那么说明这个小红点也是属于B类。

    k近邻算法示例.png
    • kNN算法实现

    算法流程

    1. 计算待分类点与已知类别数据集中每个点的距离;
    2. 按照距离递增次序排序;
    3. 选取与待分类点距离最小的k个点;
    4. 确定前k个点类别出现的频率;
    5. 返回前k个点出现频率最高的类别作为当前点的预测分类。

    python代码实现

    from numpy import *
    
    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]
    

    四不四很简单?吼吼吼~~~

    使用k-近邻算法快速判定她是不是你喜欢的类型?

    1. 问题描述
      比如你的朋友经常上约会网站寻找自己的约会对象,你的朋友选定约会对象的时候主要看重三点“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”,你阅人无数的朋友已经约会过很多个对象了,并且把这些对象分为三类“她是我喜欢的类型”、“一般喜欢”,“她不是我喜欢的类型”,经过无数次的约会之后,你的朋友心已经很累了,他想能否输入某人的“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”这三项数据,就能判断她是不是他喜欢的类型呢?

    2. 已有资源
      为了简化问题,我们假设你的朋友,已经整理了一份数据,如下图所示:

      数据.png
      其中前三列分别表示“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”,第四列表示分类。其中“1”表示“她不是我喜欢的类型”、“2”表示“一般喜欢”,“3”表示“她是我喜欢的类型”。
    3. 如何使用kNN算法?
      在前一篇博文机器学习实战入门篇之一:机器学习中必会的基础概念!中,我们介绍了使用机器学习算法解决问题的一般步骤,我们再一次回顾一遍流程图。

    开发机器学习应用程序步骤.png

    下面我们将一步一步来完成。

    • 收集数据
      为简单起见,已经提供txt文本数据。

    • 数据预处理
      数据预处理中,我们得将txt文本中提供的数据放到矩阵或矢量中进行存储,然后还需要将数据进行归一化。
      (1) 把txt文本中的数据转换成矩阵或矢量进行存储

    #函数名:file2matrix
    #输入:文件名
    #输出:returnMat为txt文本数据的前三列构成的二维数组
     #     classLabelVector为txt文本数据第四列的分类信息的一维矢量
    def file2matrix(filename):
        fr = open(filename)
        numberOfLines = len(fr.readlines())         #get the number of lines in the file
        returnMat = zeros((numberOfLines,3))        #prepare matrix to return
        classLabelVector = []                       #prepare labels return   
        fr = open(filename)
        index = 0
        for line in fr.readlines():
            line = line.strip()
            listFromLine = line.split('\t')
            returnMat[index,:] = listFromLine[0:3]
            classLabelVector.append(int(listFromLine[-1]))
            index += 1
        return returnMat,classLabelVector
    

    (2) 数据归一化
    为什么要进行数据归一化?分析下数据可以看出,飞行距离相对于其他两个特征的数据来说通常要大的多,如果不进行数据归一化,那么在计算距离的时候飞行距离对结果的影响占绝对主导性,这显然是不合理的,所以需要进行数据归一化,归一化的python代码如下所示:

    #函数名:autoNorm
    #输入:dataSet为原始数据二维数组
    #输出:normDataSet归一化之后的二维数组,ranges为每一列最大值减去最小值的范围,minVals为每一列的最小值。
    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))   #element wise divide
        return normDataSet, ranges, minVals
    
    • 分析输入数据
      可以将数据用二维散点图画出来,直观感受一下。

    • 训练算法
      此步骤不适用于kNN算法

    • 测试算法
      通常来说,我们使用数据的90%作为训练数据,10%的数据作为测试数据。测试的指标为出错率,当预测的分类和实际的分类结果不一致时,记录一个错误,错误的总数/测试的样本数即为出错率。
      python代码:

    #函数名:datingClassTest
    #输入:无
    #输出:无,但是会打印出错个数及错误率。
    def datingClassTest():
        hoRatio = 0.50      #hold out 10%
        datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #load data setfrom file
        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
    

    运行结果:


    测试程序运行结果.png

    可以看出,错误率为6.4%,大家可以改变参数值k,观察下出错率的变化。

    • 应用算法
      测试出错率达到满意结果之后,我们就可以拿来用了,应用程序如下:
    def classifyPerson():
        resultList = ['not like','so so','very like']
        gamePercent = float(raw_input("gaming time percent:"))
        flyMiles = float(raw_input("flying miles per year:"))
        bookNum = float(raw_input("reading books per month:"))
        datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")
        normMat, ranges, minVals = autoNorm(datingDataMat)
        inArray = array([flyMiles, gamePercent, bookNum])
        classifyResult = classify0((inArray - minVals)/ranges, normMat, datingLabels, 3)
        print "prediction result is: ", resultList[classifyResult - 1]
    

    运行结果:


    运行结果.png

    可以看出,具有这些特征数据的她对你吸引力一般般啦,你可以自己测试看看,看到底什么样的她才是你喜欢的类型呢?

    kNN算法总结

    • 优点:简单有效
    • 缺点:经过前面的介绍可以看出,kNN算法必须保存全部的数据集,如果训练数据集很大,那么就需要耗费大量的存储空间。此外,由于必须对待分类数据计算与每一个训练数据的距离,非常耗时。

    终于写好了,码字好累,欢迎志同道合的朋友留言交流,有什么写的不对的地方敬请指出!

    相关文章

      网友评论

      • simpower:你好,你用的hoRatio值是0.5, 我用的是0.1和书上一样, 为什么我的错误率是5%, 书上是2.4%, 如果数据和数据划分是一样的话,结果应该是一样的,:pray:
      • lingo_xp:我觉得“安装完Anaconda之后,import matplotlib的时候,提示"no module named matplotlib”可能的原因是在电脑上装了多个版本的python,ide使用的python可能和默认的不是同一个,注意下库的安装路径和ide的python版本选择
      • 猪猪奋斗记:在安装的时候我觉得可能用PIP会更加方便
        猪猪奋斗记:@shareLin 我记得PIP似乎是会帮你把依赖都给装下来,版本匹配似乎也会考虑到,好吧这些都是细节:smile:
        shareLin:@bigbigship 我用pip安装了numpy是比较方便的,但是matplotlib需要很多依赖库,比较麻烦。
      • Joy___:学习下
      • lvjing2:喔 写的好用心啊 很容易就看懂了 赞
        shareLin:@lvjing2 谢谢亲的表扬,吼吼,写了这么多都感觉不累了呢! :blush:

      本文标题:机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?

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