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

【机器学习实战-kNN:手写识别】python3实现-书本知识【3】

2016-11-28 14:15 786 查看

说明: 本文内容为【Peter Harrington -机器学习实战】一书的学习总结笔记。

 

前文:

【机器学习实战-kNN:约会网站约友分类】python3实现-书本知识【2】

【机器学习实战-kNN(k-近邻)】python3实现-书本知识【1】

功能描述:

手写识别分类程序作为进一步加深理解kNN的示例,手写识别分类程序功能:有手写数字【0-9】的图片转化的近2000个32*32位01矩阵。

 

一、数据结构

备注:脚本中涉及数据均为《机器学习实战》一书示例数据,数据在网上均可找到。
   

手写图片32*32位01矩阵数据如下 :
00000000000001111000000000000000
00000000000001111110000000000000
00000000000001111111000000000000
00000000000001111111100000000000
00000000000111111111000000000000
00000000000111111110000000000000
00000000001111111000000000000000
00000000001111110000000000000000
00000000001111110000000000000000
00000000011111100000000000000000
00000000011111000000000000000000
00000000011111000000000000000000
00000000011110000000000000000000
00000000011111000000000000000000
00000000111110000000000000000000
00000000011111000000000000000000
00000000111111111111111000000000
00000000111111111111111100000000
00000000011111111111111111000000
00000000111111111111111111100000
00000000011111111111111111110000
00000000111111110000000111110000
00000000111111100000000011110000
00000000011111100000000001111000
00000000011111100000000011111000
00000000001111110000000111111000
00000000001111100000000111111000
00000000000111111100111111110000
00000000000011111111111111110000
00000000000001111111111111100000
00000000000000011111111111000000
00000000000000000001111000000000


二、功能实现

   

手写图片32*32位01矩阵数据如下

# coding=utf-8
# 手写识别系统
# 备注:k-近邻值算法在实际使用中,计算量大、需要大量内存空间;k-决策树是k-近邻值的优化算法
from numpy import *
from os import listdir
import operator

# 【1】将32*32的二进制图像矩阵 转为1*1024的向量返回
def img2vector(filename):
rs_vec = zeros((1, 1024))  # 一行1024列
f = open(filename)
for i in range(32):
line = f.readline()
for j in range(32):
rs_vec[0, 32*i+j] = int(line[j])
return rs_vec

# 【2】kNN实现 input_set:输入集 data_set:训练集
def classify0(input_set, data_set, labels, k):
data_set_size = data_set.shape[0]
# 计算距离tile 重复以input_set生成跟data_set一样行数的mat
diff_mat = tile(input_set, (data_set_size, 1)) - data_set
sq_diff_mat = diff_mat ** 2
sq_distances = sq_diff_mat.sum(axis=1)
distances = sq_distances ** 0.5
# print(distances)
# 按照距离递增排序
sorted_dist_indicies = distances.argsort()  # argsort返回从小到大排序的索引值
# print(sorted_dist_indicies)
class_count = {}  # 初始化一个空字典
# 选取距离最小的k个点
for i in range(k):
vote_ilabel = labels[sorted_dist_indicies[i]]
# 确认前k个点所在类别的出现概率,统计几个类别出现次数
class_count[vote_ilabel] = class_count.get(vote_ilabel, 0) + 1

# 返回前k个点出现频率最高的类别作为预测分类
sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
return sorted_class_count[0][0]

# 【3】使用k-近邻算法的手写数字识别测试
def hand_writing_test():
hw_labels = []
# 【1】获取训练集 目标路径文件目录名
file_list = listdir('F:\Python\data\kNN\digits\\trainingDigits')
m = len(file_list)
data_mat = zeros((m, 1024))  # 初始化m行1024列的0矩阵
for i in range(m):
file_name = file_list[i]
file_num = int((file_name.split(".")[0]).split("_")[0])  # 从文件名获取文件里存储的数字
hw_labels.append(file_num)
# 读取文件 数据转为向量返回
data_mat[i, :] = img2vector('F:\Python\data\kNN\digits\\trainingDigits\%s' % file_name)
# 【2】获取测试集 目标路径文件目录名
test_file_list = listdir('F:\Python\data\kNN\digits\\testDigits')
error_count = 0.0
n = len(test_file_list)
for j in range(n):
file_name = test_file_list[j]
file_num = int((file_name.split(".")[0]).split("_")[0])  # 从文件名获取文件里存储的数字
vec_test = img2vector('F:\Python\data\kNN\digits\\testDigits\%s' % file_name)
# k-近邻算法计算距离
classifier_result = classify0(vec_test, data_mat, hw_labels, 3)
print("this classifier came back with : %d, the real answer is :% d" % (classifier_result, file_num))

# 计算准确率
if classifier_result != file_num:
error_count += 1.0
right_ratio = 1 - error_count/float(n)
print("the total right rate is :%f %%" % (right_ratio*100))

# 主函数
if __name__ == "__main__":
print("the digits recognition  begin…………:")
# 测试手写识别系统的准确率:the total right rate is :98.837209 %
hand_writing_test()


总结:

k-近邻值算法在实际使用中,计算量大、需要大量内存空间;k-决策树是k-近邻值的优化算法。

--------------------------------------------我是分割线--------------------------------------------

高峰屹立,积跬步,行不止。

--------------------------------------------我是分割线--------------------------------------------

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