Back to Blog

Fraud Detection with Machine Learning

How machine learning models detect and prevent financial fraud in real time, protecting businesses and customers alike.

The Growing Threat of Digital Fraud

As Indonesia’s digital economy expands, so does the surface area for fraud. The country’s fintech sector processes billions of transactions annually, and every one of those transactions is a potential target. Credit card fraud, account takeovers, synthetic identity fraud, and payment manipulation cost Indonesian businesses hundreds of billions of rupiah each year.

Traditional rule-based fraud detection systems catch known patterns: transactions above a certain amount, multiple purchases in quick succession, or transactions from blacklisted locations. But fraudsters adapt. They learn the rules and work around them. This is where machine learning changes the equation.

ML-based fraud detection systems learn from data, adapt to new patterns, and catch sophisticated fraud schemes that no static rule set could anticipate.

Why Machine Learning Excels at Fraud Detection

Fraud detection is fundamentally a pattern recognition problem with several characteristics that make it ideal for ML:

High dimensionality. Each transaction has dozens of features: amount, time, location, device, merchant category, user history, network patterns. ML models process all these dimensions simultaneously, finding subtle combinations that indicate fraud.

Evolving patterns. Fraudsters constantly change tactics. ML models retrained on recent data capture new patterns automatically, while rule-based systems require manual updates.

Massive scale. A mid-sized Indonesian payment platform might process millions of transactions per day. ML models evaluate each one in milliseconds.

Imbalanced data. Fraud typically represents less than 1% of transactions. ML algorithms specifically designed for imbalanced classification handle this effectively.

Core Approaches

Supervised Learning

Train a model on labeled historical data (transactions marked as fraudulent or legitimate). The model learns to distinguish between the two classes.

import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, precision_recall_curve
from imblearn.over_sampling import SMOTE

# Load transaction data
data = pd.read_csv("transactions.csv")

# Feature engineering
features = [
    "amount", "hour_of_day", "day_of_week",
    "distance_from_home", "distance_from_last_transaction",
    "ratio_to_median_amount", "time_since_last_transaction",
    "transaction_count_last_24h", "unique_merchants_last_7d",
    "is_weekend", "is_international",
]

X = data[features]
y = data["is_fraud"]

# Handle class imbalance with SMOTE
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=42
)
smote = SMOTE(random_state=42)
X_train_balanced, y_train_balanced = smote.fit_resample(X_train, y_train)

# Train gradient boosting classifier
model = GradientBoostingClassifier(
    n_estimators=200,
    max_depth=5,
    learning_rate=0.1,
    random_state=42,
)
model.fit(X_train_balanced, y_train_balanced)

# Evaluate
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))

Unsupervised Learning

Detect fraud without labeled data by identifying transactions that deviate significantly from normal behavior. Useful when labeled fraud data is scarce or when you want to catch entirely new fraud patterns.

Isolation Forest isolates anomalies by randomly partitioning the data. Fraudulent transactions, being rare and different, are isolated in fewer partitions.

from sklearn.ensemble import IsolationForest

# Train anomaly detection model on legitimate transactions
legitimate_data = data[data["is_fraud"] == 0][features]

iso_forest = IsolationForest(
    contamination=0.01,  # Expected fraud rate
    random_state=42,
    n_estimators=200,
)
iso_forest.fit(legitimate_data)

# Score new transactions (-1 for anomaly, 1 for normal)
data["anomaly_score"] = iso_forest.predict(data[features])
potential_fraud = data[data["anomaly_score"] == -1]
print(f"Flagged transactions: {len(potential_fraud)}")

Graph-Based Detection

Fraud often involves networks of connected accounts. Graph-based approaches analyze relationships between accounts, devices, IP addresses, and transactions to identify fraud rings.

If account A shares a device with account B, and account B shares an IP address with account C, and account C is a known fraud account, then A and B deserve closer scrutiny.

Ensemble Methods

Production fraud detection systems typically combine multiple models:

  1. A supervised model trained on historical fraud labels
  2. An unsupervised anomaly detector for novel fraud patterns
  3. A graph-based model for network analysis
  4. Business rules for known, high-confidence fraud indicators

Each model produces a score, and a final ensemble combines them into an overall fraud probability.

Feature Engineering for Fraud Detection

The quality of your features matters more than the choice of algorithm. Effective fraud detection features fall into several categories:

Transaction Features

  • Amount, merchant category, payment method
  • Time of day, day of week, holiday indicator

Behavioral Features

  • Average transaction amount over past 30 days
  • Standard deviation of transaction amounts
  • Number of transactions in the last hour, day, week
  • Number of unique merchants in the last 7 days
  • Time since last transaction

Velocity Features

  • Number of failed authentication attempts
  • Rate of address or payment method changes
  • Frequency of transactions from new devices

Geographic Features

  • Distance from user’s typical transaction locations
  • International transaction indicator
  • Transaction location versus registered address

Device and Session Features

  • Device fingerprint match
  • Browser or app version
  • Session duration before transaction
  • Number of pages viewed before purchase
def engineer_fraud_features(transactions_df: pd.DataFrame) -> pd.DataFrame:
    """Create fraud detection features from raw transaction data."""
    df = transactions_df.copy()

    # Time-based features
    df["hour"] = pd.to_datetime(df["timestamp"]).dt.hour
    df["is_night"] = df["hour"].between(0, 5).astype(int)
    df["is_weekend"] = pd.to_datetime(df["timestamp"]).dt.dayofweek.isin([5, 6]).astype(int)

    # User behavioral aggregates (rolling windows)
    user_groups = df.sort_values("timestamp").groupby("user_id")

    df["avg_amount_30d"] = user_groups["amount"].transform(
        lambda x: x.rolling("30D", min_periods=1).mean()
    )
    df["amount_zscore"] = (df["amount"] - df["avg_amount_30d"]) / (
        user_groups["amount"].transform(
            lambda x: x.rolling("30D", min_periods=1).std()
        ).fillna(1)
    )

    # Velocity features
    df["txn_count_1h"] = user_groups["amount"].transform(
        lambda x: x.rolling("1H", min_periods=1).count()
    )

    return df

Deployment Architecture

Real-Time Scoring Pipeline

For payment fraud, decisions must happen in milliseconds. A typical architecture:

  1. Transaction arrives at the payment gateway
  2. Feature computation service enriches the transaction with behavioral and contextual features
  3. ML scoring service evaluates the enriched transaction against the model
  4. Decision engine applies the score along with business rules
  5. Transaction is approved, declined, or flagged for manual review

Target latency: under 100 milliseconds from transaction receipt to decision.

The Review Queue

Not every flagged transaction should be automatically blocked. Implement a tiered response:

Score RangeActionDescription
0.0 to 0.3Auto-approveLow risk, process normally
0.3 to 0.7Step-up authRequest additional verification (OTP, biometric)
0.7 to 0.9Manual reviewQueue for human analyst review
0.9 to 1.0Auto-blockHigh confidence fraud, decline immediately

Adjust thresholds based on your false positive tolerance and fraud loss targets.

Indonesian Fraud Landscape

Common Fraud Types

Account takeover. Fraudsters gain access to legitimate user accounts through credential stuffing, phishing, or social engineering. Particularly prevalent targeting e-wallet accounts.

Synthetic identity fraud. Creating fake identities using combinations of real and fabricated personal information. A growing concern in digital lending.

Transaction fraud. Using stolen card details or compromised payment credentials for purchases. Often targeting high-value electronics and easily resalable goods.

Promo abuse. Exploiting promotional offers through fake accounts or automated systems. Especially common during major sale events.

Regulatory Context

Bank Indonesia and OJK (Financial Services Authority) have issued guidelines on fraud prevention for financial institutions and fintech companies. Implementing ML-based fraud detection aligns with these regulatory expectations and demonstrates proactive risk management.

Measuring Performance

Fraud detection requires careful metric selection because of the class imbalance:

  • Precision: Of all flagged transactions, what percentage were actually fraud? High precision means fewer false alarms.
  • Recall: Of all actual fraud, what percentage did the system catch? High recall means fewer missed fraud cases.
  • F1 Score: Harmonic mean of precision and recall. Useful as a single summary metric.
  • False positive rate: Percentage of legitimate transactions incorrectly flagged. This directly impacts customer experience.
  • Detection rate at low FPR: How much fraud do you catch while keeping false positives below 1%?

The ideal balance depends on your business. A payment platform might tolerate more false positives to catch more fraud, while a retail checkout might prioritize minimizing friction for legitimate customers.

Getting Started

Start by auditing your current fraud prevention approach. Identify the gaps: what types of fraud are getting through? What is your false positive rate? How quickly can you adapt to new fraud patterns?

Then build a proof of concept using your historical transaction data. Even a simple gradient boosting model trained on well-engineered features will likely outperform a rule-based system.

Idea Comindo helps Indonesian financial institutions and e-commerce platforms build ML-powered fraud detection systems. From feature engineering through model deployment and monitoring, we bring the technical expertise to protect your business and your customers from evolving fraud threats.

Baca dalam Bahasa Indonesia Versi Indonesia