Skip to content

Credit Card Fraud Detection

Credit Card Fraud Detection is a Python project that uses machine learning to detect fraudulent transactions. The application features data preprocessing, model training, and evaluation, demonstrating best practices in data science and security.

  • Python 3.8 or above
  • A code editor or IDE
  • Basic understanding of machine learning and data science
  • Required libraries: pandas, scikit-learn, matplotlib

Install Python and the required libraries:

Install dependencies
pip install pandas scikit-learn matplotlib
  1. Create a folder named credit-card-fraud-detection.
  2. Open the folder in your code editor or IDE.
  3. Create a file named credit_card_fraud_detection.py.
  4. Copy the code below into your file.
Credit Card Fraud Detection pch.viewSource
Credit Card Fraud Detection
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score
import matplotlib.pyplot as plt

import os

import numpy as np


def sample_dataset(rows=20000, fraud_rate=0.0017, seed=0):
    """Stand in for the Kaggle credit-card dataset, which is not in this repo.

    The real file is ~150 MB and cannot be redistributed here, so this builds
    one with the property that actually matters for the lesson: fraud is rare.
    At 0.17% positives, a model that predicts "legitimate" every time scores
    99.83% accuracy -- which is why the classification report below, not the
    accuracy line, is the thing to read.
    """
    rng = np.random.default_rng(seed)
    frauds = int(rows * fraud_rate)
    labels = np.zeros(rows, dtype=int)
    labels[rng.choice(rows, frauds, replace=False)] = 1

    features = rng.normal(0, 1, (rows, 28))
    # Fraudulent rows differ on a handful of components, faintly.
    features[labels == 1, 3] += 2.2
    features[labels == 1, 11] -= 1.9
    features[labels == 1, 17] += 1.4

    frame = pd.DataFrame(features, columns=[f"V{i}" for i in range(1, 29)])
    frame["Time"] = rng.uniform(0, 172800, rows)
    frame["Amount"] = np.abs(rng.lognormal(3.0, 1.2, rows)).round(2)
    frame["Class"] = labels
    return frame


# Load dataset (replace with your dataset path)
if os.path.exists("creditcard.csv"):
    data = pd.read_csv("creditcard.csv")
else:
    data = sample_dataset()
    print(f"creditcard.csv not found, so a synthetic set was generated: "
          f"{len(data):,} rows, {int(data['Class'].sum())} frauds "
          f"({data['Class'].mean():.4%})")
    print("the real dataset is on Kaggle; the imbalance is what matters here\n")

baseline = 1 - data["Class"].mean()
print(f"always predicting 'legitimate' would score {baseline:.4%}")
print("so accuracy alone cannot tell you whether the model learned anything\n")

# Features and target
y = data['Class']
X = data.drop(['Class', 'Time'], axis=1)

# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Predict
y_pred = model.predict(X_test)

# Evaluation
print('Accuracy:', accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred, zero_division=0))

# The line above is the point of the whole project. Read the recall on class 1.
caught = int(((y_pred == 1) & (y_test == 1)).sum())
total_fraud = int((y_test == 1).sum())
print(f"frauds in the test set : {total_fraud}")
print(f"frauds the model caught: {caught}")
print(f"accuracy               : {accuracy_score(y_test, y_pred):.4f}")
print()
print("a model that catches none of the fraud still scores about 99.8%,")
print("because 99.8% of the rows are not fraud. Accuracy is the wrong metric")
print("for a rare event; recall on the positive class is the one that moves.")
print("Fixing it means class weights, resampling, or a threshold chosen from")
print("the precision-recall curve -- not a bigger forest.")

# Feature importance plot
importances = model.feature_importances_
features = X.columns
plt.figure(figsize=(10,6))
plt.barh(features, importances)
plt.xlabel('Importance')
plt.title('Feature Importances')
plt.tight_layout()
plt.savefig("credit_card_fraud_detection.png", dpi=120, bbox_inches="tight")
print("saved credit_card_fraud_detection.png")
plt.show()
Run fraud detection
python credit_card_fraud_detection.py

Running the file exactly as it ships takes 6.6 s and prints:

python credit_card_fraud_detection.py
creditcard.csv not found, so a synthetic set was generated: 20,000 rows, 34 frauds (0.1700%)
the real dataset is on Kaggle; the imbalance is what matters here
 
always predicting 'legitimate' would score 99.8300%
so accuracy alone cannot tell you whether the model learned anything
 
Accuracy: 0.9985
              precision    recall  f1-score   support
 
           0       1.00      1.00      1.00      3994
           1       0.00      0.00      0.00         6
 
    accuracy                           1.00      4000
   macro avg       0.50      0.50      0.50      4000
weighted avg       1.00      1.00      1.00      4000
 
frauds in the test set : 6
frauds the model caught: 0
accuracy               : 0.9985
 
...

The first 20 of 26 lines are shown; the run continues past this point.

figure Produced by this project, not drawn for the page matplotlib
Output of credit_card_fraud_detection.py, produced by running the file.
Written by the run above. If the project stops producing it, the page's figure asset goes missing and check_docs reports it — which is the point of generating it rather than drawing it.

Read from the top: this is what runs when you execute the file, and which function calls which. It is generated from the code, so it cannot drift from it.

diagram Diagram mermaid
  • Data Preprocessing: Cleans and prepares transaction data.
  • Model Training: Trains a machine learning model to detect fraud.
  • Evaluation: Assesses model performance.
  • Error Handling: Validates inputs and manages exceptions.
  1. What it imports (lines 1–5)
credit_card_fraud_detection.py
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, accuracy_score
import matplotlib.pyplot as plt

The file defines 0 top-level symbols in all; the whole thing is above under Write the Code.

  • Fraud Detection: Data preprocessing, model training, and evaluation
  • Modular Design: Separate functions for each task
  • Error Handling: Manages invalid inputs and exceptions
  • Production-Ready: Scalable and maintainable code

Enhance the project by:

  • Integrating with real transaction datasets
  • Supporting advanced ML algorithms
  • Creating a GUI for detection
  • Adding real-time monitoring
  • Unit testing for reliability

This project teaches:

  • Data Science: Fraud detection and ML
  • Software Design: Modular, maintainable code
  • Error Handling: Writing robust Python code
  • Banking Security
  • Financial Analytics
  • Fraud Prevention Platforms

Credit Card Fraud Detection demonstrates how to build a scalable and accurate fraud detection tool using Python. With modular design and extensibility, this project can be adapted for real-world applications in finance, security, and more. For more advanced projects, visit Python Central Hub.

  • Accuracy is the wrong metric and it is the default one. Measured on the shipped project: 0.9985 accuracy, 0 of 6 frauds caught. Predicting “legitimate” for every row scores 99.83%, so accuracy cannot distinguish a working model from no model at all.
  • predict() hard-codes a 0.5 threshold. In the exercise below the same trained model catches 13 of 51 frauds at 0.5 and 32 of 51 at 0.02. Nothing was retrained; the threshold is a deployment decision that the default silently makes for you.
  • class_weight='balanced' is not a fix on its own. Measured: recall 0.255 at defaults, 0.235 balanced, 0.235 at a 50:1 weight. The weighting changes the tree splits and leaves the 0.5 cut in place.
  • Report the number the business acts on. Precision at a chosen recall — how many reviews buy one caught fraud — is actionable. Accuracy is not, and stays above 0.998 at every threshold in the table.
  • Average precision, not ROC AUC, for a rare positive. ROC AUC is dominated by the enormous negative class; the measured average precision of 0.310 describes the part anyone cares about.
  • Six frauds in a test set is not enough to measure anything. The shipped project has exactly that, which is why the exercise raises the sample until the test set holds 51.
  • Measured: accuracy 0.9985, frauds in the test set 6, frauds caught 0.
  • The all-legitimate baseline scores 99.83% — the number to beat before any accuracy figure means anything.
  • Threshold sweep on one model: 0.50 → 13 caught at 72.2% precision; 0.02 → 32 caught at 6.7% precision.
  • Fixing it means class weights, resampling, or a threshold chosen from the precision–recall curve — not a bigger forest.
pch.quizTag pch.quizDefaultTitle
  1. The model scores 0.9985 accuracy and catches 0 of 6 frauds. How is that possible?

    pch.quizShowAnswer

    B — 99.83% of the rows are legitimate, so a model that labels everything legitimate scores 99.83% — accuracy has almost no room to reflect the fraud

  2. The same trained model caught 13 frauds at threshold 0.5 and 32 at 0.02. What changed?

    pch.quizShowAnswer

    B — Nothing about the model — predict() uses 0.5 by default, and that cut is only right when the classes are balanced and both mistakes cost the same

  3. Why report average precision rather than ROC AUC here?

    pch.quizShowAnswer

    B — ROC AUC is dominated by the huge negative class and stays flattering; average precision summarises the precision-recall curve, which is where a rare positive class actually lives

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading