戦略・検証

カーブフィッティング(過剰最適化)とは?その好成績を疑うべき5つの兆候


※本記事にはアフィリエイト広告(プロモーション)が含まれています。

バックテストでパラメータを調整していると、ある設定で突然「勝率70%、プロフィットファクター1.8」のような好成績が出ることがあります。嬉しい反面、「これは本当に機能する戦略なのか、それともたまたま過去データに合わせ込んだだけなのか」という不安もつきまといます。この記事では、その不安の正体である**カーブフィッティング(過剰最適化)**を見分けるための着眼点を整理します。

カーブフィッティングとは何か

カーブフィッティングとは、戦略のパラメータを過去データに合わせ込みすぎた結果、そのデータ区間だけで異常に良い成績が出るものの、未来のデータや別の区間ではまったく機能しなくなる現象です。バックテストの罠についての記事で触れたように、わずかにデータ期間をずらすだけで成績が大きく崩れるのは、この典型的な症状です。

本質的な問題は「パラメータを調整すること自体」ではなく、調整の過程で、ノイズ(その区間特有の偶然の値動き)にまで合わせ込んでしまうことにあります。ノイズに合わせたパラメータは、同じノイズが二度と起きない以上、未来では意味を持ちません。

なぜ起きるのか:パラメータ数とデータ量のバランス

過剰最適化が起きやすいかどうかは、おおまかに「パラメータの自由度」と「データの情報量」のバランスで決まります。

例えば移動平均の期間を1つだけ調整するのと、移動平均期間・RSIのしきい値・ストップロス幅・テイクプロフィット幅・フィルター条件……と5つ6つのパラメータを同時に調整するのとでは、後者のほうが「たまたま過去データに合う組み合わせ」を見つけてしまう確率がはるかに高くなります。

さらに、1時間足のローソク足を2年分集めても、見た目のデータ数は多くても、相場の「レジーム(トレンド・レンジなどの地合い)」で見れば実質的に数パターンしか経験していない、ということもあります。パラメータ数に対してデータの情報量が不足している状態が、過剰最適化の土台になります。

兆候1: パラメータの数がデータ量に対して多すぎる

目安として、調整するパラメータが増えるほど、それを支えるのに必要なデータ量(期間・資産数)も増えます。数ヶ月〜1年程度のデータで5つ以上のパラメータを同時に最適化している場合は、過剰最適化を疑う材料になります。移動平均クロス戦略の検証記事のように、パラメータを少数に絞ったシンプルな戦略から検証を始めるのは、この問題を小さくする意味でも有効なアプローチです。

兆候2: パラメータをわずかに変えると結果が大きく変わる

本当に機能している戦略は、パラメータを多少変えても成績がなめらかに変化するはずです。逆に、パラメータをわずかにずらした途端に成績が崩壊するなら、その「最良の組み合わせ」はピンポイントでノイズに当たっていた可能性が高いです。

これはパラメータの組み合わせを格子状に試す「感度分析」で確認できます。考え方を示す簡単な例です。

import pandas as pd
from itertools import product

def run_backtest(ohlcv: pd.DataFrame, short_window: int, long_window: int) -> dict:
    """自前のバックテスト関数。指標を一例として返す想定。"""
    # 実際の発注シミュレーションロジックはここに実装する
    ...
    return {"profit_factor": ..., "win_rate": ..., "trades": ...}

short_candidates = range(5, 30, 5)
long_candidates = range(30, 120, 10)

results = []
for short_w, long_w in product(short_candidates, long_candidates):
    if short_w >= long_w:
        continue
    metrics = run_backtest(ohlcv_df, short_w, long_w)
    results.append({"short": short_w, "long": long_w, **metrics})

summary = pd.DataFrame(results)
heatmap = summary.pivot(index="short", columns="long", values="profit_factor")
print(heatmap)

出力されるヒートマップ(heatmap)の中で、良い成績のセルが一つだけ孤立して飛び出しているなら過剰最適化を疑うべきサインです。逆に、近い設定のセルがなめらかに似た値を示す「高台」のような形になっているなら、その付近の設定は構造的に機能している可能性が高くなります。

兆候3: イン-サンプルとアウト-オブ-サンプルの差が大きい

パラメータを決めるのに使ったデータ区間(イン-サンプル)での成績と、それ以外の未使用データ区間(アウト-オブ-サンプル)での成績を比べることも欠かせません。前者だけが異常に良く、後者では平凡またはマイナスになるなら、過剰最適化の典型的なパターンです。この検証を体系的に行う方法はウォークフォワード検証の実装記事で解説しています。

兆候4: 「なぜ効くのか」をロジックで説明できない

統計的に良い数字が出ていても、「なぜこの条件で勝てるのか」を市場の構造や参加者の行動から説明できないなら注意が必要です。例えば「ボラティリティが拡大した方向にはしばらく勢いが続きやすい」というブレイクアウトの考え方には、トレンドフォロワーの追随や踏み上げといった一定の説明がつきます。一方、「なぜか火曜日の午前3時だけ成績が良い」のような条件は、説明がつかない時点でノイズに合わせ込んだ可能性を強く疑うべきです。

兆候5: 取引コストを抜いた成績でしか勝てていない

取引コストが戦略の成績に与える影響についての記事で触れたように、手数料やスリッページを含めると成績は必ず悪化します。コスト抜きのバックテストでようやく勝てている戦略は、実運用のコストを乗せた途端にマイナスへ転じるケースが多く、これも過剰最適化と合わせて確認しておきたいポイントです。

過剰最適化を避けるための実務的な工夫

  • パラメータの数を可能な限り絞り、増やすたびに「本当に必要か」を自問する
  • 複数の資産・複数の期間でも同じ傾向が出るかを確認する
  • アウト-オブ-サンプルのデータは何度も見返さず、最終確認として一度だけ使う
  • 感度分析でパラメータ周辺の成績がなめらかかどうかを必ず確認する
  • 手数料・スリッページを含めた成績で評価する

いずれも地味な作業ですが、「本番で崩れない戦略」を選ぶためには、好成績の数字そのものより、その数字がどう作られたかを確認する手間のほうが重要になります。

まとめ

  • カーブフィッティングとは、過去データのノイズにまで合わせ込んでしまい、未来では機能しなくなる状態
  • パラメータ数がデータ量に対して多すぎると過剰最適化が起きやすい
  • パラメータをわずかに変えて結果が大きく崩れるなら、良い成績はノイズに当たっていた可能性が高い
  • イン-サンプルとアウト-オブ-サンプルの成績差、ロジックの説明可否、コスト込みでの成績も合わせて確認する
  • パラメータを絞り、複数資産・複数期間で検証し、アウト-オブ-サンプルは一度だけ使うのが実務上の基本

好成績のバックテスト結果を見たときほど、一度立ち止まってこれらの兆候を確認する価値があります。