数据使用的这个 https://github.com/Jack-Cherish/Machine-Learning/tree/master/kNN/3.数字识别
样本数据是很多的文本文件,文件名 “number_index.txt” 这样的,即每个数字有多个样本文件。测试用的文件在另一个目录,也可自己直接复制部分原样本文件。
文本内容如图:
和 使用python knn交友预测示例 中的操作类似,
先整理数据,得到样本特征值及对应标签的序列,仍然把测试数据逐个与样本集进行knn运算。
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 |
from os import listdir, path import numpy as np import operator def number32x32To1x1024(path): # 把32x32的数据转为1行1024列的 vect = np.zeros((1, 1024)) with open(path) as file: # 打开数据文件,读取每行内容 for i in range(32): line = file.readline() # 行 for j in range(32): letter = int(line[j]) # 列 vect[0, 32*i+j] = letter return vect def clearData(_path): # 整理数据。返回特征值mat和标签list labelList = [] fileList = listdir(_path) # 样本数据文件列表 fileCount = len(fileList) numberMat = np.zeros((fileCount, 1024)) for i in range(fileCount): fileName = fileList[i] # 数字_序号.txt filepath = path.join(_path, fileName) numberMat[i, :] = number32x32To1x1024(filepath) name = fileName.split('.')[0] number = int(name.split('_')[0]) # 数字即数据的标签 labelList.append(number) return numberMat, labelList def knn(featreList, knnMat, knnLabelList, k): # knn运算 rowCount = knnMat.shape[0] # 行数 featreMat = np.tile(featreList, (rowCount, 1)) # 将原矩阵横向、纵向地复制。 diffMat = featreMat - knnMat # 对应元素差值矩阵 sqDiffMat = diffMat**2 # 每个元素平方 sqDistances = sqDiffMat.sum(axis=1) # 行元素求和 distances = sqDistances**0.5 # 开方,计算出每个元素到featre的距离 sortedDistIndices = distances.argsort() # 从小到大排序后的索引值 labelCount = {} # 标签出现次数 for i in range(k): index = sortedDistIndices[i] # 根据排序后的索引,取出标签 label = knnLabelList[index] labelCount[label] = labelCount.get(label, 0) + 1 # 计数累加 sortedClassCount = sorted( # 根据标签的次数次再排序。返回元素为(k-v)的列表 labelCount.items(), # 标签-kv key=operator.itemgetter(1), # key=operator.itemgetter(1)根据字典的值进行排序。0)根据字典的键进行排序 reverse=True) # 降序 return sortedClassCount[0][0] # 次数最多的标签 def testErrorRate(testMat, testLabels, numberMat, labelList, k): # 样本测试 srcCount = numberMat.shape[0] print("样本数据数量:{}".format(srcCount)) testCount = testMat.shape[0] print("测试数据数量:{}".format(testCount)) print("测试数据比例:{}".format(testCount/float(srcCount)*100)) errorCount = 0.0 # 错误计数 for i in range(testCount): # 遍历测试数据 featreList = testMat[i,:] knnResultLabel = knn(featreList, numberMat, labelList, k) # 测试集knn处理后得出的标签 testLabel = testLabels[i] # 测试集对应的原始标 if knnResultLabel != testLabel: print("错误,特征集:%s\t knn标签:%d\t 真实标签:%d" % (featreList, knnResultLabel, testLabel)) errorCount += 1.0 print("错误数量:{}".format(errorCount)) errorRate = errorCount/float(testCount)*100 return errorRate if '__main__' == __name__: numberMat, labelList = clearData('./trainingDigits') # 样本数据 testMat, testLabels = clearData('./testDigits') # 测试数据 errorRate = testErrorRate(testMat, testLabels, numberMat, labelList, 3) print("错误率{}".format(errorRate)) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ 样本数据数量:1934 测试数据数量:946 测试数据比例:48.91416752843847 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:1 真实标签:8 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:3 真实标签:8 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:7 真实标签:9 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:9 真实标签:3 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:1 真实标签:8 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:1 真实标签:9 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:1 真实标签:8 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:7 真实标签:1 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:6 真实标签:5 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:3 真实标签:5 错误,特征集:[0. 0. 0. ... 0. 0. 0.] knn标签:6 真实标签:8 错误数量:11.0 错误率1.1627906976744187 $ |
最后一步就是自己手写文字,转为32x32的文本,代入进行预测。
步骤大概就是:拍照,压缩,去色/二值化,转文本。
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/3462.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设