pybaseball 公式戦の区分け

# MLB 2024年シーズンデータ分析：正規シーズン期間の正確な区分けとデータ抽出ガイド

**概要**

MLB（メジャーリーグベースボール）のデータ分析において、統計的な信頼性を確保するためには、「正規シーズン」の期間を正確に定義し、オープン戦（スプリングトレーニング）とポストシーズンを除外することが不可欠です。本ガイドでは、2024年シーズンを例に、公式戦データの適切な抽出方法を、日程構造、データソースの特性、実践的な検証手法、および地域特性まで考慮して詳細に解説します。

**MLBシーズン構造**

MLBの年間スケジュールは、大きく以下の3つの段階に分けられます。

1.  **オープン戦（スプリングトレーニング）**: 2月下旬から3月下旬にかけて行われる、調整および選手評価を目的とした非公式試合。
2.  **レギュラーシーズン（正規シーズン）**: 3月下旬から9月下旬にかけて行われる、全30球団が各162試合を戦う公式戦。
3.  **ポストシーズン**: 10月から11月上旬にかけて行われる、各リーグの優勝チームおよびワイルドカードチームによるトーナメント戦。

データ分析の対象となるのは、**レギュラーシーズン（正規シーズン）** のみです。

**1. オープン戦（スプリングトレーニング）の除外**

*   **期間**: 2024年は2月22日～3月26日（現地時間）
*   **特徴**:
    *   公式戦績には反映されない。
    *   若手選手のテスト、主力選手の調整が主な目的。
    *   投手は短いイニングでの登板が一般的（3イニング以下など）。
    *   実験的な打順や守備位置が試されることが多い。
*   **除外理由**: 選手のパフォーマンスが正規シーズンとは異なるため、データ分析に含めると結果に偏りが生じる可能性がある。

**2. レギュラーシーズン（正規シーズン）の日程と注意点**

*   **期間**:
    *   **全体**: 2024年3月20日～10月1日（現地時間）(ソウルシリーズを含めました)
    *   **分析対象期間**: 2024年3月20日～10月1日 (分析対象期間を長めに設定しました。)

*   **注意点**:
    *   **ダブルヘッダー**: 雨天中止などにより、1日に2試合が行われる場合がある。
    *   **試合の延期・中止**: 天候などにより、試合日程が変更される可能性がある。
    *   **ソウルシリーズ**: 3月20日、21日に韓国で開催される開幕戦。これも正規シーズンに含む。
    *   **ロンドンシリーズ**: 6月8日、9日にイギリスで開催される試合。これも正規シーズンに含む。
    *   **オールスターゲーム**: 7月中旬に開催されるが、これはエキシビションマッチのため、分析対象から除外する。

**3. ポストシーズンの除外**

*   **期間**: 2024年は10月上旬～11月上旬（日程はリーグの勝敗状況により変動）
*   **構成**:
    *   ワイルドカードシリーズ（3戦2勝制）
    *   ディビジョンシリーズ（5戦3勝制）
    *   リーグチャンピオンシップシリーズ（7戦4勝制）
    *   ワールドシリーズ（7戦4勝制）
*   **除外理由**: 短期決戦であり、選手の起用法や戦略が正規シーズンとは大きく異なるため。

**データ抽出：技術的詳細**

正規シーズンのデータを正確に抽出するためには、以下の点に留意する必要があります。

1.  **データソースの選択**:
    *   **Baseball Savant (Statcast)**: MLB公式の詳細データ。`game_type` フィルターを使用可能。
    *   **Retrosheet**: 過去の試合データを含む。`GAME_ID` でフィルタリング可能。
    *   **FanGraphs**: 高度な指標を提供。`season` と `gamelevel` パラメータを使用。

2.  **日付フィルタリング**:

    *   **基本**: 開始日と終了日を指定してデータを抽出。
    *   **タイムゾーン**: 米国東部時間（ET）を基準とするため、日本時間との時差を考慮。
    *   **Python (pybaseball, pandas) での例**:

    ```python
    from pybaseball import statcast
    import pandas as pd
    from pytz import timezone

    # 日本時間で範囲設定
    jst_start = pd.Timestamp('2024-03-20', tz='Asia/Tokyo')
    jst_end = pd.Timestamp('2024-10-01', tz='Asia/Tokyo')

    # 米国東部時間に変換
    est_start = jst_start.tz_convert('US/Eastern')
    est_end = jst_end.tz_convert('US/Eastern')

    # 文字列フォーマット (YYYY-MM-DD)
    start_dt = est_start.strftime('%Y-%m-%d')
    end_dt = est_end.strftime('%Y-%m-%d')

    # Statcastデータ取得
    df = statcast(start_dt=start_dt, end_dt=end_dt)

    # game_typeでフィルタリング (R: Regular Season)
    df_regseason = df[df['game_type'] == 'R']
    ```

3.  **例外処理**:
    *   ダブルヘッダー、試合延期・中止への対応は、データソースごとに異なる。
    *   Baseball Savant では `game_date` と `game_pk` (試合ID) を組み合わせて重複を除去。

**データソース別: 詳細なフィルタリング**

*   **Baseball Savant (Statcast)**:

    ```python
    df_clean = df_regseason[
        (df_regseason['game_date'].between(start_dt, end_dt)) &
        (df_regseason['game_type'] == 'R')
    ]
    ```

    *   `game_type` の有効値:
        *   `S`: スプリングトレーニング
        *   `R`: レギュラーシーズン
        *   `F`: ワイルドカードシリーズ
        *   `D`: ディビジョンシリーズ
        *   `L`: リーグチャンピオンシップシリーズ
        *   `W`: ワールドシリーズ

*   **Retrosheet**:

    ```python
    # 正規シーズンのGAME_IDパターン: 年月日+チームコード
    df_retro = df_retro[
        df_retro['GAME_ID'].str.match(r'^2024(03|04|05|06|07|08|09|10)\d{5}') #2024年3月から10月まで
        ]
    ```

*   **FanGraphs**:

    ```python
    from fangraphs import api

    params = {
        'season': 2024,
        'gamelevel': 'Majors',  # マイナーリーグ除外
        'startdate': start_dt,
        'enddate': end_dt
    }
    data = api.get('leaders', params=params)
    ```

**データ検証: 品質チェック**

抽出したデータが正確であることを確認するために、以下の検証を行います。

1.  **試合数**:

    *   理論値: 30球団 × 162試合 ÷ 2 = 2430試合
    *   抽出データの試合数が理論値と一致することを確認。

    ```python
    total_games = df_regseason['game_pk'].nunique()
    assert total_games == 2430, f"試合数不一致: {total_games}" #ソウルシリーズとロンドンシリーズ含めると2430試合にはならない可能性がある。
    ```

2.  **日付範囲**:
    *   月ごとの試合数分布を確認し、オープン戦とポストシーズンの期間に試合が含まれていないことを確認。

3.  **投球数 (サンプリング)**:
    *   3月と4月の平均最大投球数を比較し、オープン戦の影響がないことを確認（4月以降の方が多くなるはず）。

**地域特性と注意点**

*   **ドーム球場**: 天候の影響を受けにくいが、それ以外の球場では天候による試合延期・中止が発生しやすい。
*   **寒冷地**: 3-4月は寒冷な地域（例: ミネソタ）では、試合延期のリスクが高い。
*   **サマータイム**: 3月第2日曜日に開始。日本との時差が1時間変わる（14時間→13時間）。

**応用分析 (例)**

1.  **開幕戦**:

    ```python
    df_opening = df_regseason[
        df_regseason['game_date'].between('2024-03-20', '2024-03-24') #ソウルシリーズを含めた開幕
    ]
    ```

2.  **月別成績**:

    ```python
    df_monthly = []
    for month in range(3, 11): #3月から10月まで
        start = f'2024-{month:02d}-01'
        end = f'2024-{month:02d}-{pd.Timestamp(start).days_in_month}' #月末
        df_month = df_regseason[df_regseason['game_date'].between(start, end)]
        df_monthly.append(df_month)
    ```

3.  **特定チームのホームゲーム**:

    ```python
    df_team_home = df_regseason[
        (df_regseason['home_team'] == 'NYY') &  # 例: ニューヨーク・ヤンキース
        (df_regseason['game_type'] == 'R')
    ]
    ```

**結論(改訂)**

MLB 2024年シーズンの正規シーズンデータ抽出は、**2024年3月20日から10月1日**（現地時間）を対象とし、`game_type='R'` でフィルタリングすることが基本です。日本時間での分析では、データソースのタイムゾーン設定を確認し、必要に応じて変換を行います。データ抽出後は、試合数、日付範囲、投球数などの検証を行い、データの品質を確保することが重要です。さらに、地域特性やサマータイムなども考慮し、より詳細な分析を行うことができます。