ML Documentation

tickデータを用いたVDP LSTM機械学習による価格予測

概要

本ドキュメントでは、暗号通貨のtickデータを用いたVDP LSTM(Variational Dropout LSTM)による価格予測手法について詳しく解説します。VDP LSTMは従来のLSTMよりも優れた不確実性定量化機能を持ち、高頻度取引や投資判断において重要な信頼区間付きの予測を提供します。

1. VDP LSTMとは

1.1 理論的基盤

VDP LSTMは、Yarin GalとZoubin Ghahramani(2016年)による「A Theoretically Grounded Application of Dropout in Recurrent Neural Networks」に基づく手法です。この手法は、深層ガウス過程における近似ベイズ推論の理論的基盤を持ちます。

1.2 従来のLSTMとの違い

特徴 通常のLSTM VDP LSTM
ドロップアウト 各時刻で異なるマスク 全時刻で同一マスク
再帰層への適用 なし あり
理論的基盤 経験的 ベイズ理論に基づく
不確実性定量化 なし 内蔵

2. 金融時系列データにおける利点

2.1 暗号通貨市場での特徴

2.2 VDP LSTMの利点

  1. 不確実性定量化: 予測に信頼区間を提供
  2. 過学習防止: 変動の激しい金融データでの汎化性能向上
  3. リスク管理: 予測の不確実性を考慮した投資判断
  4. 安定性: 従来手法よりも低い総不確実性

3. 技術的詳細

3.1 変分ドロップアウトの仕組み

# 変分ドロップアウトの基本概念
class VariationalDropout:
    def __init__(self, dropout_rate=0.2):
        self.dropout_rate = dropout_rate
        self.mask = None

    def forward(self, x, training=True):
        if training or self.monte_carlo:
            # 同一マスクを時系列全体で使用
            if self.mask is None:
                self.mask = self.generate_mask(x.shape)
            return x * self.mask
        return x

3.2 モンテカルロドロップアウト(MCD)

推論時にもドロップアウトを適用し、複数回の前向き伝播を実行:

def predict_with_uncertainty(model, x, n_samples=100):
    """不確実性付きの予測を実行"""
    predictions = []

    # モンテカルロサンプリング
    for _ in range(n_samples):
        pred = model(x, training=True)  # 推論時もドロップアウト有効
        predictions.append(pred)

    # 統計量の計算
    mean_pred = np.mean(predictions, axis=0)
    uncertainty = np.std(predictions, axis=0)

    return mean_pred, uncertainty

4. 実装アーキテクチャ

4.1 推奨アーキテクチャ

import tensorflow as tf
from tensorflow.keras.layers import LSTM, Dense, Dropout, BatchNormalization

def build_vdp_lstm_model(sequence_length, n_features):
    """
    VDP LSTMモデルの構築
    """
    model = tf.keras.Sequential([
        # 第1LSTM層
        LSTM(128, return_sequences=True, dropout=0.5, 
             recurrent_dropout=0.5, input_shape=(sequence_length, n_features)),
        BatchNormalization(),

        # 第2LSTM層
        LSTM(80, dropout=0.5, recurrent_dropout=0.5),
        BatchNormalization(),

        # 全結合層
        Dense(50, activation='relu'),
        Dropout(0.3),

        # 出力層
        Dense(1, activation='linear')
    ])

    return model

4.2 ハイパーパラメータ設定

パラメータ 推奨値 説明
ドロップアウト率 0.5 LSTM層での設定
再帰ドロップアウト 0.5 再帰接続への適用
バッチサイズ 32-64 メモリと性能のバランス
シーケンス長 60-120 1-2時間のtickデータ
MCサンプル数 100 不確実性推定用

5. tickデータの前処理

5.1 データ準備

import pandas as pd
import numpy as np

def prepare_tick_data(df, sequence_length=60):
    """
    tickデータの前処理
    """
    # 技術指標の計算
    df['returns'] = df['price'].pct_change()
    df['ma_5'] = df['price'].rolling(window=5).mean()
    df['ma_20'] = df['price'].rolling(window=20).mean()
    df['volatility'] = df['returns'].rolling(window=20).std()

    # 正規化
    features = ['price', 'volume', 'ma_5', 'ma_20', 'volatility']
    df[features] = (df[features] - df[features].mean()) / df[features].std()

    # シーケンスデータの作成
    X, y = [], []
    for i in range(sequence_length, len(df)):
        X.append(df[features].iloc[i-sequence_length:i].values)
        y.append(df['price'].iloc[i])

    return np.array(X), np.array(y)

5.2 時間窓の設定

6. 性能評価指標

6.1 予測精度指標

def evaluate_predictions(y_true, y_pred, uncertainty):
    """
    VDP LSTMの評価指標
    """
    # 基本的な精度指標
    mse = np.mean((y_true - y_pred) ** 2)
    mae = np.mean(np.abs(y_true - y_pred))
    mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100

    # 不確実性関連指標
    coverage = np.mean(
        (y_true >= y_pred - 1.96 * uncertainty) & 
        (y_true <= y_pred + 1.96 * uncertainty)
    )

    # シャープレシオ(取引戦略評価用)
    returns = np.diff(y_true) / y_true[:-1]
    sharpe = np.mean(returns) / np.std(returns) * np.sqrt(252)

    return {
        'MSE': mse,
        'MAE': mae,
        'MAPE': mape,
        'Coverage': coverage,
        'Sharpe': sharpe
    }

6.2 ベンチマーク結果

実際の研究結果に基づく性能比較:

モデル MAPE (%) シャープレシオ
通常LSTM 4.2 0.73 1.45
VDP LSTM 3.6 0.78 2.09
Transformer 3.8 0.75 1.82

7. 実際の取引戦略への応用

7.1 信頼区間を用いた取引シグナル

def generate_trading_signals(predictions, uncertainty, threshold=0.02):
    """
    不確実性を考慮した取引シグナル生成
    """
    signals = []

    for pred, unc in zip(predictions, uncertainty):
        # 高い確信度での上昇予測
        if pred > threshold and unc < 0.01:
            signals.append('BUY')
        # 高い確信度での下降予測
        elif pred < -threshold and unc < 0.01:
            signals.append('SELL')
        # 不確実性が高い場合は待機
        else:
            signals.append('HOLD')

    return signals

7.2 リスク管理

8. 実装例とコード

8.1 完全な実装例

import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler

class VDPLSTMPredictor:
    def __init__(self, sequence_length=60, n_features=5):
        self.sequence_length = sequence_length
        self.n_features = n_features
        self.model = None
        self.scaler = MinMaxScaler()

    def build_model(self):
        """モデル構築"""
        self.model = tf.keras.Sequential([
            LSTM(128, return_sequences=True, dropout=0.5, 
                 recurrent_dropout=0.5, 
                 input_shape=(self.sequence_length, self.n_features)),
            BatchNormalization(),
            LSTM(80, dropout=0.5, recurrent_dropout=0.5),
            BatchNormalization(),
            Dense(50, activation='relu'),
            Dropout(0.3),
            Dense(1)
        ])

        self.model.compile(
            optimizer='adam',
            loss='mse',
            metrics=['mae']
        )

    def train(self, X_train, y_train, epochs=100, batch_size=32):
        """モデル訓練"""
        early_stopping = tf.keras.callbacks.EarlyStopping(
            patience=10, restore_best_weights=True
        )

        history = self.model.fit(
            X_train, y_train,
            epochs=epochs,
            batch_size=batch_size,
            validation_split=0.2,
            callbacks=[early_stopping],
            verbose=1
        )

        return history

    def predict_with_uncertainty(self, X, n_samples=100):
        """不確実性付き予測"""
        predictions = []

        for _ in range(n_samples):
            # 推論時もドロップアウトを有効にする
            pred = self.model(X, training=True)
            predictions.append(pred.numpy())

        predictions = np.array(predictions)
        mean_pred = np.mean(predictions, axis=0)
        uncertainty = np.std(predictions, axis=0)

        return mean_pred, uncertainty

8.2 データ収集とリアルタイム予測

def real_time_prediction_pipeline():
    """リアルタイム予測パイプライン"""
    # データ収集(WebSocket等から)
    tick_data = collect_tick_data()

    # 前処理
    processed_data = preprocess_tick_data(tick_data)

    # 予測実行
    prediction, uncertainty = model.predict_with_uncertainty(processed_data)

    # 取引シグナル生成
    signal = generate_trading_signal(prediction, uncertainty)

    # ログ出力
    print(f"予測価格: {prediction:.2f} ± {uncertainty:.2f}")
    print(f"取引シグナル: {signal}")

    return prediction, uncertainty, signal

9. 注意点と制限事項

9.1 実装上の注意点

  1. 計算コスト: MCサンプリングにより推論時間が増加
  2. メモリ使用量: 複数の予測結果を保存する必要
  3. ハイパーパラメータ調整: ドロップアウト率の慎重な設定が必要

9.2 市場環境での制限

  1. ブラックスワンイベント: 極端な市場イベントは予測困難
  2. 構造変化: 市場の根本的変化への適応に時間要
  3. 流動性: 低流動性時の価格予測精度低下

10. 今後の発展方向

10.1 技術的改善

10.2 実用化への道筋

  1. リアルタイムシステム: 低遅延予測システムの構築
  2. リスク管理: より高度なポートフォリオ管理手法
  3. 規制対応: 金融規制への準拠

参考文献

  1. Gal, Y., & Ghahramani, Z. (2016). A theoretically grounded application of dropout in recurrent neural networks.
  2. Hassan, M. (2024). Bitcoin Price Prediction Using Deep Bayesian LSTM With Uncertainty Quantification.
  3. Borovkova, S. (2019). An ensemble of LSTM neural networks for high‐frequency stock market classification.

まとめ

VDP LSTMは暗号通貨のtickデータ予測において、従来のLSTMを上回る性能を示します。特に不確実性定量化機能により、リスクを考慮した取引判断が可能になります。実装時は計算コストと予測精度のバランスを取りながら、市場環境に応じた調整が重要です。