ToB企服应用市场:ToB评测及商务社交产业平台

标题: 最新实践!怎样基于 DB-GPT 搭建财报分析助手? [打印本页]

作者: 铁佛    时间: 2024-9-20 04:54
标题: 最新实践!怎样基于 DB-GPT 搭建财报分析助手?
DB-GPT
财报分析助手
精准剖析数据
实现智慧决议
背景
近来,使用大模型进行财务报表分析正徐徐成为垂直范畴的一个热门应用。大模型可以大概比人类更准确地理解复杂的财务规则,并在基于专业知识的基础上输出合理的分析结果。然而,财务报表信息庞大且复杂,对数据分析的准确性要求极高,通用的RAG和Agent的解决方案往往难以满足这些需求。
以某公司的2022年财务报表为例,传统方法在处置惩罚类似“2022年XXX子公司的第三季度的业务净利润是多少?”的查询时,通常通过知识向量相似检索和匹配来召回最相关的文本块进行总结和问答。然而,财务年报中包罗多处相关信息,如差别季度的利润表、现金流量表等,这些信息可能会引发误判。假如不能准确召回并理解正确部分,就容易天生错误答案。假如涉及到财务指标的盘算,分析过程可能会变得更加复杂。例如,盘算毛利率、净利率等指标需要对收入和本钱等多方面的数据进行综合分析。
为了克服大模型应用中的这些挑战,我们需要结合财务范畴的知识背景,添加专门的外部模块来增强其功能。本文将以DB-GPT的AWEL编排模式为例,借助DB-GPT-Hub的几个关键原子,详细阐述怎样使用大模型进行有效的财报数据分析,希望能为在垂直范畴的进行数据AI赋能的朋侪提供一些思考。
架构方案介绍
目前我们的实现方式是通过上传公司年报,使用大模型作为知识驱动引擎,调用向量数据库、关系型数据库、OCR服务以及相关模型等组件,通过AWEL(agent流式编排)构建一个财报分析的问答助手,可以大概直接回答用户这几类问题:

这里的架构设计紧张是通过意图分类解决财报分析中可能出现的问题。针对每类意图执行单独的处置惩罚链路,每条处置惩罚链路基于差别场景精心设计。同时为了保证数据分析的正确性,我们还会通过剖析和抽取用户查询中的相关参数,调用工具或执行 SQL 查询,为分析结果提供更准确的数据支持。因此整个架构围绕 3 部分进行实现,金融知识构建,查询意图识别,以及金融知识检索。


金融知识构建
在A股上市公司发布的财务报告中,通常会包罗一些紧张的文本形貌、财务表格和其他附注信息。每个财务报表都提供了差别方面的财务数据,用来展示公司的财务状态、经营结果和现金流情况:

这些表格数据布局化程度高,需要提取出完整有用的数据信息进行加工处置惩罚。而财报文本部分则包罗大量公司简介、业务形貌、风险分析和管理层讨论等紧张信息。我们希望大模型可以大概通过深入理解文本内容,提取对投资决议有帮助的信息,如公司将来的战略规划、市场风险和机遇等。
数据预处置惩罚,让杂乱数据布局化
针对财报pdf这样的非布局化数据处置惩罚,考虑到针对财报文档的一些特性,表格数据麋集,专业术语繁多等情况,需要在信息抽取之前对pdf这样的非布局化数据进行预处置惩罚,紧张的思路是将非布局化数据 —> 布局化数据,因此起首在数据读取和数据预处置惩罚模块,使用pdfplumber按页读取并转换为json格式,而且识别出哪些是需要的文本数据,哪些是表格数据,哪些是不需要的数据,比如页眉,页脚等等。

知识抽取,精准提炼文本和表格信息
数据预处置惩罚后,我们得到了标准的布局化的json数据,基于处置惩罚后的json数据,我们将内容分别为文本和表格两大块,针对这两块数据分别进行文本信息抽取和表格抽取。
●文本抽取:
文本抽取包括知识切片,元数据信息抽取,embedding等一系列子任务构成。
知识切片紧张目的是:
1.保持语义相关性,也就是上下文相关性,这直接关乎回复准确率。
2.保持在大模型的上下文限制内,分块保证输入到LLMs的文本不会凌驾其token limitations。这里有很多种分片计谋进行选择:按照文本大小切分,按照页切分,按照标题进行切分。
本次案例为了保持语义的相关性,推荐采取按照页切分和按照标题级别进行切分:
1.按照页切分:
按照 pdf 每一页进行切分,保留每一页的完整性。

2.按照标题级别切分:
这里需要识别财报里面的标题信息,以标题层级构建chunk的树形节点,形成一个多叉树布局,每一层级节点只需要存储文档标题,叶子节点存储具体的文本内容。这样使用树的遍历算法,假如用户问题命中相关非叶子标题节点,就可以将相关的子节点数据进行召回。


●表格抽取:
我们的目标是对金融财报指标进行盘算和分析,这里有两个****难点

因此,针对这两个问题,我们需要对财报里面的表格进行归并,这里有两种归并方案:
1.归并成一张大宽表,由于差别公司的紧张财报数据的表格定义都是相似的,因此可以针对财报数据的表格进行分类:

根据分类情况单独提取每一种别的表格信息进行归并,最后再将 3 类表格汇总成一张大宽表,天生终极的 DataFrame。
优点:

**缺点:**在表格提取和数据归并的过程中,存在一部分数据的丢失,导致有些信息的缺失。

2.归并成多张表数据,包括基本信息表,员工信息表,资产负债表,现金流表,其他信息表等等。

意图识别
一、问题分类
用户的查询需求多种多样,包括数据查询、年报问答等。模型需要准确识别用户意图,调用相应功能模块。例如,用户查询公司资产负债率时,模型需要识别这是一个数据查询哀求,并调用相关公式进行SQL查询;询问公司将来增长计谋时,模型需调用年报问答模块,基于RAG模块提供回复。
目前我们提供了几种差别的意图识别方案,每种方案各有优缺,大家可以根据自己的资源和精度要求进行选择实现:
方案一、基于embedding(Bert)的识别


方案二、大模型prompt的ICL能力

方案三、大模型SFT

方案四、在大模型上sequence标签监督微调

还有的工作是在微调到时候将因果掩码去除了,因为因果掩码的存在会导致token级别表示的致命信息丢失,会限制双向信息流的交互,模型难以理解关键信息
(https://arxiv.org/pdf/2310.01208)
当标注数据语料匮乏时,可以应用大模型+sft+prompt工程模式辅助冷启动,积累一定标注语料后切BERT式微调方式,以提升任务精度。
二、槽位提取
处置惩罚用户查询时,需要识别query中的关键槽位(slot),并根据这些槽位在数据库中进行精准匹配。例如,用户查询“2023年Q1的净利润”时,系统需要识别时间(2023年Q1)和指标(净利润),据此查询数据库获取结果。我们具体也做了以下实现:

  1. sentence = "请问你知道《Harry Potter and the Philosopher's Stone》的作者是谁吗?"
  2. [{'entity_group': 'book', 'score': 0.8257975, 'word': "Harry Potter and the Philosopher's Stone", 'start': 6, 'end': 47}]
  3. sentence = "近日,北京市市场监管局召集美团等互联网企业负责人,召开落实“长江禁捕打非断链”工作电商平台行政约谈会。"
  4. [{'entity_group': '约谈机构', 'score': 0.8824913, 'word': '北京市市场监管局', 'start': 3, 'end': 11}, {'entity_group': '公司名称', 'score': 0.9569145, 'word': '美团', 'start': 13, 'end': 15}]
复制代码

Text2SQL
财务分析过程中,大模型Text2SQL的能力很关键。用户查询经过意图识别后,输出意图假如为数据分析类,则会调用为Text2SQL模块进行数据查询与盘算。

数据库布局



Query 查询预处置惩罚:

SQL 优化

接下来我们看下每个细分种别的 text2sql 的处置惩罚和优化:
1.基础信息查询
基础信息查询最大的挑战就是需要找到正确的数据列,将原始查询信息进行改写。包括公司名称,年份,查询信息意图,假如用户输入’贵州航天公司2019代表人是谁’基础信息问题,假如不做任何改写,天生的sql就变成了’SELECT 代表人 FROM fin_report WHERE 公司名称=‘贵州航天公司’,这样天生的sql执行的结果肯定是不正确的。因此需要根据正确的数据列预先对查询进行改写,这样天生sql才是符合预期的。

2.财务指标盘算
财务分析中常用很多专业财务指标形貌企业经营状态,例如资产负债率、业务利润率、速动比率等。这要求模型可以大概使用这些公式盘算特定财务指标。因此我们需要事先建立财务盘算指标公式库,例如:
  1. "毛利率": {"公式": "毛利率=(CAST(营业收入)-CAST(营业成本))/CAST(营业收入)", "数值": ["营业收入", "营业成本"]},
  2. "营业利润率": {"公式": "营业利润率=CAST(营业利润)/CAST(营业收入)", "数值": ["营业利润", "营业收入"]},
  3. "流动比率": {"公式": "流动比率=CAST(流动资产合计)/CAST(流动负债合计)", "数值": ["流动资产合计", "流动负债合计"]},
  4. "速动比率": {"公式": "速动比率=(CAST(流动资产合计)-CAST(存货))/CAST(流动负债合计)", "数值": ["流动资产合计", "存货", "流动负债合计"]},
  5. "资产负债比率": {"公式": "资产负债比率=CAST(负债合计)/CAST(资产总计)", "数值": ["负债合计", "资产总计"]},
  6. "现金比率": {"公式": "现金比率=CAST(货币资金)/CAST(流动负债合计)", "数值": ["货币资金", "流动负债合计"]},
  7. "非流动负债合计比率": {"公式": "非流动负债合计比率=CAST(非流动负债合计)/CAST(负债合计)", "数值": ["非流动负债合计", "负债合计"]},
  8. "流动负债合计比率": {"公式": "流动负债合计比率=流动负债合计/负债合计", "数值": ["流动负债合计", "负债合计"]},
  9. "净利润率": {"公式": "净利润率=CAST(净利润)/CAST(营业收入)", "数值": ["净利润", "营业收入"]}
复制代码
与基础信息查询差别的是,财务指标盘算需要预置指标库,将指标的盘算公式通过RAG方式进行召回,帮助模型更好的理解指标的盘算规则是什么。

3.信息统计分析
统计分析种别中,经常需要涉及分组(GROUP BY)和排序(ORDER BY), 因此,除了前面讲到的需要召回到具体查询的数据列以后,还需要召回统计维度和规则,是需要分组还是需要排序等等。

金融知识检索
通过对查询进行意图识别后,通过知识检索模块,根据用户的query精准的找到相关性比较高、有一定时效性、比较丰富的内容。目前分为四个阶段,query的改写,元数据过滤,多级召回以及相关性重排序。

查询改写
有了意图识别后,查询改写目的是将用户的query改写成语义更清晰、含义更丰富的一个可检索的Query。比如用户问贵州公司资产负债率是多少,但是实际数据库存的公司名称是贵州航天电器股份有限公司,因此需要对查询的主体进行补全改写,当然常用的改写手段还有查询纠错,使用大模型来进行改写等等。通过这一系列的处置惩罚,终极目的是把用户的Query从一个主体缺失,语义不明确、不完整、有歧义、有错的改写成一个正确的、语义表达清晰的,可召回的Query。

元数据过滤

当我们把索引分成很多 chunks 而且都存储在相同的知识空间里面,检索服从会成为问题。比如用户问浙江我武科技公司相关信息时,并不想召回其他公司的信息。因此,假如可以通过公司名称元数据属性先进行过滤,就会大大提升服从和相关度。

多级召回

传统 Native RAG 的做法是依靠向量相似度进行单独召回获取相关上下文,假如只靠向量相似度召回,可能检索的内容存在缺失或者语义不够完整的问题,因此在财报除了向量相似度召回以外,我们也需要关键词召回,文档树召回,SQL 盘算召回和 GraphRAG 召回来增补 Native RAG 的单一召回完整性不够的问题。

相关性重排序

有时候随着知识空间的文档越来越多,我们的检索结果并不抱负,缘故原由是 chunks 在系统内数目很多,我们检索的维度不一定是最优的,一次检索的结果可能就会在相关度上面没有那么抱负。仅仅靠 embedding 模型的向量召回,这时候我们需要有一些计谋来对检索的结果做重排序,比如使用 planB 重排序,或者把组合相关度、匹配度等因素做一些重新调整,得到更符合我们业务场景的排序。因为在这一步之后,我们就会把结果送给 LLM 进行终极处置惩罚了,以是这一部分的结果很紧张。
与 Embedding 模型差别,重排序模型以查询和上下文作为输入,直接输出相似度分数,而不是 Embeddings。紧张的是要留意,重新排序模型是使用交叉熵损失函数进行优化的,答应不限于特定范围的相关性分数,乃至可以是负的。目前,没有很多可用的重排模型。一种选择是 Cohere 提供的在线模型,可以通过 API 访问。还有一些开源模型,如 bge-reranker-base 和 bge-reranker-large 等。
应用实践
本章节会介绍怎么通过AWEL表达式语言实现金融财报答疑机器人应用。安装金融财报分析应用相关教程:

财报知识加工workflow


财报智能问答 workflow


读者福利:假如大家对大模型感兴趣,这套大模型学习资料一定对你有用
对于0基础小白入门:
   假如你是零基础小白,想快速入门大模型是可以考虑的。
  一方面是学习时间相对较短,学习内容更全面更会合。
二方面是可以根据这些资料规划好学习计划和方向。
  包括:大模型学习线路汇总、学习阶段,大模型实战案例,大模型学习视频,人工智能、机器学习、大模型书籍PDF。带你从零基础系统性的学好大模型!





欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4