IS-OOS split で過学習を防ぐ実践 — backtest +30% が live で -10% になる理由

TL;DR

  • backtest で優秀な数字が出るのに live で出ないのは、ほぼすべて 過学習 (overfit) が原因
  • IS (in-sample) で最適化 → OOS (out-of-sample) で評価が最低限のバリデーション
  • walk-forward (rolling window) は時系列で自然な OOS テスト
  • look-ahead bias、data snooping、regime mismatch という補助的罠も意識する
  • Lopez de Prado の Combinatorial Purged CV (CPCV) はより robust な選択肢

Hook

新しい戦略を組んだ。backtest で 5 年分回したら ROI +30%、Sharpe 2.5、最大 drawdown -8%。完璧な数字が並んだ。実運用したら 1 ヶ月で -10% を喰らって停止した。

これは戦略運用者が誰でも 1 度は通る道。原因はほぼ確定で 過学習。backtest はパラメータを「過去のデータを見ながらチューニング」する行為なので、本物の signal ではなくノイズに fit する。それを live で確認するのは高くつく。

過学習の本質 — なぜ起きるか

過学習は「訓練データに過度にフィットして、未知データで性能が落ちる」現象。ML の世界での古典的問題だが、quantitative strategy 開発でも完全に同じメカニズムで発生する。

具体的には:

  1. パラメータ空間 (例: 移動平均の長さ、シグナル閾値) を grid search する
  2. backtest 期間で最良のパラメータを選ぶ
  3. その「最良」は、本物の signal ではなく、その期間特有のノイズパターンに fit している
  4. 別期間で同じパラメータを使うと性能が落ちる

ML 同様、パラメータ次元数が高いほど、データに対する自由度が大きくなり、過学習しやすい。

最低限の対策 — IS-OOS Split

データを 2 分割する。例えば 5 年分のデータなら、最初の 3.5 年を IS (In-Sample)、残りの 1.5 年を OOS (Out-of-Sample) にする。

手順

  1. IS でパラメータを最適化
  2. 確定したパラメータで OOS を一度だけ評価
  3. OOS の結果が IS と乖離が大きければ過学習を疑う

重要な原則

OOS は一度だけ使う。OOS の結果を見て IS のパラメータを調整したら、それは事実上 OOS が IS の一部になり、再度過学習を始める。これを data snooping と呼ぶ。

OOS は最終評価で 1 回触る。それで結果が悪ければ、戦略を捨てる、もしくは IS / OOS を再分割して仕切り直す (= 期間を変えて 2 セット目で回す)。

Walk-Forward — 時系列の自然な拡張

時系列データで IS-OOS を 1 度だけ切るのは、「ある特定期間の OOS」での性能を見ているだけ。複数期間で robust か確認したいなら Walk-Forward Optimization を使う。

アルゴリズム

  1. 全期間を時系列に rolling window で分割
  2. 各 window で「直近 T_train で最適化 → 次の T_test で評価」を繰り返す
  3. 全期間の OOS リターンを連結して評価
[----train1----][test1]
        [----train2----][test2]
                [----train3----][test3]
                        ...

時系列の局所性 (regime) に rolling で適応する設計。retail 視点でも実装可能で、財務系 quant では標準。

補助的な罠

Look-Ahead Bias

未来の情報が無意識に features に混ざる罠。例えば:

  • 「当日 close で signal 計算 → 当日中に entry」と書いてあるが、close は当日終了時点でしか確定しないため、実運用では翌日まで使えない
  • earnings announcement の数字を、発表前の trade 判定に使っている
  • 「当日の volatility」が「当日の close」を含む計算で生成されている

backtest の features を生成する時点で、必ず「この情報は実運用時に既知だったか」を timestamp ベースで点検する。

Data Snooping

OOS の結果を見て IS パラメータを調整するパターン。「OOS で性能悪い → IS を broaden → またチューン → OOS チェック → …」のループに入った時点で、OOS は事実上 IS の延長。

防御策は OOS の結果を見る回数を物理的に制限する こと。pre-registration、別人による評価、結果を封筒に入れる (運用記録上)、などの工夫。

Regime Mismatch

IS が bull market、OOS が bear market のように、期間が異なる regime に属していると、IS の最良パラメータが OOS で逆方向に効く。これは「過学習」というより「学習データの代表性問題」。

対策:

  • 複数 regime をまたぐ長期間データ
  • regime 別に分けて検証 (regime indicator を作る)
  • robust な戦略は regime 横断で機能するもの

より robust な選択肢 — Combinatorial Purged CV

Lopez de Prado (AFML Ch. 6) が提示した Combinatorial Purged Cross-Validation (CPCV) は、retail には実装ハードルがあるが理論上 powerful。

要点:

  • データを N 個の連続パーティションに分割
  • k 個を test、残り N-k 個を train として、組み合わせ全通りを試す
  • 訓練と検定の境界に purge zone (重複情報を除去) と embargo (波及効果を除去) を入れる
  • 結果として、より多くの OOS 評価点を得る + label leakage を防ぐ

retail で完全実装は重いが、概念は知っておく価値がある (label leakage の存在、purge zone の必要性)。

個人的経験

ある OOS でとても強いシグナルが見えた。喜んで live に入れる前に、IS 側の挙動を chained で確認したら、IS では同じ signal が逆方向に動いていたことが分かった。これは「OOS で偶然強く出た」だけで、signal の sign すら time に依存して反転する noise の典型 だった。

OOS でいいスコアが出た時こそ、IS との整合を疑う習慣がついた。整合しなければ、それは「OOS の偶然」を信じすぎているサイン。

まとめ

  • IS-OOS split は最低限のバリデーション
  • walk-forward で時系列 robust に
  • look-ahead bias は features 生成時の timestamp 確認で防ぐ
  • OOS の結果を見て IS パラメータを直すのは circular reasoning (= 効果的に再過学習)
  • 上級: CPCV で label leakage まで防ぐ

次回は、backtest を Monte Carlo で再シミュレーションしたのに live で出ない、なぜか。iid 仮定が消す時間構造 を扱う。

参考文献

  • Lopez de Prado, M. (2018). Advances in Financial Machine Learning. Wiley. Ch. 6, 7.
  • Pardo, R. (2008). The Evaluation and Optimization of Trading Strategies. Wiley.
  • Bailey, D.H., Lopez de Prado, M. (2014). The Deflated Sharpe Ratio. Journal of Portfolio Management, 40(5), 94-107.
  • Aronson, D. (2006). Evidence-Based Technical Analysis. Wiley.
  • Wikipedia, “Walk forward optimization”.

コメントする