Fraud detection on imbalanced credit-card transaction data — SMOTE + Logistic Regression / XGBoost / LightGBM / CatBoost, packaged in Python and served via FastAPI + Docker.
Serving model LightGBM — fraud precision 0.405 · recall 0.714 · F1 0.517 (holdout; 21 fraud cases) · 0.385% fraud prevalence · verified this session
docker compose up --build → POST /predict with engineered feature JSON (API on :8000, or API_PORT=8001 if busy).
Repo: github.com/ArchanaChetan07/Credit-Card-Transactions-Fraud-Detection-Project
Verified holdout results from artifacts/metrics.json, generated by fraud_detection/pipeline.py:
| Model | Fraud precision | Fraud recall | Fraud F1 | False positives | True positives |
|---|---|---|---|---|---|
| Logistic Regression | 0.0432 | 0.6190 | 0.0807 | 288 | 13 |
| XGBoost | 0.3000 | 0.7143 | 0.4225 | 35 | 15 |
| LightGBM (served) | 0.4054 | 0.7143 | 0.5172 | 22 | 15 |
| CatBoost | 0.0180 | 0.8095 | 0.0353 | 926 | 17 |
False positives create unnecessary fraud-review work and customer friction, while false negatives allow missed fraud and financial loss; LightGBM is the production choice because it preserves strong recall while reducing CatBoost's operationally unusable 926 false positives to 22.
ADS505-origin portfolio project upgraded from a notebook-only bake-off to a reproducible package, pytest suite, LightGBM FastAPI scorer, and Docker Compose deploy. Source of truth for metrics is python -m fraud_detection.pipeline → artifacts/metrics.json (not stale notebook outputs).
| Signal | Value |
|---|---|
| File | fraud.csv (committed) |
| Rows | 27,785 |
| Fraud / legit | 107 / 27,678 |
| Fraud prevalence | 0.3851% |
| Origin | Kaggle-style kartik2112 transaction sample (not ULB creditcard.csv) |
| Holdout | 5,557 rows · 21 fraud (stratified test_size=0.2, random_state=42) |
| SMOTE train | 22,142 / 22,142 |
| Engineered features | 29 |
- Feature engineering: haversine customer→merchant distance, generation from DOB, OECD city-pop bins, time-of-day / weekend, one-hot category/gender
- Stratified train/test split
- SMOTE on train only +
StandardScaler - Train four classifiers with notebook-faithful settings
- Evaluate fraud-class precision / recall / F1 (accuracy is a weak signal at 0.385% fraud)
flowchart LR
CSV[fraud.csv] --> FE[Feature engineering]
FE --> SPLIT[Stratified split]
SPLIT --> SMOTE[SMOTE on train]
SMOTE --> M[LR XGB LGBM CatBoost]
M --> EVAL[Fraud P/R/F1]
EVAL --> API[Serve LightGBM FastAPI]
Command: python -m fraud_detection.pipeline · artifact: artifacts/metrics.json
| Model | Fraud precision | Fraud recall | Fraud F1 | TN | FP | FN | TP |
|---|---|---|---|---|---|---|---|
| Logistic Regression | 0.0432 | 0.6190 | 0.0807 | 5248 | 288 | 8 | 13 |
| XGBoost | 0.3000 | 0.7143 | 0.4225 | 5501 | 35 | 6 | 15 |
| LightGBM (served) | 0.4054 | 0.7143 | 0.5172 | 5514 | 22 | 6 | 15 |
| CatBoost | 0.0180 | 0.8095 | 0.0353 | 4610 | 926 | 4 | 17 |
xychart-beta
title Fraud precision on holdout
x-axis [LogReg, XGBoost, LightGBM, CatBoost]
y-axis "Precision" 0 --> 0.5
bar [0.0432, 0.30, 0.4054, 0.018]
xychart-beta
title Fraud recall on holdout
x-axis [LogReg, XGBoost, LightGBM, CatBoost]
y-axis "Recall" 0 --> 1
bar [0.619, 0.7143, 0.7143, 0.8095]
Committed notebook display previously showed CatBoost fraud P≈0.02 / R≈0.86. This package re-run (current library versions) yields P=0.018 / R=0.8095. LightGBM/XGB/LR align closely with the notebook (LGBM 0.405/0.714, XGB 0.30/0.714). README uses this session’s numbers only.
CatBoost FP note: precision 0.018 with 926 false positives vs 17 true positives means roughly ~54× more legitimate transactions flagged than true fraud caught as positives — strong coverage, unusable review queue without aggressive thresholding.
Served model: LightGBM
| Criterion | Why LightGBM wins for serving |
|---|---|
| Fraud F1 | 0.517 highest of the four |
| Fraud precision | 0.405 (vs CatBoost 0.018) |
| Fraud recall | 0.714 (ties XGBoost; CatBoost higher at 0.810 but floods FPs) |
| FP count | 22 vs CatBoost 926 on the same 5,557-row holdout |
CatBoost is retained in the comparison for honesty, not as the production scorer.
git clone https://github.com/ArchanaChetan07/Credit-Card-Transactions-Fraud-Detection-Project.git
cd Credit-Card-Transactions-Fraud-Detection-Project
python -m venv .venv
# Windows: .\.venv\Scripts\Activate.ps1
source .venv/bin/activate
pip install -r requirements-dev.txt
pip install -e .
# Train all models + write artifacts/serving_bundle.joblib + metrics.json
python -m fraud_detection.pipeline
uvicorn app.main:app --host 0.0.0.0 --port 8000Docker:
# pipeline must have produced artifacts/serving_bundle.joblib
API_PORT=8001 docker compose up --build
curl http://127.0.0.1:8001/health
curl -X POST http://127.0.0.1:8001/predict -H "content-type: application/json" \
-d "{\"features\":{\"amt\":9000}}"
# Missing keys default to 0; /features lists training columns.Exploration notebook (historical): notebooks/exploration.ipynb
pytest tests/ -v -m "not integration"
pytest tests/ -v -m integrationVerified this session: 11/11 passed. Covers CSV shape/prevalence, SMOTE class balance, metric helpers on synthetic labels, API /health + /predict against the trained bundle.
| Layer | Technology |
|---|---|
| Package | fraud_detection/ (data, preprocessing, models, evaluate, pipeline) |
| ML | scikit-learn · imbalanced-learn SMOTE · XGBoost · LightGBM · CatBoost |
| API | FastAPI + uvicorn |
| Containers | Dockerfile · Docker Compose |
| CI | GitHub Actions (flake8 · train · pytest · Docker build) |
See repository. Project PDF writeup: ADS505_FinalProject_Group4Code (1).pdf.
Archana Chetan · @ArchanaChetan07