Перейти к содержимому

Дистилляция дерева решений для трейдинга: Извлечение интерпретируемых правил из сложных моделей

Дистилляция дерева решений — это мощный метод интерпретации моделей, который извлекает простые, понятные человеку правила принятия решений из сложных моделей машинного обучения типа “чёрный ящик”. В алгоритмической торговле этот подход связывает высокоэффективные ансамблевые модели или нейронные сети с необходимостью прозрачных, объяснимых торговых решений.

Основная идея элегантно проста: обучить сложную модель с высокой предсказательной точностью, а затем обучить более простое дерево решений имитировать предсказания сложной модели. Полученное дерево решений “дистиллирует” знания, полученные сложной моделью, в интерпретируемый формат, раскрывая лежащую в основе логику принятия решений в виде правил “если-то”.

В торговых приложениях дистилляция дерева решений решает критические задачи:

  • Соответствие регуляторным требованиям: Финансовые регуляторы всё чаще требуют объяснимости алгоритмических торговых систем
  • Управление рисками: Понимание, почему модель рекомендует сделку, помогает оценивать и управлять рисками
  • Валидация модели: Дистиллированные правила показывают, изучила ли модель разумные паттерны или ложные корреляции
  • Операционное доверие: Трейдеры и портфельные менеджеры могут проверять и утверждать торговую логику, выраженную в виде чётких правил

Содержание

  1. Понимание дистилляции дерева решений
  2. Алгоритм дистилляции
  3. Дистилляция дерева решений для трейдинга
  4. Примеры кода
  5. Практическое применение
  6. Бэктестинг дистиллированных моделей
  7. Ссылки

Понимание дистилляции дерева решений

Фреймворк передачи знаний

Передача знаний (Knowledge Distillation), представленная Хинтоном и др. (2015), — это техника передачи знаний от большой сложной модели (“учителя”) к меньшей, более простой модели (“ученику”). Ключевое понимание в том, что предсказания модели-учителя содержат больше информации, чем просто финальные метки классов — они кодируют относительные сходства и связи между классами.

В контексте интерпретации торговых моделей мы адаптируем этот фреймворк:

Модель-учитель (сложная):
- Случайный лес с 500 деревьями
- Градиентный бустинг
- Глубокая нейронная сеть
- Ансамбль нескольких моделей
Модель-ученик (интерпретируемая):
- Дерево решений (глубина 3-10)
- Список правил
- Линейная модель

Модель-ученик учится имитировать поведение учителя, а не оригинальные обучающие метки. Это критически важно, потому что:

  1. Учитель уже научился игнорировать шум в обучающих данных
  2. Мягкие предсказания учителя предоставляют более богатую информацию, чем жёсткие метки
  3. Ученик может достичь более высокой точности, обучаясь у учителя, чем на сырых данных

Почему дистиллировать в деревья решений

Деревья решений — идеальные модели-ученики для торговых приложений, потому что они производят:

Явные правила принятия решений:

ЕСЛИ RSI_14 < 30 И MACD_histogram > 0 И Volume_ratio > 1.2
ТО Покупать (уверенность: 0.78)

Иерархическую важность признаков:

  • Разделение в корне = самый важный признак
  • Более глубокие разделения = уточняющие условия
  • Длина пути = сложность решения

Естественные пороговые значения:

  • Точки разделения показывают критические значения (например, RSI < 30)
  • Эти пороги можно проверить на соответствие торговой интуиции
  • Аномальные пороги могут указывать на проблемы с данными

Аудиторский след:

  • Каждое предсказание можно проследить через дерево
  • Комплаенс-офицеры могут проверять и утверждать конкретные пути
  • Изменения в поведении модели сразу видны в правилах

Мягкие метки vs жёсткие метки

Традиционное обучение модели использует жёсткие метки (0 или 1 для классификации). Дистилляция обычно использует мягкие метки — вероятностные выходы модели-учителя:

Жёсткие метки (исходные данные):

Образец 1: Цена пошла ВВЕРХ → Метка: 1
Образец 2: Цена пошла ВНИЗ → Метка: 0

Мягкие метки (предсказания учителя):

Образец 1: Учитель предсказывает ВВЕРХ с P(ВВЕРХ)=0.73 → Метка: 0.73
Образец 2: Учитель предсказывает ВНИЗ с P(ВНИЗ)=0.85 → Метка: 0.15

Мягкие метки сохраняют информацию о неопределённости:

  • Предсказания 0.51 и 0.99 оба дают “ВВЕРХ” в жёстких метках
  • Мягкие метки различают уверенные и неуверенные предсказания
  • Ученик узнаёт, какие случаи лёгкие, а какие сложные для учителя

В трейдинге это особенно ценно, потому что рыночные предсказания по своей природе неопределённы, и понимание, когда модель уверена, а когда нет, критически важно для размера позиции и управления рисками.

Алгоритм дистилляции

Математическое обоснование

Дано: модель-учитель T и обучающие данные X. Процесс дистилляции ищет дерево решений-ученика S, которое минимизирует:

L(S) = Σᵢ L_distill(S(xᵢ), T(xᵢ)) + λ · Complexity(S)

Где:

  • L_distill — функция потерь дистилляции (например, кросс-энтропия, MSE)
  • T(xᵢ) — предсказание учителя (мягкая метка) для образца xᵢ
  • Complexity(S) — член регуляризации (глубина дерева, количество листьев)
  • λ контролирует компромисс между точностью и простотой

Для классификации с мягкими метками функция потерь дистилляции часто:

L_distill = -Σᵢ Σⱼ T(xᵢ)ⱼ · log(S(xᵢ)ⱼ)

Где j — индекс по классам.

Фреймворк учитель-ученик

Процесс дистилляции следует этим шагам:

1. ОБУЧИТЬ модель-учителя на исходных данных
T = TrainComplex(X_train, y_train)
2. СГЕНЕРИРОВАТЬ мягкие метки с помощью учителя
y_soft = T.predict_proba(X_train)
3. ОБУЧИТЬ дерево решений-ученика на мягких метках
S = DecisionTree(max_depth=d)
S.fit(X_train, y_soft)
4. ОЦЕНИТЬ точность воспроизведения и accuracy
fidelity = agreement(S.predict(X_test), T.predict(X_test))
accuracy = agreement(S.predict(X_test), y_test)

Метрика fidelity измеряет, насколько хорошо ученик имитирует учителя, в то время как accuracy измеряет производительность на исходной задаче. Высокая fidelity с высокой accuracy указывает на успешную дистилляцию.

Компромисс между точностью и интерпретируемостью

Существует фундаментальный компромисс между тем, насколько точно ученик имитирует учителя, и насколько интерпретируемым остаётся ученик:

Глубина дерева Fidelity Интерпретируемость
───────────────────────────────────────────────
2 60% Отличная
3 72% Очень хорошая
5 85% Хорошая
7 92% Умеренная
10 96% Плохая
15 99% Очень плохая

Для торговых приложений мы обычно нацеливаемся на:

  • Решения с высокими ставками: Глубина 3-5 (должны быть полностью проверяемы)
  • Исследования/разработка: Глубина 7-10 (баланс понимания и точности)
  • Автоматизированные системы: Глубина 5-7 (проверяемые, но детальные)

Оптимальная глубина зависит от:

  1. Сложности базовой торговой стратегии
  2. Регуляторных требований к объяснимости
  3. Количества признаков в модели
  4. Требуемого порога fidelity

Дистилляция дерева решений для трейдинга

Дистилляция моделей торговых сигналов

Рассмотрим сложную ансамблевую модель, которая предсказывает сигналы покупки/продажи на основе технических индикаторов:

# Учитель: Сложный ансамбль
teacher_features = ['RSI_14', 'MACD', 'MACD_signal', 'BB_upper', 'BB_lower',
'Volume_SMA_20', 'ATR_14', 'ADX_14', 'CCI_20', 'ROC_10']
# Учитель предсказывает: ПОКУПКА (0.73), ДЕРЖАТЬ (0.15), ПРОДАЖА (0.12)
# Дистиллированное дерево решений показывает:
ЕСЛИ RSI_14 < 35:
ЕСЛИ MACD > MACD_signal:
ЕСЛИ Volume_SMA_20 > 1.5:
ПОКУПКА (вероятность: 0.78)
ИНАЧЕ:
ДЕРЖАТЬ (вероятность: 0.52)
ИНАЧЕ:
ДЕРЖАТЬ (вероятность: 0.61)
ИНАЧЕ ЕСЛИ RSI_14 > 70:
ЕСЛИ ADX_14 > 25:
ПРОДАЖА (вероятность: 0.71)
ИНАЧЕ:
ДЕРЖАТЬ (вероятность: 0.58)
ИНАЧЕ:
ДЕРЖАТЬ (вероятность: 0.64)

Дистиллированное дерево показывает, что сложный ансамбль в основном опирается на:

  1. RSI для определения условий перепроданности/перекупленности
  2. Пересечение MACD для подтверждения импульса
  3. Объём для валидации силы сигнала
  4. ADX для силы тренда в решениях о продаже

Извлечение правил для управления рисками

Дистиллированные деревья решений предоставляют явные правила, которые можно мониторить для управления рисками:

Правила размера позиции:

Уверенность пути дерева → Размер позиции
───────────────────────────────────────────
> 0.80 → Полная позиция
0.65 - 0.80 → 75% позиции
0.50 - 0.65 → 50% позиции
< 0.50 → Без позиции

Оповещения о рисках:

ЕСЛИ дистиллированное_правило использует признак НЕ В approved_list:
ОПОВЕЩЕНИЕ: Модель может использовать неожиданные данные
ЕСЛИ глубина_дерева_для_решения > max_approved_depth:
ОПОВЕЩЕНИЕ: Путь решения слишком сложен для автоисполнения
ЕСЛИ образцов_в_листе < minimum_samples:
ОПОВЕЩЕНИЕ: Недостаточно исторической поддержки для этого правила

Дистилляция по рыночным режимам

Рыночные режимы (трендовый, боковой, волатильный) могут требовать разной логики решений. Дистилляция по режимам обучает отдельные деревья для каждого режима:

Определение режима:
ЕСЛИ Volatility_20d > 0.3 И ADX < 20:
режим = "Высокая волатильность, без тренда"
ИНАЧЕ ЕСЛИ ADX > 25:
режим = "Трендовый"
ИНАЧЕ:
режим = "Боковой"
Дистиллированные деревья по режимам:
ТРЕНДОВЫЙ РЕЖИМ:
ЕСЛИ MACD > MACD_signal И ADX > 30:
→ ПОКУПКА
ЕСЛИ MACD < MACD_signal И ADX > 30:
→ ПРОДАЖА
БОКОВОЙ РЕЖИМ:
ЕСЛИ RSI < 30 И Price < BB_lower:
→ ПОКУПКА
ЕСЛИ RSI > 70 И Price > BB_upper:
→ ПРОДАЖА
ВОЛАТИЛЬНЫЙ РЕЖИМ:
ЕСЛИ ATR_14 > 2 * ATR_14_avg:
→ УМЕНЬШИТЬ_ПОЗИЦИЮ
ИНАЧЕ:
→ Использовать обычные правила с 50% размером

Примеры кода

Реализация на Python

Реализация на Python в python/ предоставляет:

  • python/model.py: Базовая реализация дистилляции

    • Класс DistillationModel для обучения и извлечения правил
    • Поддержка различных моделей-учителей (sklearn, XGBoost, LightGBM)
    • Утилиты для извлечения и визуализации правил
  • python/backtest.py: Фреймворк бэктестинга

    • Сравнение производительности учителя и дистиллированной модели
    • Отслеживание использования правил и уровней уверенности
    • Атрибуция производительности по пути решения
  • python/data_loader.py: Утилиты загрузки данных

    • Интеграция с Yahoo Finance для акций
    • API Bybit для криптовалютных данных
    • Вычисление технических индикаторов

Пример использования:

from model import DistillationModel
from data_loader import load_stock_data, load_crypto_data
# Загрузка данных
stock_data = load_stock_data('AAPL', period='2y')
crypto_data = load_crypto_data('BTCUSDT', interval='1h', limit=5000)
# Обучение модели-учителя (сложный ансамбль)
from sklearn.ensemble import GradientBoostingClassifier
teacher = GradientBoostingClassifier(n_estimators=200, max_depth=10)
teacher.fit(X_train, y_train)
# Дистилляция в интерпретируемое дерево решений
distiller = DistillationModel(max_depth=5, min_samples_leaf=50)
distiller.fit(X_train, teacher)
# Извлечение и отображение правил
rules = distiller.extract_rules()
for rule in rules:
print(f"ЕСЛИ {rule.conditions} ТО {rule.prediction} (уверенность: {rule.confidence:.2f})")
# Оценка fidelity
fidelity = distiller.fidelity_score(X_test, teacher)
print(f"Точность воспроизведения учителя: {fidelity:.2%}")

Реализация на Rust

Реализация на Rust в rust/ обеспечивает высокопроизводительную дистилляцию для продакшена:

  • rust/src/lib.rs: Основная библиотека с алгоритмами дистилляции
  • rust/src/model/: Реализации дерева решений и дистилляции
  • rust/src/data/: Загрузка данных из API Bybit
  • rust/src/backtest/: Фреймворк бэктестинга
  • rust/examples/: Запускаемые примеры

Запуск базового примера:

Окно терминала
cd rust
cargo run --example basic_distillation

Запуск примера торговой стратегии:

Окно терминала
cargo run --example trading_strategy

Практическое применение

Извлечение торговых правил из нейросетей

Нейросети часто достигают лучшей предсказательной производительности, но полностью непрозрачны. Дистилляция раскрывает, что сеть изучила:

# Нейросеть-учитель
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
teacher_nn = Sequential([
Dense(128, activation='relu', input_shape=(n_features,)),
Dropout(0.3),
Dense(64, activation='relu'),
Dropout(0.3),
Dense(32, activation='relu'),
Dense(3, activation='softmax') # ПОКУПКА, ДЕРЖАТЬ, ПРОДАЖА
])
teacher_nn.fit(X_train, y_train_onehot, epochs=100)
# Дистилляция в дерево решений
soft_labels = teacher_nn.predict(X_train)
distiller = DistillationModel(max_depth=6)
distiller.fit(X_train, soft_labels)
# Дистиллированное дерево показывает, какие паттерны изучила нейросеть
print(distiller.tree_to_text())

Интерпретация ансамблевых моделей

Ансамблевые модели (Random Forest, Gradient Boosting) объединяют сотни деревьев, что затрудняет интерпретацию. Одно дистиллированное дерево суммирует коллективную мудрость ансамбля:

Исходный ансамбль:
- 500 деревьев решений
- Каждое дерево: глубина 10-15
- Всего: ~5000+ узлов решений
Дистиллированное дерево:
- 1 дерево решений
- Глубина: 5
- Всего: 31 узел решений
- Fidelity: 89%

Дистиллированное дерево захватывает 89% поведения ансамбля при 0.6% сложности.

Торговля в реальном времени на основе правил

Дистиллированные деревья позволяют создавать эффективные системы торговли в реальном времени:

Конвейер сложной модели:
Вход → Создание признаков → Ансамбль (500 деревьев) → Предсказание
Задержка: 50-200мс
Конвейер дистиллированной модели:
Вход → Создание признаков → Дерево решений (5 уровней) → Предсказание
Задержка: 1-5мс

Дистиллированная модель обеспечивает:

  • В 10-40 раз более быстрый вывод
  • Детерминированный путь выполнения
  • Простую аппаратную реализацию (совместима с FPGA)
  • Уменьшенный объём памяти

Бэктестинг дистиллированных моделей

Бэктестинг должен сравнивать как точность, так и торговую производительность:

from backtest import DistillationBacktester
backtester = DistillationBacktester(
teacher_model=teacher,
student_model=distiller,
data=test_data,
initial_capital=100000
)
results = backtester.run()
print("Сравнение производительности:")
print(f"Sharpe Ratio учителя: {results['teacher_sharpe']:.2f}")
print(f"Sharpe Ratio ученика: {results['student_sharpe']:.2f}")
print(f"Процент согласия: {results['agreement_rate']:.2%}")
print(f"Влияние расхождений: ${results['disagreement_pnl']:,.2f}")

Ключевые метрики для отслеживания:

  • Fidelity: Как часто учитель и ученик согласны
  • Сохранение точности: Точность ученика vs точность учителя
  • Сохранение Sharpe Ratio: Сравнение доходности с поправкой на риск
  • Анализ расхождений: Когда и почему модели расходятся
  • Стабильность правил: Меняются ли извлечённые правила со временем?

Ссылки

  1. Distilling a Neural Network Into a Soft Decision Tree

    • Авторы: Nicholas Frosst, Geoffrey Hinton
    • URL: https://arxiv.org/abs/1711.09784
    • Год: 2017
    • Представляет мягкие деревья решений, обученные через дистилляцию
  2. Distilling Knowledge from Deep Networks with Applications to Healthcare Domain

    • Авторы: Zhengping Che, Sanjay Purushotham, Robber Khemani, Yan Liu
    • URL: https://arxiv.org/abs/1512.03542
    • Год: 2015
    • Передача знаний для интерпретируемых моделей
  3. Born Again Neural Networks

  4. Interpretable Machine Learning

  5. Model Compression

    • Авторы: Cristian Bucila, Rich Caruana, Alexandru Niculescu-Mizil
    • Год: 2006
    • Ранняя работа по сжатию моделей через дистилляцию

Источники данных

  • Yahoo Finance / yfinance: Исторические цены акций и фундаментальные данные
  • Bybit API: Криптовалютные рыночные данные (OHLCV, стакан заявок)
  • Alpha Vantage: Альтернативный источник данных по акциям
  • Kaggle: Различные финансовые датасеты для экспериментов

Библиотеки и инструменты

Python

  • scikit-learn: Реализация дерева решений, ансамблевые модели
  • xgboost, lightgbm: Реализации градиентного бустинга
  • tensorflow, pytorch: Нейросети-учителя
  • pandas, numpy: Работа с данными
  • yfinance: API Yahoo Finance
  • matplotlib, graphviz: Визуализация деревьев

Rust

  • ndarray: N-мерные массивы
  • linfa: ML-тулкит (деревья решений)
  • polars: Быстрые DataFrames
  • reqwest: HTTP-клиент для API-запросов
  • serde: Сериализация/десериализация
  • plotters: Визуализация