ML Documentation

暗号通貨価格予測:LSTMとARIMAモデルの実装ガイド

概要

本ドキュメントでは、LSTM(Long Short-Term Memory)ニューラルネットワークとARIMA(自己回帰和分移動平均)モデルを使用した暗号通貨価格予測の実装方法について説明します。

1. モデルの特徴と期待される効果

1.1 LSTM(Long Short-Term Memory)

特徴

期待される効果

1.2 ARIMA(自己回帰和分移動平均)

特徴

期待される効果

2. 使用する特徴量

2.1 基本的な価格データ

- 始値(Open)
- 高値(High)
- 安値(Low)
- 終値(Close)
- 取引量(Volume)

2.2 テクニカル指標

- 移動平均(MA): 7日、21日、50日、200日
- 相対力指数(RSI): 14日
- ボリンジャーバンド: 20日、標準偏差2
- MACD: 12日、26日、シグナル9日
- 出来高加重平均価格(VWAP)
- 平均真幅(ATR): 14日

2.3 派生特徴量

- 価格変化率(リターン)
- ボラティリティ(標準偏差)
- 価格レンジ(High - Low)
- 取引量変化率
- 価格と移動平均の乖離率

2.4 外部要因(オプション)

- ビットコイン価格(他のアルトコインの場合)
- 市場全体の時価総額
- Fear & Greed Index
- Google Trends データ
- ソーシャルメディアセンチメント

3. 実装の進め方

3.1 データ準備フェーズ

Step 1: データ収集

# 必要なライブラリ
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# データソース例
- Exchange API (Binance, Coinbase等)
- CoinGecko API
- Yahoo Finance

Step 2: データ前処理

# 欠損値処理
- 前方補完ffillまたは線形補間
- 異常値の検出と処理

# 正規化/標準化
- Min-Max スケーリング0-1の範囲
- Z-score 標準化平均0標準偏差1

Step 3: 特徴量エンジニアリング

# テクニカル指標の計算
def calculate_technical_indicators(df):
    # RSI
    df['RSI'] = calculate_rsi(df['Close'], 14)

    # ボリンジャーバンド
    df['BB_upper'], df['BB_middle'], df['BB_lower'] = calculate_bollinger_bands(df['Close'])

    # MACD
    df['MACD'], df['MACD_signal'], df['MACD_hist'] = calculate_macd(df['Close'])

    return df

3.2 ARIMAモデルの実装

Step 1: 定常性の確認

from statsmodels.tsa.stattools import adfuller

# ADF検定
result = adfuller(price_series)
if result[1] > 0.05:
    # 差分を取って定常化
    price_diff = price_series.diff().dropna()

Step 2: パラメータの選択

from statsmodels.tsa.arima.model import ARIMA
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# ACF/PACFプロットでp,q値を決定
# または自動選択
from pmdarima import auto_arima
model = auto_arima(train_data, seasonal=False, stepwise=True)

Step 3: モデル訓練と予測

# ARIMAモデルの訓練
model = ARIMA(train_data, order=(p,d,q))
model_fit = model.fit()

# 予測
forecast = model_fit.forecast(steps=forecast_period)

3.3 LSTMモデルの実装

Step 1: データの準備

def create_sequences(data, seq_length):
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length])
    return np.array(X), np.array(y)

# シーケンス長の設定(例:過去60日で予測)
sequence_length = 60

Step 2: モデル構築

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout

def build_lstm_model(input_shape):
    model = Sequential([
        LSTM(100, return_sequences=True, input_shape=input_shape),
        Dropout(0.2),
        LSTM(100, return_sequences=True),
        Dropout(0.2),
        LSTM(50, return_sequences=False),
        Dropout(0.2),
        Dense(25),
        Dense(1)
    ])

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

Step 3: モデル訓練

# 訓練
history = model.fit(
    X_train, y_train,
    epochs=50,
    batch_size=32,
    validation_data=(X_val, y_val),
    callbacks=[
        EarlyStopping(patience=10),
        ReduceLROnPlateau(patience=5)
    ]
)

3.4 ハイブリッドアプローチ

アンサンブル予測

# 両モデルの予測を組み合わせる
def ensemble_prediction(lstm_pred, arima_pred, weights=[0.6, 0.4]):
    return weights[0] * lstm_pred + weights[1] * arima_pred

# 動的重み付け(誤差に基づく)
def dynamic_weights(lstm_error, arima_error):
    total_error = lstm_error + arima_error
    lstm_weight = 1 - (lstm_error / total_error)
    arima_weight = 1 - (arima_error / total_error)
    return [lstm_weight, arima_weight]

4. 評価指標

4.1 予測精度の評価

from sklearn.metrics import mean_squared_error, mean_absolute_error

# RMSE (Root Mean Squared Error)
rmse = np.sqrt(mean_squared_error(y_true, y_pred))

# MAE (Mean Absolute Error)
mae = mean_absolute_error(y_true, y_pred)

# MAPE (Mean Absolute Percentage Error)
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100

# 方向性精度(上昇/下降の予測精度)
direction_accuracy = np.mean((np.sign(y_true[1:] - y_true[:-1]) == 
                            np.sign(y_pred[1:] - y_pred[:-1]))) * 100

4.2 リスク調整後リターン

# シャープレシオ
def sharpe_ratio(returns, risk_free_rate=0.02):
    excess_returns = returns - risk_free_rate/252  # 日次リターンの場合
    return np.sqrt(252) * excess_returns.mean() / excess_returns.std()

# 最大ドローダウン
def max_drawdown(returns):
    cumulative = (1 + returns).cumprod()
    running_max = cumulative.cummax()
    drawdown = (cumulative - running_max) / running_max
    return drawdown.min()

5. 実装上の注意点

5.1 過学習の防止

5.2 データリーケージの回避

5.3 実運用での考慮事項

6. 期待される成果と限界

6.1 期待される成果

6.2 モデルの限界

7. 改善の方向性

7.1 高度な手法

7.2 追加データソース

まとめ

LSTMとARIMAを組み合わせたハイブリッドアプローチは、それぞれのモデルの長所を活かし、暗号通貨価格予測の精度向上に寄与します。ただし、市場の予測不可能性を認識し、適切なリスク管理と組み合わせて使用することが重要です。