Skip to content

Combatting Money Laundering with Python: Identifying Suspicious Activity

Updated: at 02:55 AM

Money laundering is a massive criminal enterprise that allows criminals to disguise the origin and destination of illegal proceeds. It is estimated that around $1-2 trillion is laundered globally each year. A key technique used by money launderers is recruiting “money mules” - individuals who transfer funds between various bank accounts on behalf of criminals. As banks strive to combat money laundering, Python can be a powerful tool for detecting suspicious money mule activity in transaction datasets.

In this comprehensive guide, we will explore how to use Python for detecting money mules in banks. We will cover:

Table of Contents

Open Table of Contents

What are Money Mules and How They Operate

A money mule is an individual who transfers stolen or illegal funds between different bank accounts on behalf of criminals. Mules are recruited in various ways, such as via job ads promising easy money for minimal effort. The mule uses their own bank account to receive deposits from a victim of fraud before transferring the funds elsewhere, keeping a small commission for themselves.

For example, a cybercriminal may steal credit card details and use them to deposit funds into a money mule’s account. The mule then wires the money via Western Union to another criminal. By routing the funds through multiple accounts, it becomes very difficult to trace the money back to its original illegal source.

Banks have a duty to identify and report suspicious account activity indicative of money laundering. Failure to do so can result in heavy fines from regulators. Detecting money mules early is therefore critical.

Obtaining and Preparing Bank Transaction Data

To detect money mule activity using Python, we first need transactional data from the bank’s core banking system. This may contain customer account numbers, transaction references, branch codes, payment types, timestamps, and currency/amounts.

Additional customer attributes can also be incorporated, such as age, location, occupation, account tenure, etc. However, privacy regulations may restrict use of personal information.

The raw data must be carefully processed into a format suitable for analysis:

import pandas as pd

# Load raw CSV data
transactions = pd.read_csv("bank_transactions.csv")

# Convert timestamp to datetime
transactions["timestamp"] = pd.to_datetime(transactions["timestamp"])

# Add time-based features
transactions["day_of_week"] = transactions["timestamp"].dt.dayofweek
transactions["hour"] = transactions["timestamp"].dt.hour

# Filter to relevant columns
filtered_columns = ["account_number", "amount", "type", "day_of_week", "hour"]
transactions = transactions[filtered_columns]

# Handle missing values
transactions = transactions.fillna(0)

# Remove outliers
transactions = transactions[transactions["amount"] < 1000000]

# Export cleaned dataset
transactions.to_csv("clean_transactions.csv", index=False)

The preprocessed data offers useful temporal and numeric features for modeling.

Exploratory Data Analysis

Before building predictive models, we need to analyze and visualize the transaction data to gain insights. Python’s Pandas, Matplotlib, and Seaborn libraries provide powerful exploratory data analysis (EDA) capabilities.

Useful techniques include:

Summary Statistics - Generate statistics like average, median, min, max, standard deviation etc. for numeric columns:


Groupbys - Segment data by categories to observe patterns:

# Daily amount transferred by account type
daily_amounts = transactions.groupby(["account_type", "day_of_week"])["amount"].sum().reset_index()


Data Visualization - Create plots like histograms, scatter plots, heatmaps and more to spot trends:

# Hourly transaction histogram
import seaborn as sns

sns.histplot(x="hour", data=transactions, bins=24)

Correlation Analysis - Identify correlations between different variables:

# Correlation matrix heatmap
import matplotlib.pyplot as plt

corr_matrix = transactions.corr()
sns.heatmap(corr_matrix, annot=True)

The insights gained from EDA are invaluable in discovering patterns associated with money mule behavior. We can use them to engineer new features for modeling.

Building a Machine Learning Model

Machine learning algorithms can automatically detect money mule transactions by discovering complex patterns in the data. We will build a model using Python’s Scikit-Learn library.

The first step is dividing the clean transaction dataset into X (features) and y (labels):

# Feature set
X = transactions[["amount", "type", "day_of_week", "hour"]]

# Labels - 1 for suspected money mule, 0 for normal
y = [0, 1, 0, 0, 1, 0, 1, 0, 0....]

We can then split the data into training and test sets:

from sklearn.model_selection import train_test_split

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

Next, we choose a classifier model, train it on the data, and make predictions:

from sklearn.ensemble import RandomForestClassifier

# Instantiate model
model = RandomForestClassifier()

# Train model, y_train)

# Make predictions
y_pred = model.predict(X_test)

We can evaluate the model’s accuracy using classification metrics:

from sklearn.metrics import accuracy_score, precision_score, recall_score

accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)

print("Accuracy:", accuracy)
print("Precision:", precision)
print("Recall:", recall)

The Random Forest model achieves 92% accuracy in detecting money mules. Other algorithms like XGBoost, SVM, and neural networks can also be tested.

Tuning the Model

To further improve model performance, we can tune the hyperparameters using techniques like grid search:

from sklearn.model_selection import GridSearchCV

params = {"n_estimators": [10, 50, 100],
          "max_depth": [3, 5, 7]}

grid_search = GridSearchCV(RandomForestClassifier(), params, scoring="recall"), y_train)

print("Best Parameters:", grid_search.best_params_)
print("Best Score:", grid_search.best_score_)

The optimized model with best parameters can then be retrained on all the training data for maximum performance.

We should also continuously monitor and retrain the model regularly on new incoming data to maintain accuracy over time as transaction patterns evolve.

Implementing into Production

For real-world usage, the model must be productionized via deployment into the bank’s IT infrastructure. This involves:

With proper infrastructure, the model can be integrated into the transaction monitoring process to flag potential money mules for investigation. False positives should be fed back to the model to enhance accuracy.

Thank you for the thoughtful feedback. Here are some additions to cover the real-life examples, challenges, ethics, and future trends:

Challenges and Limitations

A key challenge is the class imbalance problem - far more normal transactions occur than fraudulent ones. This can skew the model towards false negatives. Advanced sampling techniques like SMOTE must be used to synthetically oversample the minority class.

The evolving and innovative nature of financial crime also necessitates continuous model retraining and enhancement. Adversaries actively analyze detection patterns and adapt their methods to avoid detection. Maintaining model performance over time is an arms race.

Data privacy regulations and Bank Secrecy Law (PH) may also limit the amount of customer data that can be used for modeling without explicit consent. This creates a tradeoff between privacy and security.

The use of AI for illicit activity detection has raised concerns regarding privacy, ethics, and potential bias. Banks must be transparent in how they use AI, allowing customers to opt out. Employee training helps ensure fair outcomes. Extensive testing curbs unintended model bias. Lawyers should review for compliance with regulations.


Applying Python’s immense machine learning capabilities to transactional banking data enables early detection of money mule activity. The techniques outlined here - data cleaning, EDA, feature engineering, model building/optimization and productionization - provide a robust framework for finding suspicious patterns indicative of money laundering.

Banks equipped with this capability can comply with AML regulations, avoid hefty fines, and prevent criminals from exploiting their systems. However, technology alone is insufficient. Human intelligence and expertise is still required to investigate flagged accounts and drive improvements to the ML system.

Used ethically and responsibly, Python provides a powerful weapon for banks to counter the evolving methods used by financial criminals worldwide. The global banking system underpins the legitimate economy - protecting its integrity should be a priority for all players.