基于贝叶斯模型和KNN模型分别对手写体数字进行识别

首先,我们准备了0~9的训练集和测试集,这些手写体全部经过像素转换,用0,1表示,有颜色的区域为0,没有颜色的区域为1。实现代码如下:

# 图片处理
# 先将所有图片转为固定宽高,比如32*32,然后再进行处理
from PIL import Image as imgf = open('f:/result/weixin.txt', 'a')
im = img.open('f:/data/weixin.jpg')
# im.save('f:/data/weixin.bmp')
length = im.size[0]  # 长
width = im.size[1]  # 宽
# k=im.getpixel((1,9)) #获取图片某个像素的色素
for i in range(0, length):for j in range(0, width):RGB = im.getpixel((i, j))RGB_SUM = RGB[0] + RGB[1] + RGB[2]if RGB_SUM == 0:# 说明当前位置为黑色f.write('1')else:f.write('0')f.write('\n')
f.close()

手写数字体转换为0,1像素矩阵如下:

我们一共准备了1934个训练集和934个测试集,分别为0~9的手写体像素矩阵

基于贝叶斯模型对手写体数字进行识别

贝叶斯模型实现代码:

from numpy import *
from os import listdirclass Bayes:def __init__(self):self.length = -1  # 如果未进行训练,则length为-1self.labelcount = dict()self.vectorcount = dict()def fit(self, dataSet: list, labels: list):if (len(dataSet) != len(labels)):raise ValueError("输入的测试数组和类别数组不一致")self.length = len(dataSet[0])  # 测试数据特征值的长度labelsnum = len(labels)  # 所有类别数量no_repeat_lables = len(set(labels))  # 不重复类别的数量for item in range(no_repeat_lables):# 当前类别的数量占总类别数量的比例self.labelcount[item] = labels.count(item) / labelsnumfor vector, label in zip(dataSet, labels):if (label not in self.vectorcount):self.vectorcount[label] = []self.vectorcount[label].append(vector)print('训练结束')return selfdef btest(self, TestData, labelSet):if (self.length == -1):raise ValueError("还未进行训练")# 计算当前testdata分别为各个类别的概率lbDict = dict()for thislb in labelSet:p = 1alllabel = self.labelcount[thislb]allvector = self.vectorcount[thislb]vnum = len(allvector)allvector = array(allvector).Tfor index in range(0, len(TestData)):vector = list(allvector[index])p = p * vector.count(TestData[index]) / vnumlbDict[thislb] = p * alllabel  # 当前标签的概率thislabel = sorted(lbDict, key=lambda x: lbDict[x], reverse=True)[0]return thislabel

之后,我们利用建立好的贝叶斯模型加载训练集、训练模型,实现代码如下:

# 加载数据
def dataToArray(filename):arr = []f = open(filename)for i in range(0, 32):thisline = f.readline()for j in range(0, 32):arr.append(int(thisline[j]))return arr# 建立一个函数取文件名前缀
def seplabel(fname):filestr = fname.split(".")[0]label = int(filestr.split("_")[0])return label# 建立训练数据
def traindata():labels = []trainfile = listdir("f:/data/traindata/")num = len(trainfile)# 长度1024(列),每一行存储一个文件# 用一个数组存储所有训练数据,行:文件总数,列:1024trainarr = zeros((num, 1024))for i in range(0, num):thisfname = trainfile[i]thislabel = seplabel(thisfname)labels.append(thislabel)trainarr[i, :] = dataToArray("f:/data/traindata/" + thisfname)return trainarr, labels

在对数据进行训练后,我们建立好的模型对测试数据中的手写体"8"进行测试,实现代码如下:

# 抽某一个测试文件出来进行试验
trainarr, labels = traindata()
thistestfile = "8_76.txt"
testarr = dataToArray("f:/data/testdata/" + thistestfile)
b = Bayes()
b.fit(trainarr, labels)
label = b.btest(testarr, labels)
print(label)

结果如下:

结果证明贝叶斯方法可以准确地识别出手写体“8”,接下来我们对贝叶斯方法的精度进行测试,这次我们对所有的测试集进行识别,实现代码如下:

# 识别多个手写体数据
testfile = listdir("f:/data/testdata/")
num = len(testfile)
count = 0
for i in range(0, num):this_file = testfile[i]this_label = seplabel(this_file)  # 正确的labeltest_arr = dataToArray("f:/data/testdata/" + this_file)result = b.btest(test_arr, labels_all)if (result == this_label):count += 1acc = count / numprint(acc)

结果显示,最终精度为:

实验结果还不错,证明贝叶斯模型的确是一个较好的分类模型

基于KNN模型对手写体数字进行识别

接下来我们使用KNN对手写体数字进行识别,实验控制变量,继续采用之前的测试集和数据集。
首先,我们实现KNN模型:

from numpy import *
import operator
from os import listdirdef knn(k, testdata, traindata, labels):traindatasize = traindata.shape[0]dif = tile(testdata, (traindatasize, 1)) - traindata  # 扩展数组行sqdif = dif ** 2sumsqdif = sqdif.sum(axis=1)  # 行求和dis = sumsqdif ** 0.5  # 距离sort_dis = argsort(dis)  # 排序,返回的是索引count = {}for i in range(0, k):vote = labels[sort_dis[i]]  # 显示当前类count[vote] = count.get(vote, 0) + 1  # 统计各类别次数sortcount = sorted(count.items(), key=operator.itemgetter(1), reverse=True)  # 按照降序排列字典return sortcount[0][0]

然后,我们利用训练集创建KNN模型:

# 加载数据
def dataToArray(filename):arr = []f = open(filename)for i in range(0, 32):thisline = f.readline()for j in range(0, 32):arr.append(int(thisline[j]))return arr# 取出文件前缀,获得label
def seplabel(filename):filestr = filename.split(".")[0]label = int(filestr.split("_")[0])return label# 建立训练数据
def traindata():labels = []trainfile = listdir("f:/data/traindata/")num = len(trainfile)# 长度1024(列),每一行存储一个文件# 用一个数组存储所有训练数据,行:文件总数,列:1024trainarr = zeros((num, 1024))for i in range(0, num):thisfname = trainfile[i]thislabel = seplabel(thisfname)labels.append(thislabel)trainarr[i, :] = dataToArray("f:/data/traindata/" + thisfname)return trainarr, labels

最后,利用创建的KNN模型对测试集进行测试,同样是测试手写体“8”:

#抽某一个测试文件出来进行试验
trainarr,labels=traindata()
thistestfile="8_76.txt"
testarr=dataToArray("f:/data/testdata/"+thistestfile)
rknn=knn(3,testarr,trainarr,labels)
print(rknn)

结果为:

说明KNN模型也可以识别出手写体“8”,接下来我们利用所有测试集求出KNN模型的精度:

#用测试数据调用KNN算法去测试,看是否能够准确识别
def datatest():trainarr,labels=traindata()testlist=listdir("f:/data/testdata")tnum=len(testlist)count = 0for i in range(0,tnum):thistestfile=testlist[i]this_label = seplabel(thistestfile)testarr=dataToArray("f:/data/testdata/"+thistestfile)rknn=knn(3,testarr,trainarr,labels)if (rknn == this_label):count += 1acc = count / tnumprint(acc)

结果为:

说明KNN也是一个较为良好的分类模型,而且比贝叶斯模型分类效果好。

手写体数字识别的两种方法相关推荐

  1. 命名实体识别python_命名实体识别的两种方法

    作者 | Walker [磐创AI导读]:本文主要介绍自然语言处理中的经典问题--命名实体识别的两种方法. 目录 一.什么是命名实体识别 二.基于NLTK的命名实体识别 三.基于Stanford的NE ...

  2. 批量替换字符串,将其中的数字递增(两种方法)和circlr.js插件的使用

    使用circlr.js插件实现3D效果的时候,不想在JS中写追加,直接写html又太麻烦(使用的是HBuilder X),所以找到了两种批量替换字符串,将其中的数字递增的方法. 想要实现的效果: 1. ...

  3. 解析数字证书的两种方法—openssl命令和python pyopenssl模块

    本文介绍两种方法获取数字证书文件中有用的信息. 证书文件的格式有多种,包括cer,der,crt,pem等.对于这些格式的文件通常可以使用openssl来查看相关的信息并进行输出.同时openssl ...

  4. 命名实体识别的两种方法

    作者:Walker 目录     一.什么是命名实体识别     二.基于NLTK的命名实体识别     三.基于Stanford的NER     四.总结 一 .什么是命名实体识别? 命名实体识别( ...

  5. 判断一个字符串是否为数字字符串(两种方法)

    第一种方法: //正则表达式判断是否是数字字符串(可判断正数,负数和小数)public boolean isNumberString(String str) {java.util.regex.Patt ...

  6. python 命名实体识别_命名实体识别的两种方法

    作者:Walker 目录 一.什么是命名实体识别 二.基于NLTK的命名实体识别 三.基于Stanford的NER 四.总结 一 .什么是命名实体识别? 命名实体识别(Named Entity Rec ...

  7. 监督学习:KNN(K-近邻)算法实现手写数字识别的三种方法

    没人会看的开场白:本来觉得自己从数据建模转人工智能方向应该问题不大(自我感觉自己算法学的不错).结果一个K-邻近实现手写数字识别的代码就让我改了三四天.虽然网上这方面的代码是很多,但是我运行了好几个, ...

  8. 数字分割(拆数字)的两种方法

    最近做了下蓝桥杯的初赛训练题,发现经常需要用到数字分割(例如把一个数字1234拆成1,2,3,4) 所以总结了两种常用的拆分数字的方法:一个是while循环方法,一个是递归方法 //数字分割,whil ...

  9. 数字识别实例两种实现方式(tensorflow2.x):1.调用高级API 2.手写简单神经网络 3.手写深度神经网络(DNN)

    MNIST手写数字数据库的训练集为60,000个示例,而测试集为10,000个示例. 一共4个文件,训练集.训练集标签.测试集.测试集标签,这些数据直接可以用mnist = tf.keras.data ...

最新文章

  1. 阿里云云盾-风险识别-增强版模式发布
  2. python3 环境变量
  3. DeepStream开发日志
  4. 计算机系统集成项目的管理及应用
  5. 深究 ElasticSearch 查询的秘密
  6. QT的QHBoxLayout类的使用
  7. Matlab subs函数的用法
  8. 假如,绿茶婊的目标变成女生......
  9. TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
  10. c语言案例朗读工具源码,C语言编写简单朗读小工具(有源码)
  11. typescript parseint不能传number_Typescript 使用日志
  12. c语言课后题第一章答案,C语言教材课后习题(含答案)
  13. 百度文库免下载券下载的方法
  14. 基于java+swing的物业收费管理系统(java+swing+Gui)
  15. QODBC查询Oracle中文乱码问题
  16. Laravel核心概念:服务容器(ServiceContainer),服务提供者(Service Provider),门面(Facade),契约(Contracts)
  17. 入职要求提供上家公司的工资银行流水?
  18. 2009年以来我买过的书(部分)
  19. python怎么群发邮件_python群发邮件怎么做
  20. android中集成阿里云金融级实人认证

热门文章

  1. context.write
  2. ntpdate解决同步时间报错 the NTP socket is in use, exiting
  3. Linux命令学习总结
  4. Qt中的UI文件介绍
  5. 微信小程序——设置tabBar
  6. 20180710-B · Craft Beer USA · ggplot2 geom_density_ridges_gradient 核密度估计峰峦图 字体设置 · R 语言数据可视化 案例 源码
  7. 敏捷项目管理的前世今生及应用-Part 2(之3355)
  8. 苹果开发者:如何将准备好的应用上传到iTunes Connect
  9. Pre-Upgrade Utility---下载并运行Oracle数据库预升级实用程序 (文档 ID 1577379.1)
  10. 简单小白vr效果制作(unity)