top of page

如何避免深度學習Overfitting

  • 4分钟前
  • 讀畢需時 13 分鐘

在足球數據分析和博彩市場預測之中,Deep Learning 經常被包裝成一種近乎萬能的技術。只要把大量歷史賽果、球隊數據、球員數據和賠率資料輸入模型,系統就好像可以自動找出勝率最高的方向。但真正做過預測模型的人都明白,模型能力愈強,風險亦愈高;其中最核心的風險,就是 Overfitting

所謂 Overfitting,簡單來說,就是模型不是學懂了足球比賽背後的規律,而只是「記住」了歷史數據中的噪音。它在回測中可以表現得非常漂亮,但一到真實市場、未來賽事、不同聯賽環境、不同賠率結構,表現便會明顯下降。對於任何以長期回報為目標的預測系統而言,Overfitting 不是小問題,而是足以令整個策略失效的根本風險。

重要聲明:本文從資料科學、機器學習工程與風險管理角度說明模型設計原理,並附帶示範代碼供技術參考,不構成投注建議或保證回報。博彩受法律、年齡限制、平台條款與負責任博彩規範約束。

AIP 系統採用 Deep Learning、機器學習及足球大數據分析技術,但核心設計理念並不是單純追求最高的回測命中率,而是透過多層風險控制、數據分割、特徵約束、模型驗證及市場校準,盡量減少 Overfitting,提升模型在真實投注環境中的泛化能力(generalization)。以下十四個部分,會逐一拆解具體做法,並附上可運行的示範代碼與數學說明,方便有技術背景的讀者對照。


一、Overfitting 的本質:Bias-Variance Tradeoff 與訊噪比

要理解 Overfitting,先要理解機器學習其中一條最基本的分解式:

Expected Error = Bias^2 + Variance + Irreducible Error

Bias 反映模型本身太簡單,學不到真正規律;Variance 反映模型太敏感,連噪音都一併學走;Irreducible Error 是足球比賽本身無法消除的隨機性,例如十二碼、VAR、傷停時間的偶然入球。足球數據的訊噪比(signal-to-noise ratio)本身偏低,一個賽季一支球隊只有 30–40 場比賽,這代表可用「有效樣本」遠比表面數據列數少,模型容量(capacity)一旦超出這個上限,Variance 就會迅速主導誤差。

以下用一個與足球評分同構的簡化例子說明:用不同複雜度的多項式擬合一組帶噪音的資料,觀察 train 與 test 誤差如何隨複雜度分歧。

import numpy as np
from sklearn.metrics import mean_squared_error

rng = np.random.default_rng(42)

def true_signal(x):
    return 0.6 * x + 0.15 * np.sin(3 * x)

n_train, n_test = 60, 400
x_train = rng.uniform(-3, 3, n_train)
x_test = rng.uniform(-3, 3, n_test)

noise_std = 0.5  # 模擬足球賽果標籤中偏高的隨機噪音
y_train = true_signal(x_train) + rng.normal(0, noise_std, n_train)
y_test = true_signal(x_test) + rng.normal(0, noise_std, n_test)

for degree in [1, 3, 6, 10, 15]:
    coeffs = np.polyfit(x_train, y_train, degree)
    train_pred = np.polyval(coeffs, x_train)
    test_pred = np.polyval(coeffs, x_test)
    train_rmse = mean_squared_error(y_train, train_pred) ** 0.5
    test_rmse = mean_squared_error(y_test, test_pred) ** 0.5
    print(f"degree={degree:>2} | train_rmse={train_rmse:.3f} | test_rmse={test_rmse:.3f}")

跑完這段代碼會見到一個典型模式:degree 由 1 升到 15,train_rmse 一直下跌,但 test_rmse 在某個複雜度之後反而回升。這條「train 愈好、test 愈差」的分叉線,正正就是 Overfitting 的數學本質——AIP 系統所有防禦措施,最終都是圍繞著怎樣把這個分叉點推得愈遠愈好。


二、學習目標唔止賽果:用 Process Data 對抗結果噪音

如果一個模型只用「勝、和、負」或「大、小」作為訓練目標,表面上很直接,但其實非常容易 Overfitting。足球比賽的最終賽果本身包含大量隨機性,例如紅牌、十二碼、補時入球、門將失誤、VAR 判決、臨場天氣、球員傷出等。這些事件會改變比賽結果,但未必代表賽前判斷本身錯誤。

AIP 系統在建立模型時,不會只看最終比數,而會更重視過程數據和質量數據,例如 Expected Goals(xG)、攻勢質量、射門位置、入球機會創造、攻防轉換效率、控球推進、對手壓迫強度、賽程密度、主客場差異、歷史對賽結構,以及市場賠率變化。

若模型只學習賽果,例 1 的球隊會被錯誤標記為「弱勢」,例 2 的球隊會被錯誤標記為「強勢」;但若模型同時理解 xG、射門質量和進攻結構,便較能分辨「結果」與「過程」之間的差異。工程上,這通常以 multi-task learning 實現:主任務預測賽果概率,輔助任務同時預測 xG 差、控球優勢等連續變量,讓網絡在共享表徵層學到更貼近比賽本質的特徵,而不是單純記住標籤。


三、時間結構分割與 Walk-Forward Testing

在一般機器學習訓練中,很多人會把數據隨機分成 training set、validation set 和 test set。這種做法在某些領域可行,但在足球預測中,如果處理不當,很容易產生 data leakage

足球數據具有明顯的時間順序。模型預測未來賽事時,理論上不應該接觸未來資料。如果把同一賽季甚至相近時間的賽事隨機打散,模型可能間接學到未來資訊,例如球隊後期狀態、教練更換後的結果、球員傷停影響,甚至某些賠率調整後才出現的市場反應。這樣的回測成績會被高估,因為模型其實已經「偷看」了未來。

AIP 系統在驗證模型時,會採用 time-based splitwalk-forward testing:用過去的數據訓練模型,再用較後時間的賽事作測試,盡量模擬真實預測環境。

import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import log_loss

matches = pd.read_csv("matches.csv", parse_dates=["match_date"]).sort_values("match_date")

feature_cols = [
    "home_xg_form5", "away_xg_form5",
    "home_rest_days", "away_rest_days",
    "market_implied_home",
]
label_col = "home_win"
seasons = sorted(matches["season"].unique())

results = []
for i in range(3, len(seasons)):
    train_seasons, test_season = seasons[:i], seasons[i]
    train_df = matches[matches["season"].isin(train_seasons)]
    test_df = matches[matches["season"] == test_season]
    if train_df.empty or test_df.empty:
        continue

    model = GradientBoostingClassifier(max_depth=3, n_estimators=200, learning_rate=0.03)
    model.fit(train_df[feature_cols], train_df[label_col])

    proba = model.predict_proba(test_df[feature_cols])[:, 1]
    loss = log_loss(test_df[label_col], proba)
    results.append({"test_season": test_season, "n_train": len(train_df), "log_loss": round(loss, 4)})

print(pd.DataFrame(results))

留意這裡刻意不使用 train_test_split(shuffle=True)。若把所有年份混合後再隨機分割,模型可能「偷看」到 2025 年球員轉會後的狀態去預測 2023 年的比賽,回測數字會漂亮得不真實。上面的 expanding-window 寫法,令每一個測試 season 只能用之前的資料訓練,比隨機切分更嚴格,也更接近實戰。


四、選擇性出手:信心與市場價值先於出貨量

Overfitting 其中一個常見表現,是模型對太多賽事都給出過度自信的判斷。尤其在博彩市場中,如果模型每一場都能輸出一個方向,表面看似產量高,但其實很多時只是把低信心訊號包裝成推介。

AIP 系統的做法並不是追求最多場次,而是讓模型在賽事數據、盤口條件、市場價格和統計優勢同時達標時,才篩選出具備較高 value 的入場位置。足球市場有很多賽事其實不適合模型判斷:冷門盃賽數據不足、友誼賽輪換不確定性太高、低組別聯賽資訊透明度不足、臨場陣容變化過大,或市場盤口本身已充分反映風險。在這些情況下強行輸出推介,反而會增加噪音。

AIP 系統重視的是長期 expected value,而不是短期推介數量。當沒有足夠 edge 時,不出手本身就是一種風險管理。


五、控制模型複雜度:Regularization  技術

Deep Learning 的一個常見誤區,是以為模型愈大、層數愈深、參數愈多,預測能力就一定愈好。但足球賽事的數據量、訊號質素和市場效率本身都有上限。若模型容量遠超有效訊號量,它就很容易把偶然關係、歷史特殊情況和市場短期偏差當成穩定規律。

AIP 系統在模型設計上,會控制神經網絡的複雜度,並配合三種常用 regularization 技術:dropoutweight decayearly stopping,以及特徵重要性監控。

import torch
import torch.nn as nn

class MatchOutcomeNet(nn.Module):
    def __init__(self, n_features, hidden=32, dropout=0.3):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(n_features, hidden),
            nn.ReLU(),
            nn.Dropout(dropout),
            nn.Linear(hidden, hidden // 2),
            nn.ReLU(),
            nn.Dropout(dropout),
            nn.Linear(hidden // 2, 1),
        )

    def forward(self, x):
        return self.net(x)

model = MatchOutcomeNet(n_features=24)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
criterion = nn.BCEWithLogitsLoss()

best_val_loss, patience, patience_counter = float("inf"), 8, 0

for epoch in range(200):
    model.train()
    optimizer.zero_grad()
    loss = criterion(model(X_train_tensor), y_train_tensor)
    loss.backward()
    optimizer.step()

    model.eval()
    with torch.no_grad():
        val_loss = criterion(model(X_val_tensor), y_val_tensor).item()

    if val_loss < best_val_loss - 1e-4:
        best_val_loss, patience_counter = val_loss, 0
        best_state = {k: v.clone() for k, v in model.state_dict().items()}
    else:
        patience_counter += 1
        if patience_counter >= patience:
            print(f"Early stopping at epoch {epoch}")
            break

model.load_state_dict(best_state)

Dropout 在訓練時隨機關閉部分神經元,逼使網絡不能依賴單一路徑記住個別比賽;weight_decay(即 L2 regularization)懲罰過大的權重,令模型偏好較平滑的函數;patience 機制則在驗證誤差連續多個 epoch 沒有改善時停止訓練,避免模型繼續在訓練集上「死記」。三者合力,等於把上一節那條 train/test 分叉線的分叉點推遲。

例如某一季某支球隊在主場入球特別多,模型不能簡單把「主場」和「入球大」建立過強關係,因為這可能只是由當季前鋒狀態、賽程安排或幾場大比數所造成。Regularization 的作用,就是抑制模型對這類短期特殊情況過度反應。


六、Feature Engineering 先於 Deep Learning

Deep Learning 可以自動學習複雜關係,但這不代表 feature engineering 不重要。相反,在足球預測這類高噪音市場中,輸入特徵的質量往往比模型本身更重要。如果輸入資料本身充滿噪音、重複、偏差或不可持續訊號,即使使用最先進的 neural network,模型也只會更快、更精細地學錯方向。

經過調整後的 chance creation trenddefensive pressure resistancetransition efficiency,比表面數字更有機會成為跨賽季延續的穩定訊號。AIP 系統的重點,是把足球本身的邏輯轉化成模型可以理解的結構,而不是把原始數字無差別丟給模型。


七、多模型架構與 Ensemble:用分散降低單一模型偏差

單一模型即使回測表現良好,也可能有其盲點。某類模型較擅長捕捉入球大細,另一類模型較擅長分析讓球盤,亦有模型對強弱懸殊的賽事較敏感,但在均勢盤中表現未必穩定。

因此,AIP 系統透過多模型架構和 ensemble 思維,綜合不同角度的訊號。部分模型負責評估球隊基本面,部分模型負責捕捉市場價格偏差,部分模型負責處理近期狀態與賽程因素,亦有模型會針對特定盤口類型作校準。

import numpy as np

def ensemble_probability(model_probs: dict[str, float], weights: dict[str, float]) -> float:
    total_weight = sum(weights.values())
    weighted_sum = sum(model_probs[name] * weights[name] for name in model_probs)
    return weighted_sum / total_weight

probs = {"fundamentals_model": 0.58, "market_bias_model": 0.51, "form_model": 0.55}
weights = {"fundamentals_model": 0.4, "market_bias_model": 0.35, "form_model": 0.25}

print(round(ensemble_probability(probs, weights), 4))

Ensemble 有效的前提是各模型的錯誤不完全相關——若三個模型都在同一類比賽犯同一方向的錯,加權平均只會放大偏差,而不會抵消。因此 AIP 在設計上會刻意讓子模型使用不同特徵集、不同訓練窗口甚至不同算法(例如 gradient boosting 對比 neural network),確保分散真正存在。只有當多個獨立訊號同時支持同一方向,而市場價格又仍然提供足夠 value 時,系統才會傾向輸出推介。


八、市場賠率是校準基準:Implied Probability 與 Value Bet

很多人誤以為 AI 足球預測就是「模型覺得邊隊會贏」,然後直接下注。但在真正的博彩分析中,問題不是單純判斷哪個結果機率最高,而是判斷市場價格是否低估或高估了某個結果。

十進制賠率下,隱含機率(implied probability)為 1 / odds。以下用具體數字說明「高機率」不等於「有 value」:

def implied_probability(decimal_odds: float) -> float:
    return 1.0 / decimal_odds

def expected_value(model_prob: float, decimal_odds: float, stake: float = 1.0) -> float:
    payout_if_win = stake * (decimal_odds - 1.0)
    return model_prob * payout_if_win - (1.0 - model_prob) * stake

def kelly_fraction(model_prob: float, decimal_odds: float) -> float:
    b = decimal_odds - 1.0
    edge = model_prob * b - (1.0 - model_prob)
    return max(edge / b, 0.0)

print(expected_value(0.45, 2.86))   # 正 EV
print(kelly_fraction(0.45, 2.86))   # 建議注碼比例(未計安全係數)

AIP 系統會將模型機率與市場 implied probability 作比較,重點不是「命中率最高」,而是「是否具備正期望值」。這正是避免 Overfitting 的關鍵,因為模型若只追求預測結果,很容易偏向熱門、低賠率、表面穩陣的選項;但長期回報真正取決於機率與價格之間的差距。市場賠率本身包含傷停、資金流向、莊家風控、公開消息和市場情緒等集體資訊,AIP 不會盲目否定市場,而是把市場視為一個需要被比較、校準和評估的基準。


九、命中率與回報率分開睇:EV、ROI 與 Drawdown

在足球博彩預測中,如果模型只以命中率作訓練或優化目標,很容易產生偏差。它可能傾向選擇熱門盤、低波動方向,令回測看起來穩定,但實際期望值並不理想。這種情況其實也是一種策略層面的 Overfitting,因為模型只是適應了歷史樣本中較容易命中的選項,而不是學懂如何尋找被市場錯價的機會。

AIP 系統會將 hit rateodds levelexpected valuerisk-reward ratiodrawdown 風險分開觀察。真正專業的分析系統,必須接受短期有輸有贏,重點不是每一場都準,而是在足夠樣本之下,是否能夠持續捕捉被市場低估的機會。


十、跨聯賽與盤口類型的穩定性監察

Overfitting 不一定只出現在整體模型層面,也可能出現在特定聯賽、特定賠率區間或特定盤口類型中。例如模型可能在歐洲主流聯賽表現穩定,但在低組別聯賽失效;亦可能在入球大細盤具備優勢,但在讓球盤較不穩定。

AIP 系統不會只看整體回測結果,而會進一步拆分主流聯賽與冷門聯賽、盃賽與聯賽、強弱懸殊與均勢對賽、早盤與臨場盤、讓球盤與入球大細盤等,判斷模型的優勢是否真正穩定,而不是由少數場景拉高整體表現。若某些聯賽或盤口類型的表現不穩定,系統便需要降低其權重,甚至在該類場景中減少輸出推介。


十一、唔追短期結果:統計顯著性與樣本量

除了 Overfitting 歷史數據,另一個常見問題是 overreacting to recent results。當模型短期連續失準時,很容易產生衝動想立即大幅調整參數;但如果調整過度,系統便可能只是追逐最近幾場的噪音。

足球結果有天然波動。即使一個具備正期望值(真實勝率 75%)的策略,短期樣本亦可能出現遠低於 75% 的命中率。以下用二項分佈計算信賴區間說明:

from scipy import stats

n_games = 30
true_edge_prob = 0.75

low, high = stats.binomtest(int(n_games * true_edge_prob), n_games, p=true_edge_prob).proportion_ci(
    confidence_level=0.95
)
print(f"n={n_games} 時,觀察命中率 95% 信賴區間大約落在 [{low:.1%}, {high:.1%}]")

即使真實勝率固定在75%,在僅得 30 場的樣本下,觀察到的命中率仍可能大幅偏離這個數字——單靠幾場輸波就斷定「模型壞咗」,本身就是一種統計上的誤判。AIP 系統在優化模型時,會區分「正常波動」與「結構性失效」:若只是短期 variance,系統不應過度反應;但如果某類市場、某種盤口或某些數據特徵持續失效,才需要進一步檢查和調整。這種做法與量化交易十分相似——成熟的策略管理不是見輸就改,而是用足夠樣本、合理統計檢驗和風險指標去判斷策略是否仍然有效。


十二、資料質素:Garbage In, Garbage Out

再先進的 Deep Learning 模型,也無法彌補低質量數據帶來的問題。足球數據常見問題包括資料缺漏、不同供應商定義不一致、球員傷停更新延遲、陣容資訊不完整、賽事延期、盤口異常跳動、低流動性市場報價失真等。

若這些資料未經處理便直接輸入模型,系統便可能學到錯誤訊號。例如某些比賽盤口變化並非因為真實市場共識,而是因為流動性太低;某些冷門賽事的統計數據樣本不足,不能與主流聯賽等量齊觀。AIP 系統會在數據進入模型前進行清洗、標準化、異常檢測和可信度評估——這是系統穩定性的基礎,也是 Deep Learning 真正發揮價值的前提。


十三、機率校準(Calibration):唔止睇分類結果

一個預測模型不應只告訴我們「大」或「小」、「主隊」或「客隊」,更重要的是它估算的機率是否可靠。如果模型認為某方向有 75% 機會,但長期實際只發生 52%,這代表模型的 probability calibration 有問題;即使命中率看起來不差,在投注決策上仍可能造成嚴重誤判。

from sklearn.calibration import calibration_curve
from sklearn.isotonic import IsotonicRegression
from sklearn.metrics import brier_score_loss

model_prob = model.predict_proba(X_test)[:, 1]
actual = y_test.values

print("Brier score(校準前):", round(brier_score_loss(actual, model_prob), 4))

mean_pred, frac_pos = calibration_curve(actual, model_prob, n_bins=10)
for bucket_pred, bucket_actual in zip(mean_pred, frac_pos):
    print(f"predicted={bucket_pred:.2f} | actual={bucket_actual:.2f}")

iso = IsotonicRegression(out_of_bounds="clip")
calibrated_prob = iso.fit_transform(model_prob, actual)
print("Brier score(校準後):", round(brier_score_loss(actual, calibrated_prob), 4))

calibration_curve 會把預測機率分成若干個 bucket,比較每個 bucket 的平均預測機率與實際發生比例;若兩者長期不吻合,代表模型系統性高估或低估某類事件。IsotonicRegression 是常用的事後校準方法,可在不改變模型排序能力的情況下修正機率偏差。

舉例,模型給出入球大 2.5 的機率為 78%,市場賠率反映 62%,表面上看似有 value;但如果模型長期在這類場景中高估入球機率,實際優勢可能根本不存在。因此,校準模型比單純提高分類準確率更重要。這也解釋為何 AIP 不會只用一個簡單的「AI 預測結果」作決策,而是會配合信心區間、盤口價格、歷史校準表現和市場條件進行綜合判斷。


十四、接受不確定性:紀律重於「必勝」幻覺

足球本質上是一個高不確定性的運動。即使數據再完整、模型再先進,也不可能消除所有偶然因素。真正專業的系統,不應該宣稱每一場都能準確預測,而是要誠實面對不確定性,並在不確定性之中尋找長期優勢。

AIP 系統採用 AI 和 Deep Learning 技術,但從不把它包裝成必勝工具。相反,系統更重視風險控制、樣本穩定性、長期回報和策略紀律。模型可以提高分析效率,協助識別市場錯價,但不能改變足球比賽本身存在 randomness 的事實。這一點非常重要——如果一個系統追求的是「永不失準」,它很容易走向過度擬合:不斷修正過去錯誤、不斷迎合短期結果、不斷把偶然事件包裝成新規律,最後反而失去泛化能力。


總結:AI、數據與紀律的結合

AI 模型本身只是工具,真正決定系統質素的,是模型如何被設計、驗證、監控和使用。AIP 系統的核心並不是單純使用 Deep Learning,而是將 Deep Learning 放入一個完整的決策框架之中——高質量足球數據、時間序列驗證、特徵穩定性分析、多模型比對、市場賠率校準、風險管理、低質量賽事過濾、樣本外測試,以及對 Overfitting 的持續監察,這些環節共同構成一套更接近實戰環境的分析系統。

在足球預測市場中,真正困難的不是建立一個能在歷史數據中跑出漂亮成績的模型,而是建立一個能在未來市場仍然保持紀律和穩定性的系統。Deep Learning 可以為足球預測帶來更強大的非線性分析能力,處理球隊風格、攻防節奏、盤口變化、數據趨勢和市場定價偏差等複雜互動,但能力愈強,愈需要控制 Overfitting,否則模型只會在歷史中表現優秀,在未來中失去作用。

AIP 系統的目標不是製造一個完美預言機,而是建立一套能夠長期運作、持續校準、抵抗噪音並捕捉正期望值的足球數據分析系統。這亦是「質素重於數量」、「長期回報重於短期輸贏」、「數據紀律重於情緒判斷」的原因所在。真正的 AI 預測,不是比誰的模型更複雜,而是比誰更能在複雜市場中保持清醒、克制和穩定。


Reference

  1. T. Hastie, R. Tibshirani, J. Friedman. The Elements of Statistical Learning: Data Mining, Inference, and Prediction. 2nd ed., Springer, 2009.

  2. N. Srivastava, G. Hinton, A. Krizhevsky, I. Sutskever, R. Salakhutdinov. Dropout: A Simple Way to Prevent Neural Networks from Overfitting. Journal of Machine Learning Research, 15(1), 1929–1958, 2014. https://jmlr.org/papers/v15/srivastava14a.html

  3. A. Niculescu-Mizil, R. Caruana. Predicting Good Probabilities with Supervised Learning. Proc. ICML, 2005.

  4. M. J. Dixon, S. G. Coles. Modelling Association Football Scores and Inefficiencies in the Football Betting Market. Journal of the Royal Statistical Society: Series C (Applied Statistics), 46(2), 265–280, 1997.

  5. M. López de Prado. Advances in Financial Machine Learning. Wiley, 2018.(walk-forward validation 與 backtest overfitting 之工程實踐)

  6. J. L. Kelly Jr. A New Interpretation of Information Rate. Bell System Technical Journal, 35(4), 917–926, 1956.(Kelly criterion 原始論文)

  7. Pedregosa et al. Scikit-learn: Machine Learning in Python. JMLR 12, 2825–2830, 2011. https://jmlr.org/papers/v12/pedregosa11a.html

  8. Scikit-learn documentation. Probability calibration. https://scikit-learn.org/stable/modules/calibration.html

  9. PyTorch documentation. torch.nn.Dropout / AdamW. https://pytorch.org/docs/stable/nn.html



bottom of page