Кросс-валидация (Cross Validation) - Лена Капаца
Кросс-валидация (Cross Validation) by Лена Капаца April 28, 2021

Кросс-валидация (перекрестная проверка) – это метод оценки Моделей (Model) Машинного обучения (ML) путем обучения нескольких из них на подмножествах доступных входных данных и их оценки на другом дополнительном подмножестве. Такая проверка используется для обнаружения Переобучения (Overfitting), т.е. неспособности распознать паттерн.

Всегда необходимо проверять стабильность предсказывающего Алгоритма (Algorithm): нам нужна уверенность в том, что модель имеет представление о большинстве шаблонов в данных, что ее эффективность не падает от шумных данных, или, другими словами, у нее низкий уровень Смещения (Bias) и Дисперсии (Variance).

Проверка

Валидация – это процесс принятия решения о том, приемлемы ли числовые результаты, определяющие предполагаемые взаимосвязи между переменными в качестве характеристики данных. Как правило, оценка Ошибки (Error) для модели выполняется после обучения, более известного как оценка Остатков (Residuals). Мы выполняем численную оценка ошибкой обучения – разницы в предсказанных и истинных ответах. Однако это только дает нам представление о том, насколько хорошо модель работает с Тренировочными данными (Train Data). Однако вероятно, что модель склонна к переобучению или Недообучению (Underfitting). Проблема этого метода оценки заключается в том, что он не гарантирует приемлемый уровень обобщения новых неизвестных данных.

Метод удержания (Holdout Method)

Простое решение вышеописанной проблемы заключается в удержании части обучающих данных и использовании ее для оценки предсказательной способности. Ошибка сообщает затем, как наша модель работает с новыми данными или валидационным набором. Хотя этот метод не требует дополнительных вычислительных затрат и лучше, чем традиционная проверка, он все же подвержен высокой дисперсии. Неизвестно, какие точки данных попадут в набор для проверки, и результат может быть совершенно разным для каждой случайной Выборки (Sample).

Кросс-валидация по K блокам

Поскольку все возможные варианты загрузить в модель непросто, удержание части Датасета (Dataset) для проверки создает проблему недообучения. Уменьшая объем обучающих данных, мы рискуем потерять важные закономерности и тенденции в наборе, что, в свою очередь, увеличивает ошибку, вызванную смещением. Итак, нам нужен метод, который предоставляет достаточно данных для обучения модели, а также оставляет достаточно данных для проверки. Кросс-валидация по K блокам (K-Fold Cross Vaidation) делает именно это.

При K-Fold проверке данные делятся на k подмножеств. Теперь удержание повторяется k раз, так что каждый из k подмножеств используется в качестве проверочного набора, а другие подмножества k-1 объединяются, чтобы сформировать обучающий набор. Ошибка усредняется по всем k испытаниям, чтобы получить обощенную эффективность нашей модели. Каждая точка данных попадает в набор для проверки ровно один раз и попадает в обучающий набор k-1 раз. Это значительно снижает смещение, поскольку мы используем большую часть данных для подгонки, а также значительно сокращаем дисперсию, поскольку большая часть данных также используется в наборе для проверки. Перестановка тренировочного и тестового наборов также повышает эффективность этого метода. По умолчанию K равен 5 или 10, но может принимать и любое другое значение.

Стратифицированная кросс-валидация по K блокам

В некоторых случаях может быть большой естественный дисбаланс. Например, в датасете о ценах на недвижимость может быть большое количество домов с высокой ценой. Или в случае Классификации (Classification), представителей одного класса может быть в несколько раз больше, чем другого. Для таких ситуаций и делается небольшое изменение в методике перекрестной проверки, так что каждый блок содержит примерно такую же пропорцию классов. Этот вариант проверки также известен как стратифицированная кросс-валидация по K блокам.

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

Перекрестная проверка без исключения

Leave-P-Out Cross Validation (LPO) оставляет P точек данных за пределами обучающего набора, т.е. если в исходной выборке имеется N точек данных, тогда N-P выборок используются для обучения модели, а P точек используются в качестве набора для проверки. Это повторяется для всех комбинаций, в которых исходный образец может быть отделен таким образом, а затем ошибка усредняется для всех испытаний, чтобы оценить общую эффективность.

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

Частным случаем этого метода является P = 1. Он известен как Поэлементная кросс-валидация (LOO). Этот метод предпочтительнее предыдущего, потому что не страдает от массивных вычислений, и количество возможных комбинаций равно количеству точек данных в исходной выборке (N).

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

Кросс-валидация и Scikit-learn

Давайте посмотрим, как кросс-валидация реализована в SkLearn. Для начала импортируем необходимые библиотеки:

import sklearn as sk
from sklearn import datasets, linear_model
from sklearn.model_selection import cross_validate
from sklearn.metrics import make_scorer
from sklearn.metrics import confusion_matrix
from sklearn.svm import LinearSVC

Используем датасет о пациентах, у которых диагностируют диабет. Отделим Предикторы (Predictor Variable) от Целевой переменной (Target Variable), создав объекты X и y соответственно. Для совершенствования модели используем так называемую Регуляризацию Лассо (L1 Regularization):

diabetes = datasets.load_diabetes()
X = diabetes.data[:150]
y = diabetes.target[:150]
lasso = linear_model.Lasso()

Создадим объект cv_results, в который загрузим результаты перекрестной проверки. Помимо переданных аргументов – типа регуляризации lasso, предикторов и целевой переменной, мы также определяем, насколько частей разделять датасет (cv = 3):

cv_results = cross_validate(lasso, X, y, cv = 3)
sorted(cv_results.keys())

cv_results['test_score']

Отсортированный от большего к меньшему список точностей выглядит весьма плачевно: линейная модель справилась лишь с 33% наблюдений:

array([0.33150734, 0.08022311, 0.03531764])

Перезапустим перекрестную проверку с другими настройками. Теперь мы используем стратегию оценки производительности r2, и отрицательное значение Среднеквадратической ошибки (MSE – Mean Squared Error):

scores = cross_validate(lasso, X, y, cv = 3,
                        scoring = ('r2', 'neg_mean_squared_error'),
                        return_train_score = True)
print(scores['test_neg_mean_squared_error'])
print(scores['train_r2'])

Ну что ж, модель учебная, так что низкая предсказательная способность здесь не главное, хоть результат и улучшился до 39%. Процесс совершенствования модели здесь только начинается, и MSE каждой итерации – прекрасный способ сравнивать между собой качество последующих апгрейдов:

[-3635.51152303 -3573.34242148 -6114.78229547]
[0.28010158 0.39088426 0.22784852]

Ноутбук, не требующий дополнительной настройки на момент написания статьи, можно скачать здесь.

Фото: @tricell1991

Автор оригинальной статьи: @prashantgupta17

© Лена Капаца. Все права защищены.