3.5. Кривые валидации: построение графиков оценок для оценки моделей
У каждого оценщика есть свои преимущества и недостатки. Его ошибка обобщения может быть разложена на смещение, дисперсию и шум. Смещение оценщика — это его средняя ошибка на различных обучающих наборах. Дисперсия оценщика показывает, насколько он чувствителен к различным обучающим наборам. Шум — это свойство данных.
На следующем графике показана функция \(f(x) = \cos (\frac{3}{2} \pi x)\) и несколько зашумлённых выборок из этой функции. Мы используем три разных оценщика для аппроксимации функции: линейную регрессию с полиномиальными признаками степени 1, 4 и 15. Видно, что первый оценщик может лишь плохо аппроксимировать выборки и истинную функцию, поскольку он слишком прост (высокое смещение); второй оценщик аппроксимирует её почти идеально, а последний оценщик идеально аппроксимирует обучающие данные, но плохо аппроксимирует истинную функцию, то есть он очень чувствителен к различным обучающим данным (высокая дисперсия).
Смещение и дисперсия — неотъемлемые свойства оценщиков, и обычно нам приходится подбирать алгоритмы обучения и гиперпараметры так, чтобы и смещение, и дисперсия были как можно ниже (см. дилемму смещения и дисперсии). Ещё один способ уменьшить дисперсию модели — использовать больше обучающих данных. Однако собирать больше обучающих данных следует только в том случае, если истинная функция слишком сложна, чтобы её можно было аппроксимировать оценщиком с меньшей дисперсией.
В рассмотренной нами простой одномерной задаче легко определить, страдает ли оценщик от смещения или дисперсии. Однако в пространствах высокой размерности визуализировать модели бывает очень сложно. Поэтому зачастую полезно использовать описанные ниже инструменты.
Примеры
- Недообучение и переобучение
- Влияние регуляризации модели на ошибку на обучающей и тестовой выборках
- Построение кривых обучения и проверка масштабируемости моделей
3.5.1. Кривая валидации
Для проверки модели нам нужна функция оценки (см. Метрики и оценивание: количественная оценка качества прогнозов), например точность для классификаторов. Разумеется, правильный способ подбора нескольких гиперпараметров оценщика — поиск по сетке или аналогичные методы (см. Настройка гиперпараметров оценщика), которые выбирают гиперпараметр с наибольшей оценкой на валидационном наборе или нескольких валидационных наборах. Обратите внимание: если мы оптимизируем гиперпараметры по оценке на валидационном наборе, эта оценка будет смещённой и перестанет быть хорошей оценкой обобщающей способности. Чтобы получить корректную оценку обобщающей способности, нужно вычислить оценку на другом тестовом наборе.
Однако иногда бывает полезно построить график влияния одного гиперпараметра на оценки на обучающей и валидационной выборках, чтобы выяснить, переобучается или недообучается ли оценщик при некоторых значениях гиперпараметра.
В этом случае может помочь функция validation_curve:
>>> import numpy as np
>>> from sklearn.model_selection import validation_curve
>>> from sklearn.datasets import load_iris
>>> from sklearn.svm import SVC
>>> np.random.seed(0)
>>> X, y = load_iris(return_X_y=True)
>>> indices = np.arange(y.shape[0])
>>> np.random.shuffle(indices)
>>> X, y = X[indices], y[indices]
>>> train_scores, valid_scores = validation_curve(
... SVC(kernel="linear"), X, y, param_name="C", param_range=np.logspace(-7, 3, 3),
... )
>>> train_scores
array([[0.90, 0.94, 0.91, 0.89, 0.92],
[0.9 , 0.92, 0.93, 0.92, 0.93],
[0.97, 1 , 0.98, 0.97, 0.99]])
>>> valid_scores
array([[0.9, 0.9 , 0.9 , 0.96, 0.9 ],
[0.9, 0.83, 0.96, 0.96, 0.93],
[1. , 0.93, 1 , 1 , 0.9 ]])
Если вы собираетесь строить только кривые валидации, класс ValidationCurveDisplay удобнее, чем строить графики вручную с помощью matplotlib по результатам вызова validation_curve. Для создания и построения кривой валидации можно использовать метод from_estimator так же, как и validation_curve:
from sklearn.datasets import load_iris from sklearn.model_selection import ValidationCurveDisplay from sklearn.svm import SVC from sklearn.utils import shuffle X, y = load_iris(return_X_y=True) X, y = shuffle(X, y, random_state=0) ValidationCurveDisplay.from_estimator( SVC(kernel="linear"), X, y, param_name="C", param_range=np.logspace(-7, 3, 10) )
Если оценки на обучающей и валидационной выборках низкие, оценщик будет недообучен. Если оценка на обучающей выборке высокая, а на валидационной — низкая, оценщик переобучен; в противном случае он работает очень хорошо. Низкая оценка на обучающей выборке и высокая на валидационной обычно невозможны.
3.5.2. Кривая обучения
Кривая обучения показывает оценки оценщика на валидационной и обучающей выборках при разном количестве обучающих образцов. Этот инструмент помогает выяснить, насколько полезно добавление обучающих данных и сильнее ли оценщик страдает от ошибки дисперсии или ошибки смещения. Рассмотрим следующий пример, в котором мы строим кривые обучения для наивного байесовского классификатора и SVM.
Для наивного байесовского классификатора с увеличением размера обучающего набора и оценка на валидационной выборке, и оценка на обучающей выборке сходятся к довольно низкому значению. Поэтому дополнительный объём обучающих данных, вероятно, не принесёт большой пользы.
Напротив, при небольшом количестве данных оценка SVM на обучающей выборке намного выше, чем на валидационной. Добавление обучающих образцов, скорее всего, улучшит обобщающую способность.
Для получения значений, необходимых для построения такой кривой обучения (количество использованных образцов, средние оценки на обучающих наборах и средние оценки на валидационных наборах), можно использовать функцию learning_curve:
>>> from sklearn.model_selection import learning_curve
>>> from sklearn.svm import SVC
>>> train_sizes, train_scores, valid_scores = learning_curve(
... SVC(kernel='linear'), X, y, train_sizes=[50, 80, 110], cv=5)
>>> train_sizes
array([ 50, 80, 110])
>>> train_scores
array([[0.98, 0.98 , 0.98, 0.98, 0.98],
[0.98, 1. , 0.98, 0.98, 0.98],
[0.98, 1. , 0.98, 0.98, 0.99]])
>>> valid_scores
array([[1. , 0.93, 1. , 1. , 0.96],
[1. , 0.96, 1. , 1. , 0.96],
[1. , 0.96, 1. , 1. , 0.96]])
Если вы собираетесь строить только кривые обучения, удобнее будет воспользоваться классом LearningCurveDisplay. Для создания и построения кривой обучения можно использовать метод from_estimator так же, как и learning_curve:
from sklearn.datasets import load_iris from sklearn.model_selection import LearningCurveDisplay from sklearn.svm import SVC from sklearn.utils import shuffle X, y = load_iris(return_X_y=True) X, y = shuffle(X, y, random_state=0) LearningCurveDisplay.from_estimator( SVC(kernel="linear"), X, y, train_sizes=[50, 80, 110], cv=5)
Примеры
- См. пример использования кривых обучения для проверки масштабируемости прогнозной модели в разделе Построение кривых обучения и проверка масштабируемости моделей.
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/modules/learning_curve.html