Menu
CoddyTech

モデルを公平に比較する

CoddyのMachine Learningジャーニー「教師あり学習」セクションの一部。レッスン 38/58。

1つの分割でモデルを比較するのはコイントスのようなものです。運よくテストセットに恵まれるモデルがあるかもしれません。代わりに、すべてのモデルに同じ5つのフォールドを使いましょう。150枚の紙幣が本物か偽物かを判定します。

モデルごとの5つのフォールドのスコアを点で示し、平均値に黒い線を引いている。k-NNの点は0.867前後に密集している。ロジスティック回帰は0.873前後で0.73から0.93まで広がっている。決定木は0.807で最も低い

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

平均が最も高いものを選びます。平均が近い場合は、標準偏差が小さいものを選びます。

challenge icon

チャレンジ

中級

料理サイトは、訪問者が開いたレシピを作るかどうかを予測します。最初のプログラムでは、1つの分割で3つのモデルを評価し、決定木が勝ちます。公平に評価しましょう。プログラムは分割数を読み込みます。

  1. その分割数を指定し、shuffle=True と random_state=0 を使って KFold を作成します。
  2. その分割で各モデルを交差検証し、平均と標準偏差を小数点以下3桁で出力します。
  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)]}")

# 以下にコードを書いてください
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

教師あり学習のすべてのレッスン

自分で練習してみよう: Pythonオンラインコンパイラ