モデルを公平に比較する
CoddyのMachine Learningジャーニー「教師あり学習」セクションの一部。レッスン 38/58。
1つの分割でモデルを比較するのはコイントスのようなものです。運よくテストセットに恵まれるモデルがあるかもしれません。代わりに、すべてのモデルに同じ5つのフォールドを使いましょう。150枚の紙幣が本物か偽物かを判定します。
k-NNとロジスティック回帰は揺らぎの範囲内で同等で、k-NNのほうが安定しています。決定木は劣ります。
KFold分割器は行を一度シャッフルし、各モデルに同じフォールドを渡します。
from sklearn.model_selection import KFold
folds = KFold(n_splits=5, shuffle=True, random_state=0)
for model in [knn, logistic, tree]:
scores = cross_val_score(model, X, y, cv=folds)
print(f"{scores.mean():.3f} {scores.std():.3f}")グラフ内の数値を出力します。
0.867 0.042
0.873 0.074
0.807 0.077平均が最も高いものを選びます。平均が近い場合は、標準偏差が小さいものを選びます。
チャレンジ
中級料理サイトは、訪問者が開いたレシピを作るかどうかを予測します。最初のプログラムでは、1つの分割で3つのモデルを評価し、決定木が勝ちます。公平に評価しましょう。プログラムは分割数を読み込みます。
- その分割数を指定し、
shuffle=Trueとrandom_state=0を使ってKFoldを作成します。 - その分割で各モデルを交差検証し、平均と標準偏差を小数点以下3桁で出力します。
- 平均が最も高いモデルを出力します。
ほかの訪問者と 5 の場合:
One split picks: k-NN
k-NN: mean 0.833, std 0.045
logistic: mean 0.860, std 0.044
tree: mean 0.787, std 0.029
Cross-validation picks: logistic自分で試してみよう
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score, KFold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
n_folds = int(input())
# 以下の行は変更しないでください:訪問者は300人、閲覧習慣は6種類。ラベル1は、その人がレシピどおりに料理を作ったことを意味します
X, y = make_classification(n_samples=300, n_features=6, n_informative=4, n_redundant=0,
flip_y=0.06, class_sep=0.8, random_state=0)
names = ["k-NN", "logistic", "tree"]
models = [KNeighborsClassifier(), LogisticRegression(max_iter=1000),
DecisionTreeClassifier(max_depth=4, random_state=0)]
# 1回のデータ分割で勝者が決まる
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
single = []
for model in models:
model.fit(X_train, y_train)
single.append(model.score(X_test, y_test))
print(f"One split picks: {names[np.argmax(single)]}")
# 以下にコードを書いてください
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
教師あり学習のすべてのレッスン
自分で練習してみよう: Pythonオンラインコンパイラ