0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は Zenn に投稿したものの再掲です。初出: 過学習は「特徴量を減らせば直る」——それ、嘘でした

系列トレードの検証で踏む罠を扱う連載の第4回(山場)です。第1回(未来参照バグ)・第2回(特徴量リーク)・第3回(ライブ/BT乖離)の続きです。

前回までの3回で、検証は信用できるものになりました。時間の漏れ(第1回・未来参照)も情報の漏れ(第2回・特徴量リーク)もなく、ライブとの差も説明できる(第3回)。武器は揃った。

その正しい検証ハーネスで、いよいよパラメータ探索を回します。そして——それでも過学習します。

ここからが本題です。敵はもう、データの中にもコードの中にもいません。探索のやり方と、評価の構造の中にいます。このシリーズの山場、過学習との戦いです。

なぜ相場のMLはこれほど過学習するのか

まず、相場のMLが構造的に過学習しやすい理由を3つ。

  1. 低いシグナル/ノイズ比。 値動きはほとんどがノイズです。柔軟なモデルは、わずかなシグナルではなく、大量のノイズの方を覚えます
  2. 非定常(レジーム変化)。 過去に効いた関係が、未来も効く保証がない。学習した相関が賞味期限切れになります
  3. 探索による多重検定。 これが一番効きます。多数の設定を試して「検証で一番良かったもの」を選ぶと、その"一番"には必ず運が混じります

3番目が本記事の中心です。でもその前に、多くの人(私も含む)が最初に試して、そして裏切られる対策の話をします。

一番効かなかった対策:特徴量削減

直感はこうです。「特徴量が多い→モデルの自由度が高い→過学習する。だから特徴量を減らせばいい。」

私もそう考えて、特徴量を大きく削りました(仮に40個から15個へ)。過学習は、これで確実に減るはずだった。

結果は——ほとんど減りませんでした。

これは、当時いちばん重要な発見でした。もしモデルの容量(自由度)が過学習の主犯なら、容量を削れば効くはずです。効かなかったということは、主犯は特徴量の数ではないということ。

過学習の源は、モデルの容量よりも、評価の構造と探索のプロセスの側にありました。これが分かると、「正則化を強める」「特徴を減らす」「木を浅くする」といった容量いじりが、なぜ限定的にしか効かないのかが腑に落ちます。すべて対症療法だからです。真犯人は別にいます。

本当の敵:探索そのもの(選択バイアス)

多数の設定を検証で評価し、最良を選ぶ。この「選ぶ」行為そのものが過学習を生みます。

コインを100人に投げさせれば、10連続で表を出す人が必ず現れます。その人を「表を出す才能がある」と採用するのが、素朴なパラメータ探索です。選ばれた設定の検証スコアは、真の実力より楽観的に偏ります。試行回数が増えるほど、偶然の勝者が生まれやすくなる。これが多重検定・選択バイアスです。

だから、こう認識を改める必要があります。

検証スコアが良いこと自体は、もう証拠になりません。

必要なのは「その良さが運ではない」ことを示す仕組みです。以下、その仕組みを装置として重ねていきます。

対策の体系:運を無効化する装置を重ねる

1. 正しい時間評価(walk-forward + purge/embargo)

第2回の続きです。時系列を尊重した分割で、学習と検証が未来を跨がないようにする。重なるラベルはpurgeし、境界にembargoを置く。ここが崩れていると、以降の装置は全部無意味になります。土台です。

2. 一度も触っていないホールドアウト

探索にもチューニングにも一度も使わない最終区間を確保します。すべての探索が終わった後、その区間で初めて「本番相当」を測る。

# 探索・チューニング中は絶対に参照しない
holdout = data[data.index >= HOLDOUT_START]
search_pool = data[data.index < HOLDOUT_START]
# ...全ての探索が終わってから、最後に一度だけholdoutで評価する

鉄則は、探索中に一度でも覗いたら、それはもうホールドアウトではないこと。「ちょっとだけ見て調整」を許した瞬間、ホールドアウトは汚染されます。

3. 複数指標の同時ゲート

単一の数字で合否を決めない。これが効きます。たとえば「正規化したPnL」と「素のPnL」の両方が同時に条件を満たすことを要求する。

# 片方の指標だけで合格にしない。複数の独立な指標の同時通過を要求する
passed = (holdout["pnl_normalized"] >= 0) and (holdout["pnl_raw"] >= 0)

片方の指標だけで良く見える設定は、その指標に過適合しているだけのことが多い。独立な複数の物差しを同時に満たす設定は、運だけでそこに到達しにくくなります。ゲートを増やすほど、偶然の通過は難しくなる。

4. 異常値の無効化

「プロフィットファクターが異常に高い × 取引数が極端に少ない」は、勝利ではなくノイズです。これを採用候補から積極的に外します。

def score_stats(stats):
    # 取引数が少なすぎる結果は統計的に無意味なので無効化
    if stats["trades"] < MIN_TRADES:
        return -np.inf
    # PFが異常に高い × 取引数が少ない = 偶然のヒット。採用しない
    if stats["pf"] >= PF_CAP and stats["trades"] < LOW_TRADE_GUARD:
        return -np.inf
    return stats["score"]

好成績を「無効化する」ロジックをわざと書く、という発想が肝です。探索は放っておくと必ずこういう偶然のヒットを拾い上げるので、こちらから先回りして潰します。

5. 取引数の下限

上と重なりますが独立に重要です。数件の取引で出た好成績は、統計的に何も言っていません。最低試行回数を満たさない設定は、そもそも評価の土俵に上げない。

6. サンプル重みで偏りを均す

特定の時間帯やレジームだけに過適合して勝っている場合、その領域のサンプル重みを段階的に調整し、一部の局面に頼った勝ちを抑えます。「全体で薄く勝つ」方向へ寄せることで、特定局面への依存を減らせます。

マインドの転換(ここが核心)

ここが、このシリーズ全体で一番伝えたいことです。過学習対策の本質は、テクニックの寄せ集めではありません。目的の再定義です。

  • 最良パラメータを探すのをやめる。頑健性を証明する作業に切り替える。 探索は「一番良いのはどれか」を探す営みではなく、「運に頼らず安定して条件を満たすのはどれか」を探す営みになります
  • 合格基準は固定する。動かさない。 成績が基準に届かないとき、基準を下げて通すのは自分を騙す行為です。上げるべきは基準ではなく、トレードの質の方
  • 対症療法より根本原因。 「正則化を上げたら過学習が減った」で満足しない。なぜ過学習していたのか(多重検定か、リークか、レジーム依存か)を突き止める。特徴量削減が効かなかった話は、まさにこの姿勢から生まれました
  • 結論の前に、定量的な証拠。 「たぶん効いた」で採用しない。ホールドアウトの数字と、複数指標での一致を要求する

この4つは、私が開発の最初期から一貫して守っている原則です。派手なモデルより、この規律の方が、システムの生死を分けました。

まとめ

  • 相場のMLが過学習する構造的理由は、低S/N・非定常・多重検定
  • 「特徴量を減らせば直る」は限定的にしか効かない。主犯はモデルの容量ではなく、評価構造と探索
  • 本当の敵は探索の選択バイアス。検証スコアが良いこと自体は、もう証拠にならない
  • 対策は装置を重ねる:正しい時間評価/触らないホールドアウト/複数指標ゲート/異常値の無効化/取引数の下限/サンプル重み
  • 核心は目的の再定義——最良を探すのをやめ、頑健性を証明する

ここまでの4回で、検証が嘘をつく主要なパターン(時間の漏れ・情報の漏れ・ライブ乖離・過学習)を潰してきました。シリーズの背骨は、これで通りました。

次回は箸休めに、これまで何度も顔を出した「タイムスタンプとタイムゾーン」——地味なのに何日も溶かす、あの罠を単独で掘り下げます。


質問や「うちはこの装置で過学習を止めた」という話があればコメントで。連載として、検証が嘘をつくパターンを順に潰してきました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?