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

Python Opencv实战之数字识别之knn算法入门

2017-02-26 22:51 701 查看
学过中学向量知识的都很容易理解knn ,我们知道2个向量(a,b)和(c,d)之间的距离为sqrt((a-c)*(a-c)+(b-d)*(b-d));

在knn分类算法基本思想就是我们预先设置好训练数据和每个数据对应的标签值,根据标签值我们可以将数据进行分类。我们的测试数据为新数据,我们定义每个数据都为n个特征值组成,这些特征值组成一个向量,这样包括测试数据集合和待测数据的每个单一数据都被转换为一个具有n维的向量。我们可以根据测试数据向量与训练数据集合的距离求得距离待测数据最近的k个训练数据,判断这k个训练数据的分类标签出现的次数最多,我们可以预测新数据出现在某个分类。从而达到分类的效果。

例如:

#我们要知道我们的测试数据向量与训练集上的每个向量的距离集合,并且求出离测试数据向量最近的k个训练集上的个向量, 并且根据传进来的
#labels 数组,我们知道这k个向量属于哪一个类的可能性最大,返回该类标签

#步骤1:我们要知道我们的测试数据向量与训练集上的每个向量的距离集合,假设训练数据为((2,3),(3,4),(4,5)),标签为(B,B,G)
#假如我们要求(1,1)与((2,3),(3,4),(4,5))的距离集合数组,我们可以实用如下方法求得
#  (1,1) (2,3)		  (1,4)	      (sqrt(5))
#A=(1,1)-(3,4),然后B=A××2=    (4,9),距离为(sqrt(13)),距离数组为(2.2,3.6,5.0)
#  (1,1) (4,5)		  (9,16)      (sqrt(25))
#步骤2:
#我们将距离数组按升序排序
#定义类识别数组,根据最近的k个向量的在原先的距离数组的下标对应的标签值作为数组的key,并且求出类识别数组出现次数最多的,其中标签值为key,
    #例如上面数据((2,3),(3,4),(4,5))的标签为(B,B,G),取k=2;
    #sortedDistIndices的value:0,1,2,对应为(B,B,G)
    距离(1,1)最近的2点的标签值为(B.B)
    #我们认为(1,1)为B
接下来十一个简单knn分类器的实现

#coding=utf-8
from numpy import *
import operator
#一个简单knn分类器,根据机器学习实战一书而来的
def kNNClassify(inX, dataSet, labels, k):
#测试数据集的行数,代表训练集的大小
datasetsize = dataSet.shape[0]
#knn 基本思想
#我们要知道我们的测试数据向量与训练集上的每个向量的距离集合,并且求出离测试数据向量最近的k个训练集上的个向量, 并且根据传进来的
#labels 数组,我们知道这k个向量属于哪一个类的可能性最大,返回该类标签

#步骤1:我们要知道我们的测试数据向量与训练集上的每个向量的距离集合
#假如我们要求(1,1)与((2,3),(3,4),(4,5))的距离集合数组,我们可以实用如下方法求得
#  (1,1) (2,3)		  (1,4)	      (sqrt(5))
#A=(1,1)-(3,4),然后B=A××2=    (4,9),距离为(sqrt(13)),距离数组为(2.2,3.6,5.0)
#  (1,1) (4,5)		  (9,16)      (sqrt(25))
diff = tile(inX, (datasetsize, 1)) - dataSet
squaredDiff = diff ** 2
squaredDist = sum(squaredDiff, axis = 1)
distance = squaredDist ** 0.5

#步骤2:
#我们将距离数组按升序排序,sortedDistIndices的value是原先的距离数组的下标
sortedDistIndices = argsort(distance)
#定义类识别数组,根据最近的k个向量的在原先的距离数组的下标对应的标签值作为数组的key,并且求出类识别数组出现次数最多的,其中标签值为key,
#例如上面数据((2,3),(3,4),(4,5))的标签为(B,B,G),取k=3;
#sortedDistIndices的value:0,1,2,对应为(B,B,G)
#则class[B]=2,class[G]=1;
#我们认为(1,1)为B
classCount = {}
for i in xrange(k):
#排序后,求出第i个向量对应的原先训练数组的下标索引,并根据下标索引,求出类识别数组对应的key
voteLabel = labels[sortedDistIndices[i]]

#根据类识别数组对应的key求得数组元素,该数组元素的value值加一,
classCount[voteLabel] = classCount.get(voteLabel, 0) + 1

#数组排序,求出值最大的数组元素下标,这个地方我看到一种方法(1):,但是万能的numpy有一个很好的sorted函数,帮助我们降序排序,我们可以直接求出值最大的
#数组元素下标
#(1)
#    maxCount = 0
#    for key, value in classCount.items():
#        if value > maxCount:
#            maxCount = value
#            maxIndex = key
sortedClassCount = sorted(classCount.iteritems(),
key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
简单的使用:

#coding=utf-8
from numpy import *
import operator
import knn
# create a matrix: each row as a sample
group = array([[2.0, 3.0], [3.0, 4.0], [4.0, 5.0], [6.0, 7.0]])
labels = ['B', 'B', 'G', 'G'] # four samples and two classes
inX=[1,1]
r=knn.kNNClassify(inX,group,labels,2);
print r;
输出结果为

huanghongren@ubuntu:~/Desktop/opencv_project/ml/knn1$ python main.py

B

具体的细节可以去网易云上去看《Python 那些事》这门课程,里面有详细的数学讲解。代码部分可以查阅相关的机器学习的书籍,本代码参考《机器学习实战》这本书。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: