python机器学习理论与实战(一)K近邻法

yipeiwu_com7年前Python基础

机器学习分两大类,有监督学习(supervised learning)和无监督学习(unsupervised learning)。有监督学习又可分两类:分类(classification.)和回归(regression),分类的任务就是把一个样本划为某个已知类别,每个样本的类别信息在训练时需要给定,比如人脸识别、行为识别、目标检测等都属于分类。回归的任务则是预测一个数值,比如给定房屋市场的数据(面积,位置等样本信息)来预测房价走势。而无监督学习也可以成两类:聚类(clustering)和密度估计(density estimation),聚类则是把一堆数据聚成弱干组,没有类别信息;密度估计则是估计一堆数据的统计参数信息来描述数据,比如深度学习的RBM。

根据机器学习实战讲解顺序,先学习K近邻法(K Nearest Neighbors-KNN)

K近邻法是有监督学习方法,原理很简单,假设我们有一堆分好类的样本数据,分好类表示每个样本都一个对应的已知类标签,当来一个测试样本要我们判断它的类别是,就分别计算到每个样本的距离,然后选取离测试样本最近的前K个样本的标签累计投票,得票数最多的那个标签就为测试样本的标签。

例子(电影分类):

(图一)

(图一)中横坐标表示一部电影中的打斗统计个数,纵坐标表示接吻次数。我们要对(图一)中的问号这部电影进行分类,其他几部电影的统计数据和类别如(图二)所示:

(图二)

从(图二)中可以看出有三部电影的类别是Romance,有三部电影的类别是Action,那如何判断问号表示的这部电影的类别?根据KNN原理,我们需要在(图一)所示的坐标系中计算问号到所有其他电影之间的距离。计算出的欧式距离如(图三)所示:

(图三)

     由于我们的标签只有两类,那假设我们选K=6/2=3,由于前三个距离最近的电影都是Romance,那么问号表示的电影被判定为Romance。

代码实战(Python版本):

先来看看KNN的实现:

from numpy import * 
import operator 
from os import listdir 
 
 
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]]  #前K个距离最近的投票统计 
    classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #前K个距离最近的投票统计 
  sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #对投票统计进行排序 
  return sortedClassCount[0][0]  #返回最高投票的类别 

下面取一些样本测试KNN:

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

上面的代码中第一个函数从文本文件中读取样本数据,第二个函数把样本归一化,归一化的好处就是降低样本不同特征之间数值量级对距离计算的显著性影响

datingClassTest则是对KNN测试,留了一半数据进行测试,文本文件中的每条数据都有标签,这样可以计算错误率,运行的错误率为:the total error rate is: 0.064000

总结:

优点:高精度,对离群点不敏感,对数据不需要假设模型

缺点:判定时计算量太大,需要大量的内存

工作方式:数值或者类别

下面挑选一步样本数据发出来:

参考文献:machine learning in action

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

Python 获取 datax 执行结果保存到数据库的方法

执行 datax 作业,创建执行文件,在 crontab 中每天1点(下面有关系)执行: 其中 job_start 及 job_finish 这两行记录是自己添加的,为了方便识别出哪张表...

使用k8s部署Django项目的方法步骤

接触了一下docker和k8s,感觉是非常不错的东西。能够方便的部署线上环境,而且还能够更好的利用机器的资源,感觉是以后的大趋势。最近刚好有一个基于django的项目,所以就把这个项目打...

浅谈python中的实例方法、类方法和静态方法

在学习python代码时,看到有的类的方法中第一参数是cls,有的是self,经过了解得知,python并没有对类中方法的第一个参数名字做限制,可以是self,也可以是cls,不过根据人...

python+opencv实现动态物体识别

python+opencv实现动态物体识别

注意:这种方法十分受光线变化影响 自己在家拿着手机瞎晃的成果图: 源代码: # -*- coding: utf-8 -*- """ Created on Wed Sep 2...

python使用matplotlib模块绘制多条折线图、散点图

python使用matplotlib模块绘制多条折线图、散点图

今天想直观的展示一下数据就用到了matplotlib模块,之前都是一张图只有一条曲线,现在想同一个图片上绘制多条曲线来对比,实现很简单,具体如下: #!usr/bin/env pyt...