任务描述:
在
digits
目录下存在1934张手写数字训练数据集(trainSet,标签为文本_前数字)和946张手写数字测试训练集(testSet,真实值为标签文本_前数字),使用kNN算法对测试集数字进行识别。
部分图片内容如下:
实现步骤与上一节
机器学习实战之分类篇 一 k-近邻算法(从电影分类到海伦约会)
基本一致,都是将信息(图像)转换为向量,计算未知向量到训练数据集的前k个最近距离,通过频率得出识别类别。
使用sklearn机器学习算法库,其分类算法库目录
sklearn Classification
.在1.6.2节介绍了kNeighborsClassifier分类器。
API实例及介绍如下:
使用sklearn库的目的在于,该库算法底层进行了优化算法,而且像很多分类器一样,具有一致的参数接口和函数名,使用也极其方便。使用KNN算法的关键调用语句为:
#call the kNN classifier
from sklearn.neighbors import KNeighborsClassifier as kNN
#set parameters
neigh = kNN(n_neighbors = 3, algorithm = 'auto')
#train classifier
neigh.fit(trainMatrix, labels)
#claddifier prediction
predLabel = neigh.predict(vectorImg)
最终实现代码如下:
import operator
import numpy as np
from os import listdir
from sklearn.neighbors import KNeighborsClassifier as kNN
'''
Function : img2vector(filename)
Description : to covert img(in filename) to vector
Args : filename
Rets : vectorImg
'''
def img2vector(filename):
vectorImg = np.zeros((1, 1024))
fr = open(filename)
for i in range(32):
line = fr.readline()
for j in range(32):
vectorImg[0, 32*i + j] = int(line[j])
return vectorImg
'''
Function : train()
Description : use kNN to train and test digits
Args : None
Rets : None
'''
def train():
labels = []
trainSet = listdir('./digits/trainSet')
numTrain = len(trainSet)
trainMatrix = np.zeros((numTrain, 1024)) #32*32 img size
for i in range(numTrain):
filename = trainSet[i]
label = int(filename.split('_')[0])
labels.append(label)
trainMatrix[i, :] = img2vector('./digits/trainSet/%s'%(filename))
neigh = kNN(n_neighbors = 3, algorithm = 'auto')
neigh.fit(trainMatrix, labels)
testSet = listdir('./digits/testSet')
errorCount = 0.0
numTest = len(testSet)
for i in range(numTest):
filename = testSet[i]
label = int(filename.split('_')[0])
vectorImg = img2vector('./digits/testSet/%s'%(filename))
predLabel = neigh.predict(vectorImg)
print('label: %d vs predLabel: %d'%(label, predLabel))
if(label != predLabel):
errorCount += 1.0
print('Error Rate : %f%%'%(errorCount / numTest * 100))
if __name__ == '__main__':
train()
实验结果:
注:
实际使用这个算法时,算法的执行效率并不高。因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计要执行900次,此外,我们还需要为测试向量准备2MB的存储空间。是否存在一种算法减少存储空间和计算时间的开销呢?
k决策树就是k-近邻算法的优化版,可以节省大量的计算开销。