DIY自动分类“错题集”:一种基于视觉词汇的文本分类法

本文涉及的产品
教育场景识别,教育场景识别 200次/月
文档理解,结构化解析 100页
个人证照识别,个人证照识别 200次/月
简介:
本文来自AI新媒体量子位(QbitAI)

一年多以前我脑子一热,想做一款移动应用:一款给学生朋友用的“错题集”应用,可以将错题拍照,记录图像的同时,还能自动分类。比如拍个题目,应用会把它自动分类为”物理/力学/曲线运动”。

当然,这个项目其实不靠谱,市场上已经有太多“搜题”类应用了。但过程很有趣,导致我过了一年多,清理磁盘垃圾时,还舍不得删掉这个项目的“成果”,所以干脆回收利用一下,写篇文章圈圈粉。

源码地址:

https://github.com/caoym/odr

这个项目,核心要解决的问题就是文本分类。所以最初想到的方案是先 OCR 图片转文本,然后分词,再计算 tf-idf,最后用 SVM 分类。但这个方案的问题是:开源 OCR 普遍需要自己训练,且需要做大量的优化、调校和训练,才能在中文识别上有不错的效果,加上图像上还会有公式、几何图形,这些特征也会决定分类,这又提高了对 OCR 的要求。

所以我最终选择的方案是,不使用 OCR,而是直接从图像中寻找有区分性的、鲁棒的特征,作为视觉词汇。之后再通过传统文本分类的方法,训练分类器。

下面将展示整个训练过程,训练的样本来自《2016 B版 5年高考3年模拟:高考理数》,并手工标注了14个分类,每个分类下约50个样本,每个样本为一个题目, 图像为手机拍摄。

样本数据下载地址:

https://github.com/caoym/odr

本文中大部分算法库来自numpy、scipy、opencv、skimage、sklearn。

1. 预处理

为了获取到稳定的特征,我们需要对图像进行预处理,包括调整图像大小,将图像缩放到合适尺寸;旋转图像,或者说调整成水平;二值化,去除色彩信息,产生黑白图像。

1.1. 调整图像大小

调整的目的是为了让图像中文字的尺寸保持大致相同的像素尺寸。这里做了一个简单假设,即:图像基本是一段完整的文本,比如一个段落,或者一页文档,那么不同的图像中,每行文本的字数相差不会很大。

这样我就可以从我所了解的、少得可怜的图像工具库里找到一个工具了:直线拟合。即通过拟合的直线(线段)长度与图像宽度的比例,调整图像的大小。下图为两张不同尺寸图像,经过多次拟合+调整大小后的结果,其中红色算法检查到的直线(线段)。

下面是使用 opencv 直线拟合的代码:

1.2. 图像二值化

二值算法选用skimage.filters.threshold_adaptive(局部自适应阀值的二值化), 试下来针对这种场景,这个算法效果最好,其他算法可以去scikit-image文档了解。下图为全局阀值和局部自适应阀值的效果对比:

文档地址:

http://scikit-image.org/docs/dev/api/skimage.filters.html?highlight=threshold_adaptive#skimage.filters.threshold_adaptive

相关代码如下:

1.3. 旋转图像

从第一步获取到的直线,可以计算出图像的倾斜角度,针对只是轻微倾斜的图像,可以反向旋转进行调整。由于可能存在干扰线条,所以这里取所有直线倾斜角度的中值比平均值更合适。下图展示了图像旋转跳转前后的效果:

相关代码如下:

2. 提取特征

这里的思路是,首先通过形态学处理,可以分割出文本行(的图像),再从文本行中分割出词汇(的图像),然后从”词汇”中提取特征。但这里的需要克服的困难是:

  • 很多汉字分左右部,容易被错分,比如你好, 可能被分割成以4块图像:亻、尔、女、子。
  • 独立的“字”并不适合于文本分类,还需能学习出词汇。

针对以上问题的解决方案是:

  • 将小的图像块进行组合,组合后的新图像块和原来的小块图像一起作为原始图像的特征,如你好将得到10个特征:亻、你、你女,你好,尔、尔女、尔好、女、好、子。
  • 得益于上面的方案,词汇信息也被保留了下来,所以第二个问题也就解决了,同时增加了算法的鲁棒性。

下面将介绍具体实现。

2.1. 提取文本行

由于预处理过程中已经将样本的图像尺寸基本调整一致,所以可以比较容易的利用形态学的处理方法,分割出文本行。过程如下:

下图展示了每一步的变化:

接下来可以利用scipy库中的measurements.label方法,标记出不同的的区域,下图展示了标注后的效果,不同区域以不同的灰度表示。

相关代码如下:

接下来根据标记的区域,可从图像中裁剪出每行的数据,如下图:

相关代码如下:

2.2. 提取特征(视觉词汇)

裁剪出单行文本图像后,我们可以将图像中各列的像素的值各自累加,得到一个一纬数组,此数组中的每个局部最小值所在的位置,即为文字间的空隙。如下图所示,其中蓝色线为像素值的累加值,绿色线为其通过高斯滤波平滑后的效果,红色线为最终检测到的分割点。

详细过程见下面代码:

将单行的图像按上述方法获取的分割点进行裁剪,裁剪出单个字符,然后再把相邻的单个字符进行组合,得到最终的特征数据。组合相邻字符是为了使特征中保留词汇信息,同时增加鲁棒性。下图为最终获得的特征信息:

本文中使用的所有样本,最终能提取出约30万个特征。

2.3. 选择特征描述子

选择合适的特征描述子通常需要直觉+运气+不停的尝试(好吧我承认这里没有什么经验可分享),经过几次尝试,最终选中了HOG(方向梯度直方图)描述子。HOG 最让人熟悉的应用领域应该是行人检测了,它很适合描述钢性物体的边缘特征(方向),而印刷字体首先是刚性的,其次其关键信息都包含在边缘的方向上,所以理论上也适合用 HOG 描述。下图为文字图像及其 HOG 描述子的可视化:

更多关于HOG的介绍请点击:

http://scikit-image.org/docs/dev/auto_examples/features_detection/plot_hog.html#sphx-glr-auto-examples-features-detection-plot-hog-py

代码如下:

3. 训练词汇分类器

对词汇进行人工标注工作量太大,所以最好能做到自动分类。我的做法是先聚类,再基于聚类的结果训练分类器。

但有个问题,主流的聚类算法中,除了 K-Means 外,其他都不适合处理大量样本(目前有30万+样本),但 K-Means 在这个场景上聚类效果不佳,高频但不相关的词汇容易被聚成一类,而 DBSCAN 效果很好,但样本数一多,所需时间几何级增长(在我的机器上,超过两万个样本就需要耗费数个小时)。

下图来自sklearn 文档,对各聚类算法做了比较:

为解决这一问题,我的做法是:

1. 先对每类样本下的词汇用 DBSCAN 聚类(约1万个词汇样本),得到一级分类。

2. 聚类后,计算每个一级分类的中心,然后以所有中心为样本再用DBSCAN聚类,得到二级分类。完成后,原一级分类中心的新分类,即代表其原一级分类下所有元素的分类。

聚类的过程为,使用前面提取的HOG特征,先 PCA 降纬,再 DBSCAN 聚类。这里注意,计算二级分类时,PCA应使用全局样本计算。

分类器使用SGDClassifier,原因是其支持分批计算,不至于导致内存不足。

本文中使用的样本,最终得到3000+词汇类型。下图为分类效果,其中每一行为一个分类:

4. 训练文本分类器

有了词汇分类器,我们终于可以识别出每个文本样本上所包含的词汇了(事实上前面步骤的中间过程也能得到每个样本的词汇信息),于是我们可以给每个样本计算一个词袋模型(即用每个词出现的次数表示一篇文本),再通过池袋模型计算TF-IDF模型(即用每个词的 TF*IDF 值表示一篇文本),并最终训练 SVM 分类器。

下面展示了此过程的主要代码:


执行结果如下:

测试集上正确率81%,召回率 78%。个别分类正确率较低,可能是因为样本数太少,另外训练过程大多使用默认参数,若进行细致调校,应该还有提高空间。

5. 结束

此项目完整代码及样本数据均可下载,地址为:

https://github.com/caoym/odr

任何想在实际项目中使用此方法的朋友请注意,以上方法目前只在一个样本库中测试过,在其他样本库中表现如何还不知道,但愿没把你带坑里。


点击左下角“阅读原文”,可解锁更多作者的文章

还可以直接参与讨论~

量子位特约稿件,转载请联系原作者。

本文作者:曹阳敏
原文发布时间:2017-09-23
相关文章
|
8月前
|
机器学习/深度学习 搜索推荐 计算机视觉
ComicTrainee_v1.0模型——专注生成动漫风格人物画像
ComicTrainee_v1.0模型——专注生成动漫风格人物画像
82 0
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
当大火的文图生成模型遇见知识图谱,AI画像趋近于真实世界
本文介绍了阿里云机器学习PAI团队开发的名为ARTIST的中文文图生成模型,该模型融合了知识图谱信息,能够生成更加符合常识的图像。ARTIST基于Transformer架构,将文图生成任务分为图像矢量量化和文本引导的图像序列生成两个阶段。在第一阶段,模型使用VQGAN对图像进行矢量量化;在第二阶段,通过GPT模型并结合知识图谱中的实体知识来生成图像序列。在MUGE中文文图生成评测基准上,ARTIST表现出色,其生成效果优于其他模型。此外,EasyNLP框架提供了简单易用的接口,用户可以基于公开的Checkpoint进行少量领域相关的微调,实现各种艺术创作。
|
4月前
|
机器学习/深度学习 数据采集 自然语言处理
使用Python实现深度学习模型:智能新闻生成与校对
使用Python实现深度学习模型:智能新闻生成与校对
136 10
|
3月前
Midjourney-03 收集Prompt 动漫风格 樱花 武士 魔法少女 自然 机甲 拟人动物 歌剧场景 星际飞船 神秘森林 精灵 详细记录 超多图片 多种风格 附带文本 关键词
Midjourney-03 收集Prompt 动漫风格 樱花 武士 魔法少女 自然 机甲 拟人动物 歌剧场景 星际飞船 神秘森林 精灵 详细记录 超多图片 多种风格 附带文本 关键词
55 0
|
5月前
|
机器学习/深度学习 人工智能 语音技术
情感识别与表达:FunAudioLLM的情感智能技术
【8月更文第28天】随着人工智能的发展,语音交互系统越来越普遍。其中,情感智能技术成为提高用户体验的关键因素之一。本文将探讨 FunAudioLLM 如何利用情感识别和表达技术来增强语音交互的真实感,并提供具体的代码示例。
207 0
|
8月前
|
自然语言处理 数据可视化 Python
NLP自然语言处理—主题模型LDA案例:挖掘人民网留言板文本数据
NLP自然语言处理—主题模型LDA案例:挖掘人民网留言板文本数据
|
8月前
|
自然语言处理 数据可视化 算法
R语言文本挖掘、情感分析和可视化哈利波特小说文本数据
R语言文本挖掘、情感分析和可视化哈利波特小说文本数据
|
8月前
|
机器学习/深度学习 自然语言处理 数据可视化
R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据
R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据
|
机器学习/深度学习 图计算 图形学
NeurIPS 2022 | 文本图片编辑新范式,单个模型实现多文本引导图像编辑
NeurIPS 2022 | 文本图片编辑新范式,单个模型实现多文本引导图像编辑
365 0
|
数据挖掘
【论文写作分析】之三《基于预训练语言模型的案件要素识别方法》
【论文写作分析】之三《基于预训练语言模型的案件要素识别方法》
101 0
【论文写作分析】之三《基于预训练语言模型的案件要素识别方法》