Anti-money-laundering monitoring
Money laundering hides a large amount by breaking it into many small, individually unremarkable pieces — so the model has to look at patterns across transactions, not at any single one.
- 10 min read
- 3 reading levels
- Published
Read these first
On this page 6
One lesson, three depths. Pick the one that fits you today — you can switch any time.
Beginner — No maths. Plain English.
Anti-money-laundering monitoring looks for patterns across many transactions, because one transaction alone is designed to look ordinary.
Think about filling a bathtub with a small cup instead of a bucket. One cupful looks like nothing. Thirty cupfuls, poured quietly over an hour, fill the tub completely. Nobody watching any single pour would have noticed. Someone moving a large, suspicious amount of money uses exactly this trick. It is called structuring: breaking one large amount into many small transactions, each below the size that triggers automatic reporting.
Anti-money-laundering, shortened to AML, is the set of systems built to notice the tub filling up. Not only each individual cup.
Why it exists
Banks in most countries must report transactions above a certain size to a regulator. This stops criminals from walking large sums of illegal cash straight into the banking system. Structuring exists specifically to defeat that rule. Keep every transaction narrowly under the reporting line, and the amount never gets reported.
Money laundering means moving money to hide where it came from. It traditionally happens in three loose stages. Placement gets dirty money into the financial system at all, often via structuring. Layering moves it through many accounts to obscure the trail. Integration spends or invests it as if it were clean. An AML system has to catch behaviour at every stage, not only one.
This is a regulated activity, like credit scoring. Banks that fail to detect and report money laundering face serious legal penalties. A false negative here is not only a bad prediction. It can mean the bank has become part of a real crime.
How it works
Transaction 1: 9,800 (below the 10,000 reporting line)
Transaction 2: 9,600 (also below)
Transaction 3: 9,700 (also below)
|
v
[ pattern check, ACROSS transactions, not within one ]
|
v
Same account, same day, 3 transactions,
total = 29,100 -- well above the reporting line
|
v
FLAGGED for human review, possibly filed as a
Suspicious Activity Report (SAR)No single transaction above breaks any rule. The pattern across them is the entire signal.
A real example you have seen
News reports about a bank fined for "AML failures" almost always describe this same pattern. Transactions that individually looked fine. A system that either did not look across them, or looked and was ignored.
The honest part
Real AML systems generate an enormous number of alerts that turn out to be nothing. Industry commentary commonly cites false-positive rates of 90% or higher for rule-based systems. The exact number varies a great deal by bank, and is not something to treat as a precise fact. That flood of false alerts is not a minor annoyance. It buries the real cases under noise. It burns out the human investigators who have to clear each one. That is exactly why better models, not only more rules, matter here.
Remember this
- Money laundering is designed to make each transaction look ordinary. The signal lives in the pattern across transactions.
- Structuring means breaking a large amount into many small transactions, to stay under a reporting threshold.
- This is a heavily regulated area with real legal consequences. Current rule-based systems suffer from very high false-positive rates.
What to learn next
- Model risk management — the governance layer every model in this section eventually has to pass through.
- Finding fraud rings with graphs — a closely related technique, since layering often moves money through connected accounts.
- Time-series features — the general technique behind building pattern-across-time features like the one below.
Developer — Code and libraries.
Setup
pip install pandasMinimal runnable code
We look for the simplest, best-known AML pattern: several same-day transactions from one account, each below a reporting threshold, that add up to well above it.
import pandas as pd
THRESHOLD = 10_000 # a round number standing in for a real reporting threshold
transactions = pd.DataFrame({
"account": ["A1", "A1", "A1", "A2", "A3", "A3", "A3", "A3", "A4"],
"timestamp": pd.to_datetime([
"2024-03-01 09:00", "2024-03-01 09:15", "2024-03-01 09:40",
"2024-03-01 10:00",
"2024-03-02 08:00", "2024-03-02 08:20", "2024-03-02 08:45", "2024-03-02 09:10",
"2024-03-03 12:00",
]),
"amount": [9800, 9600, 9700, 500, 9500, 9200, 9800, 9100, 15000],
})
transactions["date"] = transactions["timestamp"].dt.date
daily = transactions.groupby(["account", "date"]).agg(
num_transactions=("amount", "count"),
total_amount=("amount", "sum"),
max_single=("amount", "max"),
).reset_index()
# Classic "structuring": several transactions, each below the threshold alone,
# that add up to well above it on the same day.
suspicious = daily[
(daily["num_transactions"] >= 2)
& (daily["max_single"] < THRESHOLD)
& (daily["total_amount"] >= THRESHOLD)
]
print("daily summary per account:")
print(daily.to_string(index=False))
print()
print("flagged for possible structuring:")
print(suspicious.to_string(index=False))daily summary per account:
account date num_transactions total_amount max_single
A1 2024-03-01 3 29100 9800
A2 2024-03-01 1 500 500
A3 2024-03-02 4 37600 9800
A4 2024-03-03 1 15000 15000
flagged for possible structuring:
account date num_transactions total_amount max_single
A1 2024-03-01 3 29100 9800
A3 2024-03-02 4 37600 9800What actually happened
Notice account A4: one transaction of 15,000, well above the threshold, and it is not flagged. That is correct — a single large transaction above the threshold gets reported through the normal, existing process automatically. There is nothing hidden about it.
Accounts A1 and A3 are the actual find: every individual transaction sits below 10,000, so none would trigger an automatic report alone. Grouped by account and day, though, both total well above the threshold, which is exactly the structuring pattern.
groupby(["account", "date"])is doing the entire job here — turning per-transaction rows into per-account-per-day summaries is what makes the pattern visible at all.- The three conditions in
suspiciousare combined with&, and each side must be wrapped in parentheses — a common pandas gotcha, since&binds tighter than comparison operators in Python. max_single < THRESHOLDis what separates "one big legitimate transaction" (A4) from "many small suspicious ones" (A1, A3) even though both end up with a large daily total.
Common mistakes
Only checking a single day's window. A patient launderer spreads transactions across many accounts and many days specifically to avoid a same-day, same-account check like this one. Real systems use rolling windows (7, 30, 90 days) and check across related accounts, not only one.
Setting the threshold check exactly at the legal reporting line. Someone structuring transactions is actively trying to stay under that exact number, so the smart move is to flag amounts approaching it (say, within 10-20%), not only amounts that cross it.
No human review step. A flagged pattern here is a lead for a trained investigator, never an automatic account freeze. Filing a false Suspicious Activity Report on an innocent customer has real consequences too.
Treating this rule as a complete AML system. This is one narrow pattern among many. Real systems also watch for rapid movement of funds through many accounts (layering), transactions with no clear business purpose, and connections to known high-risk entities.
Try it yourself
Add a fifth account, A5, that makes 6 transactions of 1,800 each across a single day — each one far below the threshold individually. Confirm the current rule still catches it (total = 10,800), then try lowering the reporting threshold to 5,000 and see which previously-hidden accounts show up.
What to learn next
- Finding fraud rings with graphs — catching money moved between accounts, the layering stage.
- Time-series features — building richer rolling-window features than the single-day check used here.
- Model risk management — the review process a real AML model has to pass before deployment.
Researcher — Mathematics and papers.
Framing as anomaly detection over behavioural graphs
Modern AML systems typically combine three modelling families rather than relying on any one:
- Rule-based scenarios (structuring, rapid movement, round-dollar amounts, dormant-account reactivation) — high precision on known patterns, zero ability to catch anything novel, and the dominant source of the high false-positive rates discussed in the beginner section.
- Unsupervised anomaly detection over account behaviour profiles — flagging accounts whose transaction pattern deviates sharply from their own history or from peer accounts, using methods from outlier detection, useful precisely because confirmed money-laundering labels are extremely rare and unevenly distributed.
- Graph-based analysis over the transaction network, treating layering as a structural problem: money moving through unusually long or unusually circular chains of accounts, a natural extension of the graph techniques in the previous lesson to directed, weighted edges (amount, timestamp) rather than undirected shared-attribute edges.
The extreme label scarcity problem
Confirmed laundering cases (accounts that led to an actual conviction or regulatory action) are vanishingly rare relative to the volume of flagged alerts, and even alert-to-SAR-filed is a heavily imbalanced label with substantial label noise — an analyst filing an SAR is itself a judgement call, not ground truth about whether laundering occurred. This pushes practical systems toward semi-supervised and weakly-supervised approaches: using analyst SAR decisions as noisy positive labels, and unresolved or cleared alerts as noisy (not confirmed) negatives, rather than treating the problem as clean binary classification.
Structuring detection, formalised
A simple formal version of the beginner-block detector: for account a, day d, and threshold T, flag when:
count( { txn in D(a,d) : amount(txn) < T } ) >= 2
AND
SUM( amount(txn) for txn in D(a,d) ) >= TReal implementations extend D(a,d) to a rolling window rather than a calendar day, and often add a proximity-to-threshold weighting — transactions clustered narrowly below T (e.g. within 10%) score as more suspicious than transactions that are only slightly under it, since genuine structuring is characterised by that specific proximity, not by smallness in general.
Cost
AML transaction volumes at a large bank run into the hundreds of millions of transactions monitored per day, generating alert volumes that require substantial dedicated investigator headcount to triage under current false-positive rates — reducing the false-positive rate by even a modest amount translates into direct, measurable operational savings, which is why AML modelling investment is unusually well funded relative to its technical difficulty.
Key references
- FATF (Financial Action Task Force). International Standards on Combating Money Laundering and the Financing of Terrorism — the primary international regulatory framework AML systems are built to satisfy.
- Weber, M., et al. (2019). Anti-Money Laundering in Bitcoin: Experimenting with Graph Convolutional Networks for Financial Forensics. KDD Workshop — introduces the Elliptic dataset, one of the few public labelled AML-adjacent datasets, built on Bitcoin transaction graphs.
- Savage, D., et al. (2016). Detection of Money Laundering Groups Using Supervised Learning in Networks. arXiv — an early treatment of graph-based AML group detection.
Current state
Public, labelled AML datasets remain rare because transaction data is commercially and legally sensitive; the Elliptic Bitcoin dataset is the most widely used public benchmark specifically because so few alternatives exist, which means most published AML-ML results are on cryptocurrency data and may not transfer cleanly to traditional banking rails. Treat AML-ML benchmark claims with the same caution urged throughout this section: ask what data they were validated on before trusting the number.
What to learn next
- Isolation forest — a standard unsupervised anomaly-detection technique used in AML behavioural profiling.
- Model risk management — the governance and validation process this system must pass.
- Finding fraud rings with graphs — the structural techniques layering detection builds on.