Примечание
Перейти к концу для загрузки полного примера кода. или запустить этот пример в вашем браузере через JupyterLite или Binder
Построение кривых обучения и проверка масштабируемости моделей
В этом примере показано, как использовать класс LearningCurveDisplay, чтобы легко построить кривые обучения. Кроме того, мы даём интерпретацию кривых обучения, полученных для классификаторов наивного Байеса и SVM.
Затем мы исследуем и делаем выводы о масштабируемости этих предсказательных моделей, рассматривая их вычислительную стоимость, а не только их статистическую точность.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Кривая обучения
Кривые обучения показывают влияние добавления большего количества образцов во время процесса обучения. Влияние изображается путём проверки статистической производительности модели с точки зрения оценки качества обучения и оценки качества проверки.
Здесь мы вычисляем кривые обучения для классификатора наивного Байеса и классификатора SVM с ядром RBF, используя набор данных цифр.
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__}")

Сначала мы анализируем кривую обучения для классификатора наивного Байеса. Его форма часто встречается в более сложных наборах данных: оценка качества обучения очень высока при использовании небольшого количества образцов для обучения и уменьшается при увеличении количества образцов, тогда как оценка качества проверки очень низка в начале, а затем увеличивается при добавлении образцов. Оценки качества обучения и проверки становятся более реалистичными при использовании всех образцов для обучения.
Мы видим другую типичную кривую обучения для классификатора 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")

Мы видим, что масштабируемость классификаторов 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()

В этих графиках мы можем искать точку перегиба, после которой оценка перекрёстной проверки больше не увеличивается, а увеличивается только время обучения.
Общее время выполнения скрипта: (0 минут 31.850 секунд)
Связанные примеры
© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/model_selection/plot_learning_curve.html