Разработка AI-системы для детекции отмывания денег

Пропуск подозрительного перевода или блокировка добросовестного клиента — цена ошибки в антиотмывочной системе критична. Мы разрабатываем гибридные AI-системы для детекции отмывания денег, сочетая детерминированные правила и ML-модели. Наша команда реализует проект под ключ — от аудита до внедрения и последующей поддержки, обеспечивая надёжную защиту вашего бизнеса.
Часто задаваемые вопросы

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): крупная сумма разбивается на мелкие транзакции ниже порога контроля ($5.4k–7.8k. в РФ).

Layering: многоуровневые переводы через цепочку счетов и юрисдикций для сокрытия источника. Integration: отмытые средства вводятся в легальный бизнес — аффилированные услуги, недвижимость.

Red flags:

  • Транзакции ровными суммами ($?.) — ниже порога, но подозрительно.
  • Всплеск активности: нет операций → внезапно 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 месяц пост-продакшн, обучение команды.

Процесс разработки

  1. Аналитика — сбор требований, аудит текущих логов, нормативных актов (ФЗ-115, FATF).
  2. Проектирование — выбор архитектуры, определение признаков, конфигурация пилота.
  3. Разработка — написание кода, обучение моделей, настройка пайплайна.
  4. Тестирование — кросс-валидация на исторических данных, сценарное тестирование.
  5. Деплой — развёртывание, интеграция, нагрузочное тестирование.

Сроки: от 6–8 недель на базовую версию (правила + LightGBM + SAR) до 4–5 месяцев на полную (с GNN, real-time, графическим анализом).

Сравнение моделей: LightGBM vs GNN

Характеристика LightGBM GNN (SAGEConv)
Тип данных Табличные признаки (транзакции) Графовые данные (сеть счетов)
Выявляет Аномалии в поведении клиента Сложные цепочки переводов (layering)
Обучаемость Быстрое обучение, мало данных Требует много данных и GPU
Интерпретация SHAP, важность признаков Визуализация графа, attention

Регуляторное соответствие

ФЗ-115 (Россия): обязательный контроль операций >$5.4k–7.8k., передача SAR в Росфинмониторинг в течение 3 рабочих дней.

FATF/EU AMLD: KYC на онбординге, continuous monitoring, усиленная проверка (EDD) для high-risk клиентов. Регуляторные требования описаны в Рекомендациях FATF.

Как мы обеспечиваем объяснимость?

Каждое подозрительное решение сопровождается SHAP-объяснением. Рассмотрим пример: перевод $8.6k–12k. из Саратова в Сингапур. 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-системы под ваши данные — получите консультацию по архитектуре и срокам. Свяжитесь с нами для обсуждения.

Направления AI-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1140