码迷,mamicode.com
首页 > 其他好文 > 详细

机器学习-KNN分类器

时间:2017-10-05 00:22:40      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:else   ges   分类器   set   相加   lis   ext   存在   rest   

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

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

 

2.  KNN算法过程

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

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

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

 

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

(1)   欧氏距离

可称为L2范数:

技术分享

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

技术分享


 

又称欧式距离。

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

技术分享

 

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

 

(2)   夹角余弦

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

技术分享


 

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

 

4.   一个简单的例子

      Python代码示例:

# coding: utf-8

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  # 输入分类之后所属的标签

 

执行结果:

技术分享

 

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

机器学习-KNN分类器

标签:else   ges   分类器   set   相加   lis   ext   存在   rest   

原文地址:http://www.cnblogs.com/tan-v/p/7628079.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!