本文へスキップ
BecomeCoder

Python AIコース · 第4章 モデルを正しく評価する · レッスン13

過学習(オーバーフィッティング)

ブラウザで完結

導入

モデルが訓練データに合わせ込みすぎて、未知のデータで当たらなくなる現象を**過学習(オーバーフィッティング)**と言います。機械学習で最大の敵です。

説明

決定木の深さ max_depth を変えて、訓練とテストの正解率のズレを観察します。深くするほど訓練データには完璧に合いますが、テストでは頭打ち、あるいは悪化します。

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.3, random_state=1
)

print("depth  train   test")
for depth in [1, 2, 3, 5, 10]:
    model = DecisionTreeClassifier(max_depth=depth, random_state=0)
    model.fit(X_train, y_train)
    tr = model.score(X_train, y_train)
    te = model.score(X_test, y_test)
    print(f"{depth:>5}  {tr:.3f}   {te:.3f}")

表を見ると、深さを増やすほど train(訓練)の正解率は上がり続けるのに、test(テスト)は途中から伸びないのが分かります。この「訓練だけ良くてテストが良くならない」状態が過学習です。訓練とテストのスコア差が大きいほど、過学習を疑います。

対策は、モデルを複雑にしすぎない(max_depth を抑える)、データを増やす、などです。「訓練で満点」を喜んではいけない、というのが教訓です。

やってみよう

random_state=1 の数字を変えて、過学習が始まる深さが動くのを観察しましょう。どの分け方でも「trainは上がり続け、testは頭打ち」の傾向は共通です。

演習

上のループの深さリスト [1, 2, 3, 5, 10]20 を加えて実行し、depth=20 でも test の正解率が train ほど上がらない(過学習)ことを確かめてください。

ヒント1を見る

for depth in [1, 2, 3, 5, 10, 20]: に変えるだけです。

実際に動かしてみよう

下のエディタにPythonを書いて「実行」を押すと、scikit-learn で本物の機械学習モデルをその場で訓練できます。scikit-learn を使う回は初回の読み込みに時間がかかります(数十秒かかることがあります)。本文の例をそのまま試したり、数値を書き換えたりして、結果の変化を確かめましょう(グラフ内の文字は英字で書きます)。

Python — ライブラリ付きで実行(Pyodide)

numpy / pandas / matplotlib が使える本物のPython(Pyodide)を読み込みます。初回のみ読み込みに少し時間がかかります(以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。