i-hridaysaha/fraud-detection-xgboost

GitHub: i-hridaysaha/fraud-detection-xgboost

基于XGBoost的生产级信用卡欺诈检测pipeline,涵盖防泄漏特征工程、类别不平衡处理、SHAP可解释性和FastAPI实时评分服务,专为高并发支付场景设计。

Stars: 0 | Forks: 0

# 企业欺诈检测平台 这是一个基于 XGBoost 构建的生产级信用卡欺诈检测 pipeline, 专为真实支付环境的规模和限制而设计 (每天 100 万+ 笔交易,约 0.1-0.3% 的欺诈率,低于 100ms 的评分延迟)。 本仓库展示了完整的生命周期:数据 → 防泄漏的特征 工程 → 不平衡处理 → 模型比较 → 阈值调优 → SHAP 可解释性 → API 服务 → 漂移监控。 ## 结果 以下结果基于合成数据(参见 [数据](#about-the-data) 部分)—— PCA 式特征是随机生成的,仅带有微弱的欺诈/合法信号,这限制了绝对的精确率。这里应该评估的是 pipeline 的设计(防泄漏拆分、因果特征、阈值调优、SHAP);在真实的 Kaggle 数据集(见下文)上运行相同的代码,预计会产生更强有力的区分度,因为与这种合成近似相比,真实的欺诈会在底层的 PCA 成分中留下强烈得多的信号。 ![SHAP 汇总](https://static.pigsec.cn/wp-content/uploads/repos/cas/40/40232e0d94e69399832687f88dbdb7f57b1ee6511ea540758f74d99e3746f8d9.png) | 模型 | ROC-AUC | PR-AUC | 精确率 | 召回率 | F1 | |---|---|---|---|---|---| | Logistic Regression | 0.542 | 0.101 | 0.026 | 0.465 | 0.050 | | Random Forest | 0.756 | 0.127 | 0.050 | 0.697 | 0.093 | | XGBoost(调优阈值,F1 最优) | 0.723 | 0.110 | 0.067 | 0.242 | 0.105 | | XGBoost(默认 0.5 阈值) | 0.723 | 0.110 | 0.052 | 0.560 | 0.095 | **解读这些结果:** XGBoost 总体上提供了最佳的 PR-AUC/F1 权衡。 Random Forest 实现了最高的召回率(捕获了 70% 的欺诈),但代价 是非常高的假阳性率——这说明了真实的欺诈团队会根据分析师审查能力进行调优的精确率/召回率 权衡,这正是 `src/imbalance.py` 中阈值调优逻辑的用途。 ## 为什么这不仅仅是“调用 `.fit()`” 欺诈检测具有一些特性,使得朴素的机器学习方法在生产环境中 极其危险,而这个仓库的结构专门用于避免 它们: 1. **极端的类别不平衡**(约 0.1-0.3% 的正样本率)——在这里准确率是一个 无用的指标(99.8% 的准确率 = 总是预测为“非欺诈”)。 我们报告精确率/召回率/F1/PR-AUC,而不是准确率。 2. **时间泄漏** —— 随机的训练/测试拆分会泄漏未来的 信息(例如,使用未来交易计算的滚动特征)。 此 pipeline 中的每次拆分和每个特征都是**基于时间和 因果关系的**——参见 `src/data_loader.py::time_based_split` 和 `src/feature_engineering.py` 中的文档字符串。 3. **延迟的真实标签** —— 确认的欺诈(退款)通常在 交易发生后的几天或几周后才会出现。`src/monitoring.py` 将数据漂移 (立即可用)和概念漂移/性能衰退(只有在延迟的标签到达后 才可用)视为两个独立的监控 问题,因为它们本来就是如此。 4. **可解释性是一项合规要求**,而不是可有可无的选项,特别是在 金融服务领域。SHAP 被用于全局模型验证和 面向分析师的每笔交易解释。 ## 项目结构 ``` fraud_detection_platform/ ├── data/ │ └── generate_synthetic_data.py # synthetic Kaggle-schema-compatible data generator ├── src/ │ ├── config.py # all tunable parameters in one place │ ├── data_loader.py # loading + time-based split │ ├── feature_engineering.py # velocity, recency, merchant risk, device consistency │ ├── imbalance.py # class weighting, SMOTE, threshold tuning │ ├── models.py # LR / RF / XGBoost factories │ ├── evaluate.py # precision/recall/F1/AUC reporting │ ├── explainability.py # SHAP (global + per-transaction) │ ├── api.py # FastAPI real-time scoring service │ └── monitoring.py # PSI-based data drift + delayed performance tracking ├── tests/ │ └── test_pipeline.py # leakage/sanity tests ├── train.py # end-to-end training entry point ├── requirements.txt └── reports/ # generated metrics + SHAP plots land here ``` ## 关于数据 此问题的经典公开数据集是 Kaggle ["Credit Card Fraud Detection"](https://www.kaggle.com/mlg-ulb/creditcardfraud) 数据集:包含约 28.5 万条 2013 年 9 月欧洲持卡人的交易记录, 具有 `Time`,28 个 PCA 匿名化特征(`V1`-`V28`),`Amount` 和 `Class` (1 = 欺诈)。这是此问题的标准基准,但它 是**完全匿名化的**——没有客户、商家或设备标识符——因此它 本身无法演示速度、商家风险或 设备一致性特征,这些特征需要实体标识符才能计算。 本仓库提供了 `data/generate_synthetic_data.py`,它: - 生成与 Kaggle 数据集具有**相同 schema** 的交易 (`Time`,`V1`-`V28`,`Amount`,`Class`),其欺诈/合法分布 是根据真实数据集的已知结构建模的(欺诈在少数几个 PCA 成分上与 合法交易区分开来),**并且** - 为每一行增加了 `customer_id`、`merchant_id`、 `merchant_category`、`device_id` 和真实的 `timestamp`,以便可以端到端地构建和演示完整的 特征集。 **要改用真实的 Kaggle 数据:** 从 上面的链接下载 `creditcard.csv`,将其放置在 `data/transactions.csv`,然后正常运行 `train.py` —— `src/data_loader.py` 会检测到该文件缺少身份列, 并在*真实的* `Amount`/`V1-V28`/`Class` 值之上动态生成这些列, 使用与合成生成器完全相同的逻辑。这使得欺诈 信号保持真实,同时仍然支持完整的特征集。这是 对真实内部数据仓库连接的一个合理替代(在生产环境中, `customer_id`/`merchant_id`/`device_id` 将来自您的交易 系统,而不是合成出来的)。 ## 快速开始 ``` pip install -r requirements.txt # 生成数据(或提供你自己的 transactions.csv — 见上文) python data/generate_synthetic_data.py --n_rows 500000 --fraud_rate 0.0017 # 训练所有三个模型,评估并生成 SHAP 报告 python train.py --imbalance_strategy class_weight # (或 --imbalance_strategy smote / none) # 部署训练好的 XGBoost 模型 uvicorn src.api:app --host 0.0.0.0 --port 8000 # 运行测试 pytest tests/ -v ``` ## 特征工程 所有特征都是**基于因果关系**计算的(仅使用每笔交易时间戳之前严格可用的 信息): | 特征 | 描述 | |---|---| | `seconds_since_last_txn` | 该客户上一笔交易以来的时间。有史以来的第一笔交易将获得一个较大的哨兵值,而不是 0。 | | `velocity_count_{10,60,1440}m` | 该客户在过去 10 分钟/1 小时/24 小时窗口内的交易计数,不包含当前交易。 | | `velocity_amount_{10,60,1440}m` | 相同过去时间窗口内的 `$` 金额总和。 | | `merchant_risk_score` | 经过平滑处理的、基于目标编码的每个商家历史欺诈率,仅在训练拆分上进行拟合。 | | `merchant_category_risk_score` | 同上,但在商家类别层面进行聚合(例如:日用品与加密货币交易所与赌博等)。 | | `is_new_device` | 截至当前时间点,该设备是否为该客户前所未见。 | | `distinct_device_count_so_far` | 该客户迄今使用过的不同设备的滚动计数。 | ## 不平衡处理 可通过 `--imbalance-strategy` 进行配置: - `class_weight`(默认):XGBoost 使用 `scale_pos_weight` / sklearn 模型使用 `class_weight="balanced"` —— 重新加权损失,而不是改动数据。 - `smote`:在基于时间的拆分**之后**(绝不是之前——在拆分之前拟合 SMOTE 会将源自验证/测试欺诈样本的合成点泄漏到训练中)通过 SMOTE 对少数类进行过采样。 - `none`:不进行校正,可用作基线,以查看上述方法实际上有多大帮助。 决策阈值仅在**验证集**上进行调优(`src/imbalance.py::tune_threshold_for_f1`),同时报告 F1 最优阈值和受精确率约束的“高召回率”替代方案(当业务希望在最低精确率下限制分析师的假阳性审查工作量时非常有用)。 ## 模型对比 1. **Logistic Regression** —— 快速、可解释的基线 / 完整性检查,用于验证特征是否携带了信号。 2. **Random Forest** —— 更强的非线性基线,是特征重要性的有效交叉验证手段。 3. **XGBoost** —— 最终的生产模型。因其在高交易量下的准确性/延迟权衡、原生的 `scale_pos_weight` 支持以及一流的 SHAP `TreeExplainer` 支持(精确、快速的 SHAP 值而非近似值)而被选中。 `train.py` 在相同的留出、按时间排序的最近测试拆分上训练并评估这三者,并将比较表写入 `reports/model_comparison.json`。 ## 可解释性 `src/explainability.py` 使用 SHAP 的 `TreeExplainer` 达到两个目的: - **全局**:`reports/shap_summary.png` 和 `reports/shap_top_features.csv` —— 哪些特征在整体上驱动了模型(用于模型治理/验证审查)。 - **局部**:`explain_single_transaction()` —— 呈现单笔交易的首要贡献因素,当传入 `explain: true` 时,直接在 `/score` API 响应中返回。这就是欺诈分析师的警报分类 UI 将会展示的内容。 ## 部署 `src/api.py` 是一个暴露了 `POST /score` 的 FastAPI 服务。它期望在 请求中包含预计算的流式特征(速度、近因、设备标志)—— 在真实的部署中,这些特征来自于实时更新的流式特征存储 (例如 Feast、Flink 或基于 Kafka 的聚合器),而不是 在每个请求中从头开始计算,因为速度特征需要 API 本身并不持有的历史上下文。 此外还包含:用于存活/就绪探针的 `GET /health`。 ## 监控 `src/monitoring.py` 区分了两种不同的故障模式,因为它们需要 不同的响应: - **数据漂移**(`compute_feature_drift_report`、`compute_prediction_drift`):每个特征以及模型输出分数分布的 Population Stability Index(总体稳定性指数)。立即可用,无需真实标签。PSI < 0.1 稳定,0.1-0.25 需调查,> 0.25 为显著偏移。 - **概念漂移 / 性能衰退**(`compute_delayed_performance_report`):当过去的批次收到延迟的真实标签(退款、确认的欺诈报告)后,重新计算精确率/召回率/F1,作为定时任务运行。这是实际的重新训练触发器——单纯的数据漂移并不一定意味着模型变差了。 ## 已知局限性 / 针对真实部署的下一步计划 - 合成数据生成器的欺诈/合法分离经过了简化;真实的部署将根据确认的欺诈调查结果进行验证,而不仅仅是留出集上的 PR-AUC。 - `is_new_device`/速度特征在这里是通过遍历整个数据集的 Python 循环来计算的,这是为了清晰起见——在每天 100 万+ 笔交易的情况下,此逻辑应移至流式聚合层(如 Flink/Kafka Streams),而不是在批处理中重新计算。 - 未包含超参数搜索(使用了固定的、合理的 XGBoost 默认参数)——在将其视为最终版本之前,请接入 Optuna/Ray Tune。 - 未包含正式的模型卡片/跨客户群体的偏差审计——在受监管的环境中投入生产使用之前,这些都是值得添加的内容。
标签:Apex, AV绕过, FastAPI, XGBoost, 安全规则引擎, 数据科学, 机器学习, 模型可解释性, 欺诈检测, 资源验证, 逆向工具