Объяснение всех процедур CV, которые вам нужно знать как специалисту по данным
Зачем перекрестная проверка?
Пока я не начну продавать сопутствующие товары, я должен рекламировать основную идею. Вот оно.
Давайте представим мир, в котором вы не знаете, что такое процедура перекрестной проверки. В этом сумасшедшем мире вы, очевидно, разделили свои данные на один набор поездов и тестов. Модель учится на обучающих данных, и вы проверяете ее производительность, прогнозируя так называемые невидимые данные, которые являются вашим тестовым набором. Если вас не устраивает оценка, вы настраиваете свою модель, используя одни и те же наборы, пока GridSearch (или Оптуна) не закричит хватит!.
Вот два способа, которыми этот процесс может пойти ужасно неправильно:
- Наборы плохо отражают все население. В качестве крайнего примера: из строк с тремя категориями (a, b, c) все категории a и b могут оказаться в обучающем наборе, в то время как все c зависают в тестовом наборе. Или числовая переменная разделена так, что значения слева и справа от некоторого порога плохо распределяются между поездами и наборами. Или ситуация, близкая к той, когда новые распределения переменных в обоих наборах настолько отличаются от исходных, что модель учится на неверной информации.
- Вы передаете знания о наборе тестов в модель во время настройки гиперпараметров. После завершения поиска платформа выдает параметры, которые лучше всего подходят для этого конкретного набора тестов. Поскольку я использую слово конкретный, вы уже должны начать думать о переоснащении. Потому что это то, что происходит, если вы постоянно тестируете один и тот же набор тестов — поисковая система просто выдает вам результат, который делает вас счастливым для этого конкретного набора тестов.
Итак, если мы вернемся в мир, где CV любят и широко используют инженеры по всему миру, все эти проблемы будут решены. Вот магия CV, показанная в Руководстве пользователя Sklearn (лицензия BSD):
Выше приведен пример 5-кратного процесса перекрестной проверки, для завершения которого требуется пять итераций. Новая модель обучается на четырех сгибах в каждой итерации и тестируется на последнем удержанном сгибе. Таким образом, модель обучается и тестируется на всех данных без потерь.
Затем сообщаются усредненные баллы с их стандартными отклонениями в качестве доверительного интервала. Только тогда вы сможете по-настоящему оценить производительность своей модели с выбранными параметрами, потому что полученная вами средняя оценка будет отражать истинный потенциал модели для эффективного обучения на основе данных и точного прогнозирования на невидимых выборках.
1. KFold
Теперь давайте начнем обсуждать различные способы выполнения процедуры CV. Самый простой из них — KFold
, как показано на изображении выше. Это реализовано с тем же именем в Sklearn. Здесь мы напишем быструю функцию, которая визуализирует индексы разделения CV-разделителя:
Теперь давайте передадим в эту функцию разветвитель KFold с семью разбиениями:
Так выглядит ванильный KFold.
Другая версия перетасовывает данные перед выполнением разделения. Это еще больше сводит к минимуму риск переобучения, нарушая первоначальный порядок выборок:
Как видите, индексы проверочных образцов выбираются в случайном порядке. Даже в этом случае общее количество выборок по-прежнему составляет одну седьмую от всех данных, потому что мы делаем 7-кратное CV.
KFold является наиболее часто используемым разделителем CV. Это легко понять и смертельно эффективно. Однако, в зависимости от характеристик ваших наборов данных, иногда вам нужно быть более разборчивым в том, какую процедуру CV использовать. Итак, давайте обсудим альтернативы.
2. Стратифицированный KFold
Еще одна версия KFold, разработанная специально для задач классификации, — StratifiedKFold
.
При классификации целевое распределение должно сохраняться даже после разделения данных на несколько наборов. В частности, бинарная цель с соотношением классов от 30 до 70 должно по-прежнему иметь одинаковые соотношения как в обучающей, так и в тестовой выборках.
Это правило нарушается в ванильном KFold, потому что он не заботится о соотношении классов или перемешивает данные перед разделением. В качестве решения используем еще один класс-разделитель в Sklearn — StratifiedKFold
:
Он выглядит так же, как KFold, но теперь соотношения классов сохраняются для всех сгибов и итераций.
3. Выйти
Иногда данные, которые у вас есть, настолько ограничены, что вы даже не можете позволить себе разделить их на обучающие и тестовые наборы. В этом случае вы можете выполнить резюме, в котором вы выделяете только несколько строк данных на каждой итерации. Это известно как LeavePOut CV, где p — это параметр, который вы выбираете для указания количества строк в каждом наборе ограничений.
Наиболее крайним случаем является разделитель LeaveOneOut
, когда вы используете только одну строку в качестве тестового набора, а количество итераций равно количеству строк в полных данных. Если создание 100 моделей для небольшого набора данных из 100 строк кажется безумием, я всегда с вами.
Даже для более высоких чисел p
количество итераций растет экспоненциально по мере увеличения размера вашего набора данных. Только представьте, сколько моделей будет построено, когда p
равно пяти, а ваши данные содержат всего 50 строк (подсказка — используйте формулу перестановок).
Итак, вы редко видите это на практике, но достаточно часто Sklearn реализует эти процедуры как отдельные классы:
from sklearn.model_selection import LeaveOneOut, LeavePOut
4. ПеремешатьСплит
Как насчет того, чтобы вообще не делать CV и просто несколько раз повторить процесс разделения обучения/тестирования? Что ж, это еще один способ, которым вы можете заигрывать с идеей перекрестной проверки и все же не делать этого.
По логике создание нескольких наборов обучения/тестов с использованием разных случайных начальных значений должно напоминать надежный процесс CV, если выполняется достаточное количество итераций. Вот почему в Sklearn есть сплиттер, который выполняет этот процесс:
Преимущество ShuffleSplit заключается в том, что вы полностью контролируете размеры поезда и наборов в каждой складке. Размер сетов не обязательно должен быть обратно пропорционален количеству сплитов.
Однако, в отличие от других разделителей, нет гарантии, что случайные разделения будут генерировать разные складки на каждой итерации. Поэтому используйте этот класс с осторожностью.
Кстати, есть и стратифицированная версия ShuffleSplit для классификации:
5. Разделение временных рядов
Наконец, у нас есть особый случай данных временных рядов, где порядок выборок имеет значение.
Мы не можем использовать ни один из традиционных классов CV, потому что это приведет к катастрофе. Есть большая вероятность, что вы будете тренироваться на будущих образцах и прогнозировать прошлые.
Чтобы решить эту проблему, Sklearn предлагает еще один разделитель — TimeSeriesSplit
, где он гарантирует, что вышеперечисленное не произойдет:
Красиво и аккуратно!
Другие разветвители CV для данных, отличных от IID
До сих пор мы имели дело с данными IID (независимыми и одинаково распределенными). Другими словами, процесс, сгенерировавший данные, не имеет памяти о прошлых выборках.
Однако бывают случаи, когда ваши данные не IID — что некоторые группы выборок зависят друг от друга. Например, в конкурсе Google Brain Ventilator Pressure на Kaggle участники должны работать с данными, не относящимися к IID.
Данные записывают тысячи вдохов и выдохов, которые делает искусственное легкое, и регистрируют давление воздуха для каждого вдоха с интервалом в несколько миллисекунд. В результате данные содержат около 80 строк для каждого вдоха, что делает эти строки зависимыми.
Здесь традиционные разделители CV не будут работать должным образом, потому что существует определенная вероятность того, что разделение может произойти прямо в середине вдоха. Вот еще один пример из Руководства пользователя Sklearn:
Такая группировка данных зависит от предметной области. Примером может служить случай, когда медицинские данные собираются у нескольких пациентов, при этом у каждого пациента берется несколько образцов. И такие данные, скорее всего, будут зависеть от отдельной группы. В нашем примере идентификатор пациента для каждого образца будет идентификатором его группы.
Он также указывает решение сразу после этого:
В этом случае мы хотели бы знать, хорошо ли модель, обученная на определенном наборе групп, обобщается на невидимые группы. Чтобы измерить это, нам нужно убедиться, что все образцы в контрольной выборке получены из групп, которые вообще не представлены в парной обучающей выборке.
Затем Sklearn перечисляет пять разных классов, которые могут работать с сгруппированными данными. Если вы усвоили идеи из предыдущих разделов и поняли, что такое данные, отличные от IID, у вас не возникнет проблем с ними:
Каждый из этих сплиттеров имеет аргумент groups
, где вы должны передать столбец, в котором хранятся идентификаторы групп. Это говорит классам, как различать каждую группу.
Краткое содержание
Наконец пыль улеглась, и мы здесь.
Один вопрос, который я, вероятно, оставил без ответа: «Всегда ли следует использовать перекрестную проверку?» Ответ предварительный да. Когда ваш набор данных достаточно велик, любое случайное разделение, вероятно, будет хорошо напоминать исходные данные в обоих наборах. В этом случае резюме не является строгим требованием.
Однако статистики и люди, гораздо более опытные, чем я, в StackExchange говорят, что вы должны выполнять как минимум двух- или трехкратную перекрестную проверку независимо от размера данных. Просто никогда нельзя быть слишком осторожным.
Спасибо за чтение!
Понравилась эта статья и, скажем прямо, ее причудливый стиль написания? Представьте себе, что у вас есть доступ к десяткам таких же, написанных блестящим, обаятельным, остроумным автором (кстати, это я :).
Всего за 4,99 $ членства вы получите доступ не только к моим историям, но и к сокровищнице знаний от лучших и самых ярких умов на Medium. А если вы воспользуетесь моей реферальной ссылкой, то получите мою сверхновую благодарность и виртуальную пятерку за поддержку моей работы.