Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Построение кривых обучения и проверка масштабируемости моделей

В этом примере мы покажем, как использовать класс LearningCurveDisplay для простого построения кривых обучения. Кроме того, мы интерпретируем кривые обучения, полученные для классификаторов наивного Байеса и SVM.

Затем мы рассмотрим масштабируемость этих прогностических моделей и сделаем некоторые выводы, оценивая их вычислительные затраты, а не только статистическую точность.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Кривая обучения

Кривые обучения показывают эффект добавления новых образцов в процессе обучения. Этот эффект отображается с помощью проверки статистических показателей модели — оценки на обучающей и тестовой выборках.

Здесь мы вычислим кривые обучения классификатора наивного Байеса и классификатора SVM с ядром RBF, используя набор данных digits.

from sklearn.datasets import load_digits
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

X, y = load_digits(return_X_y=True)
naive_bayes = GaussianNB()
svc = SVC(kernel="rbf", gamma=0.001)

from_estimator отображает кривую обучения для заданного набора данных и анализируемой прогностической модели. Чтобы оценить неопределённость оценок, этот метод использует процедуру перекрёстной проверки.

import matplotlib.pyplot as plt
import numpy as np

from sklearn.model_selection import LearningCurveDisplay, ShuffleSplit

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 6), sharey=True)

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "score_type": "both",
    "n_jobs": 4,
    "line_kw": {"marker": "o"},
    "std_display_style": "fill_between",
    "score_name": "Accuracy",
}

for ax_idx, estimator in enumerate([naive_bayes, svc]):
    LearningCurveDisplay.from_estimator(estimator, **common_params, ax=ax[ax_idx])
    handles, label = ax[ax_idx].get_legend_handles_labels()
    ax[ax_idx].legend(handles[:2], ["Training Score", "Test Score"])
    ax[ax_idx].set_title(f"Learning Curve for {estimator.__class__.__name__}")
Learning Curve for GaussianNB, Learning Curve for SVC

Сначала проанализируем кривую обучения классификатора наивного Байеса. Её форма часто встречается на более сложных наборах данных: оценка на обучающей выборке очень высока при обучении на небольшом количестве образцов и снижается с увеличением их количества, тогда как оценка на тестовой выборке вначале очень низкая, а затем растёт при добавлении образцов. Оценки на обучающей и тестовой выборках становятся реалистичнее, когда для обучения используются все образцы.

Для классификатора SVM с ядром RBF мы видим другую типичную кривую обучения. Оценка на обучающей выборке остаётся высокой независимо от размера обучающей выборки. В то же время оценка на тестовой выборке растёт с увеличением размера обучающего набора данных. Она растёт до тех пор, пока не достигает плато. Наличие такого плато указывает на то, что сбор новых данных для обучения модели может быть бесполезен, поскольку качество обобщения модели больше не будет повышаться.

Анализ сложности

Помимо этих кривых обучения, можно также оценить масштабируемость прогностических моделей с точки зрения времени обучения и вычисления оценок.

Класс LearningCurveDisplay не предоставляет такую информацию. Вместо этого нам нужно использовать функцию learning_curve и построить график вручную.

from sklearn.model_selection import learning_curve

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "n_jobs": 4,
    "return_times": True,
}

train_sizes, _, test_scores_nb, fit_times_nb, score_times_nb = learning_curve(
    naive_bayes, **common_params
)
train_sizes, _, test_scores_svm, fit_times_svm, score_times_svm = learning_curve(
    svc, **common_params
)
fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(16, 12), sharex=True)

for ax_idx, (fit_times, score_times, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [score_times_nb, score_times_svm],
        [naive_bayes, svc],
    )
):
    # scalability regarding the fit time
    ax[0, ax_idx].plot(train_sizes, fit_times.mean(axis=1), "o-")
    ax[0, ax_idx].fill_between(
        train_sizes,
        fit_times.mean(axis=1) - fit_times.std(axis=1),
        fit_times.mean(axis=1) + fit_times.std(axis=1),
        alpha=0.3,
    )
    ax[0, ax_idx].set_ylabel("Fit time (s)")
    ax[0, ax_idx].set_title(
        f"Scalability of the {estimator.__class__.__name__} classifier"
    )

    # scalability regarding the score time
    ax[1, ax_idx].plot(train_sizes, score_times.mean(axis=1), "o-")
    ax[1, ax_idx].fill_between(
        train_sizes,
        score_times.mean(axis=1) - score_times.std(axis=1),
        score_times.mean(axis=1) + score_times.std(axis=1),
        alpha=0.3,
    )
    ax[1, ax_idx].set_ylabel("Score time (s)")
    ax[1, ax_idx].set_xlabel("Number of training samples")
Scalability of the GaussianNB classifier, Scalability of the SVC classifier

Мы видим, что масштабируемость классификаторов SVM и наивного Байеса сильно различается. Сложность классификатора SVM при обучении и вычислении оценок быстро растёт с увеличением количества образцов. Известно, что временная сложность обучения этого классификатора растёт быстрее квадратичной относительно количества образцов, поэтому его трудно масштабировать для наборов данных, содержащих более нескольких десятков тысяч образцов. В отличие от него, классификатор наивного Байеса масштабируется гораздо лучше и имеет меньшую сложность при обучении и вычислении оценок.

Далее мы можем проверить компромисс между увеличением времени обучения и оценкой при перекрёстной проверке.

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 6))

for ax_idx, (fit_times, test_scores, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [test_scores_nb, test_scores_svm],
        [naive_bayes, svc],
    )
):
    ax[ax_idx].plot(fit_times.mean(axis=1), test_scores.mean(axis=1), "o-")
    ax[ax_idx].fill_between(
        fit_times.mean(axis=1),
        test_scores.mean(axis=1) - test_scores.std(axis=1),
        test_scores.mean(axis=1) + test_scores.std(axis=1),
        alpha=0.3,
    )
    ax[ax_idx].set_ylabel("Accuracy")
    ax[ax_idx].set_xlabel("Fit time (s)")
    ax[ax_idx].set_title(
        f"Performance of the {estimator.__class__.__name__} classifier"
    )

plt.show()
Performance of the GaussianNB classifier, Performance of the SVC classifier

На этих графиках можно найти точку перегиба, после которой оценка при перекрёстной проверке больше не растёт, а увеличивается только время обучения.

Общее время выполнения скрипта: (0 минут 23.527 секунд)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_learning_curve.ipynb

Download Python source code: plot_learning_curve.py

Download zipped: plot_learning_curve.zip

Связанные примеры

Масштабирование параметра регуляризации для SVC

Калибровочные кривые вероятностей

ROC-кривая с API визуализации

Построение графиков различных классификаторов SVM на наборе данных iris

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/model_selection/plot_learning_curve.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API