hiendat04/fraudstream
GitHub: hiendat04/fraudstream
一个生产级数据工程与 MLOps 平台,通过模拟真实金融交易中的脏数据和质量问题,为基于 Spark Lakehouse 的欺诈检测管道奠定基础。
Stars: 1 | Forks: 0
# FraudStream:实时金融交易智能平台
FraudStream 是一个数据工程和 MLOps 项目,旨在构建一个生产级的欺诈分析平台。它会模拟杂乱的金融交易数据,保留原始源记录,并为基于 Spark 的 lakehouse 处理、欺诈特征工程、模型训练和运营监控奠定基础。
该项目围绕一个现实世界中常见的问题而构建:在模型训练开始之前,欺诈模型高度依赖于可靠的数据。交易数据可能会延迟到达、出现重复、发生 schema 偏移、在短暂的流量突增期间激增、包含缺失值,或者严重倾斜至少数商家和城市。FraudStream 将这些问题转化为明确的工程需求。
## 本项目展示的内容
FraudStream 旨在展示实用的数据平台技能:
- 合成但逼真的金融交易数据生成
- 源格式的原始数据分区及可复现的生成器配置
- 针对客户、账户、商家、交易和设备实体的高基数标识符
- 为下游 Bronze 和 Silver 处理制造逼真的数据质量问题
- 跨历史源分区的 schema 演进
- 包含 `event_timestamp` 和 `created_ts` 的事件时间和到达时间语义
- 一条面向 lakehouse 的路径,通向 Parquet、Spark、特征表和模型操作
## 当前实现
当前代码库实现了离线源数据生成器。它会创建分区的 CSV 文件,位于:
```
data/raw_source/offline_transactions/
```
生成的源数据集当前包含:
| 指标 | 数值 |
|---|---:|
| 基础交易数 | 500,000 |
| 注入重复项后的行数 | 510,000 |
| 每日 CSV 分区数 | 180 |
| 本地输出大小 | ~85 MB |
| 重复行数 | 10,000 |
| 延迟到达行数 | 20,574 |
| 包含缺失值的行数 | 7,655 |
| 格式不一致的行数 | 5,076 |
| 欺诈行数 | 7,803 |
| 欺诈团伙行数 | 3,060 |
| 独立客户数 | 197,404 |
| 独立商家数 | 40,000 |
| 独立设备数 | 193,863 |
生成器会将证据工件写入源数据旁边:
```
data/raw_source/offline_transactions/_manifest.json
data/raw_source/offline_transactions/_quality_summary.json
data/raw_source/offline_transactions/_quality_summary.csv
```
## 系统架构
FraudStream 遵循分层的数据平台设计。当前实现主要生成原始源数据。处理架构设计为可扩展至 Spark、Flink、Airflow、DataHub、MLflow 和监控组件。
```
flowchart LR
generator[Data Generator]
raw[Raw Source Files]
bronze[Bronze Parquet]
silver[Silver Clean Tables]
gold[Gold Facts and Features]
spark[Spark Jobs]
kafka[Kafka]
flink[Flink Jobs]
airflow[Airflow]
mlflow[MLflow]
api[Fraud Scoring API]
monitor[Monitoring]
generator --> raw
raw --> spark
spark --> bronze
bronze --> spark
spark --> silver
silver --> spark
spark --> gold
generator --> kafka
kafka --> flink
flink --> gold
airflow --> generator
airflow --> spark
airflow --> flink
gold --> mlflow
mlflow --> api
gold --> monitor
api --> monitor
```
## 数据湖设计
该项目将源数据与分析存储格式分离开来。
| 层级 | 存储目的 | 表示例表 |
|---|---|---|
| 原始源 | 源格式 CSV 提取,尽可能保留生产者格式 | `offline_transactions` 文件 |
| Bronze | 带有源元数据且进行了最少转换的已摄取 Parquet | `raw_transactions` |
| Silver | 经过清理、类型化、去重且 schema 对齐的 Parquet | `stg_transactions`、`stg_customers`、`stg_merchants` |
| Gold | 面向业务的事实表、维度表和 ML 特征表 | `fact_transactions`、`dim_customer_scd2`、`feat_customer_transaction_rolling` |
在原始源边界处特意使用 CSV,因为许多生产系统在将其转换为分析格式之前,会先从外部系统摄取文件。Spark 作业应读取原始 CSV 分区,保留源元数据,并写入 Bronze Parquet 以便进行高效的下游处理。
## 交易源设计
每一生成的行代表源系统粒度下的一笔交易事件。
核心列包括:
```
transaction_id
account_id
customer_id
merchant_id
merchant_category
amount
currency
city
channel
transaction_status
is_fraud
event_timestamp
created_ts
```
较新的源分区添加了演进的列:
```
device_id
ip_address
authentication_method
risk_signal_version
```
生成器特意使用了两个时间戳:
| 列 | 含义 |
|---|---|
| `event_timestamp` | 交易实际发生的时间。用于业务逻辑、窗口计算、特征和定点时间(point-in-time)正确性。 |
| `created_ts` | 记录生成或到达的时间。用于摄取行为、延迟到达分析和 pipeline 新鲜度检测。 |
## 模拟的数据工程问题
离线生成器为 Spark 和 lakehouse 处理制造了逼真且可解决的数据问题。
| 问题 | FraudStream 如何模拟 | 下游处理方式 |
|---|---|---|
| 重复项 | 重复受控比例的源行 | 在 Silver 层通过 `transaction_id` 去重 |
| 延迟到达 | 将部分 `created_ts` 值延迟超过 60 分钟 | 使用事件时间逻辑和到达时间监控 |
| Schema 演进 | 在 `schema_change_date` 之后添加设备/IP/认证列 | 使用可为空的演进列读取新旧分区 |
| 倾斜 | 将交易量集中在纽约和在线市场交易中 | 测试 Spark joins、分区和聚合行为 |
| 高基数 | 生成数十万的客户/设备 ID | 练习 joins、特征分组和去重计数验证 |
| 缺失值 | 留空选定的城市、商家、设备、IP 或认证字段 | 在 Silver 层进行验证和标准化 |
| 格式不一致 | 注入带有填充字符的城市、大写状态和小写货币 | 在清理过程中标准化字符串 |
| 突发流量 | 将更大比例的记录发送至选定的突发日期 | 测试分区不平衡和工作负载激增 |
| 欺诈团伙行为 | 在高风险交易中重用可疑的设备/IP 对 | 围绕实体重用和速度构建欺诈特征 |
## 代码库结构
```
financial-fraud-detection/
├── AGENTS.md
├── README.md
├── configs/
│ └── generator/
├── data/
│ └── raw_source/
├── docs/
├── src/
│ └── fraudstream/
│ └── generators/
├── tests/
│ └── unit/
├── main.py
├── pyproject.toml
└── uv.lock
```
重要路径:
| 路径 | 用途 |
|---|---|
| `configs/generator/offline_transactions.json` | 离线数据生成的 runtime 配置 |
| `src/fraudstream/generators/offline_transactions.py` | 离线交易生成器实现 |
| `data/raw_source/offline_transactions/` | 生成的源格式交易文件 |
| `docs/01_data_generator.md` | 详细的生成器设计和运行文档 |
| `tests/unit/test_offline_transactions.py` | 针对生成器行为和证据工件的单元测试覆盖率 |
## 在本地运行
生成默认的离线交易数据集:
```
PYTHONPATH=src python -m fraudstream.generators.offline_transactions
```
通过项目入口点运行:
```
PYTHONPATH=src python main.py
```
将生成的数据写入临时输出目录:
```
PYTHONPATH=src python -m fraudstream.generators.offline_transactions \
--output-dir /tmp/fraudstream_offline_transactions
```
运行单元测试:
```
PYTHONPATH=src python -m unittest tests.unit.test_offline_transactions
```
运行语法/导入编译检查:
```
PYTHONPATH=src python -m compileall -q src tests main.py
```
## 配置
默认的生成器配置位于:
```
configs/generator/offline_transactions.json
```
关键设置:
| 设置 | 用途 |
|---|---|
| `n_transactions` | 注入重复项之前的唯一基础交易计数 |
| `n_customers`、`n_accounts`、`n_merchants` | 控制实体基数 |
| `days_history` | 生成的交易日期数 |
| `skew_city_ratio` | 控制地理倾斜 |
| `skew_merchant_category_ratio` | 控制商家类别倾斜 |
| `duplicate_rate` | 控制重复的原始行 |
| `late_arrival_rate` | 控制延迟的源记录 |
| `missing_value_rate` | 控制选定字段中的空白值 |
| `inconsistent_format_rate` | 控制易于清理的字符串格式问题 |
| `burst_day_count` | 控制大交易量日期的数量 |
| `fraud_ring_count` | 控制可疑的重用设备/IP 对 |
| `schema_change_date` | 分割旧的和演进的源 schema |
## 工程方向
下一个工程层是通过 Spark 将原始 CSV 摄取为 Bronze Parquet。该作业应保留源记录,添加摄取元数据,处理 schema 演进,并写入分区的 Parquet。Silver 处理随后应对记录去重、标准化格式、强制执行类型,并为 Gold 特征表准备干净的交易数据。
这使得该项目符合生产数据平台模式:
```
raw source files -> Bronze Parquet -> Silver clean tables -> Gold facts/features -> model training and monitoring
```
标签:MLOps, 数据工程, 数据湖仓, 数据生成, 特征工程, 逆向工具, 金融风控