3、金融数据源分析:结构化数据(财报、行情)、半结构化数据(新闻XML)、非结构化数据(研报PDF、公告)
做金融事件图谱,第一步不是写代码,而是搞清楚数据从哪来、长什么样、能挖出什么。
我见过不少团队,一上来就怼着PDF使劲抽,结果抽出来的实体全是乱码。说白了,数据源没分析透,后面所有工作都是白费。
这一章,我把金融数据源分成三类来讲:结构化、半结构化、非结构化。每一类我都踩过坑,也总结了一些实战经验。
3.1 结构化数据:财报与行情
结构化数据,就是那种规规矩矩的表格数据。行是记录,列是字段,每个格子都是原子值。这类数据最好处理,但陷阱也不少。
3.1.1 财报数据
财报数据,说白了就是三大表:资产负债表、利润表、现金流量表。这些数据通常来自交易所、Wind、东方财富等接口。
我个人习惯把财报数据分为两类:
- 存量数据:比如总资产、净资产、股本。这些是时点数,每个报告期一个值。
- 流量数据:比如营业收入、净利润、经营活动现金流。这些是区间数,需要关注报告期覆盖的时间范围。
嗯,这里要注意一个坑:数据对齐。不同数据源对同一指标的命名可能不同。比如“营业收入”,有的叫“营业总收入”,有的叫“Revenue”。我建议在入库前做一个标准映射表。
实战经验:我在项目中遇到过,某家公司的财报数据,Q1和半年报的“净利润”口径不一致。Q1是归母净利润,半年报是合并净利润。如果不做对齐,事件抽取会直接出错。
3.1.2 行情数据
行情数据,就是股票的价格、成交量、换手率这些。这类数据的特点是:高频、海量、时间序列强。
做事件图谱时,行情数据主要用来做事件验证。比如,你抽取出一个“业绩预增”事件,那股价在事件发布后有没有异常波动?这就是一个很好的验证手段。
我建议把行情数据按频率分层:
| 频率 | 典型字段 | 用途 |
|---|---|---|
| 日频 | 开盘价、收盘价、最高价、最低价、成交量 | 事件验证、趋势分析 |
| 分钟频 | 每5分钟K线、成交明细 | 高频事件检测、盘口分析 |
| Tick级 | 逐笔成交、买卖盘口 | 量化回测、微观结构分析 |
小技巧:行情数据的时间戳,一定要统一成UTC+8。我见过有人用Unix时间戳,结果跨时区处理时,事件日期对不上。
3.2 半结构化数据:新闻XML
半结构化数据,有标签、有层级,但不像表格那么规整。新闻XML就是典型代表。
为什么新闻XML重要?因为很多金融事件,比如“并购重组”、“高管变动”、“监管处罚”,都是先出现在新闻里,然后才反映到财报里。新闻是事件图谱的第一手来源。
3.2.1 新闻XML的结构
一个典型的金融新闻XML,大概长这样:
<?xml version="1.0" encoding="UTF-8"?>
<news>
<header>
<title>XX集团拟收购YY公司51%股权</title>
<pubDate>2024-03-15 09:30:00</pubDate>
<source>证券时报</source>
<category>并购重组</category>
</header>
<body>
<paragraph>XX集团今日公告,拟以现金方式收购YY公司51%股权...</paragraph>
<paragraph>本次交易作价约为12.5亿元...</paragraph>
</body>
<metadata>
<stockCode>600000</stockCode>
<industry>金融</industry>
</metadata>
</news>
你看,XML里既有结构化字段(标题、时间、来源),也有非结构化内容(正文段落)。处理这类数据,我建议分两步走:
- 解析元数据:用XPath或DOM解析器,把header和metadata里的字段抽出来。
- 处理正文:正文部分需要做NLP,比如命名实体识别、关系抽取。
避坑指南:我曾经遇到过,某新闻XML的编码是GBK,但解析器默认用了UTF-8。结果所有中文都变成了乱码。后来我养成了一个习惯:解析XML前,先检查encoding声明。
3.2.2 新闻XML的常见问题
- 标签不统一:有的源用<title>,有的用<headline>。需要做标签映射。
- 嵌套过深:有些XML的body里还有子标签,比如<table>、<list>。解析时要递归处理。
- 特殊字符:&、<、>这些字符,在XML里需要转义。如果源数据不规范,解析会报错。
3.3 非结构化数据:研报PDF与公告
非结构化数据,是事件图谱的金矿,也是最难啃的骨头。研报PDF和公告,就是典型代表。
3.3.1 研报PDF
研报PDF,说白了就是券商分析师写的报告。里面有观点、有数据、有图表。但PDF本身是排版格式,不是数据格式。
处理研报PDF,我建议按这个流程来:
- 文本提取:用PyMuPDF或pdfplumber,把PDF里的文字抽出来。
- 表格识别:研报里经常有财务预测表、估值表。这些表格需要单独提取,用camelot或tabula。
- 图表解析:这个比较难。我一般用OCR+图表识别模型,把趋势图、柱状图转成数据点。
个人经验:我记得有一次,一份研报PDF里有个“盈利预测表”,但表格是图片格式的。pdfplumber根本抽不出来。后来我用PaddleOCR做了文字识别,再配合正则表达式,才把数据拼出来。嗯,这个过程很痛苦,但结果很值得。
3.3.2 公告PDF
公告PDF,是上市公司发布的正式文件。比如年报、临时公告、股东大会决议。这类PDF的特点是:格式相对固定,但内容长度差异很大。
公告PDF的处理,我建议重点关注这几个部分:
- 标题:公告的标题,往往直接包含事件类型。比如“关于收购XX公司的公告”。
- 重要提示:公告开头通常有一段“重要提示”,里面会说明交易金额、交易对手等关键信息。
- 正文:正文里会有详细的交易条款、风险提示、法律意见等。
小技巧:公告PDF的页眉页脚,经常有“第X页/共Y页”这样的信息。这些信息对拼接多页PDF很有用。我建议在提取文本时,保留页眉页脚,不要直接过滤掉。
3.4 知识体系总览
为了让你更直观地理解三类数据源的关系,我画了一张图:
这张图的核心逻辑是:数据源不同,处理方式不同,但最终都汇聚到事件抽取和知识图谱构建。你想想看,不管数据是表格、XML还是PDF,最后都要变成“实体-关系-事件”的三元组。
3.5 本章小结
这一章,我们聊了金融数据源的三种类型:
- 结构化数据:财报和行情,规整但要注意对齐和口径。
- 半结构化数据:新闻XML,有标签但需要解析和映射。
- 非结构化数据:研报PDF和公告,信息最丰富但提取难度最大。
我个人觉得,数据源分析这个环节,花再多时间都不为过。因为数据质量决定了事件图谱的天花板。你后面算法再牛,数据是脏的,结果也是脏的。
一句话总结:结构化数据是骨架,半结构化数据是血肉,非结构化数据是灵魂。三者缺一不可。