memily0/fraud-detection-ml-system

GitHub: memily0/fraud-detection-ml-system

一个端到端的机器学习欺诈检测系统,使用 FastAPI 提供服务,并以可复现流程解决类别不平衡下的交易风险预测问题。

Stars: 1 | Forks: 0

# 欺诈检测 ML 系统 一个用于评估欺诈交易概率的端到端 ML/backend 教学项目。 这是一个可复现的欺诈检测项目,包含训练 pipeline、用于训练和推理的共享特征工程、FastAPI API、演示 dashboard,以及用于本地启动的 Docker 配置。 ## 概述 | 项目 | 详情 | | --- | --- | | 任务 | 用于欺诈检测的二元分类 | | 数据集 | `data/creditcard.csv` | | 模型 | `RandomForestClassifier` | | API | FastAPI (`/predict`, `/health`) | | Dashboard | 位于 `/dashboard/` 的静态 Web UI | | Docker | `Dockerfile` + `docker-compose.yml` | 最终提供服务的模型:`RandomForestClassifier`,它是通过分阶段的模型比较(包含单次划分 baseline、分层交叉验证和独立的阈值调优)筛选出来的。 **最终提供服务的模型:** `RandomForestClassifier`,通过分阶段比较模型选出。 ## 技术栈 - Python - pandas - NumPy - scikit-learn - CatBoost - joblib - FastAPI - Pydantic - Uvicorn - Docker ## 项目组件 ## 项目组件 / 项目包含内容 - 源自 `data/creditcard.csv` 的可复现训练 pipeline (可复现的训练 pipeline) - 用于训练和推理的共享特征工程 (统一的特征逻辑用于 train 和 inference) - 用于欺诈评分的 RandomForest 服务模型 (用于 fraud 评分的主要模型) - 保留 CatBoost baseline 用于模型比较 (CatBoost 作为强有力的 baseline 候选模型保留) - 在分层测试集上进行评估 - 用于预测的 FastAPI 服务 - 用于手动推理检查的简单 dashboard - 用于本地演示启动的 Docker 配置 ## 指标 当前主要训练 pipeline 在测试集上的指标: **以下是当前服务模型在 test split 上的主要指标。** | 指标 | 数值 | | --- | ---: | | PR-AUC | 0.876845 | | ROC-AUC | 0.967647 | | F2 | 0.788913 | | Precision | 0.961039 | | Recall | 0.755102 | | 阈值 | 0.50 | 这些是主要 train/test pipeline 在 `threshold = 0.5` 时的默认评估指标。 最终 `RandomForestClassifier` 调整后的运行阈值在 **模型选择** 部分单独报告,目前为 `0.2`。 为什么这些指标很重要 / 为什么这些指标很重要: - 对于此数据集,`PR-AUC` 比准确率提供更多信息,因为欺诈案例很罕见。 (由于严重的类不平衡,`PR-AUC` 比准确率更重要。) - `Recall` 很重要,因为漏掉欺诈交易的代价很高。 (`Recall` 很重要,因为漏掉 fraud 操作代价高昂。) - `F2` 给予 recall 更高的权重,这比对称指标更适合欺诈检测场景。 (`F2` 更加强调 recall。) ## 快速开始 最简本地流程: ``` python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python scripts/train_model.py uvicorn app.main:app --reload ``` 启动后: - Dashboard:`http://localhost:8000/dashboard/` - 健康检查:`http://localhost:8000/health` - API 文档:`http://localhost:8000/docs` ## 问题背景 该项目将欺诈检测视为一个二元分类任务:对于每笔交易,模型预测其属于欺诈类别的概率。 数据集包含: - `Time` - `Amount` - `V1` ... `V28` - `Class` 作为目标 为什么该任务不简单: - 数据集严重不平衡,欺诈交易只占极小的比例; - API 处理的是数据集中转换后的特征空间,而不是原始的业务交易字段; - 由于不平衡,高准确率并不一定意味着模型是有用的。 ## ML Pipeline 当前 pipeline: 1. 从 `data/creditcard.csv` 加载数据 2. 构建最终的特征集 3. 使用分层抽样将数据划分为 train/test 4. 训练 `RandomForestClassifier` 5. 在 test split 上进行评估 6. 将训练好的模型保存到 `models/random_forest_fraud_model.joblib` 7. 在 FastAPI 中加载保存的模型并在 `/predict` 中使用 服务产出物是一个序列化的 sklearn `Pipeline`。它包含拟合好的 `RandomForestClassifier` 和服务所需的预处理步骤,包括针对 `time_bin` 的 one-hot 编码。 当前模型参数: - `n_estimators=200` - `class_weight='balanced'` - `n_jobs=-1` - `random_state=42` ## 模型选择 / 最终模型如何选出 该项目采用了流程驱动的模型选择方法。 **这里的模型选择是作为一个独立的、深思熟虑的过程进行的,而不是通过单次运行就做出的决定。** 本项目中的模型选择是分阶段进行的,而不是仅仅依靠直觉。 1. **单次划分基准测试** 被用作在一个分层 train/test 划分上的快速初步 baseline。 2. **分层交叉验证基准测试** 成为了主要的模型选择程序。 3. 使用跨 CV 折叠的 `mean PR-AUC` 作为主要选择指标,因为欺诈类别严重不平衡。 4. 在候选名单确定后,使用 `F2` 在单独的验证集上独立进行 **阈值调优**。 5. 基于此过程,选择 `RandomForestClassifier` 作为最终的服务模型。 模型选择总结 / 简要说明: - 单次划分基准测试作为快速的 baseline 比较; - 交叉验证基准测试是模型选择的主要来源; - `CatBoostClassifier` 作为强有力的基准候选保留在代码库中,而不是作为最终的服务模型。 - 单次划分基准测试作为快速 baseline 保留; - CV 基准测试作为模型选择的主要阶段; - `CatBoostClassifier` 在项目中作为强有力的候选者保留,但不是最终的服务模型。 交叉验证基准测试总结: | 模型 | 平均 PR-AUC | PR-AUC 标准差 | 平均 ROC-AUC | ROC-AUC 标准差 | | --- | ---: | ---: | ---: | ---: | | RandomForestClassifier | 0.855822 | 0.024644 | 0.954049 | 0.010747 | | CatBoostClassifier | 0.811840 | 0.038346 | 0.981338 | 0.001592 | | LogisticRegression | 0.760740 | 0.014065 | 0.977431 | 0.007064 | 候选模型的阈值调优: | 模型 | 阈值 | 精确率 | 召回率 | F2 | | --- | ---: | ---: | ---: | ---: | | RandomForestClassifier | 0.2 | 0.924731 | 0.877551 | 0.886598 | | CatBoostClassifier | 0.9 | 0.833333 | 0.867347 | 0.860324 | 此阈值分析有意与模型选择分开: - 模型选择基于交叉验证的 `mean PR-AUC`; - 运行阈值选择基于候选模型在单独验证集上的 `F2` 分数; - 对于最终的服务模型,调整后的运行阈值为 `0.2`,而上述主要的训练指标仍以默认的 `0.5` 进行报告。 ## 特征工程 / 特征构建 该模型使用 33 个特征。 基础特征: - `Time` - `Amount` - `V1` ... `V28` 派生特征: - `hour` — 从 `Time` 中提取,用于捕捉日内时间规律 - `log_amount` — `log1p(Amount)`,以减少长尾金额分布的影响 - `time_bin` — 分类时间桶:`night`、`morning`、`afternoon`、`evening` 重要细节 / 重要细节: - 相同的特征工程逻辑在训练和推理中都被重用,因此训练和服务保持一致。 - 在训练和推理中都使用了相同的特征逻辑,因此不会出现训练/推理不匹配的情况。 ## API ### `GET /` 重定向到 dashboard: - `http://localhost:8000/` -> `http://localhost:8000/dashboard/` ### `GET /health` 返回服务状态: ``` { "status": "ok" } ``` ### `POST /predict` 接受数据集特征格式的一笔交易,并返回欺诈概率。 响应示例: ``` { "fraud_proba": 0.39 } ```
请求 payload 示例 ``` { "Time": 0.0, "Amount": 149.62, "V1": -1.3598071336738, "V2": -0.0727811733098497, "V3": 2.53634673796914, "V4": 1.37815522427443, "V5": -0.338320769942518, "V6": 0.462387777762292, "V7": 0.239598554061257, "V8": 0.0986979012610507, "V9": 0.363786969611213, "V10": 0.0907941719789316, "V11": -0.551599533260813, "V12": -0.617800855762348, "V13": -0.991389847235408, "V14": -0.311169353699879, "V15": 1.46817697209427, "V16": -0.470400525259478, "V17": 0.207971241929242, "V18": 0.0257905801985591, "V19": 0.403992960255733, "V20": 0.251412098239705, "V21": -0.018306777944153, "V22": 0.277837575558899, "V23": -0.110473910188767, "V24": 0.0669280749146731, "V25": 0.128539358273528, "V26": -0.189114843888824, "V27": 0.133558376740387, "V28": -0.0210530534538215 } ```
注意事项: - API 期望与数据集相同的特征 schema; - 这对于演示 ML pipeline 很有用,但它并不是用于生产反欺诈服务的真实公共接口。 ## Dashboard 该代码库在 `/dashboard/` 中包含一个简单的 Web UI。 它允许你: - 手动输入交易特征; - 加载样本交易; - 向 `/predict` 发送请求; - 在轻量级界面中检查返回的欺诈概率。 此 dashboard 旨在用于演示和手动验证,而不是用于分析或运维工作。 ## 项目结构 ``` fraud-detection-ml-system/ ├── README.md ├── Dockerfile ├── docker-compose.yml ├── requirements.txt ├── app/ │ ├── main.py │ └── utils.py ├── dashboard/ │ ├── index.html │ ├── app.js │ └── styles.css ├── data/ │ └── creditcard.csv ├── models/ │ ├── catboost_fraud_model.cbm │ └── random_forest_fraud_model.joblib ├── scripts/ │ ├── compare_models.py │ ├── compare_models_cv.py │ └── train_model.py └── src/ ├── features/ │ └── fraud_features.py ├── inference/ │ └── predict.py ├── models/ │ └── model_utils.py ├── training/ │ ├── compare_models.py │ ├── compare_models_cv.py │ └── train.py └── utils/ └── metrics.py ``` 关键文件: - `src/features/fraud_features.py` — 共享特征工程 - `src/training/train.py` — 训练、划分、评估、模型保存 - `src/training/compare_models.py` — 单次划分基准测试 - `src/training/compare_models_cv.py` — 基于 CV 的模型选择和阈值调优 - `scripts/train_model.py` — 用于模型训练的 CLI 入口点 - `app/main.py` — FastAPI 应用和端点 - `models/random_forest_fraud_model.joblib` — 作为序列化 sklearn pipeline 的主要服务产出物 - `models/catboost_fraud_model.cbm` — 保留的基准产出物 ## 在本地运行 1. 创建并激活虚拟环境: ``` python3 -m venv .venv source .venv/bin/activate ``` 2. 安装依赖: ``` pip install -r requirements.txt ``` 3. 确保数据集存在于 `data/creditcard.csv` 4. 训练模型: ``` python scripts/train_model.py ``` 可选参数: ``` python scripts/train_model.py \ --data-path data/creditcard.csv \ --model-path models/random_forest_fraud_model.joblib \ --test-size 0.2 \ --random-state 42 \ --threshold 0.5 ``` 5. 启动 API: ``` uvicorn app.main:app --reload ``` ## 使用 Docker 运行 在使用 Docker 之前,模型应该已经存在于 `models/random_forest_fraud_model.joblib` 中,因为容器会使用现成的模型产出物启动 API。 构建并运行: ``` docker compose up --build ``` 启动后: - `http://localhost:8000/dashboard/` - `http://localhost:8000/health` - `http://localhost:8000/docs` 当前的 Docker 限制: - 此设置旨在用于本地演示,并且仍然将 `models/` 和 `data/` 都复制到容器中。 ## 限制 / 限制 - 这是一个学习/演示项目,不是生产部署; - API 期望接收 PCA 风格的数据集特征 `V1` ... `V28`,而不是原始交易字段; - 主要的训练指标仍然基于单次分层 train/test 划分进行报告; - 该项目确实包含 CV 基准测试和阈值调优,但不包含重复 CV、嵌套验证或超参数搜索; - 没有实验跟踪; - 目前还没有针对训练 pipeline 或 API 的自动化测试; - 没有生产级别的日志记录、监控或部署设置; - dashboard 有意保持轻量级,并不是一个完整的分析工具; - 模型选择比以前更稳健,但仍然没有完整的实验管理工作流作为后盾。 ## 未来改进 - 基于业务权衡进行阈值调优 - 针对特征工程、训练和 `/predict` 进行测试 - 用于模型和 pipeline 参数的配置/设置 - 基本的 API 日志记录和错误报告 - 更丰富的 dashboard 解释 - 保存的指标报告和简短的模型卡片 ## 展示的技能 / 该项目展示的内容 - 针对不平衡分类的表格 ML - 可复现的模型训练 pipeline - 通过 baseline 基准测试、CV 基准测试和阈值调优进行的流程驱动模型选择 - 用于训练和推理的共享特征工程 - 用于模型推理的 FastAPI 服务 - 使用 Docker 进行模型打包和本地部署 - 端到端地展示 ML 项目,以供作品集和面试讨论 - 处理表格数据和严重的类不平衡 - 可复现的训练 pipeline - 通过基准测试 + CV + 阈值调优进行深思熟虑的模型选择 - 保持训练和推理一致 - 通过 FastAPI 提供 ML 服务 - 将项目打包到 Docker 中
标签:Apex, AV绕过, CatBoost, Docker, FastAPI, Scikit-learn, 安全防御评估, 机器学习, 欺诈检测