手写数学公式的纯逻辑重构

📝 目录

成员/作者

李恬

曾寓苏

罗梓颖

运行环境/库

Python >= 3.6

版本表现记录

CROHME2012数据集测试集上

WER:0.06209459299174936

完全重构成功数量:307/488

训练/测试参考数据集

架构说明

rebuil.py:重构程序,支持分式,根号,上下标的混合直接传入DataFrame调用即可

metrics.py:用于计算WER等度量函数

重构逻辑

注:图像扩展部分由于并不稳定所以没有开启,可以手动在order_control函数中加入.

总体流程图

%E6%80%BB%E4%BD%93%E6%B5%81%E7%A8%8B%E5%9B%BE.png

格式匹配

要求输入的公式符号为Panda.core.DataFrame格式,其中为各个符号的参数:'name','x','y',‘ymax’,'ymin','xmax','xmin'

对应该符号的:

Latex符号

bounding box中心x坐标

bounding box中心y坐标

bounding box y最大值

bounding box y最小值

bounding box x最大值

bounding box x最小值

格式匹配函数(match_csv)会对传入参数进行列名以及顺序匹配,并根据从左到右,从上到下的顺序对符号进行重新排序

图像扩展

该逻辑主要用于增强部分手写符号的识别准确率,分为两部分

\sum,\lim

在识别到该类符号后,会扩展bounding box到相邻的符号边上,目的是加强后续上下标识别准确率以及修正部分手写符号的不规范情况

分数线

识别到分数线后,根据分数线上元素的y的最小值以及分数线下元素的y最大值重新确定分数线的bounding box,并用上述类似的方法进行修正,但该方法对倾斜的分数线可能并不适用

图像重构

该部分函数均为递归函数,递归调用主重构程序,目的是对子式进行重构

位置关系

使用如下井字形关系描述各个符号之间的关系构成符号关系矩阵:

%E4%BD%8D%E7%BD%AE%E5%85%B3%E7%B3%BB.png

分数重构

只有符号为‘-’才进入分数重构程序.

若关系模型同时找不到分数线的上下部分(8,4)则判断为减号.

若为分数线,根据分数线长度(注意这里会经过前述的分数线扩展)确定分子分母并分别递归调用主重构程序,分别返回重构字符串并补全\frac{up}{down}

积分重构

只有符号为‘\int’才进入积分重构程序.

根据积分号bounding box对竖直方向三等分,分别对上部分(作为积分上标)以及下部分(作为积分下标)同时范围在bounding box宽度范围内的式子分别调用主重构程序,分别返回字符串并补全\int_{down}^{up}

根号重构

只有符号为‘\sqrt’才进入积分重构程序.

对与该符号符合‘9’位置关系的内容调用主重构程序,返回字符串并补全\sqrt{ans}

极限重构

只有符号为‘\lim’才进入积分重构程序.

类似根号重构的情况,但对'4'位置关系的内容调用函数,返回字符串并补全\lim_{ans}

求和重构

只有符号为‘\sum’才进入积分重构程序.

类似分数重构逻辑,补全为\sum_{down}^{up}

上下标重构

上下标重构是最关键部分

定义不能作为上下标的符号:

上下标主体:

'\\in','=','+','-','\\times','\\div','\\rightarrow','\\neq','>','<','\\geq','\\ge','\\ldots','\\pm','\\leq','{','[','(','\\exists','\\gt',',','\\lt','\\forall','\\in','.','\\dot','\\','|','!','\\prime'

上标客体:

'\\in','=','+','\\times','\\div','\\int','\\rightarrow','\\neq','>','<','\\geq','\\ge',

'\\ldots','\\pm','\\leq',']','}','\\exists',')',',','\\gt',',','\\lt','\\forall','\\in','.','\\dot',

'\\','|','!','\\prime'

下标客体:

'\\in','=','+','\\times','\\div','\\int','\\rightarrow','\\neq','>','<','\\geq','\\ge',

'\\ldots','\\pm','\\leq',']','}','\\exists',')',',','-','\\gt',',','\\lt','\\forall','\\in','.',

'\\dot','\\','|','!','\\prime'

(1)首先依据字符的高度差来判断主体和客体,如果前一个字符比后一个高,则认为前一个字符可以作为主体,进入下一步的判断。

(2)如果主体合理,客体不合理,Return;如果主体合理,客体合理,则进入下一步的判断。

(3)根据客体中点距离主体最高点、中点、最低点的欧氏距离来判断客体是偏上、偏中还是偏下,如果$L_1\leq L_2 or L_3 \leq L_2$则进入下一步的判断.

(4)$h_1$表示主体最高点和客体中点的垂直距离;$h_2$表示主体中点和客体中点的垂直距离,$h_3$表示主体最低点和客体中点的垂直距离.如果$h_1 \leq h_2$则认为这个客体是偏上的,属于第一个上标;如果$h_3 \leq h_2$,则认为这个客体是偏下的,属于第一个下标。

(5)对于以上字符,我们按照中点x坐标的大小从左到右进行排序,然后将所有字符重构出来,对于水平位置关系来说,区别只是没有出现上下标,因此我们可以共用上下标的重构标准.

语义逻辑重构

函数传入值匹配

目前支持以下函数:\sin,\cos,\tan

根据正则表达式匹配上述函数位置,对于类似$\sin^2(x)$的情况由重构结果:

r'\sin^{2(x)}'

修正为:

r'\sin^2(x)'

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐