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–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/modules/learning_curve.html