第21章: 時系列分析とmodeltime

Tidyverseエコシステムによる高度な時系列予測

📈 時系列モデリング 🔮 予測と評価 ⚡ アンサンブル学習

📈 modeltimeの革新的時系列分析

modeltimeは、時系列予測のためのtidymodelsエコシステム拡張パッケージです。ARIMA、Prophet、機械学習モデルを統一されたインターフェースで操作し、美しい時系列分析ワークフローを実現します。

📈 Modeltime時系列分析エコシステム

📈 Modeltime時系列分析統合フレームワーク 🔄 時系列分析の基本概念 時間軸 (Time) 値 (Value) トレンド 季節性 2020 2021 2022 2023 2024 🛠️ Modeltimeコンポーネント構成 📊 統計モデル ARIMA ETS (指数平滑) STL分解 🔮 Prophet • 非線形トレンド • 年次・週次季節性 • 祝日効果 • 変化点検出 • 頑健な外れ値処理 • 不規則間隔データ対応 🤖 機械学習 Random Forest XGBoost LSTM (Neural Net) SVM 🎯 アンサンブル • 平均アンサンブル • 加重平均 • スタッキング • メタ学習 • 動的重み調整 • モデル選択 📊 評価・検証 • MAE (平均絶対誤差) • RMSE (二乗平均平方根誤差) • MAPE (平均絶対パーセント誤差) • Time Series CV • バックテスト • フォワードテスト • 信頼区間評価 • 残差分析 🔄 Modeltime分析ワークフロー 📚 データ準備 • 時系列フォーマット • 欠損値処理・外れ値 🔧 モデル構築 • モデル定義 • パラメータ調整 📋 テーブル化 • modeltime_table() • モデル管理 🎯 キャリブレーション • 検証データ適用 • 精度測定 📈 予測 • 未来予測 • 信頼区間 🎯 Modeltime高度機能 🔄 自動化機能 • Auto ARIMA パラメータ選択 • Cross-validation 自動実行 • ハイパーパラメータ最適化 • 並列処理対応 📊 可視化機能 • 対話的プロット (plotly) • 残差診断チャート • モデル比較ダッシュボード • 予測信頼区間表示 🎯 精度向上 • Ensemble Model 構築 • Feature Engineering 自動化 • 外部回帰子組み込み • オンライン学習対応 🚀 プロダクション • Shiny アプリケーション • API エンドポイント • スケジュール実行 • モデル管理・バージョニング

📦 modeltimeコアパッケージ

modeltime_setup.R
# modeltimeエコシステムの読み込み library(tidymodels) library(modeltime) library(modeltime.ensemble) library(timetk) library(tidyverse) # サンプル時系列データの準備 library(tidyquant) # 株価データの取得例 stock_data <- tq_get("AAPL", get = "stock.prices", from = "2020-01-01", to = "2023-12-31") %>% select(date, adjusted) %>% rename(value = adjusted) glimpse(stock_data)

📊 modeltime

時系列予測の統一フレームワーク。ARIMA、Prophet、機械学習モデルを同じインターフェースで操作可能。モデル比較と選択を簡素化。

modeltime_table(), modeltime_calibrate(), modeltime_forecast()

🔧 timetk

時系列データの操作と可視化。特徴量エンジニアリング、季節分解、異常検知など包括的な時系列分析ツール。

plot_time_series(), tk_augment_timeseries_signature()

🎯 modeltime.ensemble

時系列アンサンブル学習。複数の時系列モデルを組み合わせて予測精度を向上。平均、重み付き平均、スタッキングをサポート。

ensemble_average(), ensemble_weighted()

⏰ rsample

時系列専用のリサンプリング。時間順序を考慮した訓練・テスト分割とクロスバリデーション。データリークを防止。

time_series_split(), time_series_cv()
🔄 時系列分析ワークフロー
1
データ準備
時系列読み込み・前処理
2
探索的分析
季節性・トレンド分析
3
特徴量生成
ラグ・移動平均・周期特徴量
4
モデル構築
ARIMA・Prophet・ML
5
評価・選択
クロスバリデーション
6
アンサンブル
複数モデル統合

⏰ 時系列データ分割とリサンプリング

時系列分析では、時間順序を考慮したデータ分割が重要です。rsampleとtimetkパッケージは、時系列専用の分割とクロスバリデーション手法を提供します。

📊 時系列データ分割

🎯 時系列データ分割の概念図

Training Data (80%) 2020-01-01 ~ 2022-12-31 Test Data (20%) 2023-01-01~ 2020 2021 2022 2023 Future Prediction Data Leakage を防ぐ 時系列データの適切な分割
訓練期間(過去データ)
テスト期間(最新データ)
予測対象(未来)
time_series_split.R
# 時系列データの分割(最後の12か月をテスト用) splits <- stock_data %>% time_series_split( assess = "12 months", cumulative = TRUE ) # 分割結果の可視化 splits %>% tk_time_series_cv_plan() %>% plot_time_series_cv_plan(date, value, .interactive = TRUE) # 訓練・テストデータの取得 train_data <- training(splits) test_data <- testing(splits) cat("訓練データ期間:", min(train_data$date), "〜", max(train_data$date), "\\n") cat("テストデータ期間:", min(test_data$date), "〜", max(test_data$date), "\\n")

🔄 時系列クロスバリデーション

🎯 ウォークフォワード・クロスバリデーション

Time Series Cross-Validation: 6 Folds 2020 2021 2022 2023 2024 Fold 1 Training (3 years) Test (1 year) Fold 2 Training (Cumulative) Test Fold 3 Training (Cumulative) Test Fold 4 Training (Cumulative) Test Fold 5 Training (Cumulative) Test Fold 6 Training (Cumulative) Test skip: 3ヶ月 累積的な訓練データ拡張
✅ Cumulative Training

各フォールドで訓練データを累積的に増やし、実際の時系列予測環境をシミュレート

🎯 Fixed Test Window

一定期間のテストデータで一貫した評価。実用的な予測性能を測定

⏭️ Skip Parameter

オーバーラップを避けるために訓練期間を段階的にスキップ

time_series_cv.R
# 時系列クロスバリデーション設定 resamples <- stock_data %>% time_series_cv( initial = "3 years", assess = "12 months", skip = "3 months", cumulative = TRUE, slice_limit = 6 ) # CV分割の可視化 resamples %>% tk_time_series_cv_plan() %>% plot_time_series_cv_plan( date, value, .facet_ncol = 2, .interactive = TRUE ) print(resamples)

Time Series Split

時間順序を保持した訓練・テスト分割。最新のデータをテストセットとして確保し、過去のデータで訓練。実用的な予測性能評価を実現。

time_series_split(data, assess = "12 months", cumulative = TRUE)

Time Series CV

時系列専用クロスバリデーション。ウォークフォワード分析により、各時点での予測性能を評価。モデル選択の信頼性を向上。

time_series_cv(data, initial, assess, skip, cumulative)

Data Leakage防止

未来情報の漏洩を防ぐ仕組み。訓練時に未来のデータを使用せず、実際の予測状況を再現。時系列分析の信頼性を確保。

tk_time_series_cv_plan(), plot_time_series_cv_plan()

Rolling Window

動的な時間窓による評価。固定サイズまたは累積的な訓練期間を選択可能。データの時間変化に対する頑健性を測定。

rolling_origin(data, initial, assess, skip)

🔬 時系列特徴量エンジニアリング

timetkパッケージは、時系列データから豊富な特徴量を自動生成できます。日付・時刻の分解から、ラグ特徴量、移動平均、フーリエ変換まで、包括的な特徴量エンジニアリングを支援します。

📅 日付時刻特徴量の生成

time_series_features.R
# 時系列署名の生成 ts_features <- train_data %>% tk_augment_timeseries_signature(date) %>% select(-contains("hour|minute|second|am.pm")) %>% mutate( # ラグ特徴量 lag_1 = lag_vec(value, 1), lag_7 = lag_vec(value, 7), lag_14 = lag_vec(value, 14), lag_30 = lag_vec(value, 30), # 移動平均特徴量 ma_7 = slide_vec(value, mean, .before = 6, .complete = TRUE), ma_14 = slide_vec(value, mean, .before = 13, .complete = TRUE), ma_30 = slide_vec(value, mean, .before = 29, .complete = TRUE), # 差分特徴量 diff_1 = diff_vec(value, lag = 1), diff_7 = diff_vec(value, lag = 7), # 変化率特徴量 pct_change_1 = (value / lag_vec(value, 1) - 1) * 100, pct_change_7 = (value / lag_vec(value, 7) - 1) * 100 ) %>% filter(!is.na(lag_30)) glimpse(ts_features)

🔬 高度な特徴量生成

📈 時系列特徴量の全体像

🎯 元時系列データ ⏪ ラグ特徴量 lag_1 lag_7 📊 移動平均 7日移動平均 〰️ フーリエ変換特徴量 年周期 半年周期 📅 カレンダー特徴量 週末検知 📈 技術指標 売られすぎ 適正 RSI 0 30 70 100 🔄 統合された特徴量セット 機械学習モデルへの入力 50+ features → Predictive Model 特徴量の種類: 時間依存特徴量(ラグ、移動平均、差分) 周期性特徴量(フーリエ、季節性) カレンダー特徴量(曜日、月、祝日) 技術指標(RSI、MACD、ボリンジャー)
advanced_features.R
# フーリエ変換特徴量の生成 fourier_features <- ts_features %>% tk_augment_fourier(date, .periods = c(365.25, 365.25/2), .K = 2) # 滞留期間特徴量 holiday_features <- fourier_features %>% tk_augment_holiday_signature(date) %>% mutate( # カスタム特徴量 is_weekend = ifelse(wday.lbl %in% c("Saturday", "Sunday"), 1, 0), is_month_end = ifelse(mday == days_in_month(date), 1, 0), quarter_start = ifelse(month %in% c(1, 4, 7, 10) & mday == 1, 1, 0), # 技術指標風の特徴量 rsi_14 = slide_vec(pct_change_1, ~{ gains <- pmax(.x, 0) losses <- pmax(-.x, 0) avg_gain <- mean(gains, na.rm = TRUE) avg_loss <- mean(losses, na.rm = TRUE) rs <- avg_gain / avg_loss rsi <- 100 - (100 / (1 + rs)) return(rsi) }, .before = 13, .complete = TRUE) ) # 特徴量重要性の確認 feature_names <- holiday_features %>% select(-date, -value) %>% names() cat("生成された特徴量数:", length(feature_names), "\\n")

🕐 時間特徴量

日付から年、月、曜日、四半期など基本的な時間特徴量を自動抽出。周期性やトレンドの捕捉に重要な役割を果たします。

tk_augment_timeseries_signature(), year, month, wday

📈 ラグ・差分特徴量

過去の値との関係を表現する重要な特徴量。自己回帰的なパターンや変化率の情報を機械学習モデルで活用できます。

lag_vec(), diff_vec(), slide_vec()

〰️ フーリエ変換

周期的なパターンを三角関数で表現。季節性や循環的な変動を正弦波と余弦波の組み合わせで効果的にモデル化します。

tk_augment_fourier(), .periods, .K

🎄 祝日・イベント特徴量

祝日、週末、月末、四半期開始など、ビジネスに影響するイベント情報を特徴量として追加。外部要因の効果を考慮。

tk_augment_holiday_signature(), is_weekend, is_month_end

🤖 modeltimeテーブルと統合予測

modeltimeの真の力は、ARIMA、Prophet、機械学習モデルを統一されたテーブルで管理し、一括で比較・評価・予測できることです。美しいワークフローで時系列分析を効率化します。

🏗️ 複数モデルの構築

modeltime_models.R
# 1. ARIMAモデル model_arima <- arima_reg() %>% set_engine("auto_arima") %>% fit(value ~ date, data = train_data) # 2. Prophetモデル model_prophet <- prophet_reg( seasonality_yearly = TRUE, seasonality_weekly = FALSE, seasonality_daily = FALSE ) %>% set_engine("prophet") %>% fit(value ~ date, data = train_data) # 3. 機械学習モデル(Random Forest) recipe_ts <- recipe(value ~ date, data = train_data) %>% step_timeseries_signature(date) %>% step_rm(contains("hour|minute|second|am.pm")) %>% step_normalize(all_numeric_predictors()) %>% step_dummy(all_nominal_predictors()) model_rf <- rand_forest(trees = 500, min_n = 10) %>% set_engine("ranger") %>% set_mode("regression") wflow_rf <- workflow() %>% add_recipe(recipe_ts) %>% add_model(model_rf) %>% fit(train_data)

📋 modeltimeテーブルの作成と評価

modeltime_table.R
# modeltimeテーブルの作成 model_table <- modeltime_table( model_arima, model_prophet, wflow_rf ) # テストデータでのキャリブレーション calibration_table <- model_table %>% modeltime_calibrate(new_data = test_data) # 精度指標の計算 accuracy_table <- calibration_table %>% modeltime_accuracy() print(accuracy_table) # 予測結果の可視化 calibration_table %>% modeltime_forecast( new_data = test_data, actual_data = train_data, keep_data = TRUE ) %>% plot_modeltime_forecast( .facet_ncol = 2, .interactive = TRUE )

🎯 アンサンブル学習

ensemble_models.R
# 平均アンサンブルの作成 ensemble_avg <- calibration_table %>% ensemble_average(type = "mean") # 重み付きアンサンブル(精度逆数重み) weights <- 1 / accuracy_table$mae weights <- weights / sum(weights) ensemble_weighted <- calibration_table %>% ensemble_weighted(loadings = weights) # 最終モデルテーブル final_table <- modeltime_table( ensemble_avg, ensemble_weighted ) %>% combine_modeltime_tables(calibration_table) %>% modeltime_calibrate(new_data = test_data) # アンサンブル結果の評価 final_accuracy <- final_table %>% modeltime_accuracy() %>% arrange(mae) print(final_accuracy)

🏆 モデル性能比較チャート

Mean Absolute Error (MAE) 比較 4.0 3.5 3.0 2.5 2.0 1.5 1.0 2.14 Ensemble Weighted 2.18 Ensemble Mean 2.45 ARIMA (0,1,1) 2.67 Prophet 3.15 Random Forest 👑 BEST ベースライン 47%改善 性能指標サマリー • Ensemble Weighted: MAE=2.14, R²=0.95 • Ensemble Mean: MAE=2.18, R²=0.95 • ARIMA: MAE=2.45, R²=0.94 • Prophet: MAE=2.67, R²=0.93 • Random Forest: MAE=3.15, R²=0.91
Time Series Model Performance Comparison
# A tibble: 5 × 9 .model_id .model_desc .type mae mape mase smape rmse rsq <int> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 4 ENSEMBLE (WEI… Test 2.14 1.63 0.52 1.61 2.89 0.95 2 3 ENSEMBLE (MEA… Test 2.18 1.66 0.53 1.64 2.94 0.95 3 1 ARIMA(0,1,1) Test 2.45 1.87 0.60 1.85 3.12 0.94 4 2 PROPHET Test 2.67 2.03 0.65 2.01 3.34 0.93 5 5 RANDOMFOREST Test 3.15 2.41 0.77 2.39 4.02 0.91 # ✨ アンサンブルが最高性能を達成!

📊 統一インターフェース

異なる時系列モデルを同じワークフローで操作。ARIMA、Prophet、機械学習を統一されたテーブルで管理し、一括比較を実現。

modeltime_table(), modeltime_calibrate()

🎯 自動評価

複数の精度指標を自動計算。MAE、MAPE、RMSE、RSQなど、時系列予測に特化した評価指標で包括的な性能評価。

modeltime_accuracy(), modeltime_forecast()

🏆 アンサンブル学習

複数モデルの予測を統合。平均、重み付き平均、メディアンなど様々なアンサンブル手法で予測精度を向上。

ensemble_average(), ensemble_weighted()

📈 美しい可視化

インタラクティブな予測結果プロット。実測値、予測値、信頼区間を美しくプロット。複数モデルの比較も直感的。

plot_modeltime_forecast(), .interactive = TRUE

第21章の重要ポイント

実践的アドバイス

modeltimeは、時系列予測のベストプラクティスを自然に身につけられるよう設計されています。データの時間順序を考慮した分割、適切なクロスバリデーション、多様なモデル手法の統合など、実務で重要な要素が美しく組み込まれています。従来の時系列分析と比較して、より効率的で再現性の高い予測分析が可能になります。