蚂蚁获FinQA竞赛冠军,在长文本数值推理AI技术上取得突破

2022/06/21 19:55
阅读数 822
近日,由数金风险管理部模型团队组成的蚂蚁代表队Ant Risk AI,参加了金融文章数值推理竞赛FinQA (NAACL 2022 Workshop SUKI Task) ,最终斩获冠军,在长文本数值推理AI技术领域获得相应突破。本文将 对模 型方案细节做简要介绍,欢迎大家一同探讨。


图1.private test榜排名


01

背 景

财务报表数量巨大,使得人们很难获取并分析公司的财务状况,对财报自动化分析并得到稳健的、可解释性强的数值推理面临着独特的挑战。FinQA论文为此提出了一个针对金融财报的数值推理问答数据集,数据集中包含异构的(表格和文字说明)公司财报,并招募专家编写关于数值推理的问答对,答案中既包含了计算结果,也有可解释的计算过程,可以点击此处查看数据样例。竞赛主办方根据上述数据集举办了FinQA竞赛,参赛选手需要训练模型预测计算过程与计算结果来回答针对公司财报提出的一些需要数值推理计算的问题。


02

数据集

2.1 介绍

FinQA数据集包含带有表格(结构化数据)与文字说明(非结构化数据的公司财报,计算的操作包括六种数值操作和四种表格聚合操作,一个计算过程可包含多步计算操作。比赛提供了包含正确答案的train(6251)、valid(883)、test(1147)数据集和用于比赛排名且不带正确答案的private test数据集。


FinQA数据集中,23.42%的问题仅需要财报的文字叙述即可回答,62.43%的问题仅需要财报的表格即可回答,剩余14.15%的问题需要结合二者回答。同时,46.30%的问题仅涉及财报中的一句文本或者一行表格中的数值,42.63%的问题涉及两行文本或者表格,剩余11.07%则需要更多。在计算过程中,divide、subtract、add、multiply分别占据了45.29%、28.20%、14.98%、5.82%,59.10%的计算过程仅有一步。


图2.FinQA数据示例


图3.FinQA数据统计

2.2 DSL

FinQA论文中定义了Domain Specific Language,由数值操作和表格操作组成,定义program由多步操作组成:



每个操作有一个参数列表   ,计算操作包括add、subtract、multiply、divide、greater、exp 六种数值操作和table-max、table-min、table-sum、table-average 四种表格聚合操作,每一步计算可使用前面计算的结果,用#   表示第   步的结果。


2.3 评估

根据计算结果是否相等定义了execution accuracy,但有时模型可能“误碰”正确数值结果,此时存在高估的可能。


根据计算过程是否相等定义了program accuracy,但有时问题可使用不同的计算过程(仅指不同的解题思路,类似于加法的两个参数互换位置等属于相同的计算过程),同一个问题会存在多个正确的计算过程,此时存在低估的可能。


因此,模型的真正性能会在execution accuracy和program accuracy之间。


代码中使用sympy包的simplify函数判断两个数学符号表达式是否相等,因此如下的两个program是相等的:



2.4 分布不一致

我们使用adversarial validation技术对FinQA数据集进行分析,我们将train、valid、test混合到一起,训练一个分类器去区分数据的来源,分类器在train上达到了0.91的AUC,在test上达到了0.85的AUC,这意味着test和其他数据之间的分布不一致,我们重新划分train与valid减少valid与test的gap。


03

模 型


我们的模型分为两部分:从全文中召回包含计算所需数值的句子的retriever和根据问题与召回句子生成计算过程的program generator。


3.1 retriever

因为回答大部分的问题涉及的文本或表格数量都很少,因此我们首先用retriever来缩小program generator的查询范围。retriever由baseline模型、prompt learning模型和context模型三个模型集成而得到。财报由多句文本和表格组成,使用模版将表格转换为文本(同FinQA论文),retriever根据数值推理问题从所有文本中召回计算所需数值所在的文本,缩小查询计算所需数值的范围,降低program generator生成计算过程的难度。


3.1.1 baseline模型 


同FinQA论文,baseline模型在训练阶段将问题与单句文本拼接,然后输入BERT做二分类任务,计算所需数值所在的文本视为正样本,其余文本视为负样本,正负样本采样比例为1:3,每个epoch都对负样本重新采样。在预测阶段,模型对所有文本输出其正样本类别对应的分数,按照分数从高到低将这些文本排序,召回分数高的文本(表格)


3.1.2 prompt learning模型


本文数据量较少,因此我们使用经常被用在few shot的prompt learning来解决问题。实验中使用OpenPrompt实现prompt learning训练模型,我们选择了MixedTemplate和ManualVerbalizer,混合模版见下文示例,ManualVerbalizer将回答yes和no映射到二分类标签,微调的语言模型使用T5-large,正负样本采样比例为1:3,每个epoch都对负样本重新采样。预测阶段同baseline模型,召回预测分数高的文本(表格)


{"placeholder":"fact"} Question: {"placeholder":"question"} {"soft": "Is the relevant data of the problem in the previous article ?"} The answer was {"mask"} .


3.1.3 context模型


上述两种模型每次都只能考虑一句文本,无法充分利用文本的上下文信息,为此我们提出了一个新的context模型,该模型每次按照财报中的文本顺序将问题与n句话拼接,不同语句之间使用[SEP]连接,示例如下(为方便下文说明,对[SEP]进行编号)


[CLS] (Question) [SEP 0] Sentence 1 [SEP 1] Sentence 2 [SEP 2] ...... [SEP n-1] Sentence n [SEP n]


每一句文本对应两个[SEP],类似于roberta-base for QA模型预测问题答案的开始位置与结束位置,我们使用句子前的[SEP]与句子后的[SEP]来预测这句话是否包含回答问题所需的数值。在训练时,使用两个网络层分别对[SEP 0]、[SEP 1]......[SEP n-1]和[SEP 1]、[SEP 2]......[SEP n]做二分类,前者针对每句文本前的[SEP]预测,后者针对每句文本后的[SEP]预测,包含回答问题所需数值的文本前后的[SEP]对应正分类,否则分类为负。在我们的实验中 n=8,为减少文本位置对模型推理的影响,我们设置了步长为4的滑动窗口来生成训练样本。


在预测阶段,我们不设置滑动窗口(或可认为滑动窗口步长为8),对每一句文本前后的[SEP]分别预测其正类别分数,得到start_score和end_score,按照两者分数之和对所有文本从高到低排序,召回预测分数高的文本(表格)


3.1.4 集成


在图4的venn图中,绿色表示三个模型均正确预测的文本,蓝色表示仅一个或两个模型正确预测,橘黄色表示三个模型均未正确预测,可以看到三个模型虽然使用同样的数据训练,但是其预测能力仍有不同,这为集成模型提供了基础。上述三个模型均对每一句文本输出其正类别分数,利用valid数据集可以基于这些分数训练一个逻辑回归分类器来达到集成的效果。


我们为program generator生成两种模式的训练数据,第一种(stack)根据逻辑回归分类器预测的分数排序,召回top k个高分文本;第二种(stack positive)根据逻辑回归分类器的分类结果召回分为正类别的文本。前者对每个问题召回的文本数量固定,召回率较高;而后者召回数量不固定,召回率略低,但平均召回数量较少。


图4.三个模型在test上召回top3的
正确文本个数venn图


3.2 program generator


在retriever缩小了回答问题所需数值的查询范围之后,我们使用program generator来生成具体的计算过程。program generator由baseline模型、transformer decoder模型和remove redundancy模型集成而得到。program generator每一步预测计算符号及其参数,计算的参数可为先前的计算结果或召回文本(表格)中的数值,直到预测EOF符号结束计算过程。


3.2.1 baseline模型


模型结构同FinQA论文,模型使用attention和LSTM来捕获各种输入(文本、计算符号等)及历史的信息,然后在一定的规则(确保生成的计算过程合法)之下生成计算过程。但在训练原文的模型时会遇到收敛速度慢和loss突然大幅增加的问题,因此我们做了如下改动:

  • 冻结BERT(roberta)参数,先训练其余参数几个epoch,然后解冻BERT参数一起训练。

  • 使用梯度裁剪、warm up、linear scheduler和带有weight decay的AdamW优化器。


图5.generator baseline模型


下面简单介绍baseline模型:


首先做如下定义:

  • question和retriever检索到的文本经过token化后得到{   },为方便预测,记录下数值和表格行名的位置。

  • DSL中的特殊符号token{   }。

  • 表示每一步计算结果#   的 step memory token{   }


接下来使用预训练模型对{   } 编码得到{   }从相应的embedding层获取{   }和{   }的编码 {  }和 {  },用   表示这些token的embed ding[    ;   ;    ]。


baseline模型使用LSTM解码,在第T步,将经过更新的program token embeddings H输入到LSTM中得到输出   ,   与{   }、decoding history分别做attention得到   和   ,将   和   和   拼接并线性转换回   的维度,得到   =   [      ]。    与{   }做另一次attention得到   ,然后做一次线性转换得到   =   [       °    ]。最终的预测   =   (   ·   ),训练时使用cross entropy loss。


step memory tokens 对应的{   }表示生成的program每一步的信息,因此在解码的过程中需要每步更新。baseline模型在每一步计算   =   (   )来更新对应的{   }。


在推理阶段,baseline模型通过使用多种MASK来保证生成的program的结构正确性。


3.2.2 remove redundancy模型


相比于其他常见的NLP数据集,FinQA数据集所含的数据数量较少,为减少需要训练的参数数量、降低训练的难度,我们提出了remove redundancy模型。baseline模型需要将全部文本输入和计算符号一同输入decoder作预测,remove redundancy模型则仅将文本中的数值和表格行名(对应表格聚合计算)与计算符号一同输入decoder,remove redundancy意味着仅对文本中的数值和表格行名做预测。


3.2.3 transformer decoder模型


该模型使用与baseline模型相同的encoder编码输入,但为更好地捕获历史信息,我们使用4层的transformer做decoder替代LSTM,decoder输出的向量与输入做attention,根据attention权重来预测下一步,同时该模型简化了baseline模型的部分attention计算。为加快训练速度,我们使用了transformer并行化训练方法。


3.2.4 集成


program generator采取投票(vote)的方式做集成,每个模型使用其在private test上得到的execution accuracy作为投票权重。program generator的投票方式有两种:对整个program投票、对每个program的每一步step投票。经过实验对比,我们最终选择了对整个program投票的方式。


图6.  不同模型的预测差异


04

实验结果


4.1 retriever


我们在train上训练,在valid上挑选最优模型并训练逻辑回归分类器集成模型,在test上测试,retriever召回率表现见下表:



召回率计算方式:先计算单例召回率然后平均



stack由3个模型集成得到,使用全部文本数据训练分类器,根据分类器预测的分数召回固定top k个高分文本;stack positive正负样本采样比例2:1训练分类器,根据分类器预测的类别最多召回top k个文本。第二个表格统计了stack与stack positive在test上的召回率与预测准确率,stack positive相比于stack以召回率的下降为代价召回更少的文本。


4.2 program generator


program generator的模型均使用stack和stack positive生成的训练数据进行训练,我们使用valid挑选最优模型,在valid和private test上的实验结果如下:



从表中可以看到,对整个program投票的方式相对于单模型可以提升4.14%的execution accuracy和3.37%的program accuracy。上表中三个单模型的结果均基于stack生成的数据,但vote模型基于多个以stack或stack positive生成的数据训练的program generator模型。


4.3 消融实验


针对前文提到的消除数据不一致的方法,我们做了消融实验证明其作用,我们分别在原数据集和重新划分后的数据集上训练baseline模型,然后利用相应的valid来选取最优模型在private test上测试,结果见下表:



从表中可以看到,使用adversarial validation重新划分数据集,可以比较有效地消除valid和private test数据分布之间的gap。


05

实验结果


从此次比赛的结果来看,我们使用NLP预训练模型与集成的方法虽然以execution accuracy 71.93%和program accuracy 67.03%取得了第一名的成绩,但是与人类专家的execution accuracy 91.16%和program accuracy 87.49%相比仍然有很大差距,这说明当前的NLP预训练模型与常见方法仍然无法很好地解决数值推理问题,这一领域仍然需要NLPer们更为深入的研究与探索。



延伸阅读:



本文分享自微信公众号 - 支付宝技术(Ant-Techfin)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部