python起步之knn分类算法(三)

一、knn分类器简介

    在模式识别领域中,最近邻居法KNN算法,又译K-近邻算法)是将在特征空间中最接近的训练样本进行分类的方法。【维基百科

    算法步骤:

    1.第一步:求待测点到已知类别的数据集的距离  

    2.第二步:对距离进行排序(从小到大) 

    3.第三步:选择前面k个距离对应的点

    4.第四步:统计各个类别的频数(频率)

    5.第五步:将出现频率(频率)最大的类别作为测试点的类别。

    需要注意的是:K的选择很关键

二、算法实现

 python版本1(有详细的中文注释)

#coding:utf-8
import kNN1
from numpy import *

#dataSet, labels = kNN1.createDataSet()
#创建一个矩阵,每一行代表一个样本,这里有4个样本
dataSet = array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])
#创建类别标签,有2类,4个样本

labels = ['1', '1', '0', '0']
testX = array([1.2, 1.0])
newInput = testX
k = 3

print 'labels:',labels     #1xM: 1x4
print 'dataSet:',dataSet    #MxN: 4x2
print 'newInput',newInput      #1xN: 1x2

print "###############"

##step 1 计算待测试的样本到所有已标记的样本的欧式距离
#样本个数
numSamples = dataSet.shape[0]
print 'numSamples:',numSamples
#将newInput向量构造出(重复numSamples次),然后和已标记样本作差
diff = tile(newInput, (numSamples, 1)) - dataSet #diff: 4x1
print 'diff:',diff
#对每个元素进行平方操作
squaredDiff = diff ** 2
print 'squaredDiff:',squaredDiff
#对每行进行求和操作
squaredDist = sum(squaredDiff, axis = 1)
print 'squaredDist:',squaredDist
#得到待测样本到所有已标记的样本的距离,构成了一个数组
distance = squaredDist ** 0.5
print 'distance:',distance

##step 2 对距离进行从小到大排序得到他们的索引序列
sortedDistIndices = argsort(distance)
print 'sortedDistIndices:',sortedDistIndices

##step 3,step 4 选出距离待测点最近的k个点,并统计每类别出现的次数
#定义了一个字典类型
classCount = {}
for i in xrange(k):
    #step 3 选择距离待测点最近的k个点
    voteLabel = labels[sortedDistIndices[i]]
    print 'voteLabel',voteLabel
    #统计每类别出现的次数,这里是存放到了字典中
    classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
    print classCount

##step 5 找出类别中统计数最大的那个类别,为待测样本的类别
maxCount = 0
for key, value in classCount.items():
    if value > maxCount:
        maxCount = value
        maxIndex = key
#得到待测样本的类别    
predictLable = maxIndex
print 'predictLable:',predictLable
        




#outputLabel = kNN1.kNNClassify(testX, dataSet, labels, k)
#print outputLabel

结果

>>> 
labels: ['1', '1', '0', '0']
dataSet: [[ 1.   0.9]
 [ 1.   1. ]
 [ 0.1  0.2]
 [ 0.   0.1]]
newInput [ 1.2  1. ]
###############
numSamples: 4
diff: [[ 0.2  0.1]
 [ 0.2  0. ]
 [ 1.1  0.8]
 [ 1.2  0.9]]
squaredDiff: [[ 0.04  0.01]
 [ 0.04  0.  ]
 [ 1.21  0.64]
 [ 1.44  0.81]]
squaredDist: [ 0.05  0.04  1.85  2.25]
distance: [ 0.2236068   0.2         1.36014705  1.5       ]
sortedDistIndices: [1 0 2 3]
voteLabel 1
{'1': 1}
voteLabel 1
{'1': 2}
voteLabel 0
{'1': 2, '0': 1}
predictLable: 1
>>> 


 python版本2[3]

   kNN.py

#coding:utf-8
from numpy import *
import operator

# 创建一个包含4个样本,2类的数据集
def createDataSet():
    #创建一个矩阵:每一行作为一个样本,这里有4个样本,每个样本2个属性
    group = array([[1.0, 0.9], [1.0, 1.0], [0.1, 0.2], [0.0, 0.1]])
    #标签:4个样本和2类
    labels = ['1', '1', '0', '0']
    return group, labels

# 定义一个KNN分类器函数
def kNNClassify(newInput, dataSet, labels, k):
    #样本的个数
    numSamples = dataSet.shape[0] #numSamples = 4
    ###step 1 求待测样本到已知类别所有样本的距离
    #tile(A, reps): 表示通过复制A,reps次,来创建一个数组,这里是4x1
    #然后将其与已经类别的样本数据集做差
    diff = tile(newInput, (numSamples, 1)) - dataSet #newInput:1xN,dataSet:NxM
    #对矩阵中的每个元素平方
    squaredDiff = diff ** 2
    #将矩阵的每一行加起来
    squaredDist = sum(squaredDiff, axis = 1)
    #得到待测样本到已知类别的所有样本的距离,这里是一个向量,1x4
    distance = squaredDist ** 0.5

    ###step 2 对所得到的距离向量进行从小到大排序,得到对应元素的索引
    sortedDistIndices = argsort(distance)
    #定义一个字典类型
    classCount = {}
    ###step 3,4 选出距离待测点最近的k个点,并统计每个类别的出现次数
    for i in xrange(k):
        ##step 3 选出距离待测点最近的k个点
        voteLabel = labels[sortedDistIndices[i]]    
        ##step 4 统计每个类别出现的次数
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 


    ### step 5 将出现次数最大的类别作为待测样本的类别,这里是选出最大的那个值,并记录它的类别
    maxCount = 0
    for key, value in classCount.items():
        if value > maxCount:
            maxCount = value
            maxIndex = key
            
    #返回待测样本的预测值(类别)
    return maxIndex

            
    
    

结果

>>> 
Your input is: [ 1.2  1. ] and classified to class:  1
Your input is: [ 0.1  0.3] and classified to class:  0
>>> 

参考

[1]KNN分类器

[2]Machine Learning in Action

[3]机器学习算法与Python实践之(一)k近邻(KNN)



    




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值