zoukankan      html  css  js  c++  java
  • (原创)机器学习-KNN分类器

    K-近邻(k-Nearest NeighborsKNN)的原理

      通过测量不同特征值之间的距离来衡量相似度的方法进行分类。

     

     KNN算法过程

    训练样本集:样本集中每个特征值都已经做好类别标签;

    测试样本:  测试样本中每个特征值都没有类别标签;

    算法过程:  计算测试样本中特征值与训练样本集中的每个特征值之间的距离,提取与训练样本集中的特征值距离最近的前K个样本,然后选取出现次数最多的类别标签,作为测试样本的类别标签。

     

    度量特征值之间距离的方法

    (1)   欧氏距离

    可称为L2范数:

    clip_image002

    其中p=2,则特征向量a=(a1,a2,…,am)和特征向量b=( b1,b2,…,bm)之间的距离为

    clip_image004


     

    又称欧式距离。

    例如二维平面上的两点a(x1, y1)b(x2, y2)之间的欧式距离:

    clip_image006

     

    d值越小,表明特征值之间距离越小,两个特征越相似。

     

    (2)   夹角余弦

    特征向量a=(a1,a2,…,am)和特征向量b=( b1,b2,…,bm)之间的夹角余弦为:

    clip_image008


     

    cos值越大,表明特征值之间距离越小,两个特征越相似。

     

    一个简单的例子

          Python代码示例:

    # coding: utf-8
    # 作者:tany  博客:http://www.cnblogs.com/tan-v/
    from numpy import * import operator import matplotlib.pyplot as plt def createDataSet(): # 生成训练集 group = array([[1.0, 1.1], [0.9, 1.3], [ 0, 0.1], [0.1, 0.2]]) labels = ['A', 'A', 'B', 'B'] return group, labels def showDataSet(dataSet, labels): # 显示训练集 fig = plt.figure() ax = fig.add_subplot(111) index = 0 for point in dataSet: if labels[index] == 'A': ax.scatter(point[0], point[1], c='blue') ax.annotate("A", xy = (point[0], point[1])) else: ax.scatter(point[0], point[1], c='red') ax.annotate("B", xy = (point[0], point[1])) index += 1 plt.show() def eulerDist(inXmat, dataSet): # 使用欧式距离 diffMat = inXmat - dataSet # 输入向量分别与样本中其他的向量之差 sqDiffMat = diffMat**2 # 差值求平方 sqDistances = sqDiffMat.sum(axis=1) # axis=1将一个矩阵的每一行向量相加, 将差值相加 dist = sqDistances**0.5 # 开方 return dist def cosDist(inXmat, dataSet): # 使用夹角余弦 m = shape(inXmat)[0] dist = zeros((m)) # 与训练集中每一个特征求距离 for i in range(m): cos = dot(inXmat[i,:], dataSet[i,:])/(linalg.norm(inXmat[i,:])*linalg.norm(dataSet[i,:])) # 求余弦值 dist[i] = cos return dist def KNNclassify(inX, dataSet, labels, k): dataSetSize = dataSet.shape[0] # 行数 inXmat = tile(inX, (dataSetSize, 1)) # tile(A,reps)若reps为一个元组(m,n),则构造一个m行n列的数组,其中每个元素均为A, # 目的是求inX分别与其他dataSet的数据间的距离 distance = eulerDist(inXmat, dataSet) # 使用欧式距离度量向量间距离 sortedDistIndicies = distance.argsort() # 对一个数组进行升序排列,结果返回的就是a中所有元素排序后各个元素在a中之前的下标 #distance = cosDist(inXmat, dataSet) # 使用夹角余弦度量向量间距离 #sortedDistIndicies = argsort(-distance) # 降序排列 classcount = {} # 字典 for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] classcount[voteIlabel] = classcount.get(voteIlabel,0) + 1 # dict.get(key, default=None) key:字典中要查找的键。 # default -- 如果指定键的值不存在时,返回该默认值。 # classcount.iteritems()返回一个迭代器。返回一个可以调用的对象(可以从操作对象中提取item) # operator.itemgetter函数获取的不是值,而是定义了一个函数。获取对象的第1个域的值在这里使用字典中的值进行从小到大进行排序 # sorted(iterable, cmp, key, reverse),iterable指定要排序的list或者iterable, # cmp为函数,指定排序时进行比较的函数,可以指定一个函数或者lambda函数 # key为函数,指定取待排序元素的哪一项进行排序 # reverse默认为false(升序排列),定义为True时将按降序排列。 sortedClassCount = sorted(classcount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] dataSet, labels = createDataSet(); # 生成训练集 showDataSet(dataSet,labels) # 显示训练集 inX = array([1, 1]) # 输入一个测试样本 classLabel = KNNclassify(inX, dataSet, labels, 3) # 使用KNN进行分类 print classLabel # 输入分类之后所属的标签

     

    执行结果:

    image

     

                   -tany 2017年10月4日 中秋 于杭州

     

     

    人工智能从入门到专家教程资料:https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.38270209gU11fS&id=562189023765

     

  • 相关阅读:
    phalcon之视图缓存
    Java NIO框架Netty教程(一) – Hello Netty
    setsockopt的作用
    支持向量机通俗导论(理解SVM的三层境地)
    quartz中的corn表达式(转)
    Applet 数字签名技术全然攻略
    SJTU 3001. 二哥的幸运
    OGRE之跳出漫长的编译等待
    VB.NET 数组的定义 动态使用 多维数组
    【Python】用Python的“结巴”模块进行分词
  • 原文地址:https://www.cnblogs.com/tan-v/p/7628079.html
Copyright © 2011-2022 走看看