算法1:k-近邻

1.k-近邻算法概述

  简单地说,k-近邻算法采用测量不同特征值之间的距离方法进行分类,属于监督学习。

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

  • 优点:精度高、对异常值不敏感,无数据输入假定;
  • 缺点:时间和空间复杂度都高;

算法的一半流程:

  1. 收集数据:想怎么收集就怎么收集啦;
  2. 准备数据:最好是结构化数据格式;
  3. 分析数据:散点图啦等等,随意分析;
  4. 训练算法:本算法不需要这一步;
  5. 测试算法:计算错误率;
  6. 使用算法:准备输入的样本数据,调用算法计算分类结果等;

2.Python实现

  核心代码:

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]

 

  解析

  1. 4个输入参数:用于分类的输入向量inX,训练样本集dataSet,标签向量labels,用于选择最近邻的数目k;
  2. dataSetSize = dataSet.shape[0] 这一句使用到了NumPy的shape函数,返回矩阵/数组的不同维数的长度,第一个元素(shape[0])表示第一维的长度,亦即行数,可参考numpy.shape
  3. diffMat = tile(inX, (dataSetSize,1)) - dataSet 这里用到了NumPy中的tile(A,reps)函数,用于扩充A,具体用法可以参考numpy.tile
  4. sqDiffMat = diffMat**2 求平方;
  5. sqDistances = sqDiffMat.sum(axis=1) 求和可参考numpy.sum
  6. distances = sqDistances**0.5 求开方,上面的几步是用来计算距离的;
  7. sortedDistIndicies = distances.argsort()使用了argsort()函数,可以参考:numpy.argsort
  8. classCount={} 这是一个dict,用于存储不同标签出现的次数;
  9. for i in range(k):
      voteIlabel = labels[sortedDistIndicies[i]]
      classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    这里是选择距离最小的k个点, sortedDistIndicies已经排好序,只需迭代的取前k个样本点的labels(即标签),并计算该标签出现的次数,这里还用到了dict.get(key, default=None)函数,key就是dict中的键voteIlabel,如果不存在则返回一个0并存入dict,如果存在则读取当前值并+1;
  10. sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) 这里使用了sorted()函数sorted(iterable, cmp=None, key=None, reverse=False),iteritems()将dict分解为元组列表,operator.itemgetter(1)表示按照第二个元素的次序对元组进行排序,注意sort()的区别,可参考numpy.sort

 

posted @ 2015-08-09 17:45  vrfighters  阅读(1959)  评论(0)    收藏  举报