Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Intermediate ⏱ 45 min

💳 Build a Credit Card Fraud Detector with scikit-learn

🎯 What You'll Build

A fraud detection model that handles severe class imbalance with SMOTE, evaluates with precision-recall curves, and flags suspicious transactions.

📋 What You'll Need

1

Load and understand the dataset

The dataset has 284,807 transactions — only 492 are fraud (0.17%). This class imbalance is the main challenge.

import pandas as pd
import numpy as np

# Download from: https://www.kaggle.com/datasets/mlg-ulb/creditcardfraud
df = pd.read_csv('creditcard.csv')

print(df.shape)                           # (284807, 31)
print(df['Class'].value_counts())
# 0    284315  (legitimate)
# 1       492  (fraud)

fraud_pct = df['Class'].mean() * 100
print(f"Fraud rate: {fraud_pct:.2f}%")   # 0.17% — extremely rare

print(df[['Time','Amount','Class']].describe())
2

Split and apply SMOTE to handle class imbalance

SMOTE (Synthetic Minority Oversampling Technique) creates synthetic fraud examples to balance classes.

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from imblearn.over_sampling import SMOTE

X = df.drop('Class', axis=1)
y = df['Class']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Scale Amount and Time (other features are already PCA-transformed)
scaler = StandardScaler()
X_train[['Amount','Time']] = scaler.fit_transform(X_train[['Amount','Time']])
X_test[['Amount','Time']]  = scaler.transform(X_test[['Amount','Time']])

# Apply SMOTE only to training data
smote = SMOTE(random_state=42)
X_resampled, y_resampled = smote.fit_resample(X_train, y_train)

print(f"Before SMOTE: {dict(pd.Series(y_train).value_counts())}")
print(f"After  SMOTE: {dict(pd.Series(y_resampled).value_counts())}")
Before SMOTE: {0: 227451, 1: 394}
After  SMOTE: {0: 227451, 1: 227451}
3

Train and evaluate with precision-recall curve

For fraud detection, recall (catching real fraud) matters more than precision (avoiding false alarms).

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, PrecisionRecallDisplay
import matplotlib.pyplot as plt

clf = RandomForestClassifier(n_estimators=50, n_jobs=-1, random_state=42)
clf.fit(X_resampled, y_resampled)

y_pred  = clf.predict(X_test)
y_proba = clf.predict_proba(X_test)[:, 1]

print(classification_report(y_test, y_pred, target_names=['Legit','Fraud']))

# Precision-Recall curve (better than ROC for imbalanced classes)
fig, ax = plt.subplots(figsize=(6,5))
PrecisionRecallDisplay.from_predictions(y_test, y_proba, ax=ax, name='Random Forest')
ax.set_title('Precision-Recall Curve — Fraud Detection')
plt.tight_layout()
plt.savefig('precision_recall.png', dpi=120)
plt.show()
4

Flag suspicious transactions

Apply a lower threshold to catch more fraud at the cost of more false alarms.

# Default threshold is 0.5 — lower it to catch more fraud
THRESHOLD = 0.3

y_pred_low = (y_proba >= THRESHOLD).astype(int)
print(f"\nWith threshold={THRESHOLD}:")
print(classification_report(y_test, y_pred_low, target_names=['Legit','Fraud']))

# Show top 5 most suspicious transactions
suspicious = X_test.copy()
suspicious['fraud_prob'] = y_proba
suspicious['actual']     = y_test.values
top5 = suspicious.nlargest(5, 'fraud_prob')[['Amount','fraud_prob','actual']]
print("\nTop 5 most suspicious transactions:")
print(top5)
💡 Tip: Use ROC-AUC for balanced datasets and Precision-Recall AUC (Average Precision) for imbalanced ones like this. A model that just predicts "not fraud" every time gets 99.83% accuracy — but 0% recall for fraud. Always check the minority class metrics.

🎉 You Did It!

You handled the hardest problem in real-world ML: class imbalance. SMOTE + a lower decision threshold together make the model practical. The same pipeline — SMOTE, RF, precision-recall evaluation — is used in production fraud systems at banks and payment processors.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.