4. 金融图构建方法
金融图建模的第一步不是选模型,而是把分散在业务系统、公告文本和外部数据源中的金融对象与关系,抽象成一张可计算的异构图。与社交网络不同,金融图往往同时包含账户、企业、个人、证券、行业、事件等多种节点类型,边也带有方向、时间、金额、比例、置信度等属性。本节围绕四类最常见的数据源,讲清从原始记录到图结构的构建方法、字段映射与常见陷阱。
一、核心原理:金融图是“实体—关系—属性”的三元投影
任何金融数据源都可以拆成三元组:主体(谁)、关系(做了什么)、属性(何时、多少、多强)。交易记录中,主体是付款方与收款方,关系是资金流,属性是金额与时间戳;股权关系中,主体是股东与被投企业,关系是持股,属性是持股比例;供应链中,主体是供应商与采购方,关系是供货,属性是采购金额与账期;新闻共现中,主体是新闻中出现的实体,关系是共现,属性是共现次数与情感倾向。
构建金融图的关键判断是:哪些字段升格为节点,哪些字段降格为边属性。例如“行业”既可以作为节点形成企业—行业隶属边,也可以作为企业节点的一个类别属性。前者适合做跨行业传导分析,后者适合做节点分类。选择取决于下游任务:若需要沿行业路径传播风险,就应建为节点;若只做企业标签预测,作为属性更省存储。
建模原则:节点承载“可被独立查询和连接的实体”,边承载“两个实体之间可量化、可定向、可随时间变化的作用”。金额、比例、时间戳、置信度优先放在边上,而不是节点上。
二、四类数据源的构建流程与字段映射
下面给出从原始表到 PyTorch Geometric 可用的 HeteroData 对象的通用流程。核心步骤是:清洗实体标识 → 建立节点索引 → 抽取边与边属性 → 构造特征矩阵 → 封装为异构图。
# 以交易记录为例的构建骨架(伪代码)
import torch
from torch_geometric.data import HeteroData
data = HeteroData()
# 1. 节点:账户去重并建立全局索引
accounts = sorted(set(df['payer_id']) | set(df['payee_id']))
acc2idx = {a: i for i, a in enumerate(accounts)}
data['account'].x = torch.tensor(account_features) # [N_acc, F]
# 2. 边:付款方 -> 收款方,金额与时间作为边属性
src = [acc2idx[p] for p in df['payer_id']]
dst = [acc2idx[q] for q in df['payee_id']]
edge_index = torch.tensor([src, dst], dtype=torch.long)
edge_attr = torch.tensor(df[['amount', 'timestamp']].values, dtype=torch.float)
data['account', 'transfers_to', 'account'].edge_index = edge_index
data['account', 'transfers_to', 'account'].edge_attr = edge_attr
# 3. 股权:股东 -> 企业,持股比例作为边权
data['shareholder', 'holds', 'company'].edge_index = hold_index
data['shareholder', 'holds', 'company'].edge_attr = hold_ratio
# 4. 供应链:供应商 -> 采购方
data['supplier', 'supplies', 'buyer'].edge_index = supply_index
# 5. 新闻共现:实体 <-> 实体,共现次数与情感
data['entity', 'co_occurs', 'entity'].edge_index = co_index
data['entity', 'co_occurs', 'entity'].edge_attr = co_attr
四类数据源在清洗阶段各有侧重。交易记录要处理同名账户、内部转账、循环转账和金额量纲差异;股权关系要处理多层嵌套、代持和比例归一化;供应链要处理供应商名称模糊匹配和采购金额缺失;新闻共现要处理实体消歧、指代消解和共现窗口选择。下表给出对照清单。
| 数据源 | 节点类型 | 边类型 | 关键边属性 | 主要清洗难点 |
|---|---|---|---|---|
| 交易记录 | 账户、企业 | transfers_to | 金额、时间、币种 | 同名账户、循环转账 |
| 股权关系 | 股东、企业 | holds | 持股比例、层级 | 多层嵌套、代持 |
| 供应链 | 供应商、采购方 | supplies | 采购额、账期 | 名称模糊匹配 |
| 新闻共现 | 实体(公司/人) | co_occurs | 共现次数、情感 | 实体消歧、指代 |
三、案例场景:把四类边融合成一张异构图
假设我们要为一家银行构建企业客户风险图。企业节点来自对公账户开户信息,个人节点来自股东和高管,账户节点来自交易流水。交易边刻画资金往来,股权边刻画控制关系,供应链边刻画业务依赖,新闻共现边刻画舆情关联。四类边共享同一批企业节点,但边类型不同,形成典型的异构图。
在 PyG 中,异构图的价值在于可以对不同边类型分别做消息传递。例如,资金流边使用金额加权聚合,股权边使用比例加权聚合,新闻共现边使用注意力聚合。这样模型能区分“资金强关联”和“舆情弱关联”,避免把所有关系混为一谈。
四、误区与复盘:构建阶段最容易踩的五个坑
- 把边属性当节点特征:金额、比例、时间戳放在节点上会导致同一实体在不同关系下特征冲突,应保留在边上。
- 忽略时间维度:金融关系具有强时效性,交易边和新闻共现边应带时间戳,必要时按时间窗口切片建图。
- 实体消歧不彻底:同一公司在交易、股权、新闻中使用不同名称,若不统一 ID,图会被割裂成多个孤立子图。
- 边方向随意:资金流、股权、供应链都有明确方向,方向反了会导致消息传递语义错误。
- 权重未归一化:交易金额与持股比例量纲差异大,直接拼接会主导模型,应按边类型分别归一化。
复盘提醒:构建完成后,务必检查图的连通性、孤立节点比例、各边类型的数量级和度分布。若某类边占比超过 90%,模型会退化为同构图,异构图的价值将无法体现。
实践建议:先用小样本跑通“原始表 → HeteroData → 一层 HeteroConv”的链路,确认节点索引、边方向和特征维度无误后,再扩展到全量数据。构建阶段的错误往往比模型调参更致命,且更难排查。