A supervised learning pipeline that detects fraudulent credit card transactions in a highly imbalanced dataset (~2% fraud), using SMOTE resampling, Logistic Regression, and Random Forest — evaluated with metrics built for rare-event classification (Precision, Recall, F1, ROC-AUC), not accuracy.
Fraud detection is a textbook imbalanced classification problem: fraud is rare, expensive to miss, and expensive to over-flag. This project builds an end-to-end pipeline that:
- Cleans and explores a transaction dataset
- Engineers domain-informed features (timing, spend velocity, distance anomalies, account risk signals)
- Balances the training data with SMOTE
- Trains and tunes Logistic Regression and Random Forest with
GridSearchCV - Evaluates both models on Precision, Recall, F1, and ROC-AUC
data/raw/fraud_dataset.csv — 12,000+ synthetic transaction records
modeled on realistic card-fraud patterns (transaction amount, timing,
geographic distance signals, account age, merchant category, channel,
etc.), including intentionally messy elements: missing values, duplicate
rows, and a small amount of label noise, since real-world data is never
perfectly clean.
| Rows | ~12,000 |
| Features | 14 raw → 30 after encoding & feature engineering |
| Target | is_fraud (binary) |
| Class balance | ~98% legitimate / ~2% fraud |
- Python 3.12
- pandas / numpy — data manipulation
- matplotlib / seaborn — visualization
- scikit-learn — modelling, GridSearchCV, metrics
- imbalanced-learn — SMOTE
- joblib — model persistence
Project_2_Fraud_Detection/
│
├── data/
│ ├── raw/
│ │ └── fraud_dataset.csv
│ └── processed/
│ └── processed_data.csv
│
├── notebooks/
│ └── Fraud_Detection.ipynb
│
├── outputs/
│ ├── figures/ # 10 saved visualizations
│ ├── metrics/ # metrics.json, model_comparison.csv, best_hyperparameters.json
│ └── reports/ # report.md
│
├── models/
│ ├── logistic_regression.pkl
│ ├── random_forest.pkl
│ └── scaler.pkl
│
├── src/
│ ├── preprocess.py # cleaning, encoding, scaling, splitting
│ ├── feature_engineering.py
│ ├── train.py # SMOTE + GridSearchCV training
│ ├── evaluate.py # metrics + plots
│ └── utils.py # paths, logging, I/O helpers
│
├── requirements.txt
├── README.md
└── run_pipeline.py
- EDA — class distribution, missing values, correlations, feature distributions by class
- Cleaning — drop duplicates, impute missing values
- Feature Engineering — night-transaction flag, velocity flag, amount-to-limit ratio, log amount, new-account flag, decline flag, distance anomaly score
- Encoding — one-hot encode
merchant_categoryandchannel - Train/Test Split — stratified 80/20 split
- Scaling —
StandardScaler, fit on train only - SMOTE — applied to the training set only, never the test set
- Modelling — Logistic Regression and Random Forest, each tuned with
GridSearchCV(5-fold / 3-fold CV, optimizing F1) - Evaluation — Precision, Recall, F1, ROC-AUC, Average Precision; confusion matrices, ROC curve, precision-recall curve, feature importance
git clone <this-repo-url>
cd Project_2_Fraud_Detection
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtRun the full pipeline end-to-end (regenerates processed data, trained models, all 10 figures, and metrics):
python run_pipeline.pyOr step through the analysis interactively:
jupyter notebook notebooks/Fraud_Detection.ipynb| Model | Precision | Recall | F1 Score | ROC-AUC |
|---|---|---|---|---|
| Random Forest | 0.800 | 0.480 | 0.600 | 0.876 |
| Logistic Regression | 0.222 | 0.560 | 0.318 | 0.848 |
Random Forest is the stronger model overall: at a comparable recall, it achieves far higher precision, meaning significantly fewer false alarms per fraud case caught — an important property in production, where every flagged transaction typically triggers manual review or customer friction. Logistic Regression trades precision for a slightly higher recall, consistent with its simpler linear decision boundary.
Neither model is "perfect," and that's expected: with heavy class overlap between legitimate and fraudulent behavior (a realistic property of fraud data), ROC-AUC in the 0.85–0.88 range represents solid, deployable performance rather than an artifact of an overly easy dataset.
Full metrics: outputs/metrics/metrics.json · outputs/reports/report.md
| Class Distribution | ROC Curve |
|---|---|
![]() |
![]() |
| SMOTE Before/After | Feature Importance |
|---|---|
![]() |
![]() |
- Try gradient boosting (XGBoost / LightGBM), which often edges out Random Forest on tabular fraud data
- Tune the classification threshold against an explicit cost matrix (false positive vs false negative cost) instead of the default 0.5 cutoff
- Use time-aware validation (train on earlier transactions, test on later ones) to better simulate production drift
- Explore anomaly detection / autoencoder methods as a complementary signal alongside supervised classification
- Deploy behind a lightweight API (FastAPI) for real-time scoring
This project was built as part of a Data Science internship exercise.



