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

Глава 244: XLNet для финансов

Введение

XLNet — это обобщённый метод авторегрессивного предобучения, который объединяет преимущества авторегрессивных (AR) языковых моделей и автокодирующих (AE) подходов, таких как BERT. Представленный Yang и др. (2019), XLNet устраняет ключевые ограничения BERT, используя обучающую цель на основе перестановок, которая захватывает двунаправленный контекст без опоры на маскированные токены и предположение о их независимости.

В финансовых приложениях перестановочное языковое моделирование XLNet особенно ценно. Финансовые тексты — отчёты о доходах, аналитические обзоры, регуляторные документы и новости — содержат сложные зависимости между сущностями, числами и тональностью. Модель замаскированного языка BERT предполагает, что замаскированные токены независимы друг от друга при данном незамаскированном контексте, что может упустить важные межтокенные зависимости. Перестановочная цель XLNet естественным образом захватывает эти зависимости, что делает его более подходящим для понимания нюансированного финансового языка.

В этой главе рассматриваются теоретические основы XLNet, его преимущества перед BERT для финансового NLP, а также представлены рабочие реализации на Python и Rust. Мы демонстрируем анализ тональности финансовых текстов и создаём генератор торговых сигналов с подключением к криптовалютной бирже Bybit.

Ключевые концепции

Авторегрессивные vs. автокодирующие языковые модели

Авторегрессивные (AR) модели, такие как GPT, оценивают вероятность текстовой последовательности, разлагая совместную вероятность в произведение условных вероятностей в фиксированном порядке слева направо:

$$p(\mathbf{x}) = \prod_{t=1}^{T} p(x_t | x_1, \ldots, x_{t-1})$$

AR-модели хороши в генерации, но могут захватывать контекст только в одном направлении.

Автокодирующие (AE) модели, такие как BERT, используют цель обучения с шумоподавлением. При данном повреждённом входе $\hat{\mathbf{x}}$ (с некоторыми токенами, заменёнными на [MASK]) модель восстанавливает исходные токены:

$$\max_\theta \log p(\bar{\mathbf{x}} | \hat{\mathbf{x}}) \approx \sum_{t=1}^{T} m_t \log p(x_t | \hat{\mathbf{x}})$$

где $m_t = 1$ означает, что токен $t$ был замаскирован. Ключевое ограничение — предположение о независимости: BERT предполагает, что замаскированные токены независимы друг от друга при данном незамаскированном контексте, что игнорирует корреляции между замаскированными позициями.

Перестановочное языковое моделирование

Центральная инновация XLNet — перестановочное языковое моделирование. Вместо фиксации порядка факторизации (слева направо) или маскирования токенов (BERT), XLNet рассматривает все возможные перестановки порядка факторизации и максимизирует ожидаемое логарифмическое правдоподобие:

$$\max_\theta ; \mathbb{E}{\mathbf{z} \sim \mathcal{Z}T} \left[ \sum{t=1}^{T} \log p\theta(x_{z_t} | \mathbf{x}{\mathbf{z}{<t}}) \right]$$

где $\mathcal{Z}T$ — множество всех перестановок ${1, 2, \ldots, T}$, а $\mathbf{z}$ — конкретная перестановка. Для каждой перестановки $\mathbf{z}$ токен $x{z_t}$ предсказывается с использованием только токенов, которые появляются до него в порядке перестановки $\mathbf{x}{\mathbf{z}{<t}}$.

Это обеспечивает двунаправленный контекст (каждый токен может обращаться к токенам с обеих сторон в исходной последовательности), сохраняя при этом авторегрессивную факторизацию (без предположения о независимости между предсказываемыми токенами).

Двухпоточное самовнимание

Стандартные трансформеры не могут реализовать перестановочное языковое моделирование, поскольку механизм внимания должен знать, какая позиция предсказывается (чтобы избежать тривиального подсматривания ответа). XLNet решает это с помощью двухпоточного самовнимания:

  1. Поток содержания $h_{z_t}$: Стандартное скрытое состояние, кодирующее содержание токена $x_{z_t}$ вместе с его контекстом. Может обращаться ко всем токенам на позициях $z_{\leq t}$ (включая себя).

  2. Поток запроса $g_{z_t}$: Отдельное скрытое состояние, кодирующее только позицию $z_t$ и контекст $\mathbf{x}{\mathbf{z}{<t}}$ (исключая токен на позиции $z_t$). Используется для предсказания токена на позиции $z_t$.

Правила обновления для слоя $m$:

$$g_{z_t}^{(m)} \leftarrow \text{Attention}(Q = g_{z_t}^{(m-1)}, ; KV = h_{\mathbf{z}_{<t}}^{(m-1)}; \theta)$$

$$h_{z_t}^{(m)} \leftarrow \text{Attention}(Q = h_{z_t}^{(m-1)}, ; KV = h_{\mathbf{z}_{\leq t}}^{(m-1)}; \theta)$$

Архитектура Transformer-XL

XLNet построен на основе Transformer-XL, который вводит два механизма для обработки длинных последовательностей:

Рекуррентность на уровне сегментов: Скрытые состояния из предыдущих сегментов кэшируются и переиспользуются как расширенный контекст для текущего сегмента:

$$\tilde{h}^{(n-1)} = [\text{SG}(h_{\tau-1}^{(n-1)}) \circ h_{\tau}^{(n-1)}]$$

где $\text{SG}(\cdot)$ обозначает остановку градиента, а $\circ$ — конкатенацию по временной размерности.

Относительное позиционное кодирование: Вместо абсолютных позиционных эмбеддингов Transformer-XL использует относительные позиционные кодировки, зависящие от расстояния между токенами:

$$A_{i,j} = E_{x_i}^T W_q^T W_{k,E} E_{x_j} + E_{x_i}^T W_q^T W_{k,R} R_{i-j} + u^T W_{k,E} E_{x_j} + v^T W_{k,R} R_{i-j}$$

Это позволяет модели обобщаться на последовательности, более длинные, чем те, что встречались при обучении, что критически важно для обработки длинных финансовых документов.

Финансовые NLP-приложения

Анализ тональности

Анализ финансовой тональности с помощью XLNet отличается от общего анализа тональности:

  • Предметная лексика: Слова типа «обязательство», «короткая позиция» и «коррекция» имеют в финансах иной смысл, чем в повседневном языке.
  • Числовое рассуждение: Финансовые тексты содержат числа, значение которых определяет тональность. «Выручка выросла на 2%» vs. «Выручка выросла на 200%» несут совершенно разные сигналы.
  • Отрицание и хеджирование: Финансовый язык часто использует хеджирование («может», «возможно», «при условии») и отрицание.
  • Прогнозные утверждения: Отчёты о доходах содержат прогнозные формулировки, требующие понимания временного контекста.

Классификация документов

Финансовые документы могут быть классифицированы по категориям:

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

Распознавание именованных сущностей в финансах

Финансовое NER идентифицирует сущности: названия компаний, тикерные символы, финансовые показатели, денежные суммы, даты и регуляторные органы. Двунаправленное понимание контекста XLNet помогает разрешать неоднозначность сущностей.

Генерация торговых сигналов

Сигналы на основе тональности

Конвейер генерации торговых сигналов из анализа тональности XLNet:

  1. Сбор данных: Сбор финансовых текстов (новости, соцсети, отчёты) для целевых активов.
  2. Предобработка: Токенизация с использованием SentencePiece (токенизатор XLNet).
  3. Оценка тональности: Прогон текстов через дообученный XLNet для получения оценок тональности в $[-1, 1]$.
  4. Агрегация сигнала: Агрегация оценок за временное окно с экспоненциальным затуханием:

$$S_t = \sum_{i=0}^{N} \alpha^i \cdot s_{t-i}$$

  1. Размер позиции: Преобразование агрегированного сигнала в размер позиции с помощью сигмоидной функции:

$$\text{position}_t = 2 \cdot \sigma(\beta \cdot S_t) - 1$$

Комбинирование с ценовыми данными

Сигналы тональности наиболее эффективны в сочетании с ценовыми характеристиками:

  • Совпадение тональности и моментума: Когда тональность и ценовой моментум согласованы, сигнал сильнее.
  • Дивергенция тональности: Когда тональность становится негативной, но цена продолжает расти — это контрарианский предупредительный сигнал.
  • Корректировка по волатильности: Масштабирование позиций обратно пропорционально недавней волатильности для поддержания постоянного риска.

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

Анализ тональности с Hugging Face

from transformers import XLNetTokenizer, XLNetForSequenceClassification
import torch
import numpy as np
class FinancialSentimentAnalyzer:
"""Анализатор тональности на основе XLNet для финансовых текстов."""
def __init__(self, model_name="xlnet-base-cased", num_labels=3):
self.tokenizer = XLNetTokenizer.from_pretrained(model_name)
self.model = XLNetForSequenceClassification.from_pretrained(
model_name, num_labels=num_labels
)
self.model.eval()
self.label_map = {0: "bearish", 1: "neutral", 2: "bullish"}
def analyze(self, text, max_length=512):
inputs = self.tokenizer(
text, return_tensors="pt",
max_length=max_length, truncation=True, padding=True,
)
with torch.no_grad():
outputs = self.model(**inputs)
probs = torch.softmax(outputs.logits, dim=-1).squeeze().numpy()
predicted_label = int(np.argmax(probs))
return {
"label": self.label_map[predicted_label],
"confidence": float(probs[predicted_label]),
"scores": {self.label_map[i]: float(probs[i]) for i in range(len(probs))},
}

Генератор торговых сигналов

import math
class SentimentSignalGenerator:
"""Генерация торговых сигналов из оценок тональности."""
def __init__(self, decay=0.9, aggressiveness=2.0):
self.decay = decay
self.aggressiveness = aggressiveness
self.history = []
def update(self, sentiment_score):
self.history.append(sentiment_score)
return sum(
self.decay ** i * self.history[-(i + 1)]
for i in range(len(self.history))
)
def position(self, signal):
return 2.0 * (1.0 / (1.0 + math.exp(-self.aggressiveness * signal))) - 1.0
def generate(self, sentiment_score):
signal = self.update(sentiment_score)
pos = self.position(signal)
action = "BUY" if pos > 0.3 else ("SELL" if pos < -0.3 else "HOLD")
return {"signal": signal, "position": pos, "action": action}

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

Реализация на Rust обеспечивает высокопроизводительный механизм оценки тональности и генерации торговых сигналов с интеграцией Bybit API. Полный исходный код находится в каталоге rust/.

Основные компоненты

  • SentimentScorer: Классификатор тональности на основе логистической регрессии с TF-IDF-подобными признаками.
  • SignalGenerator: Преобразование оценок тональности в торговые сигналы с экспоненциальным затуханием.
  • Backtester: Симуляция торговой стратегии на основе тональности на исторических данных.
  • BybitClient: Асинхронный HTTP-клиент для Bybit V5 API.

Сравнение с BERT

ХарактеристикаBERTXLNet
Цель обученияМаскированная языковая модельПерестановочная языковая модель
Предположение о независимостиДаНет
Дальние зависимостиОграничены фиксированным контекстным окномРасширены через рекуррентность Transformer-XL
Позиционное кодированиеАбсолютноеОтносительное
Эффективность предобученияНиже (только 15% токенов предсказываются)Выше (все токены предсказываются)
Производительность на финансовых текстахСильный базовый уровеньЛучше на длинных документах и сложных зависимостях

Ссылки

  1. Yang, Z., Dai, Z., Yang, Y., Carbonell, J., Salakhutdinov, R., & Le, Q. V. (2019). XLNet: Generalized Autoregressive Pretraining for Language Understanding. Advances in Neural Information Processing Systems, 32.
  2. Dai, Z., Yang, Z., Yang, Y., Carbonell, J., Le, Q. V., & Salakhutdinov, R. (2019). Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.
  3. Araci, D. (2019). FinBERT: Financial Sentiment Analysis with Pre-trained Language Models.
  4. Malo, P., Sinha, A., Korhonen, P., Wallenius, J., & Takala, P. (2014). Good debt or bad debt: Detecting semantic orientations in economic texts.
  5. Loughran, T., & McDonald, B. (2011). When is a Liability Not a Liability? Textual Analysis, Dictionaries, and 10-Ks.