4. 金融数据源解析:结构化、半结构化与非结构化数据的获取与处理
金融知识图谱的构建质量,80% 取决于底层数据的质量与覆盖度。金融数据源按结构化程度可分为三类:结构化数据(财报、行情)、半结构化数据(公告、新闻)、非结构化数据(研报、舆情)。本章将逐一解析每类数据的获取方式、处理要点及在知识图谱中的映射策略。
4.1 结构化数据:财报与行情
结构化数据以明确的表格、行、列形式存在,字段类型固定,是知识图谱中实体属性与数值关系最直接的来源。
4.1.1 财报数据获取与处理
- 获取来源:交易所官网(上交所、深交所)、巨潮资讯网、Wind/Choice 终端 API、上市公司季报/年报 PDF 中的 XBRL 或 CSV 附件。
- 核心字段:股票代码、报告期、营业收入、净利润、每股收益、资产负债率、现金流等。
- 处理流程:
- 字段对齐:不同交易所的财报科目名称存在差异(如“营业收入”vs“营业总收入”),需建立统一科目映射表。
- 时间标准化:将“2023-12-31”、“2023/12/31”、“2023年12月31日”统一为 ISO 8601 格式。
- 单位归一化:将“万元”、“亿元”、“元”统一转换为“元”或“亿元”,并记录原始单位。
- 缺失值处理:对关键财务指标缺失,采用前向填充(FFill)或行业均值插补,并标记数据质量标签。
实战提示: 财报数据中经常出现“调整后净利润”与“归母净利润”混用的情况。在知识图谱中,建议将两种口径分别建模为独立属性,并通过
hasAdjustmentType 关系区分,避免数值冲突。
4.1.2 行情数据获取与处理
- 获取来源:交易所 Level-1/Level-2 行情、Tushare/AkShare 开源库、彭博/路透终端。
- 核心字段:时间戳、开盘价、收盘价、最高价、最低价、成交量、成交额、涨跌幅、换手率。
- 处理要点:
- 复权处理:前复权与后复权对历史回测影响巨大,图谱中应同时存储“不复权”、“前复权”两个版本。
- 停牌与异常值:停牌日数据为 NaN,需标记为
tradingStatus: suspended;涨跌幅超过 10% 的异常值需人工复核。 - 时间对齐:不同交易所(A股、港股、美股)交易时段不同,跨市场图谱需统一转换为 UTC+8 并标注时区。
| 数据类型 | 典型字段 | 常见问题 | 图谱处理策略 |
|---|---|---|---|
| 财报 | 营业收入、净利润、报告期 | 科目名称不统一、单位不一致 | 建立科目映射表 + 单位归一化 |
| 行情 | 收盘价、成交量、时间戳 | 复权差异、停牌缺失、时区混乱 | 多版本存储 + 停牌标记 + 时区统一 |
4.2 半结构化数据:公告与新闻
半结构化数据具有自描述标签(如 XML、JSON、HTML),但结构不固定,字段数量与嵌套层级随内容变化。公告和新闻是金融知识图谱中事件抽取与关系发现的主要来源。
4.2.1 公告数据获取与处理
- 获取来源:巨潮资讯网 PDF 公告、交易所信息披露平台、上市公司官网投资者关系栏目。
- 处理难点:
- PDF 解析:公告多为 PDF 格式,需使用 PyMuPDF、pdfplumber 提取文本,但表格和复杂排版容易错位。
- 公告分类:需按“重大资产重组”、“关联交易”、“分红派息”、“业绩预告”等类别进行自动分类(基于标题关键词 + 正文特征)。
- 关键信息抽取:使用正则或命名实体识别(NER)抽取“交易金额”、“交易对手”、“生效日期”等结构化字段。
公告处理最佳实践: 先通过公告标题正则匹配确定公告类型,再调用对应的抽取模板。例如“关于……的公告”匹配“关联交易”后,使用
re.search(r'交易金额[::]\s*([\d,]+\.?\d*)', text) 抽取金额。
4.2.2 新闻数据获取与处理
- 获取来源:财经新闻网站(东方财富、新浪财经)、RSS 订阅、新闻聚合 API(如 NewsAPI)。
- 处理流程:
- 网页抓取:使用 Requests + BeautifulSoup 或 Scrapy 抓取新闻正文,注意处理反爬和动态加载。
- 正文提取:使用 Readability、Newspaper3k 等库去除广告、导航栏,提取纯净正文。
- 实体识别:识别新闻中涉及的股票代码、公司名称、人名、金额、时间等实体。
- 事件分类:将新闻归类为“正面/负面/中性”情绪,并映射到“利好/利空”事件类型。
| 数据源 | 格式特点 | 核心处理工具 | 图谱映射目标 |
|---|---|---|---|
| 公告 | PDF、标题结构化、正文半结构化 | PyMuPDF、正则、分类模型 | 事件节点 + 交易关系 |
| 新闻 | HTML、动态加载、噪声多 | Scrapy、Newspaper3k、NER | 事件节点 + 情绪属性 |
4.3 非结构化数据:研报与舆情
非结构化数据以自由文本、图像、语音等形式存在,没有预定义的数据模型。研报和舆情是金融知识图谱中深度语义理解与推理的核心挑战。
4.3.1 研报数据获取与处理
- 获取来源:券商研究所官网、慧博资讯、东方财富研报中心、付费 API(如 Choice 研报接口)。
- 处理难点:
- 长文本分割:研报通常 20-50 页,需按章节(摘要、行业分析、公司分析、盈利预测)进行智能分割。
- 表格与图表提取:研报中的财务预测表格、股价走势图需 OCR 或表格识别模型(如 Table Transformer)处理。
- 观点抽取:从“我们认为……”、“预计……”、“维持买入评级”等句式抽取分析师观点与评级。
注意: 研报中的“盈利预测”表格经常出现跨页断裂。建议在 PDF 解析时先检测表格边界,若表格跨页则合并两页的表格行,再按行解析为图谱中的
FinancialForecast 节点。
4.3.2 舆情数据获取与处理
- 获取来源:雪球、股吧、微博、微信公众号、贴吧等社交平台。
- 处理流程:
- 爬虫采集:使用模拟登录、API 代理池采集帖子标题、正文、评论、转发数、点赞数。
- 文本清洗:去除表情符号、@用户、URL、重复刷屏内容。
- 情感分析:基于金融领域情感词典(如 Loughran-McDonald 词典)或预训练模型(如 FinBERT)计算情感得分。
- 舆情热度计算:综合发帖量、阅读量、情感波动率,构建舆情热度指数。
4.4 三类数据源对比与融合策略
| 维度 | 结构化数据 | 半结构化数据 | 非结构化数据 |
|---|---|---|---|
| 数据格式 | CSV、XBRL、数据库表 | PDF、HTML、JSON | 纯文本、图片、语音 |
| 解析难度 | 低 | 中 | 高 |
| 图谱映射方式 | 直接映射为属性 | 规则 + 模型抽取事件 | NLP 深度理解 |
| 数据质量 | 高(经过审计) | 中(存在噪声) | 低(主观性强) |
| 更新频率 | 季度/日 | 日/实时 | 实时 |
| 融合策略 | 作为基准事实 | 补充事件线索 | 提供市场情绪 |
融合策略建议: 在知识图谱中,以结构化数据(财报、行情)作为实体属性的“黄金标准”,半结构化数据(公告、新闻)用于构建事件节点与关系,非结构化数据(研报、舆情)用于丰富实体描述与情绪标签。三者通过
hasEvent、hasSentiment 等关系进行关联,形成完整的金融知识网络。
4.5 代码示例:财报数据清洗与图谱映射
以下示例展示从 CSV 财报数据到知识图谱三元组的转换过程:
import pandas as pd
import re
# 1. 读取原始财报数据
df = pd.read_csv('financial_report_raw.csv')
print("原始字段:", df.columns.tolist())
# 2. 字段对齐:统一科目名称
subject_mapping = {
'营业总收入': 'revenue',
'营业收入': 'revenue',
'净利润': 'net_profit',
'归属于母公司所有者的净利润': 'net_profit_parent'
}
df['subject_standard'] = df['subject'].map(subject_mapping)
# 3. 单位归一化:将“万元”转为“元”
def normalize_unit(value, unit):
if unit == '万元':
return value * 10000
elif unit == '亿元':
return value * 100000000
return value
df['value_normalized'] = df.apply(
lambda row: normalize_unit(row['value'], row['unit']), axis=1
)
# 4. 生成图谱三元组 (subject, predicate, object)
triples = []
for _, row in df.iterrows():
triple = (
f"stock:{row['stock_code']}",
f"hasFinancialMetric",
f"metric:{row['subject_standard']}_{row['report_date']}"
)
triples.append(triple)
# 5. 输出前 5 条三元组
for t in triples[:5]:
print(f"({t[0]}) -- [{t[1]}] --> ({t[2]})")
代码要点: 上述代码中,
subject_mapping 是字段对齐的核心字典,需要根据实际数据源持续维护。图谱映射时,建议将 stock_code 和 report_date 组合作为唯一标识,避免重复节点。