您的位置:首页 > 编程语言 > Python开发

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

2014-03-04 12:59 531 查看
一、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)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: