jlwang1996

  • 主页
  • 随笔
所有文章 友链 关于我

jlwang1996

  • 主页
  • 随笔

k-近邻算法实战之识别手写数字

2019-05-09

机器学习实战中的k-近邻算法实战之识别手写数字

实战背景

对于需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32像素x32像素。尽管采用本文格式存储图像不能有效地利用内存空间,但是为了方便理解,我们将图片转换为文本格式(二维数组中值为1的形状构成数字).与此同时,这些文本格式存储的数字的文件命名也很有特点,格式为:数字的值_该数字的样本序号

完整系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import numpy as np
import operator
#listdir 可以列出给定文件的目录名
from os import listdir

def classify0(inX, dataSet, labels, k):
#numpy函数shape[0]返回dataSet的行数
dataSetSize = dataSet.shape[0]
#在列向量方向上重复inX共1次(横向),行向量方向上重复inX共dataSetSize次(纵向)
#tile((1,2,3),(2,3))=array((1,2,3),(1,2,3),(1,2,3),
# (1,2,3),(1,2,3),(1,2,3))
diffMat =np.tile(inX, (dataSetSize, 1)) - dataSet
#二维特征相减后平方
sqDiffMat = diffMat**2
#sum()所有元素相加,sum(0)列相加,sum(1)行相加
#a = np.array([[0, 2, 1]])
#print a.sum()
#print a.sum(axis=0)
#print a.sum(axis=1)
#结果分别是:3, [0 1 2], [3]
sqDistances = sqDiffMat.sum(axis=1)
#开方,计算出距离
distances = sqDistances**0.5
#返回distances中元素从小到大排序后的索引值
sortedDistIndices = distances.argsort()
#定一个记录类别次数的字典
classCount = {}
for i in range(k):
#取出前k个元素的类别
voteIlabel = labels[sortedDistIndices[i]]
#dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
#计算类别次数
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#python3中用items()替换python2中的iteritems()
#key=operator.itemgetter(1)根据字典的值进行排序
#key=operator.itemgetter(0)根据字典的键进行排序
#reverse降序排序字典
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
#返回次数最多的类别,即所要分类的类别
return sortedClassCount[0][0]


###将32x32的二进制图像转换为1x1024向量
def imgToVector(filename):
returnVector=np.zeros((1,1024))
fr=open(filename)
for i in range(32):
lineStr=fr.readline()
for j in range(32):
##每一行的前32个元素依次添加到returnVect中
returnVector[0,32*i+j]=int(lineStr[j])
return returnVector

#‘\’可能会引起错误,因为有可能出现‘\t’,'\0'等等转义字符,所以用'/'比较好
#filename="F:/机器学习/kNN/testDigits/0_0.txt"
#returnVector=imgToVector(filename)
#x[i,j:k]取第i行的第j到k列的元素
#x[i:j,k:l]取第i-j行的k-l列的元素
#print(returnVector[0,0:31])

def handwritingClassTest():
hwLables=[]
#获取此目录下所有文件的名字,放到一个列表中
trainingFileList=listdir('F:/机器学习/kNN/trainingDigits')
m=len(trainingFileList)
tringMat=np.zeros((m,1024))
#从训练集中获取向量
for i in range(m):
fileNameStr=trainingFileList[i]
#取文件名的.之前的内容,如0_2.txt取完后为0_2
fileStr=fileNameStr.split('.')[0]
#取分割后_前的内容,如0_2取完后为0
classNumstr=int(fileStr.split('_')[0])
hwLables.append(classNumstr)
#print('F:/机器学习/kNN/trainingDigits'+'/'+fileNameStr)
tringMat[i,:]=imgToVector('F:/机器学习/kNN/trainingDigits'+'/'+fileNameStr)
testFileList=listdir('F:/机器学习/kNN/testDigits')
errorCount=0.0
mTest=len(testFileList)
for i in range(mTest):
fileNameStr=testFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumstr=int(fileStr.split('_')[0])
#print('F:/机器学习/kNN/testDigits'+'/'+fileNameStr)
vectorunerTest=imgToVector('F:/机器学习/kNN/testDigits'+'/'+fileNameStr)
classifierResult=classify0(vectorunerTest,tringMat,hwLables,3)
print("分类返回结果为%d\t真实结果为%d" % (classifierResult, classNumstr))
if(classifierResult!=classNumstr):errorCount+=1
print("总共错了%d个数据\n错误率为%f%%" % (errorCount, errorCount/mTest))

handwritingClassTest()
赏

谢谢你请我吃糖果

扫一扫,分享到微信

微信分享二维码
决策树
Hello World
  1. 1. 实战背景
  2. 2. 完整系统
© 2019 jlwang1996
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链
  • 关于我

tag:

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 张天宇大佬的博客
学习用的博客,闲时更新