课程综述(20分)
方法应用(25分)
1.研究背景(Why) 5分
最近在看《Python数据挖掘入门与实践》这本书,其中第8章提到了使用神经网络破解验证码。我以前调用过商业的第三方库用于识别验证码,收费达100条/元。正好借此机会,手动实现一下该项目,一探究竟。
2. 方案与技术路线(How)5分
神经网络简介
神经网络算法最初根据人类大脑的工作机制设计。神经网络由一系列相互连接的神经元组成。每个神经元都是一个简单的函数,接收一定输入,给出相应输出。
用于数据挖掘应用的神经网络,神经元按照层级进行排列。第一层,也就是输入层,接收来自数据集的输入。第一层中的每个神经元对输入进行计算,把得到的结果传给第二层的神经元。这种叫作前向神经网络。本实验暂且把它简称为神经网络。
神经元
我优先考虑使用全连接层,即上一层中每个神经元的输出都输入到下一层的所有神经元。
这是因为比起其他连接模式,全连接神经网络更简单,计算起来更快捷,适合我的小项目。
创建神经网络需要用到以下参数:神经网络共有多少层,隐含层每层有多少个神经元,神经元之间边的权重。
神经网络大小合适,且权重经过充分训练,它的分类效果才能精确。大小合适并不是越大越好,因为神经网络过大,训练时间会很长,更容易出现过拟合训练集的情况。
3. 实验或实例 数据、结果 及分析(5分)
创建验证码数据集
本试验所用验证码由我自己编写函数随机生成。
数据集产生规则为:
- 使用四个英文字母组成的单词作为文本
- 字母全大写
- 不使用数字、符号。
- 对单词使用错切变换后,生成验证码图像
多次调用该函数,就能生成验证码数据集。
训练数据集
书中采用 PyBrain 库来构建神经网络分类器,但由于环境问题,我采用sklearn库中的 MLPclassifier 来构建分类器。创建了隐含层数目为100的MLP分类器,输入神经元个数为400, 隐含层为100个,输出神经元为26个。
from sklearn.neural_network import MLPClassifier
clf = MLPClassifier(hidden_layer_sizes=(100,), random_state=14)
clf.fit(X_train, y_train)
测试数据集
初次测试结果发现:验证码正确率为77.3%,单个字母的识别正确率为84.3%
image.png
提升正确率
把经常识别错误的字母统计出来,用二维矩阵来表示。每行和每列均为一个类别。
矩阵的每一项表示一个类别(行对应的类)被错误识别为另一个类别(列对应的类)的次数。例如,(4,2)这一项的值为6,表示字母D有6次被错误地识别为字母B。
利用图像可视化,矩阵中点越亮表示值越大。
如图可见,字母U常被错误识别为H。
利用词典提升正确率
改进思想:刚刚的识别过程是,识别结果直接与正确结果比较。而我们验证码实际上是由词典中的单词生成,不如在返回结果之前,先查找词典里是否有预测结果对应的单词,若有则返回该结果,没有则返回与该结果相近的单词。
那么如何找到相近的单词?方法有很多。但是根据常识可知,在相同位置有字母相同个数越多,两个单词越相似。每次改变(增、删、改)一个字母,将两个字符串变为相同的最小处理次数被称为编辑距离。因为这不是本实验的重点,所以这里只提一下。
我使用NLTK库来计算字符串之间的编辑距离。
from nltk.metrics import edit_distance
steps = edit_distance("STEP", "STOP")
print("The number of steps needed is: {0}".format(steps))
# The number of steps needed is: 1
# 字符串编辑距离为1
改进预测算法后,重新训练并预测,单词识别率提升了3%,到达80%
预测4. 创新与特色(10分)
- 通过在词典中查找相近单词,改进提升识别正确率达80%
- 将神经网络与字母识别相结合,单个字母的识别率可达97%
- 使用Python第三方库,代码量很少,可注重优化算法。
收获与建议(5分)
这次项目手动实现了神经网络识别验证码,但是系统识别率还不够,即使经过优化后也只有80%,并且数据集由我自己生成,离商用的验证码识别系统效果还差太远。主要原因还是,模型过于简单,但毕竟是自己测试用的项目,不能过多苛求。
收获:熟悉了神经网络的设计和构建,并对图像处理、字符匹配加深了解。数据挖掘这门课和机器学习密切相关,数据挖掘对数据进行处理,再构建模型进行机器学习。
建议:没有太多建议,我当时选这课就是冲着周老师来的。因为之前上过您的组成原理、汇编,感觉虽然课程难度都很大,但是能学到很多知识,老师讲课也很清晰,课件写得也清楚,即使课上不懂课下自学也没问题。
网友评论