目次
暗号通貨価格予測: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 過学習の防止
- クロスバリデーション: 時系列データでは前方検証(Walk-forward validation)を使用
- 正則化: Dropout層やL1/L2正則化の適用
- Early Stopping: 検証損失が改善しなくなったら訓練を停止
5.2 データリーケージの回避
- 未来の情報を使わない: 特徴量計算時に未来のデータを参照しない
- 適切なデータ分割: 時系列順序を保持した訓練/検証/テストセットの分割
5.3 実運用での考慮事項
- リアルタイム予測: APIレート制限とデータ更新頻度の管理
- モデル更新: 定期的な再訓練とパフォーマンスモニタリング
- リスク管理: 予測の不確実性を考慮した取引戦略
6. 期待される成果と限界
6.1 期待される成果
- 短期予測: 1-24時間先の価格動向の予測(60-75%の方向性精度)
- ボラティリティ予測: 価格変動幅の推定
- トレンド識別: 上昇/下降トレンドの早期発見
6.2 モデルの限界
- ブラックスワンイベント: 予期せぬ市場イベントへの対応困難
- 市場構造の変化: 過去のパターンが将来も続くとは限らない
- 取引コスト: 頻繁な取引による手数料の影響
7. 改善の方向性
7.1 高度な手法
- Transformer/Attention機構: より長期的な依存関係の学習
- Graph Neural Networks: 複数通貨間の相関関係のモデリング
- 強化学習: 取引戦略の最適化
7.2 追加データソース
- オンチェーンデータ: トランザクション量、アクティブアドレス数
- デリバティブ市場: オプション、先物のデータ
- マクロ経済指標: 金利、インフレ率、株式市場指数
まとめ
LSTMとARIMAを組み合わせたハイブリッドアプローチは、それぞれのモデルの長所を活かし、暗号通貨価格予測の精度向上に寄与します。ただし、市場の予測不可能性を認識し、適切なリスク管理と組み合わせて使用することが重要です。