決定木を用いたUSD/JPY予測モデルの実装と評価:短期・長期データの影響分析

本稿では、機械学習の手法の一つである決定木を用いて、USD/JPY為替レートの変動予測モデルを構築し、その精度を評価します。
※ただし、投資は自己責任でお願いします! この記事はあくまで学習を目的としたものであり、投資を推奨するものではありません。
※このソースと、ブログはgemini 1.5 proを使って作成しました。

分析では、Alpha Vantage APIから取得した日足データを用い、過去1日、10日、100日、1000日という異なる期間のデータセットを作成、それぞれに基づいてモデルを学習させました。

さらに、為替レートの予測精度向上を目指し、独自の指標として移動平均線やRSI、MACD、ボリンジャーバンドといったテクニカル指標を特徴量に追加しました。

これらの指標が、短期的な価格変動だけでなく、長期的なトレンドを捉える上で有効であるか検証を行います。

データ取得・前処理

Alpha Vantage APIからUSD/JPYの日足データを取得し、分析に適した形式に加工しました。

具体的には、始値、高値、安値、終値、出来高に加え、日付データの整形、欠損値処理を行いました。

from alpha_vantage.timeseries import TimeSeries
import pandas as pd

# APIキーの設定
api_key = "YOUR_API_KEY"

# データの取得
ts = TimeSeries(key=api_key, output_format='pandas')
data, meta_data = ts.get_daily(symbol='USDJPY', outputsize='full')

# カラム名の変更
data = data.rename(columns={
    '1. open': 'open',
    '2. high': 'high',
    '3. low': 'low',
    '4. close': 'close',
    '5. volume': 'volume'
})

# インデックスの日付データの変換
data.index = pd.to_datetime(data.index)
data = data.sort_index(ascending=True)

特徴量エンジニアリング

予測モデルの精度向上のため、以下のテクニカル指標を特徴量に追加しました。

  • 移動平均線(MA):短期(5日)と長期(25日)の移動平均線を算出し、トレンドの方向性や転換点を捉えます。

  • RSI:過去の値上がり幅と値下がり幅から、買われすぎや売られすぎを判断する指標です。

  • MACD:短期(12日)と長期(26日)の移動平均線の収束と拡散を見ることで、トレンドの強さや変化を捉えます。

  • ボリンジャーバンド:移動平均線から標準偏差×2の幅で線を引き、価格変動の volatility やトレンドの転換点を捉えます。

# --- 移動平均線の計算 ---
data['ma_short'] = data['close'].rolling(window=5).mean()
data['ma_long'] = data['close'].rolling(window=25).mean()

# --- RSIの計算 ---
delta = data['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(window=14).mean()
avg_loss = loss.rolling(window=14).mean()
rs = avg_gain / avg_loss
data['rsi'] = 100 - (100 / (1 + rs))

# --- MACDの計算 ---
data['ema_short'] = data['close'].ewm(span=12).mean()
data['ema_long'] = data['close'].ewm(span=26).mean()
data['macd'] = data['ema_short'] - data['ema_long']
data['macd_signal'] = data['macd'].ewm(span=9).mean()

# --- ボリンジャーバンドの計算 ---
data['std'] = data['close'].rolling(window=20).std()
data['upper_band'] = data['ma_short'] + 2 * data['std']
data['lower_band'] = data['ma_short'] - 2 * data['std']

# 欠損値処理
data = data.dropna()

決定木モデルの構築と評価

目的変数を翌日の終値が上昇するか下落するかとし、それぞれ1, 10, 100, 1000日分のデータを用いて決定木モデルを学習させました。

モデルの評価には、Accuracyを用い、クロスバリデーションによるパラメータチューニングを実施しました。

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score
import numpy as np

# 各期間のwindowサイズ
window_sizes = [1, 10, 100, 1000]

# 結果を格納するリスト
results = []

for window_size in window_sizes:
    print(f"---------- {window_size}日版モデル処理開始 ----------")

    # 特徴量と目的変数の作成
    X = []
    y = []
    for i in range(len(data) - window_size - 1):
        features = data.iloc[i:i + window_size][
            ['open', 'high', 'low', 'close', 'volume', 'price_change', 'ma_short', 'ma_long', 'rsi', 'macd',
             'macd_signal', 'upper_band', 'lower_band']].values.flatten()
        target = data.iloc[i + window_size]['target']
        X.append(features)
        y.append(target)
    X = np.array(X)
    y = np.array(y)

    # データの分割
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

    # グリッドサーチによるパラメータチューニング
    param_grid = {'max_depth': range(1, 11)}
    grid_search = GridSearchCV(DecisionTreeClassifier(random_state=42), param_grid, cv=5, scoring='accuracy')
    grid_search.fit(X_train, y_train)

    # 最適なモデルを用いて予測
    best_model = grid_search.best_estimator_
    y_pred = best_model.predict(X_test)

    # Accuracyの算出
    accuracy = accuracy_score(y_test, y_pred)
    print(f"Accuracy ({window_size} days, best model): {accuracy:.2f}")

    # 結果の保存
    results.append({'window_size': window_size, 'accuracy': accuracy})
    print(f"---------- {window_size}日版モデル処理完了 ----------")

# 結果の表示
print("\n--- 各期間におけるAccuracy ---")
for result in results:
    print(f"期間: {result['window_size']}日, Accuracy: {result['accuracy']:.2f}")

結果と考察

| 期間 | Accuracy |
|---|---|
| 1日 | 0.52 |
| 10日 | 0.51 |
| 100日 | 0.52 |
| 1000日 | 0.52 |

今回の実験では、期間を問わずAccuracyが0.52前後と、ランダムに予測した場合とほぼ変わらない結果となりました。

このことから、単純な決定木モデルと今回使用した特徴量だけでは、為替レートの変動を正確に予測することは難しいことが示唆されました。

考えられる要因としては、為替レートに影響を与える要素が非常に複雑であり、今回用いた特徴量だけでは十分に捉えきれていない可能性があります。

今後の展望

今後は、以下のような点を改善することで、予測精度の向上が期待できます。

  • より複雑なモデルの構築: 決定木よりも表現力の高い、ランダムフォレストや勾配ブースティングなどのアンサンブル学習手法を検討します。

  • 特徴量の追加: 経済指標やニュースSentimentなど、為替レートに影響を与える可能性のある、より多様な特徴量を追加します。

  • ディープラーニングの導入: LSTMやGRUなどの時系列データに対応したディープラーニングモデルを適用することで、より複雑なパターンを学習させます。

まとめ

本稿では、決定木を用いてUSD/JPY為替レートの変動予測モデルを構築し、その精度を評価しました。

結果として、今回の設定では満足のいく精度は得られませんでしたが、モデルの改善や特徴量追加、より高度な学習手法の導入によって、さらなる精度向上が見込めます。

疑問点

APIキーを打たなくてもデータとれてる??なぜ??

この記事が気に入ったらサポートをしてみませんか?