Build · 4h 30m · ₹0

An end-to-end AML fraud pipeline processing 400M+ banking transactions across 187 engineered features with LightGBM and XGBoost gradient-boosted ensembles (0.9830 AUC-ROC).

LightGBM + XGBoost + PyArrow + Pandas + Scikit-Learnharder buildBy LogixLoopsLive demo \

What it does

The mechanics, data flow, and user interaction model behind Mule Account Detection.

Processes a 16GB+ banking dataset covering ~400 million transactions over a 5-year window across customer KYC, account, branch, and product tables. Computes 187 engineered behavioral and graph-level features (inbound-to-outbound velocity, burst ratios, rapid fund dissipation, geographic branch anomalies) feeding two independent gradient-boosted models (LightGBM and XGBoost) combined in an ensemble. Trained on 96,091 labeled accounts under a realistic 2.8% positive class imbalance, scoring 64,062 held-out test accounts to output calibrated mule-probability scores and suspicious-activity time windows.

Technical Highlights

  • 187 engineered features across 400M+ transactions: velocity ratios, dormance-to-burst shifts, and rapid round-trip dissipation metrics
  • Multi-table PyArrow & Parquet memory-efficient pipeline joining customer KYC, multi-account, and branch tables
  • Dual gradient-boosted models compared: LightGBM (0.9822 AUC) and XGBoost (0.9827 AUC) with ensemble reaching 0.9830 AUC
  • Optimal F1 threshold calibration (threshold = 0.82) specifically tuned for 2.8% positive class imbalance
  • Strict leakage audits: verifies all temporal features exclude post-hoc metadata (freeze dates, investigative tags)

Why it matters

The architectural judgment, practical engineering decisions, and core problems solved.

Mule accounts (compromised or complicit accounts used to receive and rapidly dissipate stolen funds) are the operational backbone of money laundering networks. This project tackles real-world Anti-Money Laundering (AML) challenges at scale: multi-table relational schema joins over 400M rows with PyArrow, heavy class imbalance (2.8%), deliberate label noise injection, and rigorous temporal validation preventing post-hoc leakage (verifying features derive strictly from transaction behavior prior to freeze/flag dates). Both models achieve 0.982+ AUC-ROC, with optimal F1 thresholding at 0.82.

01

Bank & FinTech transaction monitoring for automated suspicious activity report (SAR) prioritization

02

Peer-to-peer payment gateway fraud detection for instant account freeze recommendations

03

Cryptocurrency on-ramp/off-ramp fiat layering detection and mule ring identification

04

Reference architecture for scalable tabular feature engineering over 100M+ row relational data

System architecture

End-to-end execution pipeline running across LightGBM, XGBoost, PyArrow, Pandas, Scikit-Learn.

01 / IngestionPyArrow Parquet Pipeline

Chunked streaming and columnar storage of 400M+ transactions across 5 relational tables

02 / Feature EnginePandas & NumPy Vectorizer

Computes 187 behavioral features: velocity, nocturnal transfers, dormant-to-active burst ratios

03 / ModelsLightGBM & XGBoost

Dual gradient-boosted trees trained with early stopping, scale_pos_weight, and stratified K-fold cross validation

04 / EnsembleWeighted Soft Voting

Combines calibrated probability outputs from LightGBM and XGBoost into final mule confidence score

05 / ThresholdF1 Precision-Recall Optimizer

Calibrates decision boundary at 0.82 to balance false positives against missed high-risk laundered sums

The path

Step-by-step implementation guide. Verbatim code snippets, configurations, and prompts.

01

Streaming Multi-Table Joins with PyArrow & Parquet

Design memory-efficient chunked readers to join 400M transaction records with customer demographics, account opening channels, and branch telemetry.

Verbatim Code / Config

import pyarrow.parquet as pq
import pyarrow.compute as pc
# Read dataset in 500k-row batches to maintain under 8GB RAM footprint
for batch in pq.ParquetFile('transactions.parquet').iter_batches(batch_size=500_000):
    df_batch = batch.to_pandas()
    df_features = extract_velocity_features(df_batch)
02

Engineering the 187-Feature Behavioral AML Matrix

Construct temporal features measuring rapid fund pass-through: time-to-dissipation (minutes between deposit and withdrawal), round-amount ratios, and counterpart entropy.

Verbatim Code / Config

def calculate_mule_signals(account_txns):
    deposit_vol = account_txns[account_txns['type'] == 'CR']['amount'].sum()
    withdrawal_vol = account_txns[account_txns['type'] == 'DR']['amount'].sum()
    pass_through_ratio = min(deposit_vol, withdrawal_vol) / (max(deposit_vol, withdrawal_vol) + 1e-5)
    time_diffs = account_txns['timestamp'].diff().dt.total_seconds().dropna()
    rapid_turnaround = (time_diffs < 1800).mean() # Txns under 30 mins
    return {'pass_through_ratio': pass_through_ratio, 'rapid_turnaround': rapid_turnaround}
03

Training LightGBM and XGBoost with Imbalance Tuning

Train gradient-boosted models with stratified cross-validation, using scale_pos_weight and Focal Loss heuristics to handle the 2.8% positive class imbalance.

Verbatim Code / Config

lgb_train = lgb.Dataset(X_train, label=y_train)
params = {
    'objective': 'binary',
    'metric': 'auc',
    'scale_pos_weight': (1 - 0.028) / 0.028,
    'learning_rate': 0.03,
    'num_leaves': 63,
    'feature_fraction': 0.8
}
model_lgb = lgb.train(params, lgb_train, num_boost_round=1500, valid_sets=[lgb_val], callbacks=[lgb.early_stopping(50)])
04

Ensemble Calibration and F1 Threshold Selection

Blend predictions using weighted soft voting and evaluate precision-recall curves to identify the 0.82 decision threshold maximizing F1 score.

Verbatim Code / Config

pred_ensemble = 0.5 * pred_lgb + 0.5 * pred_xgb
precisions, recalls, thresholds = precision_recall_curve(y_test, pred_ensemble)
f1_scores = 2 * (precisions * recalls) / (precisions + recalls + 1e-9)
best_threshold = thresholds[np.argmax(f1_scores)] # 0.82

Where it broke

The failure mode, root-cause breakdown, and resolution discovered during development.

The Tell

Initial model runs scored an impossible 0.9998 AUC-ROC, alerting the team to catastrophic feature leakage.

Why it failed

The raw dataset contained an 'account_status_change_date' column. When an account was frozen by compliance, this date was populated. The model learned to identify mules solely by checking if a status change date existed, completely ignoring actual transaction patterns.

The Fix

Purged all post-investigation administrative columns from the feature matrix. Rewrote the feature pipeline to enforce strict temporal cutoff windows: only transactions occurring strictly BEFORE the first compliance review timestamp were permitted in feature generation, yielding a realistic 0.9830 AUC-ROC.

What it cost

₹0 to build and run permanently within verified free tiers.

Cost breakdown & free tier limits
Service / ToolCostFree Tier Limits
LightGBM & XGBoost₹0Open-source MIT / Apache 2.0 gradient boosting libraries
PyArrow & Pandas₹0Open-source columnar data processing tools
Local Workstation RAM₹0Chunked batch processing runs within standard 16GB RAM
Scikit-Learn Evaluation Suite₹0Open-source metric & validation framework

Make it yours

Three concrete variations you can build and ship using this exact foundation.

  • 01

    E-Commerce Promo Abuse & Reseller Ring Detector: Identifies automated multi-account voucher farming using IP clustering and card finger-printing.

  • 02

    Insurance Fraud Claims Ring Investigator: Connects body shop repair estimates, claimant relationships, and policy age features to detect staged accident claims.

  • 03

    Cryptocurrency Bridge Wash-Trading Detector: Identifies circular transaction hops across liquidity pools designed to artificially inflate trading volume.

Where next

Ready to ship Mule Account Detection?

Review the architecture, clone the prompt and implementation steps, and deploy your live URL for ₹0.