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

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第1张图片
她是不是你喜欢的类型.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的版本信息即证明安装成功,如下图所示:

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第2张图片
python安装成功示意图.png

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

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

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

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

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

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第3张图片
Anaconda安装成功示意图.png

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

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

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第4张图片
numpy正常使用示意图.png
机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第5张图片
matplotlib正确安装示意图_代码.png
机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第6张图片
使用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路径。

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第7张图片
爬过的坑2.png

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

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第8张图片
爬过的坑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类。

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第9张图片
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. 已有资源
    为了简化问题,我们假设你的朋友,已经整理了一份数据,如下图所示:

    机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第10张图片
    数据.png

    其中前三列分别表示“每年飞行的旅程数”、“玩游戏所耗时间百分比”、“每个月看书的数目”,第四列表示分类。其中“1”表示“她不是我喜欢的类型”、“2”表示“一般喜欢”,“3”表示“她是我喜欢的类型”。

  3. 如何使用kNN算法?
    在前一篇博文机器学习实战入门篇之一:机器学习中必会的基础概念!中,我们介绍了使用机器学习算法解决问题的一般步骤,我们再一次回顾一遍流程图。

机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第11张图片
开发机器学习应用程序步骤.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

运行结果:


机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第12张图片
测试程序运行结果.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]

运行结果:


机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?_第13张图片
运行结果.png

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

kNN算法总结

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

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

你可能感兴趣的:(机器学习实战入门篇之二:kNN算法 | 她是不是你喜欢的类型?)