VishnuSas21/fraud-detection-system

GitHub: VishnuSas21/fraud-detection-system

结合 SQL 规则引擎与 XGBoost 机器学习模型,通过混合决策架构实现金融交易欺诈检测的数据科学项目。

Stars: 0 | Forks: 0

# 欺诈检测系统 — SQL 规则引擎 + XGBoost ML 模型 一个基于 50,000 笔合成交易记录、具备生产级设计理念的欺诈检测系统。 结合了**基于 SQL 的规则引擎**与 **XGBoost 机器学习模型**,旨在展示 真实的反欺诈团队如何将规则与 ML 结合使用 —— 它们并非互相替代,而是作为多层防线协同工作。 ## 项目结构 ``` fraud-detection-system/ ├── sql/ │ ├── 01_exploratory_analysis.sql │ ├── 02_velocity_bin_geo.sql │ ├── 03_ato_merchant_structuring.sql │ └── 04_hybrid_decision_engine.sql ├── python/ │ └── fraud_detection_xgboost.ipynb ├── data/ │ └── fraud_db_setup.sql ├── docs/ │ └── project_findings.md └── README.md ``` ## 业务问题 金融平台每年因欺诈损失数十亿资金。目前存在两种失败模式: - **漏报欺诈** → 直接财务损失、拒付、监管处罚 - **误拦合法客户** → 收入损失、客户流失、客服成本增加 本项目构建了一个旨在将这两种损失降至最低的系统 —— 以高精准度捕捉欺诈, 同时将误报率控制在运营团队可接受的范围内。 ## 数据集 - **50,000 笔交易**,涵盖 5,000 名客户和 200 家商户 - **782 起欺诈案例** —— 1.56% 的欺诈率(符合真实的信用卡欺诈水平) - **包含的欺诈模式:** ATO、BIN 攻击、地理速度、分层洗钱、CNP 欺诈 - **特征:** 金额、交易类型、商户类别、KYC 状态、登录失败次数、 账户年龄、设备 ID、地理位置、风险细分 使用 `data/fraud_db_setup.sql` 生成 —— 可在 MySQL 中完全复现。 ## 第 1 部分 — SQL 规则引擎 由四个循序渐进的模块组成,每个模块针对特定的欺诈模式。 ### 模块 | 文件 | 涵盖的欺诈模式 | 关键 SQL 技术 | |---|---|---| | 01_exploratory_analysis | 按细分、KYC、账户年龄划分的基线欺诈率 | GROUP BY、条件聚合、CASE WHEN | | 02_velocity_bin_geo | 每日速度、滚动 1 小时速度、BIN 攻击、地理速度 | Self JOIN、INTERVAL 窗口、CTE、LAG()、TIMESTAMPDIFF | | 03_ato_merchant_structuring | 账户接管、商户拒付风险、AML 分层 | 多信号 AND 逻辑、JOIN、阈值临近检测 | | 04_hybrid_decision_engine | 风险评分引擎 + 最终决策引擎 | 加权 CASE WHEN、硬性规则、4 级 CTE 链 | ### 风险评分引擎 每笔交易都会根据 10 项欺诈信号获得一个加权风险评分。 权重最初由领域知识设定,随后通过 XGBoost 特征重要性进行验证。 | 信号 | 权重 | 依据 | |---|---|---| | 登录失败次数 > 2 | 35 | 最强 ATO 预测因子 —— XGBoost 重要性占比 60.5% | | 金额 > $800 | 10 | 高价值 = 高损失敞口 | | KYC 未验证 | 9 | 未验证身份 = 风险升高 | | 高风险细分 | 9 | 在 v1 中权重偏低 —— ML 纠正了这一点 | | 加密货币/博彩商户 | 8 | 欺诈率为 2.67%,而电商为 1.38% | | 境外交易 | 6 | 在 v1 中权重偏高 —— ML 纠正了这一点 | | 金额 > 用户平均值的 3 倍 | 5 | 行为激增信号 | | 账户年龄 < 30 天 | 5 | 新账户风险 | | 非营业时间(凌晨 2 点至 5 点) | 5 | 行为异常 | | CNP 交易 | 5 | 上下文信号 —— 单独使用时信号较弱 | ### 混合决策引擎 针对高置信度单一信号使用硬性规则。 针对较弱信号的组合使用软评分。 ``` Strong single signal → HARD BLOCK (no score needed) Weak signals combined → Score ≥ 25 → REVIEW Score < 25 → APPROVE ``` **硬性拦截条件:** - failed_logins > 5 - failed_logins > 2 且 kyc_verified = 0 - failed_logins > 2 且 amount > $800 - risk_segment = High 且 kyc_verified = 0 且 merchant = Crypto/Gaming **为什么 failed_logins 被排除在软评分之外:** 它已经是 4 项硬性规则中 3 项的触发条件 —— 如果将其包含在软评分中, 会导致对该信号进行重复计算。这两层机制保持了清晰的隔离。 ### 决策引擎结果 | 决策 | 交易数 | 欺诈数 | 欺诈率 | FP Rate | |---|---|---|---|---| | BLOCK | 285 | 112 | 39.3% | 60.7% | | REVIEW | 3,146 | 87 | 2.77% | 97.2% | | APPROVE | 46,569 | 583 | 1.25% | 0% | **整体召回率:25.4%** —— 解释详见局限性部分。 ## 第 2 部分 — XGBoost ML 模型 ### 为什么在规则之外还需要 ML? 规则引擎擅长捕捉已知的欺诈模式。而 ML 能够捕捉未知模式。 更重要的是 —— ML 会告诉你哪些信号才是真正重要的,而不是你主观假设重要的。 ### Notebook 结构 | 步骤 | 功能说明 | |---|---| | Step 1 | 从 MySQL 加载 50,000 笔交易 | | Step 2 | 特征工程 v1 —— 二元标志基线 | | Step 3 | 训练 XGBoost 模型 v1 | | Step 4 | 评估模型 v1 —— 揭示二元标志过于粗糙 | | Step 5 | 特征工程 v2 —— 原始连续值 | | Step 6 | 评估模型 v2 —— 相比 v1 有显著提升 | | Step 7 | XGBoost 特征重要性分析 | | Step 8 | 将重要性分数映射到 SQL 权重 v1 | | Step 9 | 按比例进行 ML 验证的 SQL 权重 v2 | | Step 10 | 阈值分析 —— 精准度/召回率的权衡 | | Step 11 | 信号覆盖度分析 —— 为何召回率存在上限 | | Step 12 | 混合决策引擎 —— 硬性规则 + 软评分 | | Step 13 | 最终三方对比 V1 vs V2 vs V3 | ### 模型性能 | 指标 | 模型 V1 (二元标志) | 模型 V2 (原始 + 工程化) | |---|---|---| | AUC-ROC | 0.71 | 0.9999* | | AUC-PR | 0.15 | 0.9956* | | 捕捉到的欺诈 | 41.7% | 98.1%* | | False Positives | 969 | 8* | *近乎完美的得分反映了合成数据泄露 —— 欺诈标签正是基于训练中使用的相同特征生成的。详见局限性部分。 ### XGBoost 特征重要性 — SQL 权重验证 | 特征 | ML 重要性 | 旧版 SQL 权重 | 新版 SQL 权重 | 变化 | |---|---|---|---|---| | failed_logins | 60.5% | 30 | 35 | ↑ 确认为最强信号 | | amount | 11.3% | 25 | 10 | ↓ 原先权重过高 | | kyc_verified | 8.2% | 20 | 9 | ↓ 权重下调 | | flag_high_risk_seg | 7.8% | 10 | 9 | ↑ 原先权重过低 | | flag_risky_merchant | 6.2% | 15 | 8 | ↓ 权重下调 | | is_foreign | 3.1% | 20 | 6 | ↓ 严重高估 | | daily_velocity | 0.0% | 20 | 0 | ❌ 完全移除 | ### 阈值分析 系统评估表明,没有任何单一阈值能够解决精准度与召回率的权衡问题: | 阈值 | 精准度 | 召回率 | F1 | FP Rate | |---|---|---|---|---| | 35 | 17.6% | 20.6% | 0.190 | 82.4% | | 50 | 25.9% | 8.7% | 0.130 | 74.1% | | 65 | 80.0% | 1.5% | 0.030 | 20.0% | 在阈值为 35 时 F1 表现最佳 —— 但召回率依然只有 20.6%。 这直接促成了采用混合架构的决策。 ## 决策引擎演进 | 版本 | 架构 | BLOCK 精准度 | BLOCK FP Rate | BLOCK 数量 | 召回率 | |---|---|---|---|---|---| | V1 | 领域权重,阈值 60 | 7.75% | 92.25% | 3,344 | 33.2% | | V2 | ML 验证权重,阈值 65 | 25.86% | 74.14% | 263 | 25.4% | | V3 | 混合硬性规则 + 软评分 | 39.30% | 60.70% | 285 | 25.4% | **V1 → V2:** ML 权重将 BLOCK 数量减少了 92%(3,344 → 263),同时精准度提升了 3.3 倍 **V2 → V3:** 硬性规则将 BLOCK 精准度提升至 39.3% —— 几乎每 2 次拦截中就有 1 次是真正的欺诈 ## 关键发现 **1. 登录失败次数主导了所有其他信号** failed_logins 的 XGBoost 重要性占比达 60.5%,其预测能力是次优特征的 5 倍。 任何 failed_logins > 2 且伴随一项次要信号的交易,都足以触发硬性拦截。 **2. 境外交易信号权重过高** is_foreign 在 80% 的交易中都会触发 —— 范围太广,无法有效区分。 3.1% 的 ML 重要性证实它只能作为辅助信号。 在评分引擎中的权重从 20 分降至 6 分。 **3. 混合架构优于纯评分机制** 将高置信度单一信号(硬性规则)与弱信号组合(软评分)分离, 在不改变召回率的情况下,将 BLOCK 精准度从 25.86% 提升至 39.30%。 **4. 规则与 ML 相互验证** 领域专业知识设定了初始权重。ML 纠正了三个权重过高 和一个权重过低的信号。单独采用任何一种方法都无法发现这一点。 **5. REVIEW 分组在生产环境中应使用阶梯式认证** REVIEW 中 97% 的误报率对于人工审核来说是不可接受的。 解决方案:自动化 OTP 或 3DS —— 客户可在几秒钟内自助验证通过, 运营团队根本无需介入,误报成本降至接近零。 ## 局限性 **合成数据天花板 —— 召回率上限为 25%** 有 583 起欺诈案例得分较低,因为数据生成器将它们标记为由单一孤立信号触发。 评分引擎要求多个信号同时触发,因此单信号欺诈案例在任何阈值下都会漏网。 在生产环境中,这种限制是不存在的 —— 真实的欺诈者会同时触发多个信号。 一次 ATO 攻击会同时表现出登录失败、且是新设备、且存在地理差异, 且发生在异常时间。该架构已具备生产级应用能力; 当前的瓶颈在于合成数据,而非引擎的设计。 **近乎完美的 ML 指标表明存在数据泄露** 欺诈标签是确定性基于训练中使用的相同特征生成的。 XGBoost 逆向推导了这些标签生成规则,而不是学习通用的欺诈模式。 真实世界的欺诈模型在生产数据上的 AUC-ROC 通常为 0.75–0.90。 ## 如何运行 **前置条件:** - MySQL 8.0+ - Python 3.9+ - Jupyter Notebook **第 1 步 — 设置数据库:** ``` -- In MySQL Workbench or mysql CLI source data/fraud_db_setup.sql ``` **第 2 步 — 按顺序运行 SQL 模块:** ``` USE fraud_db; source sql/01_exploratory_analysis.sql source sql/02_velocity_bin_geo.sql source sql/03_ato_merchant_structuring.sql source sql/04_hybrid_decision_engine.sql ``` **第 3 步 — 运行 Notebook:** ``` pip install pandas numpy scikit-learn xgboost==2.1.1 mysql-connector-python matplotlib jupyter notebook ``` 打开 `python/fraud_detection_xgboost.ipynb` 并运行所有单元格。 在运行之前,请更新数据库连接单元格中的 MySQL 密码。 ## 展示的技能 | 技能 | 应用位置 | |---|---| | 高级 SQL —— CTE、窗口函数、自连接 | 所有 SQL 模块 | | 欺诈领域知识 —— ATO、BIN 攻击、地理速度、分层洗钱 | sql/02、sql/03 | | 特征工程 —— 原始值与二元标志对比 | Notebook 步骤 2 和 5 | | 类别不平衡处理 —— XGBoost 中的 scale_pos_weight | Notebook 步骤 3 | | 阈值优化 —— 准度/召回率权衡 | Notebook 步骤 10 | | 信号覆盖度分析 —— 为何召回率存在上限 | Notebook 步骤 11 | | ML 与规则结合 —— 特征重要性 → SQL 权重更新 | Notebook 步骤 7–9 | | 混合架构 —— 硬性规则 + 软评分 | sql/04、Notebook 步骤 12 | | 生产级思维 —— 通过率、阶梯式认证建议 | Notebook 步骤 12 | | 客观评估 —— 正视合成数据的局限性 | 局限性部分 | ## 作者 **Vishnu Saseendran** 高级主管 —— 支付表现与风险调查 拥有 6 年以上欺诈检测、交易监控和支付风险领域的经验 [LinkedIn](https://linkedin.com/in/vishnu-saseendran-522798148) | [GitHub](https://github.com/VishnuSas21)
标签:Apex, NoSQL, SQL规则引擎, XGBoost, 代码示例, 多线程, 数据分析, 机器学习, 欺诈检测, 逆向工具, 金融风控