🧠 AI with Python – 💳 Credit Card Fraud Detection (Imbalanced ML)
Posted on: January 8, 2026
Description:
Credit card fraud detection is one of the most challenging and high-impact machine learning problems in the real world. The difficulty doesn’t come from model complexity — it comes from extreme class imbalance.
In this project, we build a fraud detection model where fraudulent transactions are rare, and we focus on learning how to model, evaluate, and reason about such systems correctly.
Understanding the Problem
In fraud detection:
- Fraud cases are often less than 1% of all transactions
- Predicting “no fraud” all the time gives high accuracy
- False negatives (missed fraud) are very costly
This makes fraud detection fundamentally different from standard classification problems. The goal is not to maximize accuracy — it is to identify rare fraud cases reliably.
1. Preparing an Imbalanced Fraud Dataset
To simulate a realistic fraud scenario, we create a dataset where fraud cases are extremely rare.
from sklearn.datasets import make_classification
import pandas as pd
X, y = make_classification(
n_samples=10000,
n_features=20,
n_informative=10,
n_redundant=5,
weights=[0.995, 0.005],
random_state=42
)
df = pd.DataFrame(X, columns=[f"feature_{i}" for i in range(20)])
df["fraud"] = y
This setup mirrors real-world fraud datasets where the positive class is heavily underrepresented.
2. Stratified Train/Test Split
To ensure fair evaluation, we preserve class distribution during splitting.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
df.drop("fraud", axis=1),
df["fraud"],
test_size=0.3,
stratify=df["fraud"],
random_state=42
)
Stratification prevents accidental loss of fraud samples in the test set.
3. Handling Extreme Imbalance with SMOTE
If trained directly, most models will ignore fraud cases entirely.
To counter this, we use SMOTE to oversample the minority class.
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)
SMOTE helps the model learn decision boundaries for fraud transactions.
4. Training a Fraud Detection Model
We use Random Forest, which performs well on tabular data with complex interactions.
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(
n_estimators=300,
max_depth=10,
random_state=42
)
model.fit(X_resampled, y_resampled)
Ensemble models are a strong baseline for fraud detection tasks.
5. Evaluating the Model Correctly
Accuracy is misleading in fraud detection.
Instead, we focus on metrics that reflect class separation and recall.
from sklearn.metrics import classification_report, confusion_matrix
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
print(confusion_matrix(y_test, y_pred))
Metrics like recall and F1-score provide better insight into fraud detection performance.
6. ROC–AUC for Fraud Detection
ROC–AUC measures how well the model separates fraud from non-fraud transactions.
from sklearn.metrics import roc_auc_score
y_proba = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_proba)
print("ROC–AUC:", auc)
A ROC–AUC around 0.6 is normal and realistic for baseline fraud models — especially with synthetic data and no heavy tuning.
Why Fraud Detection Is Hard
Fraud detection systems must deal with:
- extreme class imbalance
- constantly changing fraud patterns
- high cost of false negatives
- noisy and evolving data
This makes model evaluation and threshold tuning more important than model choice alone.
Key Takeaways
- Credit card fraud detection is an extreme imbalanced ML problem.
- Accuracy is a misleading metric in fraud use cases.
- SMOTE helps models learn rare fraud patterns, but has limits.
- ROC–AUC and recall are more meaningful than raw accuracy.
- Baseline AUC scores around 0.6 are realistic and expected.
Conclusion
Fraud detection highlights a critical truth about applied machine learning: metrics and problem framing matter more than model complexity.
By handling imbalance properly and evaluating models using the right metrics, we build systems that are not just accurate on paper, but meaningful in real-world decision-making.
This project represents a true real-world ML workflow, making it a strong addition to the AI with Python – Advanced Mini Projects series.
Code Snippet:
# =========================================================
# AI with Python – Credit Card Fraud Detection (Imbalanced ML)
# Programmer: python_scripts (Abhijith Warrier)
# =========================================================
# 📦 Import Required Libraries
import numpy as np
import pandas as pd
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (
classification_report,
confusion_matrix,
roc_auc_score
)
from imblearn.over_sampling import SMOTE
# 🧩 Create an Imbalanced Fraud Dataset
X, y = make_classification(
n_samples=10000,
n_features=20,
n_informative=10,
n_redundant=5,
n_clusters_per_class=1,
weights=[0.995, 0.005], # extreme fraud imbalance
flip_y=0,
random_state=42
)
df = pd.DataFrame(X, columns=[f"feature_{i}" for i in range(20)])
df["fraud"] = y
print("Class distribution:")
print(df["fraud"].value_counts(normalize=True))
# ✂️ Train/Test Split (Stratified)
X_train, X_test, y_train, y_test = train_test_split(
df.drop("fraud", axis=1),
df["fraud"],
test_size=0.3,
stratify=df["fraud"],
random_state=42
)
# ⚖️ Handle Class Imbalance with SMOTE
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)
print("\nAfter SMOTE class distribution:")
print(pd.Series(y_resampled).value_counts())
# 🌲 Train Random Forest Classifier
model = RandomForestClassifier(
n_estimators=300,
max_depth=10,
random_state=42,
n_jobs=-1
)
model.fit(X_resampled, y_resampled)
# 📊 Evaluate the Model
y_pred = model.predict(X_test)
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
# 📈 ROC–AUC Score
y_proba = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_proba)
print(f"ROC–AUC: {auc:.4f}")
No comments yet. Be the first to comment!