2. 风险传导基础:风险因子识别、传导路径建模、图谱数据结构基础
2.1 风险因子识别:从业务事件到可量化节点
风险因子是传导图谱的最小原子单元。识别过程遵循“业务事件 → 风险信号 → 量化指标”三层降维法:
- 业务事件层:从交易流水、舆情、监管通报中提取原始事件(如“某企业债券违约”)。
- 风险信号层:将事件映射为风险类别(信用风险、流动性风险、操作风险)。
- 量化指标层:定义可采集的数值指标(如“逾期率 > 5%”、“价格波动率 > 20%”)。
实战要点:因子识别必须同时满足“可观测”与“可传导”两个条件。仅可观测但无法影响其他节点的因子(如天气)应排除在传导图谱之外。
| 风险类别 | 典型因子 | 数据源 | 量化粒度 |
|---|---|---|---|
| 信用风险 | 违约率、评级下调、担保失效 | 征信、财报、评级机构 | 企业/债项级 |
| 流动性风险 | 资金缺口、融资成本飙升、挤兑 | 支付流水、同业拆借利率 | 机构/市场级 |
| 市场风险 | 汇率波动、大宗商品价格、利率曲线 | 交易所、路透、彭博 | 资产/组合级 |
| 操作风险 | 系统故障、人为失误、流程缺陷 | 日志、工单、审计报告 | 流程/系统级 |
2.2 传导路径建模:从线性链到网状传播
风险传导不是简单的“A→B→C”线性链,而是多路径、带反馈、有时滞的复杂网络。建模时需定义三种基本关系:
- 直接传导:因子A的变化直接导致因子B变化(如“利率上升 → 债券价格下跌”)。
- 间接传导:通过中间节点传递(如“油价上涨 → 运输成本增加 → 消费品通胀”)。
- 反馈传导:B的变化反过来影响A(如“股价下跌 → 质押物不足 → 强制平仓 → 股价进一步下跌”)。
建模原则:优先使用“有向加权图”建模传导路径。边权重代表传导强度(0~1),方向代表风险流向。时滞属性以边上的“延迟时间”字段存储,支持批流一体中的时间窗口计算。
2.3 图谱数据结构基础:属性图模型
风险传导图谱采用属性图(Property Graph)模型,这是批流一体架构下最灵活的数据表示方式。每个节点和边都可以携带任意数量的键值对属性,支持运行时动态扩展。
避坑提示:不要使用 RDF 三元组模型。属性图在批处理(批量导入/全量计算)和流处理(增量更新/实时传导)两种模式下都能保持一致的查询语义,而 RDF 在流场景下需要额外的物化视图层,增加架构复杂度。
2.3.1 节点(Vertex)结构
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| id | String | 全局唯一标识 | risk_001234 |
| label | String | 节点类型标签 | credit_risk |
| properties | Map<String, Object> | 动态属性集合 | {“name”: “违约率”, “value”: 0.08, “ts”: “2025-03-01”} |
2.3.2 边(Edge)结构
| 字段 | 类型 | 说明 | 示例 |
|---|---|---|---|
| id | String | 边唯一标识 | edge_005678 |
| source | String | 起始节点 id | risk_001234 |
| target | String | 目标节点 id | risk_005678 |
| label | String | 传导关系类型 | direct_cause |
| properties | Map<String, Object> | 权重、时滞、置信度等 | {“weight”: 0.85, “delay”: 3600, “confidence”: 0.92} |
2.3.3 批流一体下的存储策略
图谱数据在批流一体架构中采用“分层存储”策略:
- 批存储层:使用 HBase / Cassandra 存储全量图谱快照,支持大规模历史回溯和全图分析。
- 流存储层:使用 Redis / Ignite 存储活跃子图和增量变更日志,支持毫秒级传导路径查询。
- 统一访问层:通过 GraphQL 或自定义 API 屏蔽底层存储差异,上层应用无需感知数据来源。
2.4 实战案例:构建一个简单的信用风险传导子图
以下代码展示如何使用属性图模型构建一个包含“企业A违约 → 银行B不良率上升 → 银行C同业拆借利率飙升”的传导子图:
// 节点定义
Vertex v1 = new Vertex("risk_001", "credit_risk",
Map.of("name", "企业A违约", "value", 1.0, "ts", "2025-03-01T10:00:00Z"));
Vertex v2 = new Vertex("risk_002", "credit_risk",
Map.of("name", "银行B不良率", "value", 0.12, "ts", "2025-03-02T08:00:00Z"));
Vertex v3 = new Vertex("risk_003", "liquidity_risk",
Map.of("name", "银行C拆借利率", "value", 0.08, "ts", "2025-03-02T09:30:00Z"));
// 边定义
Edge e1 = new Edge("edge_001", "risk_001", "risk_002", "direct_cause",
Map.of("weight", 0.95, "delay", 79200, "confidence", 0.88));
Edge e2 = new Edge("edge_002", "risk_002", "risk_003", "indirect_cause",
Map.of("weight", 0.72, "delay", 5400, "confidence", 0.76));
// 构建图谱
Graph graph = new Graph();
graph.addVertex(v1);
graph.addVertex(v2);
graph.addVertex(v3);
graph.addEdge(e1);
graph.addEdge(e2);
批流一体提示:上述代码在批处理模式下一次性构建全量图谱;在流处理模式下,每个节点和边会作为独立事件写入 Kafka,由 Flink 或 Spark Streaming 增量更新到流存储层,同时异步合并到批存储层。