機械学習の根本的な問題
Il バイアスと分散のトレードオフ その理由を理解することが最も重要な概念です ML モデルが機能するか失敗するか。各モデルには 2 つの誤差の原因があります。 バイアス (同じくらい モデルの仮定は現実から逸脱しています)、そして 分散 (モデルはいくらですか トレーニングデータの変動に敏感です)。目標は、最適なバランス ポイントを見つけることです。
L'過学習 モデルがノイズを含むトレーニング データを保存するときに発生します。 トレーニング セットでは優れたパフォーマンスが得られますが、新しいデータではパフォーマンスが低下します。ザ」フィッティング不足 モデルが単純すぎてデータ内の実際のパターンを捉えることができない場合に発生します。認識する そして、これらの問題を解決することは、ML で最も価値のあるスキルの 1 つです。
この記事で学べること
- バイアスと分散のトレードオフとその診断方法
- 過学習と過小学習の兆候
- 診断の学習曲線
- 相互検証戦略
- L1 (なげなわ) および L2 (リッジ) の正則化
- 早期停止とデータ増強
過学習と過小学習の診断
過学習と過小学習を診断する最も直接的な方法は、パフォーマンスを比較することです。 トレーニングセットとテストセットについて。モデルが持っている場合 トレーニングでは高いパフォーマンスを発揮するが、テストではパフォーマンスが低い、 それは過学習です。ある場合 両方ともパフォーマンスが低い、適合が不十分です。の 学習曲線 量が変化するとパフォーマンスがどのように変化するかを視覚化する データの量やモデルの複雑さ。
from sklearn.model_selection import learning_curve, validation_curve
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_breast_cancer
import numpy as np
# Dataset
data = load_breast_cancer()
X, y = data.data, data.target
# Learning curve: performance vs dimensione training set
train_sizes, train_scores, val_scores = learning_curve(
DecisionTreeClassifier(random_state=42),
X, y,
train_sizes=np.linspace(0.1, 1.0, 10),
cv=5,
scoring='accuracy',
n_jobs=-1
)
print("Learning Curve (Albero Decisionale senza limiti):")
print(f"{'Train Size':<12s} {'Train Acc':<12s} {'Val Acc':<12s} {'Gap':<8s}")
for size, train, val in zip(
train_sizes,
train_scores.mean(axis=1),
val_scores.mean(axis=1)
):
gap = train - val
status = "OVERFIT" if gap > 0.05 else "OK"
print(f"{size:<12d} {train:.3f} {val:.3f} {gap:.3f} {status}")
# Validation curve: performance vs complessità' modello
param_range = range(1, 20)
train_scores_vc, val_scores_vc = validation_curve(
DecisionTreeClassifier(random_state=42),
X, y,
param_name='max_depth',
param_range=param_range,
cv=5,
scoring='accuracy',
n_jobs=-1
)
print("\nValidation Curve (max_depth):")
best_depth = 1
best_val = 0
for depth, train, val in zip(
param_range,
train_scores_vc.mean(axis=1),
val_scores_vc.mean(axis=1)
):
if val > best_val:
best_val = val
best_depth = depth
print(f" depth={depth:<3d} train={train:.3f} val={val:.3f}")
print(f"\nMiglior max_depth: {best_depth} (val accuracy: {best_val:.3f})")
相互検証: 堅牢な評価
La 相互検証 これはパフォーマンスを確実に見積もるための標準的な手法です 一般化の。の K-フォールド履歴書 データセットを K 個の等しい部分に分割します。各反復で、 一部はテストとして使用され、残りの K-1 はトレーニングとして使用されます。 K回繰り返して平均を計算します パフォーマンスの。の 層別Kフォールド 各フォールド内のクラスの割合を維持します。 不均衡なデータセットには不可欠です。
from sklearn.model_selection import (
KFold, StratifiedKFold, RepeatedStratifiedKFold,
cross_val_score, cross_validate
)
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import load_breast_cancer
import numpy as np
data = load_breast_cancer()
X, y = data.data, data.target
pipeline = Pipeline([
('scaler', StandardScaler()),
('clf', RandomForestClassifier(n_estimators=100, random_state=42))
])
# Strategie di CV
strategies = {
'5-Fold': KFold(n_splits=5, shuffle=True, random_state=42),
'Stratified 5-Fold': StratifiedKFold(n_splits=5, shuffle=True, random_state=42),
'Repeated Strat 5x3': RepeatedStratifiedKFold(
n_splits=5, n_repeats=3, random_state=42
)
}
for name, cv in strategies.items():
scores = cross_val_score(pipeline, X, y, cv=cv, scoring='accuracy')
print(f"{name:<25s}: {scores.mean():.4f} (+/- {scores.std():.4f})")
# cross_validate per metriche multiple
results = cross_validate(
pipeline, X, y,
cv=StratifiedKFold(5, shuffle=True, random_state=42),
scoring=['accuracy', 'precision', 'recall', 'f1'],
return_train_score=True
)
print("\nDettaglio cross_validate:")
for metric in ['accuracy', 'precision', 'recall', 'f1']:
train = results[f'train_{metric}'].mean()
test = results[f'test_{metric}'].mean()
gap = train - test
print(f" {metric:<12s}: train={train:.3f} test={test:.3f} gap={gap:.3f}")
正則化: L1 (なげなわ) および L2 (リッジ)
La 正則化 コスト関数にペナルティ項を追加して、阻止します。 複雑すぎるモデル。 L2(尾根) 重みの二乗和を加算し、すべてを削減します。 重みはゼロに近づきますが、決してリセットされません。 L1 (なげなわ) 絶対値の合計を加算します 重みの: 一部の重みを完全にリセットし、暗黙的に特徴選択を実行できます。 弾性ネット L1 と L2 を結合し、l1_ratio パラメーターでミックスを制御します。
パラメータ アルファ (または LogisticRegression の C=1/alpha) は、 正則化: アルファが高いほどペナルティが高くなります (モデルが単純になり、適合不足のリスク)。 アルファが低いと、ペナルティが少なくなります (モデルがより複雑になり、過学習のリスクが高まります)。
from sklearn.linear_model import Ridge, Lasso, ElasticNet, LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import load_breast_cancer
import numpy as np
data = load_breast_cancer()
X, y = data.data, data.target
# Confronto regularization per classificazione
regularizations = {
'No Reg (C=1e6)': LogisticRegression(C=1e6, max_iter=10000, random_state=42),
'L2 Weak (C=10)': LogisticRegression(C=10, penalty='l2', max_iter=10000, random_state=42),
'L2 Strong (C=0.01)': LogisticRegression(C=0.01, penalty='l2', max_iter=10000, random_state=42),
'L1 (C=1)': LogisticRegression(C=1, penalty='l1', solver='saga', max_iter=10000, random_state=42),
'ElasticNet': LogisticRegression(C=1, penalty='elasticnet', solver='saga',
l1_ratio=0.5, max_iter=10000, random_state=42)
}
print("Confronto Regularization:")
for name, model in regularizations.items():
pipeline = Pipeline([('scaler', StandardScaler()), ('clf', model)])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
# Conta coefficienti non-zero (dopo fit)
pipeline.fit(X, y)
n_nonzero = np.sum(np.abs(pipeline.named_steps['clf'].coef_) > 1e-5)
print(f" {name:<22s}: acc={scores.mean():.3f} features_attive={n_nonzero}/{X.shape[1]}")
早期停止とデータ拡張
L'早期停止 反復的にトレーニングされたモデルの正則化手法です (勾配ブースティング、ニューラル ネットワーク): 検証セットのパフォーマンスは各エポックで監視され、停止されます。 パフォーマンスの向上が止まったときのトレーニング。選択することなくオーバーフィッティングを防止 反復回数を手動で設定します。
La データ拡張 過学習に対する最も効果的な戦略は、次の場合です。 データが不足している場合: ラベルを保持した変換を通じて新しいトレーニング サンプルを生成します。 画像の場合: 回転、反転、クロップ、カラーバリエーション。テキストの場合: 同義語、逆翻訳。 表形式データの場合: 不均衡データまたはガウス ノイズの追加用の SMOTE。
経験則: トレーニング精度と検証精度の差が大きい場合 5% では、モデルはおそらく過学習になります。検証精度が 70% 未満の場合 それほど難しい問題ではありませんが、モデルはおそらく適合不足です。学習曲線は 最も有益な診断ツール。
重要なポイント
- 高いバイアス = 過小適合 (モデルが単純すぎる)。高い分散 = 過学習 (複雑すぎる)
- 学習曲線は、トレーニングと検証のパフォーマンス間のギャップを視覚化します。
- 相互検証 (階層化 K フォールド) は評価のゴールドスタンダードです
- L2 (リッジ) はすべての重量を軽減します。 L1 (なげなわ) はいくつかの重みをリセットします (暗黙的な特徴選択)
- 早期に停止すると、検証スコアの改善が停止したときにトレーニングが停止します。
- データが多い = 過学習が少ない: データセットが小さい場合、データ拡張が役立ちます







