導入
モデルが訓練データに合わせ込みすぎて、未知のデータで当たらなくなる現象を**過学習(オーバーフィッティング)**と言います。機械学習で最大の敵です。
説明
決定木の深さ 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]: に変えるだけです。