Anti-Money Laundering (AML) — антивідмивна система, область де ціна помилки критична. Пропуск підозрілого переказу (false negative) загрожує штрафами до 5% обороту згідно з ФЗ-115. Хибне блокування добросовісного клієнта (false positive) — репутаційні втрати та позови. Традиційні правилові системи детектують лише відомі патерни, генеруючи до 95% хибних спрацьовувань. Ми розробляємо гібридні AI-системи, які знижують FPR на 20–40% без втрати повноти виявлення. Наш досвід — 10+ років у фінансовому ML для банків та фінтехів.
В основі — комбінація детермінованих правил (для типових сценаріїв) та ML-моделей (для виявлення прихованих нелінійних патернів). Нижче — архітектура, моделі та етапи впровадження.
У цій статті ми розберемо ключові компоненти системи: транзакційний моніторинг, графовий аналіз та інтеграцію з KYC. Розглянемо, як гібридний підхід знижує навантаження на комплаєнс-відділ та відповідає вимогам FATF. Правила автоматично обробляють 80% операцій, залишаючи 20% на ML-перевірку, що знижує ручну працю на 60%.
Чому ML кращий за правилові системи для AML?
| Характеристика | Правила | ML-модель |
|---|---|---|
| Виявлення нових схем | Ні — лише відомі патерни | Так — виявляє приховані кореляції |
| Хибні спрацьовування (FPR) | 5–10% | 2–4% (зниження в 2–5 разів) |
| Адаптація до змін | Ручне оновлення | Автоматичне перенавчання |
| Пояснюваність | Повна (якщо правило задано явно) | Через SHAP/LIME |
| Масштабованість | Лінійно від кількості правил | Паралельна обробка |
Типологія схем відмивання
Структурування (Smurfing): велика сума розбивається на дрібні транзакції нижче порогу контролю (600 000 руб. в РФ).
Layering: багаторівневі перекази через ланцюжок рахунків та юрисдикцій для приховування джерела.
Integration: відмиті кошти вводяться в легальний бізнес — афілійовані послуги, нерухомість.
Red flags:
- Транзакції рівними сумами (999 000 руб.) — нижче порогу, але підозріло.
- Спалах активності: немає операцій → раптом 50 за день.
- Географічні невідповідності: клієнт із Саратова, перекази в Сінгапур.
- Рахунок-одноденка: новий рахунок, великий оборот, швидке виведення, закриття.
Feature Engineering
Ключ до якості ML — ознаки, що відображають поведінку клієнта. Ми використовуємо два класи:
Транзакційні ознаки (обсяг, час, суми біля порогів, концентрація контрагентів):
def extract_transaction_features(transaction_history, lookback_days=90):
"""Ознаки на основі історії транзакцій клієнта."""
df = transaction_history.copy()
features = {
# Обсяг транзакцій
'total_amount_30d': df[df['days_ago'] <= 30]['amount'].sum(),
'transaction_count_30d': len(df[df['days_ago'] <= 30]),
'avg_transaction_amount': df['amount'].mean(),
'amount_std': df['amount'].std(),
# Часові патерни
'transactions_per_active_day': len(df) / df['date'].nunique(),
'max_transactions_single_day': df.groupby('date').size().max(),
'night_transaction_ratio': (df['hour'] < 6).mean(),
'weekend_activity_change': calculate_weekend_ratio(df),
# Суми біля порогів
'near_threshold_pct': (df['amount'].between(550000, 610000)).mean(),
'round_amount_pct': (df['amount'] % 1000 == 0).mean(),
# Контрагенти
'unique_counterparties': df['counterparty_id'].nunique(),
'counterparty_concentration': df.groupby('counterparty_id')['amount'].sum().max() / df['amount'].sum(),
'new_counterparty_ratio': (df['is_new_counterparty'] == True).mean(),
# Географічні
'foreign_transaction_ratio': (df['country'] != 'RU').mean(),
'high_risk_jurisdiction_pct': df['country'].isin(HIGH_RISK_COUNTRIES).mean()
}
return features
def compute_network_features(account_id, transaction_graph):
"""Транзакції як граф: вузли = рахунки, ребра = перекази."""
G = transaction_graph
pagerank = nx.pagerank(G, weight='amount')
betweenness = nx.betweenness_centrality(G, weight='amount')
communities = nx.community.greedy_modularity_communities(G.to_undirected())
community_risk = assess_community_risk(account_id, communities, G)
return {
'pagerank_score': pagerank.get(account_id, 0),
'betweenness_score': betweenness.get(account_id, 0),
'community_risk': community_risk,
'in_degree': G.in_degree(account_id),
'out_degree': G.out_degree(account_id)
}
Мережеві ознаки (PageRank, betweenness, кластеризація) — допомагають виявляти складні layering-схеми, де рахунок виступає транзитним вузлом.
Моделі машинного навчання
LightGBM з налаштуванням під AML
import lightgbm as lgb
from sklearn.metrics import roc_auc_score, average_precision_score
n_normal = (y_train == 0).sum()
n_sar = (y_train == 1).sum()
scale_pos_weight = n_normal / n_sar
model = lgb.LGBMClassifier(
n_estimators=500,
scale_pos_weight=scale_pos_weight,
learning_rate=0.05,
num_leaves=31,
min_child_samples=20,
feature_fraction=0.8
)
# Threshold підбирається так, щоб recall >= 0.85
from sklearn.metrics import precision_recall_curve
precision, recall, thresholds = precision_recall_curve(y_val, y_scores)
optimal_threshold = thresholds[np.argmax(recall >= 0.85)]
Графова нейронна мережа (GNN) для мережевого аналізу
import torch
from torch_geometric.nn import SAGEConv
class AMLGraphNN(torch.nn.Module):
"""GNN для аналізу транзакційних мереж."""
def __init__(self, node_features, edge_features, hidden_dim=64):
super().__init__()
self.conv1 = SAGEConv(node_features, hidden_dim)
self.conv2 = SAGEConv(hidden_dim, hidden_dim)
self.edge_mlp = torch.nn.Linear(edge_features, hidden_dim)
self.classifier = torch.nn.Linear(hidden_dim * 2, 1)
def forward(self, node_features, edge_index, edge_features):
x = torch.relu(self.conv1(node_features, edge_index))
x = torch.relu(self.conv2(x, edge_index))
edge_emb = self.edge_mlp(edge_features)
source_emb = x[edge_index[0]]
target_emb = x[edge_index[1]]
edge_repr = torch.cat([source_emb, target_emb], dim=1)
return torch.sigmoid(self.classifier(edge_repr))
Як влаштована гібридна архітектура AML?
Гібридна система об'єднує правила та ML в єдиний пайплайн. Правила швидко відсіюють очевидні легітимні операції та сигналізують про явні порушення (перевищення лімітів, заборонені юрисдикції). ML-моделі аналізують ознаки, які неможливо закодувати правилами: аномальну поведінку, приховані зв'язки, нелінійні залежності. Результат: кожен переказ отримує єдиний ризик-скор, який враховує і правила, і ML.
class HybridAMLSystem:
def __init__(self, rule_engine, ml_model, threshold=0.5):
self.rules = rule_engine
self.model = ml_model
self.threshold = threshold
def evaluate_transaction(self, transaction, customer_history):
rule_alerts = self.rules.evaluate(transaction)
features = extract_transaction_features(customer_history)
ml_score = self.model.predict_proba([features])[0][1]
final_risk = max(rule_alerts.max_risk_score if rule_alerts else 0, ml_score)
if final_risk > self.threshold:
return SARCandidate(
transaction=transaction,
risk_score=final_risk,
triggered_rules=rule_alerts,
ml_explanation=shap_explain(self.model, features)
)
Що входить у роботу
- Документація: архітектурна схема, model card, керівництво адміністратора.
- ML-пайплайн: вилучення ознак, навчання, валідація, A/B-тестування.
- Інтеграція: з KYC-системою, core banking, CRM.
- Real-time API: HTTP/gRPC ендпоінт для оцінки ризику кожної транзакції.
- Дашборди: моніторинг метрик, звітність SAR, SHAP-пояснення.
- Розгортання: в контурі замовника (on-prem) або в хмарі.
- Підтримка: 1 місяць пост-продакшн, навчання команди.
Процес розробки
- Аналітика — збір вимог, аудит поточних логів, нормативних актів (ФЗ-115, FATF).
- Проектування — вибір архітектури, визначення ознак, конфігурація пілоту.
- Розробка — написання коду, навчання моделей, налаштування пайплайну.
- Тестування — крос-валідація на історичних даних, сценарне тестування.
- Деплой — розгортання, інтеграція, навантажувальне тестування.
Строки: від 6–8 тижнів на базову версію (правила + LightGBM + SAR) до 4–5 місяців на повну (з GNN, real-time, графічним аналізом).
Порівняння моделей: LightGBM vs GNN
| Характеристика | LightGBM | GNN (SAGEConv) |
|---|---|---|
| Тип даних | Табличні ознаки (транзакції) | Графові дані (мережа рахунків) |
| Виявляє | Аномалії в поведінці клієнта | Складні ланцюжки переказів (layering) |
| Навчання | Швидке навчання, мало даних | Потребує багато даних та GPU |
| Інтерпретація | SHAP, важливість ознак | Візуалізація графа, attention |
Регуляторна відповідність
ФЗ-115 (Росія): обов'язковий контроль операцій >600 000 руб., передача SAR в Росфінмоніторинг протягом 3 робочих днів.
FATF/EU AMLD: KYC на онбордингу, continuous monitoring, посилена перевірка (EDD) для high-risk клієнтів. Регуляторні вимоги описані в Рекомендаціях FATF.
Як ми забезпечуємо пояснюваність?
Кожне підозріле рішення супроводжується SHAP-поясненням. Розглянемо приклад: переказ 950 000 руб. з Саратова в Сінгапур. SHAP-значення показують, що foreign_transaction_ratio підвищив ризик на 0.34, near_threshold_pct — на 0.28, new_counterparty_ratio — на 0.21, transaction_count_30d — на 0.15, avg_transaction_amount — на 0.10. Підсумковий ризик 0.87 перевищує поріг 0.5, що генерує SAR-звіт.
import shap
def explain_sar_decision(model, features, feature_names):
"""Регулятор вимагає обґрунтування кожного SAR."""
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(features)
top_factors = sorted(
zip(feature_names, shap_values[0]),
key=lambda x: abs(x[1]), reverse=True
)[:5]
explanation = "\n".join([
f"- {name}: {'підвищив' if val > 0 else 'знизив'} ризик на {abs(val):.2f}"
for name, val in top_factors
])
return explanation
Такий підхід дозволяє не лише пройти аудит, а й дати операторам зрозумілі причини блокувань.
Готові оцінити ваш проєкт? Замовте розробку AML-системи під ваші дані — отримайте консультацію з архітектури та строків. Зв'яжіться з нами для обговорення.







