Введение
Цель этого практикумного занятия - показать, как использовать класс LearningCurveDisplay из scikit - learn для построения кривых обучения. Кривые обучения показывают влияние добавления большего количества образцов в процессе обучения. Мы будем анализировать кривые обучения для классификатора наивного Байеса и классификатора SVM с ядром RBF, используя датасет цифр. Кроме того, мы рассмотрим масштабируемость этих прогнosticательных моделей, оценивая их вычислительную стоимость, а не только их статистическую точность.
Советы по использованию ВМ
После запуска ВМ кликните в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.
Иногда может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится полностью. Валидация операций не может быть автоматизирована из - за ограничений в Jupyter Notebook.
Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь задавать вопросы Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.
Загрузка датасета
from sklearn.datasets import load_digits
X, y = load_digits(return_X_y=True)
Определение моделей
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
naive_bayes = GaussianNB()
svc = SVC(kernel="rbf", gamma=0.001)
Построение кривых обучения
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__}")
Анализ кривых обучения
## Interpret the learning curves
Мы можем проанализировать кривую обучения классификатора наивного Байеса. Его форма встречается очень часто в более сложных датасетах: оценка на обучающем наборе очень высокая, когда используется мало образцов для обучения, и уменьшается при увеличении количества образцов, в то время как оценка на тестовом наборе очень низкая в начале и затем возрастает при добавлении образцов. Оценки на обучающем и тестовом наборах становятся более реальными, когда все образцы используются для обучения.
Мы видим другую типичную кривую обучения для классификатора SVM с ядром RBF. Оценка на обучающем наборе остается высокой независимо от размера обучающего набора. С другой стороны, оценка на тестовом наборе возрастает с размером обучающего датасета. Действительно, она возрастает до определенной точки, где достигает плато. Наблюдение такого плато является индикацией того, что может быть бесполезным получать новые данные для обучения модели, так как обобщающая способность модели не будет увеличиваться больше.
Проверить масштабируемость моделей
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],
)
):
## масштабируемость по времени подгонки
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("Время подгонки (с)")
ax[0, ax_idx].set_title(
f"Масштабируемость классификатора {estimator.__class__.__name__}"
)
## масштабируемость по времени оценки
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("Время оценки (с)")
ax[1, ax_idx].set_xlabel("Количество обучающих образцов")
Проверить компромисс между увеличенным временем обучения и оценкой кросс-валидации
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("Точность")
ax[ax_idx].set_xlabel("Время подгонки (с)")
ax[ax_idx].set_title(
f"Производительность классификатора {estimator.__class__.__name__}"
)
plt.show()
Резюме
В этом практическом занятии мы показали, как использовать класс LearningCurveDisplay из scikit - learn для построения кривых обучения. Мы проанализировали кривую обучения классификатора наивного Байеса и классификатора SVM с ядром RBF на наборе данных digits. Кроме того, мы рассмотрели масштабируемость этих прогностических моделей, оценивая их вычислительную стоимость, а не только их статистическую точность. Мы увидели, что масштабируемость классификаторов SVM и наивного Байеса очень различна. Сложность классификатора SVM при подгонке и оценке растет быстро с увеличением количества образцов. В отличие от этого, классификатор наивного Байеса масштабируется намного лучше с меньшей сложностью при подгонке и оценке. Мы также проверили компромисс между увеличенным временем обучения и оценкой кросс - валидации.