Text
                    ОТ ПРОФЕССИОНАЛОВ
ДЛЯ ПРОФЕССИОНАЛОВ
kaggle
Книга
Машинное обучение
и анализ данных
Конрад Банахевич,
Лука Массарон
Packt>

The Kaggle Book Data analysis and machine learning for competitive data science Konrad Banachewicz Luca Massaron Packt> BIRMINGHAM—MUMBAI Packt and this book are not officially connected with Kaggle. This book is an effort from the Kaggle community of experts to help more developers.
Конрад Банахевич, Лука Масса рон Книга Kaggle Машинное обучение и анализ данных Санкт-Петербург « БХВ-Петербург» 2024
УДК 004.43 ББК 32.973.26-018.1 Б23 Банахевич, К. Б23 Книга Kaggle. Машинное обучение и анализ данных / К. Банахевич, Л. Массарон: Пер. с англ. — СПб.: БХВ-Петербург, 2024. — 448 с.: ил. ISBN 978-5-9775-1903-8 Книга рассказывает о продвинутых приёмах машинного обучения и науки о данных (data science) на основе задач, решаемых на всемирно известной плат- форме Kaggle. Показано (в том числе на примере увлекательных интервью с Kaggle-гроссмейстерами), как устроена платформа Kaggle и проводимые на ней соревнования. Изложенный материал позволяет развить необходимые навыки и собрать портфолио по машинному обучению, анализу данных, обработке естест- венного языка, работе с множествами. Подобран уникальный пул задач, охваты- вающих различные классификационные и оценочные метрики, методы обучения нейронных сетей, схемы валидации, выявление паттернов и трендов в материале любой сложности. Для специалистов по анализу данных и машинному обучению УДК 004.43 ББК 32.973.26-018.1 Группа подготовки издания: Руководитель проекта Зав. редакцией Редактор Компьютерная верстка Оформление обложки Олег Сивченко Людмила Гауль Анна Кузьмина Натальи Смирновой Зои Канторович © Packt Publishing 2022. First published in the English language under the title ‘The Kaggle Book - (9781801817479)’ Впервые опубликовано на английском языке под названием ’The Kaggle Book - (9781801817479)’ Подписано в печать 08.11.23. Формат 70х1001/16. Печать офсетная. Усл. печ. л. 36,12. Тираж 1300 экз. Заказ Ns 8042. "БХВ-Петербург", 191036, Санкт-Петербург, Гончарная ул., 20. Отпечатано с готового оригинал-макета ООО "Принт-М", 142300, М.О., г. Чехов, ул. Полиграфистов, д. 1 ISBN 978-1-80181-747-9 (англ.) ISBN 978-5-9775-1903-8 (рус.) © Packt Publishing, 2022 © Перевод на русский язык, оформление. ООО "БХВ-Петербург", ООО "БХВ", 2024
Содержание Предисловие.............................................................11 Составители.............................................................13 Об авторах............................................................13 О рецензентах.........................................................14 О респондентах........................................................15 Введение................................................................18 Для кого эта книга....................................................19 О чем эта книга.......................................................19 Часть I. Знакомство с соревнованиями................................19 Часть II. Оттачивание соревновательных навыков......................20 Часть III. Использование соревнований в своей карьере...............21 Как получить максимальную отдачу от этой книги........................21 Загрузите файлы с примерами кода......................................21 Загрузите цветные изображения.........................................22 Условные обозначения и соглашения.....................................22 Часть I. Знакомство с соревнованиями Kaggle.............................23 Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных.......................................................25 Появление и рост соревновательных платформ............................26 Соревновательная платформа Kaggle...................................28 История Kaggle....................................................28 Другие конкурсные платформы.........................................31 Знакомство с Kaggle...................................................33 Стадии соревнования.................................................33 Типы соревнований и примеры.........................................36
6 Содержание Отправка решения и таблица результатов..............................41 Парадигма каркаса для общих задач.................................41 Что может пойти не так............................................42 Вычислительные ресурсы..............................................44 Kaggle Notebooks..................................................45 Создание команд и нетворкинг........................................46 Уровни и рейтинг....................................................49 Критика и возможности...............................................50 Резюме................................................................51 Глава 2. Организация данных.............................................53 Создание датасета.....................................................53 Сбор данных...........................................................57 Работа с датасетами...................................................62 Kaggle Datasets и Google Colab........................................63 Юридические вопросы...................................................65 Резюме................................................................66 Глава 3. Работаем и учимся с Kaggle Notebooks......................... 67 Создание блокнота.....................................................68 Запуск блокнота.......................................................71 Сохранение блокнотов на GitHub........................................73 Как получить максимум от Kaggle Notebooks.............................75 Переход на Google Cloud Platform....................................76 На шаг дальше.......................................................77 Курсы Kaggle Learn....................................................82 Резюме................................................................86 Глава 4. Используем форумы..............................................87 Как работают форумы...................................................87 Примеры обсуждений....................................................92 Сетевой этикет........................................................97 Резюме................................................................97 Часть II. Оттачивание соревновательных навыков..........................99 Глава 5. Задачи и метрики на соревнованиях.............................101 Метрики оценивания и целевые функции.................................102 Основные типы задач..................................................103 Регрессия..........................................................104 Классификация......................................................104 Задачи ранжирования................................................105
Содержание 7 Датасет Meta Kaggle..................................................105 Как быть с незнакомыми метриками.....................................108 Метрики для задач регрессии..........................................112 Средний квадрат и R-квадрат........................................112 Среднеквадратичная ошибка..........................................113 Среднеквадратичная логарифмическая ошибка..........................114 Средняя абсолютная ошибка..........................................115 Метрики для задач классификации......................................116 Доля правильных ответов............................................116 Точность и полнота.................................................118 F-мера.............................................................120 Log Loss и ROC-AUC.................................................120 Коэффициент корреляции Мэтьюса.....................................122 Метрики для многоклассовой классификации.............................123 Метрики для задач детектирования объектов............................129 Отношение площадей ограничивающих рамок............................131 Коэффициент Дайса..................................................132 Метрики для многоклассовой классификации и построение рекомендаций...133 МАР@{К}............................................................133 Оптимизация метрики..................................................134 Нестандартные метрики и целевые функции............................135 Постобработка предсказаний.........................................138 Предсказание вероятностей и их корректировка.....................139 Резюме...............................................................143 Глава 6. Построение схемы валидации....................................144 Подглядывание........................................................144 Почему важна валидация...............................................147 Смещение и разброс.................................................150 Стратегии разделения данных..........................................152 Контроль на отложенных данных.................................... 153 Вероятностные методы оценки качества...............................154 Контроль по к блокам.............................................154 Случайные разбиения..............................................162 Бутстрэп.........................................................162 Настройка системы валидации..........................................166 Применение adversarial validation....................................169 Пример реализации..................................................171 Различные распределения обучающих и тестовых данных................172 Работа с утечками в данных......................................... 176 Резюме...............................................................180
8 ^ииержиние Глава 7. Моделирование для табличных данных............................182 Tabular Playground Series............................................183 Начальное состояние случайного генератора и воспроизводимость........186 Разведочный анализ данных............................................188 Понижение размерности методами t-SNE и UMAP........................190 Уменьшение размера данных............................................191 Преобразования признаков.............................................193 Простые производные признаки.......................................194 Метапризнаки на основе строк и столбцов............................196 Целевое кодирование................................................197 Важность признаков и оценка качества...............................202 Псевдометки..........................................................205 Удаление шума с помощью автокодировщиков...........................207 Нейросети для табличных конкурсов....................................210 Резюме...............................................................216 Глава 8. Оптимизация гиперпараметров...................................218 Базовые методы оптимизации...........................................219 Поиск по сетке.....................................................219 Случайный поиск....................................................221 Поиск сокращением вдвое............................................222 Ключевые параметры и их использование................................225 Линейные модели....................................................225 Машины опорных векторов............................................225 Случайные леса и экстремально рандомизированные деревья............227 Градиентный бустинг над деревьями..................................228 LightGBM.........................................................228 XGBoost..........................................................230 CatBoost.........................................................231 HistGradientBoosting.............................................232 Байесовская оптимизация..............................................235 Использование Scikit-optimize......................................236 Настройки байесовской оптимизации..................................241 Обобщение байесовской оптимизации на параметры нейронных сетей.....248 Создание моделей с KerasTuner......................................256 Подход ТРЕ и Optuna................................................265 Резюме...............................................................270 Глава 9. Ансамбли: блендинг и стекинг..................................271 Краткое введение в ансамблевые алгоритмы.............................272 Усреднение...........................................................275 Голосование........................................................277 Усреднение предсказаний............................................279
Содержание 9 Взвешенные средние................................................280 Усреднение и кросс-валидация......................................281 Корректируем усреднение для оценок ROC-AUC........................282 Блендинг и метамодели...............................................283 Блендинг: лучшие практики.........................................284 Стекинг.............................................................289 Варианты стекинга.................................................293 Сложные решения с блендингом и стекингом............................294 Резюме..............................................................297 Глава 10. Моделирование в компьютерном зрении.........................299 Стратегии аугментации...............................................299 Встроенные аугментации Keras......................................305 Подход на основе ImageDataGenerator.............................305 Слои предварительной обработки..................................308 Пакет albumentations..............................................309 Классификация.......................................................312 Обнаружение объектов................................................319 Семантическая сегментация...........................................333 Резюме..............................................................349 Глава 11. Моделирование для обработки естественного языка.............350 Анализ тональности текста...........................................350 Вопросы и ответы в открытом домене..................................359 Стратегии аугментации текста........................................374 Основные приемы...................................................375 Пакет nlpaug......................................................380 Резюме..............................................................383 Глава 12. Соревнования по моделированию и оптимизации.................384 Игра Connect X......................................................385 Игра "Камень, ножницы, бумага”......................................390 Соревнование Santa 2020.............................................393 Такие разные игры...................................................397 Резюме..............................................................402 Часть III. Использование соревнований в своей карьере.................403 Глава 13. Создание портфолио проектов и идей..........................405 Создание портфолио с помощью Kaggle.................................405 Использование блокнотов и обсуждений..............................410 Использование датасетов...........................................413
10 Содержание Организация своего присутствия в Интернете за пределами Kaggle.......417 Блоги и публикации.................................................418 GitHub.............................................................421 Мониторинг обновлений и информационных бюллетеней о соревнованиях....423 Резюме...............................................................425 Глава 14. Поиск новых профессиональных возможностей....................426 Налаживание связей с другими исследователями данных на соревнованиях.427 Участие в Kaggle Days и других встречах Kaggle.......................438 Привлечение к себе внимания и другие возможности трудоустройства.....439 Методика STAR......................................................440 Резюме (и несколько напутственных слов)..............................442 Предметный указатель...................................................444
Предисловие Моя специальность— эконометрия, но постепенно я заинтересовался приемами машинного обучения. Сначала рассматривал его как альтернативный подход к ре- шению задач по прогнозированию. Постепенно погружаясь в эту тему, я обнару- жил, насколько страшно входить в эту область новичкам: не знаешь ни методов, ни терминологии, а также тебе нечего предъявить, чтобы закрепиться в профессио- нальном сообществе. Поэтому я мечтал, что Kaggle позволит таким как я войти в эту мощную новую дисциплину. Чем я, пожалуй, наиболее горжусь, так это тем, в какой степени бла- годаря Kaggle удалось повысить доступность машинного обучения и data science. Многих кэгглеров мы дорастили от новичков до асов машинного обучения, они смогли устроиться в такие компании, как NVIDIA, Google, OpenAI, а также осно- вать собственные фирмы, например DataRobot. Книга Луки и Конрада еще сильнее понижает планку для входа в Kaggle. Из нее вы узнаете, как устроен Kaggle, а также познакомитесь со множеством важнейших ав- торских находок, которые были сделаны в ходе работы на сайте. Общий стаж авто- ров на Kaggle превышает 20 лет, они участвовали в 330 соревнованиях, оставили более 2000 постов на форумах Kaggle, поделились более чем сотней блокнотов и пятью десятками наборов данных (или датасетов). Оба они — из пользовательской элиты, в сообществе Kaggle их очень уважают. Читатели, которые осилят всю книгу, могут рассчитывать на уверенное участие в конкурсах Kaggle, а за уверенное участие в них полагается множество наград. Во-первых, эта книга поможет вам оставаться на гребне самых прагматичных раз- работок в сфере машинного обучения. Эта область развивается очень быстро. В 2019 г. было опубликовано более 300 научных статей по машинному обучению, прошедших экспертную оценку. Такой объем совершенно не успеваешь читать. Kaggle — очень ценный инструмент, позволяющий отфильтровать материал, оста- вив только те работы, которые касаются реальных проблем. Но Kaggle не только помогает не отставать от академической литературы. Многие инструменты, де- факто ставшие стандартными в индустрии, распространились благодаря Kaggle. Так было, например, с XGBoost в 2014 г. и с Keras в 2015 г. — сначала они закре- пились именно в сообществе Kaggle. Во-вторых, в Kaggle удобно учиться на практике. Я слышал, что активные кэгглеры сравнивают регулярные соревнования с ’’силовыми тренировками’’ по машинному
12 Предисловие обучению. Учитывая, какие разнообразные практические варианты и задачи встре- чаются в Kaggle, можно хорошо подготовиться к аналогичным задачам в реальных проектах. А поскольку во всех конкурсах есть дедлайны, Kaggle помогает быстро "нарастить мышечную массу" (итерации при работе короткие). Пожалуй, нет луч- шего способа изучить тему, чем присмотреться к задаче и оценить, как ее решали чемпионы. (Когда соревнование закончено, среди победителей принято рассказать, кто и как решал задачу.) Итак, тем из вас, кто осмелился прочесть эту книгу и пока является новичком в Kaggle, желаю преодолеть страх и решиться поучаствовать в соревнованиях. Если же вы уже некоторое время работаете на Kaggle и хотите прокачать свой уровень, то эта книга под авторством сильнейших и очень уважаемых кэгглеров поможет и вам укрепить свои позиции на сайте. Энтони Голдблум, основатель и CEO Kaggle
Составители Об авторах Конрад Банахевич (Konrad Banachewicz) — обладатель степени PhD по статистике, полученной в Свободном университете Амстердама (Vrije Universiteit Amsterdam). В период академической работы в центре его научных интересов было моделиро- вание редчайших явлений в области кредитных рисков. Кроме исследовательской деятельности Конрад работал тьютором и научным руководителем студентов- магистрантов. Он начал карьеру с классической статистики, а затем перешел к из- влечению данных (data mining) и машинному обучению (еще до того, как "дата сайнс” или ’’большие данные") стали мейнстримом. Первое десятилетие после получения степени PhD Конрад работал в различных финансовых организациях и занимался самыми разнообразными задачами из об- ласти количественного анализа данных. Так он стал настоящим экспертом, пони- мающим весь жизненный цикл продукта, связанного с обработкой данных. В области финансов он имел дело со всеми областями частотности (от высокочастотного трейдинга до кредитных рисков — и со всем, что между ними), прогнозировал це- ны на картофель, анализировал аномалии в работе крупного промышленного пред- приятия. Конрад из тех, кто "видит далеко, потому что стоит на плечах гигантов", поэтому убежден, что знаниями нужно делиться. В свободное время он участвует в сорев- нованиях на Kaggle (т. к. "здесь живет data science"). Хотел бы поблагодарить моего брата за то, что он стал мне точкой опоры в бе- зумном мире и продолжает меня вдохновлять и мотивировать. Dzi^ki, Braciszku. Лука Массарон (Luca Massaron) — исследователь данных, обладающий более чем десятилетним опытом в преобразовании данных в более интеллектуальные едини- цы. Так решаются прикладные задачи и нарабатывается ценность для бизнеса и за- казчиков. Он автор бестселлеров по искусственному интеллекту, машинному обу- чению и алгоритмам. Также Лука — гроссмейстер Kaggle, достигавший позиции 7 в мировом соревновательном рейтинге по data science, обладатель титула Google Developer Expert (GDE) по машинному обучению. Мои самые теплые слова благодарности — семье, Юкико и Амелии за их поддерж- ку, любовь и терпение, подаренные мне, пока я работал над этой книгой, одной из многих.
14 Составители Глубоко признателен Энтони Голдблуму за то, что он любезно согласился напи- сать предисловие к этой книге, а также всем мастерам и гроссмейстерам Kaggle, которые с таким энтузиазмом участвовали в ее создании, давали интервью, что- то подсказывали и предлагали помощь. Наконец, выражаю благодарность Тушару Гупте, Парвати Найр, Люси Уон, Кар- вану Сонаване и всему редакторскому и типографскому коллективу издательства "Packt Publishing" за их поддержку в этом литературном проекте. О рецензентах Андрей Костенко (Andrey Kostenko)— профессионал в области исследования данных и машинного обучения, обладающий обширным опытом в самых разных дисциплинах и отраслях. В частности, он собственноручно строил модели времен- ных рядов и программировал их на Python и R, а также обучал для прогнозирования и решения других прикладных задач. Он считает, что важнейшие составляющие для инновационного вклада в продвинутую аналитику и искусственный интел- лект — это умение учиться всю жизнь и участие в проектах с открытым исходным кодом. Недавно Андрей занял пост ведущего исследователя данных в Институте гидроин- форматики (Hydroinformatics Institute, H2i.sg). Это специализированная компания, занимающаяся консалтингом и оказывающая услуги во всех аспектах, касающихся гидрологии. До перехода в H2i Андрей в течение 3 лет работал старшим исследова- телем данных в инновационном хабе IAG InsurTech. Прежде чем перебраться в Сингапур в 2018 г., он работал исследователем данных в TrafficGuard.ai — австра- лийском стартапе, разрабатывающем инновационные алгоритмы для обработки данных, связанных с обнаружением мошеннической рекламы в сотовых сетях. В 2013 г. Андрей получил докторскую степень по математике и статистике в Универ- ситете Монаша (Monash University, Australia). К тому моменту он уже имел степень MBA, полученную в Великобритании, а также высшее образование в России. В свободное время Андрей любит участвовать в соревновательных проектах по data science, изучать новые инструменты из экосистем Python и R, исследовать новей- шие тренды в веб-разработке, решать шахматные задачи, а также читать об истории естественных наук и математики. Фират Гонен (Firat Gonen) — руководитель по исследованию данных и аналитике в компании Getir. Гонен возглавляет команды, занимающиеся исследованием и анализом данных, разрабатывающие инновационные ультрасовременные решения в области машинного обучения. Он управлял командами, занятыми внедрением искусственного интеллекта в турецком филиале Vodafone. До Vodafone Гонен ра- ботал главным исследователем данных в группе Dogus (одном из крупнейших ту- рецких концернов). Фират— обладатель разностороннего образования, в частно-
Составители 15 сти, он имеет степень PhD по нейронаукам и нейронным сетям, полученную в уни- верситете Хьюстона, а также является экспертом по машинному обучению, глубо- кому обучению, визуальному вниманию, принятию решений и генетическим алго- ритмам, более 12 лет работая в этой отрасли. Он автор нескольких научных работ, опубликованных в отраслевых журналах. Кроме того, он трехкратный гроссмейстер Kaggle, обладатель более 10 медалей за участие в международных соревнованиях. Вдобавок в 2020 г. он был выбран глобальным послом HP в области науки о дан- ных (HP Data Science Global Ambassador). О респондентах Нам посчастливилось собрать в этой книге интервью 31 талантливого представителя Kaggle, которых мы попросили рассказать о времени, проведенном на платформе. Их ответы россыпью распределены по всей книге. Высказанные ими мнения охва- тывают широкий спектр взглядов, причем многие проницательные соображения в той же степени схожи, в какой и различны. Каждого из авторов этого вклада мы выслушали с большим интересом и думаем, что эти вставки не менее понравятся и вам, читатели. Благодарим их всех и далее перечислим их в алфавитном порядке. Абхишек Тхакур (Abhishek Thakur), в настоящее время занят разработкой AutoNLP в Hugging Face. Альберто Данезе (Alberto Danese), руководитель по Data science в Nexi. Андрада Олтеану (Andrada Olteanu), исследователь данных в Endava, разработчик- эксперт по весам и смещениям, а также глобальный посол HP в области науки о данных (HP Data Science Global Ambassador). Андрей Лукьяненко (Andrey Lukyanenko), инженер по машинному обучению и технический руководитель в группе компаний МТС. Боян Тунгуз (Bojan Tunguz), разработчик моделей машинного обучения в компа- нии NVIDIA. Габриель Преда (Gabriel Preda), главный исследователь данных в Endava. Джулиано Янсон (Giuliano Janson), старший исследователь прикладных задач в области машинного обучения и обработки естественного языка в Zillow Group. Дмитрий Ларко (Dmitry Larko), главный исследователь данных в H2O.ai. Дэн Беккер (Dan Becker), вице-президент по продукту в области интеллектуальных решений в компании DataRobot. Жан-Франсуа Пюже (Jean-Francois Puget), выдающийся инженер, RAPIDS в ком- пании NVIDIA, а также руководитель команды гроссмейстеров Kaggle в составе WIDIA. Жилберту Титерич (Gilberto Titericz), старший исследователь данных в NVIDIA. Иран Чзан (Yirun Zhang), аспирант последнего курса в Королевском колледже Лондона (King’s College London), специализация — прикладное машинное обучение.
16 Составители Ифань Се (Yifan Xie), соосновательница Arion Ltd., консалтинговой фирмы по ис- следованию данных. Казуки Онодера (Kazuki Onodera), старший исследователь данных и специалист по глубокому обучению в NVIDIA, член команды KGMON в составе NVIDIA. Крис Деотт (Chris Deotte), старший исследователь данных в компании NVIDIA. Ксавье Конорт (Xavier Conort), основатель и генеральный директор компании Data Mapping and Engineering. Лора Финк (Laura Fink), руководитель направления Data science в MicroMata. Мартин Хенце (Martin Henze), обладатель степени PhD по астрофизике и исследо- ватель данных в Edison Software. Микель Бобер-Иризар (Mikel Bober-Irizar), исследователь машинного обучения в ForecomAI и студент (специализация — машинное обучение) Кембриджского уни- верситета (University of Cambridge). Осаму Акияма (Osamu Akiyama), доктор медицины в Университете Осаки (Osaka University). Павел Янкевич (Pawel Jankiewicz), главный исследователь данных и разработчик искусственного интеллекта в компании LogicAI, также являющийся ее сооснователем. Парул Пандей (Parul Pandey), исследователь данных в H2O.ai. Райан Чеслер (Ryan Chester), исследователь данных в H2O.ai. Роб Мулла (Rob Mulla), старший исследователь данных в Biocore LLC. Рохан Рао (Rohan Rao), старший исследователь данных в H2O.ai. Ручи Бхатия (Ruchi Bhatia), исследователь данных, глобальный посол HP в облас- ти науки о данных (HP Data Science Global Ambassador), аспирантка Университета Карнеги — Меллона (Carnegie Mellon University). Судалай Раджкумар (Sudalai Rajkumar), консультант по искусственному интел- лекту и машинному обучению, работающий со стартапами. Фират Гонен (Firat Gonen), директор по исследованию данных и аналитике в ком- пании Getir, а также глобальный посол HP в области науки о данных (HP Data Science Global Ambassador). Чжон Юн Ли (Jeong-Yoon Lee), старший научный сотрудник группы разработки алгоритмов ранжирования и поиска в Netflix Research. Шотаро Исихара (Shotaro Ishihara), исследователь данных в японском новостном СМИ. Эндрю Мараньяно (Andrew Maranhao), старший исследователь данных в больнице им. Альберта Эйнштейна, Сан-Паулу (Hospital Albert Einstein, Sao Paulo).
Составители Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
Введение Оба автора этой книги имеют за плечами более десяти лет участия в соревнованиях Kaggle. Были у нас взлеты и падения. Не раз нам доводилось переключаться и уде- лять внимание другим видам деятельности, связанным с Kaggle. Со временем мы посвятили себя не только соревнованиям, но и наработке контента и кода, ориенти- руясь на потребности рынка данных и исходя из наших профессиональных устрем- лений. На данном этапе пути мы ощутили, что наш совокупный опыт и неугасшая страсть к соревнованиям действительно могут пригодиться новичкам, — и вдохно- вились идеей написать книгу, в которой обобщили бы весь ключевой опыт, кото- рый может им понадобиться. Так им будет проще начать путь по дороге соревнова- тельной data science. Тогда мы решили взяться за эту книгу, поставив перед собой такую цель. • Собрать в одном источнике наилучшие советы, которые помогли бы стать конкурентоспособным. Затронуть большинство проблем, с которыми можно столкнуться при участии в конкурсах Kaggle, а также в других соревнованиях по data science. • Предложить достаточно советов, которые помогли бы читателю выйти на уровень Expert (эксперт) в любой ’’номинации” Kaggle: Competitions (сорев- нования), Datasets (датасеты), Notebooks (блокноты) или Discussion (обсуж- дения). • Дать советы, как взять максимум от Kaggle и использовать этот опыт для профессионального роста в области data science. • Собрать в одном источнике как можно больше точек зрения, отражающих, каково участвовать в соревнованиях Kaggle. Для этого взять интервью у мас- теров и гроссмейстеров Kaggle и выслушать их истории. Таким образом, мы написали книгу, в которой продемонстрировано, как преуспеть в соревнованиях и выжать максимум из возможностей, предлагаемых Kaggle. Кро- ме того, книга послужит практическим справочником, благодаря которому вы смо- жете сэкономить время и силы — ведь мы выбрали для вас множество советов и приемов, которые нелегко освоить самостоятельно, найти на форумах Kaggle и в Интернете вообще. Тем не менее книга не ограничивается чисто прикладным мате- риалом; она также призвана натолкнуть вас на идеи о том, как прокачать карьеру в области data science.
Введение 19 Сразу предупреждаем: эта книга не подходит для изучения data science с нуля. Мы не будем подробно объяснять, как устроены линейная регрессия или случайные леса, или градиентный бустинг, но расскажем, как лучше всего их использовать и получить от них максимальный результат при решении задачи на данные. Мы рас- считываем, что читатель обладает солидными базовыми знаниями и хотя бы мини- мальным профессиональным опытом в области науки о данных, а также умеет ра- ботать с Python. Если вы только начинаете путь в исследовании данных, то рекомендуем сначала почитать другие книги о data science, глубоком обучении или машинном обучении, пройти онлайн-курсы, например предлагаемые на платформе Kaggle, а также в edX или Coursera. Если вы хотите приступить к изучению data science на практике или проверить себя на нетривиальных и интригующих задачах с данными, тем временем также выстро- ив отличную сеть коллег-профессионалов, настолько же увлеченных данными, на- сколько и вы, — то это действительно книга для вас. Начинаем! Для кого эта книга К моменту завершения этой книги на Kaggle было 96 190 новичков (пользователей, только зарегистрировавшихся на сайте) и 67 666 потенциальных участников сорев- нований (тех, кто только заполнил профиль). Эта книга была написана для них и для всех остальных, кто хочет наконец-то окунуться в соревнования Kaggle и на- чать на них учиться. О чем эта книга Часть I. Знакомство с соревнованиями Глава 1 "Знакомство с Kaggle и другими соревнованиями по науке о данных". Объ- ясняется, как из спортивного программирования развились соревнования по науке о данных. Объясняется, почему платформа Kaggle — наиболее популярная среди себе подобных, и дается общее представление о том, как она работает. Глава 2 "Организация данных". В этой главе вы познакомитесь с датасетами Kaggle — именно в виде таких наборов данные стандартно хранятся на платформе. Обсудим обустройство, сбор и использование данных при работе на Kaggle. Глава 3 "Работаем и учимся с Kaggle Notebooks". Обсуждаются блокноты — базо- вая среда разработки, используемая в Kaggle. Расскажем об основах использования блокнотов и среды GCP, а также о том, как с их помощью наработать портфолио для развития в области data science.
20 Введение Глава 4 "Используем форумы". Здесь вы сможете познакомиться с форумами, на которых ведутся дискуссии, — это основные площадки, предназначенные на Kaggle для общения и обмена идеями. Часть II. Оттачивание соревновательных навыков Глава 5 "Задачи и метрики на соревнованиях". Подробно рассказано, как сильно влияют метрики, применимые для оценки конкретных задач, на сами ваши дейст- вия при выстраивании модели на соревновании по data science. Также в этой главе показано, какие разнообразные метрики применяются на соревнованиях по data science. Глава 6 "Построение схемы валидации". Рассказано, насколько важна валидация данных на описываемых соревнованиях, обсуждаются переобучение, встряска, утечка в данных, состязательная валидация, разнообразные стратегии валидации и стратегии для окончательной подачи материала. Глава 7 "Моделирование для табличных данных". Рассматриваются соревнования по работе с таблицами. В Kaggle они закрепились сравнительно недавно, в рамках конкурса Tabular Playground Series. Задачи на работу с таблицами — стандартная практика для многих исследователей данных, и именно решая такие задачи, можно многому научиться на Kaggle. Глава 8 "Оптимизация гиперпараметров". Исследуется, как распространить подход с использованием перекрестной валидации, чтобы находить для своих моделей наилучшие гиперпараметры — иными словами, такие, которые лучше всего гене- рализуются в таблице лидеров, — в условиях цейтнота и дефицита ресурсов (ти- пичная ситуация на соревнованиях Kaggle). Глава 9 "Ансамбли: блендинг и стекинг". Объясняются ансамблевые приемы обра- ботки множественных моделей, в частности усреднение, блендинг и стекинг. Здесь вам предлагаются и теория, и практика, и примеры кода, которыми вы можете поль- зоваться в качестве шаблонов для выстраивания собственных решений на Kaggle. Глава 10 "Моделирование в компьютерном зрении". Обсуждаются задачи, связан- ные с компьютерным зрением. Это одна из наиболее популярных тем в области ис- кусственного интеллекта в целом и на Kaggle в частности. Мы от начала и до конца продемонстрируем варианты конвейеров, позволяющих выстраивать решения для таких задач, как классификация изображений, детектирование объектов и сегмен- тация изображений. Глава И "Моделирование для обработки естественного языка". Здесь мы сосредо- точимся на часто встречающихся типах задач Kaggle, посвященных обработке есте- ственного языка. Продемонстрируем, как создать сквозное решение для такой по- пулярной задачи, как ответы на вопросы, в пределах заданной предметной области. Глава 12 "Соревнования по моделированию и оптимизации". Дается обзор по раз- личным вариантам симуляций — это новый класс задач, популярность которых на Kaggle в последние годы быстро растет.
Введение 21 Часть III. Использование соревнований в своей карьере Глава 13 "Создание портфолио проектов и идей". В этой главе исследуется, как выделиться, выгодно подав свою работу на Kaggle и на других сайтах. Глава 14 "Поиск новых профессиональных возможностей". Дается заключитель- ный обзор того, как Kaggle может благоприятствовать вашей карьере. Обсуждается, как можно задействовать весь приобретенный на Kaggle опыт, чтобы найти новые возможности для развития карьеры. Как получить максимальную отдачу от этой книги Код на Python, приведенный в этой книге, специально предназначен для выполне- ния в блокнотах Kaggle, не требуется ничего устанавливать на локальном компью- тере. Следовательно, можете не волноваться о том, на какой именно машине вам работать или какую версию Python следует установить. Всё, что вам потребуется, — это компьютер с выходом в Интернет и бесплатный аккаунт Kaggle. На самом деле, первое, что вам необходимо для выполнения кода в блокноте Kaggle (о том, как это делается, рассказано в главе 3), — это завести акка- унт на Kaggle. Если у вас его еще нет, просто перейдите на kaggle.com и следуйте инструкциям, данным на сайте. На протяжении всего изложения мы ссылаемся на множество разных ресурсов, ко- торые, полагаем, будут вам полезны. Если мы дали ссылку — изучите, что по ней расположено. Например, это могут быть публичные блокноты Kaggle, код из кото- рых вы можете позаимствовать, а также другие материалы, иллюстрирующие те концепции и идеи, что рассматриваются в этой книге. Загрузите файлы с примерами кода Комплект исходного кода для данной книги размещен на GitHub по адресу https://github.com/PacktPublishing/The-Kaggle-Book. У нас также есть другие комплекты исходного кода из нашего обширного каталога книг и видео, доступных по адресу https://github.com/PacktPublishing/. Рекомендуем ознакомиться с ними! Загрузите цветные изображения Мы также предоставляем PDF-файл с цветными изображениями снимков экрана и графиков, использованных в этой книге. Вы можете скачать этот файл по адресу: https://static.packt-cdn.com/downloads/9781801817479_ColorImages.pdf.1 1 Файл с цветными иллюстрациями для русскоязычного издания представлен здесь: https://zip.bhv.ru/9785977519038.zip.
22 Введение Условные обозначения и соглашения В книге используются следующие типографские условные обозначения. CodelnText указывает на примеры кода в тексте, имена таблиц баз данных, пользова- тельский ввод. Листинг кода обозначается следующим образом: from google.colab import drive drive.mount('/content/gdrive') Любые примеры ввода или вывода с использованием командной строки записыва- ются следующим образом: I genuinely have no idea what the output of this, sequence of words will be - it will be interesting to find out what nlpaug can do with this! Полужирный шрифт обозначает новый термин или важное слово, интернет-адрес и адрес электронной почты; таким же образом выделяются в тексте слова, которые вы видите на экране, — названия пунктов меню или элементов диалоговых окон. Пример: ’’Ограничения на размер на данный момент — 100 Гбайт на один датасет и 100 Гбайт в целом”. Предупреждения или важные примечания выглядят таким образом. Таким образом обозначаются советы и рекомендации.
Часть I Знакомство с соревнованиями Kaggle

1 Знакомство с Kaggle и другими соревнованиями по науке о данных Соревнования в области науки о данных существуют давно. Они начинались как увлечение горстки энтузиастов, но постепенно привлекали всё больше внимания, и теперь в них участвуют миллионы исследователей данных (специалистов по нау- кам о данных). Многие годы участвуя в конкурсах на самой популярной соревнова- тельной платформе — Kaggle, мы были свидетелями и участниками этих изменений. Сейчас, задавшись целью найти информацию о Kaggle и других соревновательных платформах, вы легко отыщите огромное количество лекций, семинаров, подкас- тов, интервью и даже онлайн-курсов, рассказывающих, как побеждать в конкурсах (обычно советы сводятся к использованию в разных пропорциях упорства, вычис- лительных ресурсов и затраченного времени). Однако только в данной книге вы обнаружите структурированное изложение того, как разобраться в многообразии соревнований и извлечь из участия в них максимум — не только для очков в рей- тинге, но и для профессионального опыта. В этой книге мы хотим, вместо простого набора подсказок о том, как добиться вы- соких результатов в конкурсах, предложить вам план, позволяющий получить от них наибольшую пользу, в частности, для вашей карьеры. Содержание книги до- полняют интервью с мастерами и гроссмейстерами Kaggle. Мы надеемся, что эти интервью покажут вам соревнования с разных сторон, мотивируют участвовать в них, а также станут источником идей. Мы передадим вам знания, извлеченные нами из разных источников и собственно- го опыта участия в соревнованиях, и к концу книги вы будете полностью готовы к дальнейшему пути, росту и развитию. В этой главе мы начнем с рассказа о том, как спортивное программирование пре- вратилось в соревнования по анализу данных, почему платформа Kaggle стала наи- более популярной и как она устроена.
26 Часть I. Знакомство с соревнованиями Kaggle Мы затронем следующие темы: • появление и рост соревновательных платформ; • парадигма каркаса для общих задач (common task framework); • платформа Kaggle и ее альтернативы; • как устроены соревнования на Kaggle: стадии, типы, посылки, таблица ре- зультатов, вычислительные ресурсы, нетворкинг и многое другое. Появление и рост соревновательных платформ Спортивное программирование имеет долгую историю, начавшуюся в 1970-е годы с первых соревнований ICPC (International Collegiate Programming Contest — Меж- дународная студенческая олимпиада по программированию). Исходно ICPC была соревнованием по написанию программ (поначалу— только на FORTRAN), ре- шающих выданный набор задач. В ней участвовали малочисленные команды, пред- ставляющие университеты и компании. Для победы требовались логическое мыш- ление, навыки программирования и командной работы. Соревновательный азарт и возможность привлечь внимание рекрутеров способст- вовали вовлечению студентов и надолго обеспечили популярность соревнований по спортивному программированию. Некоторые финалисты ICPC впоследствии стали известными людьми, например Адам д’Анджело (Adam D’Angelo), бывший технический директор Facebook и основатель Quora, Николай Дуров, сооснователь мессенджера Telegram, и Матеи Захария (Matei Zaharia), создатель Apache Spark. Все они, как и многие другие высококлассные профессионалы, участвовали в ICPC. Вслед за ICPC появились и другие соревнования по спортивному программирова- нию — в особенности после 2000 г., когда стало доступно удаленное участие, что упрощало и удешевляло проведение соревнований. Формат большинства соревно- ваний схож: имеется набор задач, необходимо написать решающий эти задачи код. Победители получают призы, а также свою долю славы и внимания со стороны рекрутеров. Тематика задач спортивного программирования разнообразна: комбинаторика, тео- рия чисел, теория графов, алгоритмическая теория игр, вычислительная геометрия, алгоритмы на строках, структуры данных. Недавно начали возникать и задачи, от- носящиеся к искусственному интеллекту, в особенности после запуска KDD Сир, соревнования по извлечению знаний и анализу данных, проводимого Специальной тематической группой (Special Interest Group, SIG) Ассоциации вычислительной техники (Association for Computing Machinery, ACM) во время ежегодной конфе- ренции (https://kdd.org/conferences). На первом KDD Сир, проведенном в 1997 г. и положившем начало продолжающейся доныне серии конкурсов, была дана задача оптимизации кривой Лоренца (также из- вестной как lift-кривая) для прямого маркетинга. Архив задач и данных, а также списки
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 27 победителей можно найти на https://www.kdd.org/kdd-cup. Страница последнего на момент написания книги конкурса расположена по адресу https://ogb.stanford.edu/ kddcup2021/. Соревнования KDD Сир оказались очень эффективными для распро- странения лучших практик анализа данных, по их результатам появилось много статей с описаниями методов, решений, датасетов, позволивших специалистам учиться, экспериментировать и сравнивать свои результаты. Успех соревнований по спортивному программированию и KDD Сир сподвиг такие компании, как Netflix, и таких предпринимателей, как Энтони Голдблум (Anthony Goldbloom), на создание первых платформ для соревнований по науке о данных, на которых компании могли бы размещать трудные задачи и пользоваться предло- женными решениями. Так как в науке о данных нет "серебряной пули", решающей все задачи, зачастую приходится пробовать все возможные подходы (что, естест- венно, занимает много времени). Как гласит теорема о бесплатном обеде (no free lunch theorem, NFL), сформулированная Дэвидом Вольпортом (David Wolpert) и Уильямом Макреди (William Macready), ни один алгоритм не может превзойти все остальные на всех задачах. Она говорит нам, что любой алгоритм ма- шинного обучения работает хорошо только тогда, когда его простран- r—-Ij ство гипотез содержит истинное решение. Таким образом, вы не можете знать заранее, сработает ли ваш подход, и остается только тестировать его на имеющихся данных. Никаких теоретических уловок, позволяю- щих срезать этот путь, никаких тайных знаний — только эмпирическая проверка. Подробнее о NFL можно прочитать в статье https://analyticsindiamag.com/ what-are-the-no-free-lunch-theorems-in-data-science/. Краудсорсинг идеален, когда необходимо перебрать большое количество алгорит- мов и преобразований данных и найти наилучшую комбинацию, а человеко-часов и вычислительных ресурсов не хватает. Поэтому конкурсы проводят и государствен- ные учреждения, и частные компании. Так, например: • Управление перспективных исследовательских проектов Министерства обо- роны США (Defense Advanced Research Projects Agency, DARPA) проводило конкурсы, касающиеся беспилотных автомобилей, робототехники, машинно- го перевода, распознавания голоса и отпечатков пальцев, информационного поиска, оптического распознавания символов, автоматического распознава- ния целей и многих других тем; • компания Netflix проводила конкурс с целью улучшить свой алгоритм выда- чи рекомендаций. Конкурс Netflix ставил целью улучшить имеющийся алгоритм коллаборативной фильтрации, предсказывающий оценку, которую пользователь даст фильму. При этом были известны только оценки, выставленные пользователем другим фильмам.
28 Часть I. Знакомство с соревнованиями Kaggle Другой информации ни о пользователях, ни о фильмах (например, названия и опи- сания) в данных не было, давались лишь их идентификаторы. Участникам конкур- са, таким образом, приходилось придумывать хитрые способы использовать пред- шествующие оценки*. Главный приз в миллион долларов можно было получить только в случае, если новый алгоритм существенно улучшал имеющийся. Конкурс проходил с 2006 по 2009 г., победу одержала команда, образовавшаяся слиянием нескольких: уже известной в мире Kaggle команды из Commendo Research & Consulting GmbH в составе Андреаса Тошера (Andreas Toscher) и Михе- ля Ярера (Michael* Jahrer), двоих исследователей из AT&T Labs и еще двоих из Yahoo!. В конечном счете победа в конкурсе потребовала такого количества вы- числительных ресурсов и такой сложной комбинации разных методов, что без слияния команд она была бы невозможной. Поэтому компания Netflix не стала применять решение полностью, а лишь позаимствовала для улучшения своего ал- горитма Cinematch Несколько ключевых идей. Подробнее об этом можно прочитать в статье журнала Wired: https://www.wired.com/2012/04/netflix-prize-costs/. Главным результатом конкурса от Netflix было не само по себе найденное решение, быстро превзойденное при смещении фокуса компании с DVD на показ фильмов онлайн. Важнее и для участников, приобретших авторитет с области коллаборатив- ной фильтрации, и для компании, которая смогла применить улучшенный алгоритм в новой области, стали идеи. Соревновательная платформа Kaggle Другие компании, помимо Netflix, также обращались к соревнованиям по науке о данных. Их список велик, приведем лишь несколько примеров, принесших органи- затору заметную выгоду. Так, например: • страховая компания Allstate смогла улучшить актуарные модели, разработанные своими экспертами, после соревнования, в котором приняли участие сотни исследователей данных (https://www.kaggle.eom/c/ClaimPredictionChallenge); • компания General Electric смогла улучшить предсказание времени прибытия самолетов на 40%, если в качестве метрики использовать среднеквадратич- ную ошибку (https://www.kaggle.eom/c/flight). На платформе Kaggle к настоящему моменту прошли сотни соревнований, и это лишь два примера компаний, успешно ими воспользовавшихся. Отвлечемся нена- долго от конкретных конкурсов и поговорим о самой компании Kaggle. История Kaggle Платформа Kaggle появилась в феврале 2010 г. благодаря австралийцу Энтони Голд- блуму. Энтони получил университетский диплом по экономике и эконометрике, за- тем работал в Казначействе Австралии и в исследовательском отделе Резервного банка Австралии, затем проходил стажировку в Лондоне в еженедельном журнале The Economist, посвященном бизнесу, политике и технологиям. Во время этой ста-
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 29 жировки ему довелось стать автором статьи о больших данных, и у него появилась идея создать соревновательную платформу, позволяющую привлекать к важным и ин- тересным задачам машинного обучения лучших экспертов (https://www.smh.com.au/ technology/from-bondi-to-the-big-bucks-the-28yearold-whos-making-data-science-a- sport-20111104-lmyql.html). Так как для него была важна именно идея совместной работы, в качестве названия он придумал слово Kaggle, рифмующееся с англий- ским gaggle — стая гусей. Гусь и стал символом платформы. Переехав в США в Кремниевую долину, Голдблум получил 11 с четвертью мил- лионов долларов инвестиций в ходе раунда А от известных венчурных инвестици- онных фондов Khosla Ventures и Index Ventures. Стартовали первые соревнования. Сообщество росло, некоторые участники достигали немалых успехов, как, напри- мер, Джереми Ховард — австралийский исследователь данных и предприниматель, который выиграл несколько конкурсов и после этого стал президентом и ведущим исследователем компании. В декабре 2013 г. Джереми Ховард ушел с поста президента и основал новый стар- тап fast.ai (www.fast.ai), предлагающий курсы по машинному обучению и библио- теку для глубокого обучения. Еще двое выдающихся кэгглеров (так называют постоянных участников соревно- ваний) — Джереми Ачин (Jeremy Achin), Тома де Годой (Thomas de Godoy), попав в топ-10 общего рейтинга платформы, решили отойти от соревнований и основать собственную компанию DataRobot. Вскоре они начали нанимать сотрудников из числа лучших участников конкурсов Kaggle, чтобы их продукты создавались с ис- пользованием самых эффективных методов машинного обучения. Сейчас DataRobot — одна из ведущих компаний, разрабатывающих решения AutoML (программы для автоматического машинного обучения). Соревнования на Kaggle привлекали всё больше внимания публики. Даже крестный отец машинного обучения Джеффри Хинтон принял участие в конкурсе, прово- дившемся компанией Merck в 2012 г. (https://www.kaggle.eom/c/MerckActivity/ overview/winners), и выиграл его. Именно на Kaggle Франсуа Шолле (Francois Chollet) представил свою библиотеку глубокого обучения Keras во время соревно- ваний Otto Group Product Classification Challenge (https://www.kaggle.com/c/otto- group-product-classification-chaHenge/discussion/13632). Аналогично, Тяньцзи Чен (Tianqi Chen) представил библиотеку XGBoost, содержащую более быстрые и акку- ратно реализованные версии алгоритмов градиентного бустинга, в ходе Higgs Boson Machine Learning Challenge (https://www.kaggle.eom/c/higgs-boson/discussion/ 10335). Заметим, что Франсуа Шолле не только создал Keras, но и дал самый полезный ответ на вопрос, как выиграть конкурс Kaggle, на сайте Quora (https://www.quora.com/Why-has-Keras-been-so-successful-lately-at- Kaggle-competitions).
30 Часть I. Знакомство с соревнованиями Kaggle По сути, все, что вам надо, — быстро двигаться от одной версии реше- ния к другой, руководствуясь более эмпирическим опытом, чем теоре- тическими соображениями. Вряд ли существуют какие-то иные секреты победы в конкурсах Kaggle, не сводящиеся к упомянутым Франсуа Шолле. Кстати, Франсуа Шолле и сам организовывал конкурс на Kaggle (https://www.kaggle.eom/c/abstraction-and-reasoning-challenge/), зачас- тую считающийся первым в мире соревнованием по общему искусст- венному интеллекту. Соревнование за соревнованием, Kaggle в 2017 г. достиг отметки в миллион поль- зователей. В том же году Фей-Фей Ли (Fei-Fei Li), главный исследователь в Google, объявила, что Google Alphabet собирается приобрести Kaggle. С тех пор Kaggle яв- ляется частью компании Google. Сообщество Kaggle продолжает расти. В своем твите (https://twitter.com/ antgoldbloom/status/1400119591246852096) Энтони Голдблум сообщил, что боль- шинство пользователей, помимо участия в соревнованиях, скачивали датасеты (Kaggle успел стать и важным хранилищем данных), создавали публичные Python- или R-блокноты или проходили один из предложенных обучающих кур- сов (рис. 1.1). Пользователи Рис. 1.1. Диаграмма активности пользователей Kaggle в 2018-2020 гг.
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 31 Kaggle помог своим пользователям добиться немалых успехов, например: • создать собственную компанию; • создать программы и библиотеки для машинного обучения; • дать интервью журналам (например, https://www.wired.com/story/solve- these-tough-data-problems-and-watch-job-offers-roll-in/); • написать книги по машинному обучению (например, https://twitter.com/ antgoldbloom/status/745662719588589568); • найти работу мечты. И, главное, научиться многим полезным в науке о данных навыкам и методам. Другие конкурсные платформы Хотя эта книга посвящена в первую очередь конкурсам Kaggle, нельзя упускать из виду, что многие состязания по наукам о данных проходят и на других платформах. На самом деле большая часть информации, которую вы найдете в этой книге, при- годится в любых соревнованиях, поскольку их принципы и плюсы от участия в них обычно схожи. Хотя часть платформ ориентирована только на определенные стра- ны или типы соревнований, мы вкратце представим некоторые из них — по край- ней мере, те, с которыми знакомы сами. • DrivenData (https://www.drivendata.org/competitions/)— платформа, посвя- щенная социально значимым задачам (https://www.drivendata.co/blog/intro- to-machine-learning-social-impact/). Задачей компании является привлечение методов науки о данных к решению самых актуальных общественных про- блем. Например, как можно прочитать в статье https://www.engadget.com/ facebook-ai-hate-speech-covid-19-160037191.html, компания Facebook выбра- ла DrivenData для конкурса, посвященного борьбе с языком ненависти и рас- пространением недостоверной информации. • Numerai (https://numer.ai/) — хедж-фонд из Сан-Франциско, основанный на использовании краудсорсинга и искусственного интеллекта. Он проводит еженедельные соревнования на замаскированных данных, победители в ко- торых могут получить приз в криптовалюте Numeraire. • Платформа CrowdANALYTIX (https://www.crowdanalytix.com/community) сейчас не так активна, но ранее провела немало интересных конкурсов, про которые можно почитать в посте https://towardsdatascience.com/how-i-won- top-five-in-a-deep-learning-competition-753c788cadel. Для того чтобы полу- чить представление о конкурсах на этой платформе, стоит обратиться к блогу сообщества: https://www.crowdanalytix.com/jq/communityBlog/listBlog.html. • Signate (https://signate.jp/competitions) — японская платформа для соревно- ваний по науке о данных. На ней проводится много конкурсов, а система рей- тинга схожа с таковой у Kaggle (см. https://signate.jp/users/rankings).
32 Часть I. Знакомство с соревнованиями Kaggle • Zindi (https ://zindi.africa/competitions) — африканская соревновательная платформа, ее конкурсы в основном посвящены самым актуальным социаль- ным, экономическим и экологическим проблемам Африки. • Alibaba Cloud (https://www.alibabacloud.com/campaign/tianchi-competitions) — китайский облачный провайдер, занимающийся также искусственным интел- лектом и запустивший серию соревнований Tianchi Academic. Организаторы сотрудничают с такими научными конференциями, как SIGKDD, IJCAI- PRICAI, CVPR, и проводят конкурсы, например, по поиску трехмерной фигу- ры по изображениям, восстановлению трехмерной фигуры и сегментации. • Analytics Vidhya (https://datahack.analyticsvidhya.com/)— крупнейшее в Индии сообщество исследователей данных, имеющее также собственную платформу для хакатонов. • CodaLab (https://codalab.lri.fr/) — французская платформа для соревнований по наукам о данных, созданная совместно Microsoft и Стэнфордским универ- ситетом в 2013 г. Для обмена методами и моделями они предлагают облач- ные блокноты Worksheets (https://worksheets.codalab.org/). К другим небольшим платформам относятся, например, CrowdAI (https://www.crowdai.org/) от Федеральной политехнической школы Лозанны, InnoCentive (https://www.innocentive.com/), Grand-Challenge (https://grand- challenge.org/) для работы с биомедицинскими изображениями, DataFountain (https://www.datafountain.cn/business?lang=en-US), OpenML (https:// www.openml.org/). Список текущих соревнований всегда можно посмотреть в рос- сийском сообществе Open Data Science (https://ods.ai/competitions). Обзор активных соревнований также можно найти на сайте mlcontests.com, YY вместе с актуальными ценами на аренду GPU (graphics processing unit, z g 4 графический процессор). Сайт оперативно обновляется и позволяет су- дить о ситуации в мире соревнований по науке о данных. Kaggle, однако, остается лучшей платформой, с самыми интересными соревнова- ниями и наибольшими возможностями быть замеченным. Однако мы рекомендуем принимать участие и в соревнованиях на других платформах, когда их тематика совпадает с вашими личными и профессиональными интересами. Таких платформ, как вы видите, довольно много, что позволяет выбрать наиболее интересный вам конкурс. Помимо прочего, на менее известных соревнованиях может быть меньшая конку- ренция и меньше стресса (что позволит добиться лучшего результата, а порой и победы). Однако стоит ожидать и меньшей готовности участников делиться своими решениями и идеями, чем на Kaggle с его уникальными возможностями для обще- ния и обмена полезной информацией.
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 33 Знакомство с Kaggle Теперь мы ближе познакомимся с особенностями Kaggle. На последующих страни- цах мы расскажем о платформе и соревнованиях на ней, дадим общее представле- ние об участии в конкурсах. В следующих главах мы вернемся к более подробному обсуждению многих затронутых тем и дадим советы по стратегии. Стадии соревнования Конкурсы Kaggle проходят в несколько стадий. Рассмотрим их внимательнее и поймем, как устроены соревнования по науке о данных и чего от них ждать. Запуск соревнования обычно анонсируется в социальных сетях, например на странице Kaggle в Twitter (https://twitter.com/kaggle), при этом название конкурса появляет- ся в разделе Active Competitions (Активные соревнования) на странице Competitions (https://www.kaggle.com/competitions). Щелкнув на названии кон- курса, вы перейдете на его страницу. Здесь можно проверить, дают ли за этот кон- курс призы (а также медали и очки в рейтинг), число команд-участников на данный момент и оставшееся для решения время. Можно начать изучение конкурса с вкладки Overview (Обзор) (рис. 1.2), дающей информацию о: • тематике соревнования; • метрике, по которой будет измеряться качество моделей; • графике соревнования; • призах; • правилах и требованиях к участникам. Часто на график обращают мало внимания, но на самом деле на него стоит смот- реть в первую очередь. В нем будут указаны не только даты начала и окончания конкурса, но и дата, до которой нужно принять его правила (крайний срок приня- тия правил, rule acceptance deadline). Эта дата— последний день, когда можно присоединиться к соревнованию (отметив, что вы принимаете его правила). Также только до определенной даты (крайний срок слияния команд, team merger dead- line) можно объединяться с другой командой. На вкладку Rules (Правила) также часто не обращают внимания и переходят сразу к данным, между тем она очень важна. Ключевая информация, которую можно найти на этой вкладке: • можете ли вы претендовать на призы; • допустимо ли для улучшения решения использовать внешние данные; • сколько отправок решения (submissions) за день вы можете сделать; • сколько решений можно выбрать в качестве итоговых.
34 Часть I. Знакомство с соревнованиями Kaggle Н&М Personalized Fashion Recommendations Provide product recommendations based on previous purchases $50,000 Prize Money JjJ. H&M Group 1,283 teams 2 months to go (a month to go until merger deadline) Overview Data Code Discussion Leaderboard Rules Overview Description H&M Group is a family of brands and businesses with 53 online markets and approximately 4,850 stores. Our online store offers shoppers an extensive selection of products to browse through. But with too many Evaluation choices, customers might not quickly find what interests them or what they are looking for, and Timeline ultimately, they might not make a purchase. To enhance the shopping experience, product recommendations are key. More importantly, helping customers make the right choices also has a Prizes positive implications for sustainability, as it reduces returns, and thereby minimizes emissions from transportation. In this competition, H&M Group invites you to develop product recommendations based on data from previous transactions, as well as from customer and product meta data. The available meta data spans from simple data, such as garment type and customer age, to text data from product descriptions, to image data from garment Images. There are no preconceptions on what information that may be useful - that is for you to find out. If you want to investigate a categorical data type algorithm, or dive into NLP and image processing deep learning, that is up to you. Рис. 1.2. Страница соревнования на Kaggle Приняв правила, вы можете скачивать данные из раздела Data (Данные) или начать работу над онлайн-блокнотом в разделе Code (Код). Возможно как писать код с нуля, так и использовать выложенный другими участниками. Для автоматизации скачивания данных и отправки решений стоит познакомиться с Kaggle API. Этот инструмент важен, если вы хотите обучать модели на своем ком- пьютере или в облачном сервисе, не относящемся к Kaggle. Подробнее узнать об API можно на https://www.kaggle.com/docs/api, код также выложен на GitHub: https://github.com/Kaggle/kaggle-api. В репозитории Kaggle на GitHub можно найти Docker-образы для блокнотов Kaggle (рис. 1.3). Мы советуем вам при работе над решением обращаться к форуму (Discussion), за- давать вопросы по конкретному конкурсу и отвечать на них. Часто можно найти на форуме информацию о проблемах в данных и идеи по поводу того, как улучшить решение. Многие успешные кэгглеры говорили, что форумы помогли им добиться лучших результатов и в целом узнать больше о машинном обучении. Когда решение готово, его надо отправить на проверку тестовой системе. На неко- торых конкурсах требуется отправить файл CSV, на некоторых — блокнот с кодом. Пока идет соревнование, можно отправлять новые решения.
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 35 notebook477901ba02 Data >l 4- Drift Session off (run a csl to start} ф + Adddite input if this Python 3 environment cases with stony helpful analytics libraries installed t It is defined by the ksggle/pythoo Docker mage; https. ^github.casfhaggle;‘docker python a for exoaple, here « several helpful packages co load Output iaport пиару a* np P linear algebra inport panda* a* pd # date processing C$t' file 1. 6 fe,g pd read.c.vj CJ rk«gg>e,*worfc)ng Setting» * Input date files ere available in the read-only ' /input'' directory H for example running this (by clicking run or pressing Shift*£mer) will list all files under the input directory Python Environment filenanee in o>.w«1k{ /fcagtgle/inpirC): Accelerator printfoa.path.joinfdirnane fllenane)) Internet # You can write up to 2№36 to the current directory (УмцмИе.'ногЫпд/} that pete praeerred as output utien you create • version using Save S Au * Pou can also write teapbrsry files ю /kaggie/teep./, but they won't be aavad outside of the current session Schedule a notebook run rmt> coot ни* C< Find Cods Help Search far examples of how to do thing* + Coda + Markdown 0 9 0 e О Рис. 1.3. Заготовка для блокнота Kaggle Вскоре после очередной отправки решения вы увидите свое место в таблице ре- зультатов и значение метрики вашего решения (время ожидания зависит от количе- ства необходимых вычислений). Они определяются только по части тестовых дан- ных (называемой публичным тестовым множеством, т. к. ваш результат на нем известен всем), поэтому могут лишь приблизительно соответствовать результатам на полных тестовых данных (рис. 1.4). Перед завершением конкурса каждый участник может выбрать несколько (как пра- вило, два) своих решений для подведения итоговых результатов. Рис. 1.4. Диаграмма, демонстрирующая, как вычисляется результат для публичной (public leaderboard) и частной (private leaderboard) таблиц результатов Лишь после завершения соревнований публикуются результаты выбранных участ- никами моделей на оставшихся тестовых данных — частном тестовом множестве.
36 Часть I. Знакомство с соревнованиями Kaggle Эта таблица результатов — private leaderboard — и будет итогом конкурса. Но пока она все еще не является окончательной и официальной. Сотрудники Kaggle потра- тят некоторое время на проверку того, что все участники соблюдали правила, и, возможно, кого-то дисквалифицируют. После этого результаты из частной таблицы становятся официальными, а список победителей объявляется. Многие участники начинают делиться своими стратегиями и кодом решений на форуме. Вы можете, если хотите, познакомиться с чужими решениями и попробовать улучшить свое. Это важный способ обучения, и мы настоятельно советуем им пользоваться. Типы соревнований и примеры Конкурсы Kaggle делятся на категории, каждая из которых имеет свои особенно- сти. Тип данных, сложность задач, призы и весь ход соревнований могут сильно разниться от одной категории к другой, поэтому в них стоит разобраться. Перед вами — официальный список категорий, который можно использовать при поиске конкурсов: • Featured (Избранные); • Masters (Мастера); • Annuals (Ежегодные); • Research (Исследовательские); • Recruitment (Найм); • Getting Started (Для начинающих); • Playground (Песочница); • Analytics (Аналитика); • Community (Соревнования сообществ). К категории Featured (Избранные) относится больше всего соревнований. Обычно они представляют собой реальную задачу от компании-спонсора. Победители по- лучают призы, но передают права на свое решение компании, они также обязаны предоставить компании подробный отчет о своем решении, а порой и лично участ- вовать во встречах. Каждый раз, заходя на Kaggle, вы обнаружите несколько активных Featured- конкурсов. Сейчас большинство из них посвящены применениям глубокого обуче- ния к неструктурированным данным, таким как текст, звук или видео. Раньше часто встречались и соревнования со структурированными, табличными данными — в то время решения кэгглеров (обычно использующие случайные леса или градиентный бустинг в сочетании с грамотным построением признаков) действительно могли улучшить существующие подходы к задаче. Сейчас они редко превзойдут решения, придуманные внутри компании хорошей командой исследователей данных или да- же созданные автоматически. При современном уровне технического прогресса и распространении знаний о машинном обучении выгода будет крайне мала. Однако в мире неструктурированных данных все иначе, и польза от улучшенного решения
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 37 может быть ощутимой. Так, предобученные нейронные сети, такие как BERT, улучшили результаты на многих задачах обработки текстов на десятки процентов. Соревнования Masters (Мастера) сейчас проходят редко. На них можно попасть только по специальному приглашению. Эта категория соревнований ориентирована на участников с высоким рейтингов — мастеров и гроссмейстеров. Ежегодные соревнования Annuals проходят каждый год в одно и то же время. Это, например, конкурс Санта Клауса (обычно посвященный задачам оптимизации ал- горитмов) и конкурс March Machine Learning Mania, проходящий с 2014 г. одно- временно с соревнованиями по баскетболу среди команд американских колледжей. Исследовательские соревнования (Research) посвящены некоторой научной про- блеме, иногда общественно значимой. Призы на таких конкурсах дают не всегда. Часто присутствует дополнительное требование — опубликовать решение в откры- том доступе. Компания Google провела в прошлом несколько конкурсов категории Research, на- пример Google Landmark Recognition 2020 (https://www.kaggle.com/c/landmark- recognition-2020), целью которого было распознавание на изображениях природ- ных и рукотворных достопримечательностей (и просто примет местности). Компании-спонсоры, желающие проверить потенциальных кандидатов на вакан- сии, проводят для этого соревнования категории Recruitment (Найм). В них могут принимать участие только команды из одного человека, а призом для лучших уча- стников является приглашение на интервью (но для этого также необходимо загру- зить свое резюме). В качестве примеров конкурсов этой категории можно привести: • конкурс от Facebook (https://www.kaggle.com/cZFacebookRecruiting)— на самом деле, эта компания проводила несколько подобных соревнований; • конкурс от Yelp (https://www.kaggle.eom/c/yelp-recruiting). На соревнованиях для начинающих (Getting Started) призов нет, зато на них пред- лагаются простые и доступные задачи, позволяющие новичкам познакомиться с принципами соревнований на Kaggle. Обычно это "полупостоянные" соревнова- ния — таблица результатов время от времени обнуляется. Если вы хотите изучать машинное обучение, стоит начать с этих соревнований — вы найдете множество блокнотов Kaggle, показывающих, как обрабатывать данные и строить модели, и вам всегда будут готовы помочь. К популярным конкурсам категории Getting Started относятся: • конкурс по распознаванию цифр {Digit Recognizer, https://www.kaggle.eom/c/ digit-recognizer); • конкурс по предсказанию, кто выжил на ’’Титанике’’ {Titanic— Machine Learning from Disaster, https://www.kaggle.eom/c/titanic); • конкурс по предсказанию цен на недвижимость {House Prices — Advanced Regression Techniques, https://www.kaggle.com/c/house-prices-advanced- regression-techniques).
38 Часть I. Знакомство с соревнованиями Kaggle Соревнования категории Playground (Песочница) чуть сложнее, чем Getting Started, однако они тоже предназначены в первую очередь для тренировки и про- верки навыков участников без того уровня стресса, который царит на соревнова- ниях категории Featured (хотя и в ’’песочнице” порой бывает нешуточный накал борьбы). Призами здесь обычно бывают небольшие денежные суммы или просто сувениры от Kaggle — чашки, футболки, носки — обозначаемые аббревиатурой swag ("Stuff We All Get" — "штучки, которые все мы получаем"). Один из самых известных конкурсов "песочницы" — "Кошки против собак" (Dogs vs. Cats. https://www.kaggle.eom/c/dogs-vs-cats), заданием в котором было отличить кошек от собак. Стоит упомянуть и соревнования категории Analytics (Аналитика), оценивание в которых не имеет численного выражения, а целью является генерация идей, набро- сков решений, презентаций и диаграмм. Скажем также про конкурсы сообществ (Community) — они раньше были известны как InClass ("в классе", "на занятиях") и проводятся как университетами, так и самими кэгглерами. Старт конкурсов этой категории анонсируется на https://www.kaggle.com/product-feedback/294337, а о том, как запустить свой конкурс, можно узнать по ссылкам https:// www.kaggle.com/c/about/host и https://www.kaggle.com/community-competitions- setup-guide. Парул Пандей https://www.kaggle.com/parulpandey Мы взяли интервью у Парул Пандей, гроссмейстера (в ка- тегории Notebooks) и мастера (в категории Datasets) Kaggle. Парул работает исследователем данных в компании H20.ai. Мы поговорили об аналитических соревнованиях и многом другом. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я очень люблю соревнования по аналитике, требующие провести анализ имею- щихся данных и представить подробный отчет. Это, например, конкурсы из се- рии Data science for Good (DS4G — наука о данных во благо), конкурсы по спор- тивной аналитике (например, результатов NFL), конкурсы по анализу опросов среди кэгглеров. В отличие от обычных соревнований, в них нет таблицы резуль- татов, позволяющей сравнить себя с другими, нет медалей и рейтинговых очков. С другой стороны, на этих конкурсах требуется привести решение полностью, от начала до конца, затрагивая все важные аспекты работы исследователя данных: очистку данных, извлечение нужных данных, визуализацию, формулировку вы- водов. Такие задачи позволяют понять, каково применение науки о данных в ре- альности. У них может не быть единственного наилучшего решения, но в них можно искать разные решения, сравнивать их и комбинировать между собой.
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 39 Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Мой первый шаг— это всегда разведочный анализ данных (exploratory data analysis, EDA) как на соревнованиях, так и на работе. Обычно я изучаю данные на предмет ’’красных флажков”, предупреждающих о возможных проблемах: не- согласованностях в данных, пропущенных значениях, выбросах и т. п. Следую- щий шаг — придумать хорошую, надежную стратегию кросс-валидации. Затем я читаю форум и смотрю некоторые из выложенных блокнотов. Обычно это слу- жит хорошей отправной точкой. Дальше я вношу изменения и дополнения, руко- водствуясь собственным опытом. Очень важно также отслеживать результаты работы модели. Однако на аналитических соревнованиях я люблю разбивать за- дачу на много маленьких этапов. Например, первым из них может быть просто понимание задачи, и на это порой уходит несколько дней. Затем я провожу раз- ведочный анализ данных, пишу базовое решение и начинаю постепенно его улучшать — по кусочку за раз. Это похоже на строительство из Lego, когда вы кладете по одному кирпичику и получаете в итоге что-то прекрасное. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, что ты вынесла из участия в нем Как я говорила, больше всего я люблю конкурсы категории Analytics, хотя ино- гда принимаю участие и в обычных. Расскажу об очень необычном конкурсе из серии Data science for Good, посвященном экологии (Environmental Insights Ex- plorer, https://www.kaggle.eom/c/ds4g-environmental-insights-explorer). Задачей было оценить выбросы в окружающую среду по показаниям датчиков. Меня поразила актуальность этой задачи. Конкурс касался изменений климата, которые сейчас происходят на нашей планете. В поисках информации для этого конкурса я, например, узнала о потрясающем прогрессе в области спутниковых изображений и в итоге достаточно глубоко погрузилась в эту тему. Я разобралась в том, как работают такие спутники, как Landsat, Modis, Sentinel, как они пере- дают собранные данные. Конкурс дал замечательную возможность изучить тему, о которой раньше я знала очень мало. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотела бы знать, когда начинала участвовать в соревнованиях? Расскажу о некоторых собственных ошибках в первые годы на Kaggle. Во- первых, многие новички рассматривают Kaggle только как платформу для сорев- нований. Да, если вы любите соревнования — их здесь много, но Kaggle есть что предложить и людям с другими интересами. Можно делиться с другими своим кодом, дискутировать, устанавливать контакты, делиться данными. Я поначалу использовала Kaggle только как источник данных и стала более активна лишь в последние пару лет. Теперь, оглядываясь назад, я считаю это большой ошибкой. Многие люди побаиваются соревнований, поэтому можно сначала освоиться на платформе, а уже потом переходить к конкурсам. Стоит сказать и о том, что мно- гие начинают работать в одиночку, теряют мотивацию и бросают. Создание ко- манды на Kaggle дает много преимуществ. Оно позволит научиться работать в команде и двигаться к общей цели в условиях ограниченного времени.
40 Часть I. Знакомство с соревнованиями Kaggle Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Хотя сейчас я провожу большую часть времени на Kaggle, раньше я пользовалась Zindi, платформой для соревнований по науке о данных, ориентированной на Африку. Там можно найти множество африканских датасетов. Kaggle очень мно- гогранен, но ему не хватает задач из различных уголков мира. Последнее время, впрочем, мы видим некоторое разнообразие задач — например, недавно прошел конкурс по обработке естественного языка, касающийся индийских диалектов (https://www.kaggle.com/competitions/chaii-hindi-and-tamil-question-answering). Я надеюсь, что подобные конкурсы, проводимые в разных странах, будут полез- ны как для исследователей, так и для всего сообщества в области науки о данных. Независимо от разделения конкурсов Kaggle на категории они могут проходить в разном формате. При обычном, простом (Simple) формате вы посылаете свое ре- шение, и оно оценивается по описанной ранее схеме. Более сложный формат — конкурсы, проходящие в две стадии. Окончательный датасет выкладывается толь- ко после завершения первой стадии конкурса и доступен лишь ее участникам. Двухстадийный формат появился, чтобы не дать отдельным участникам жульни- чать и злоупотреблять правилами: он позволяет оценить решения на ранее полно- стью неизвестном и доступном лишь на короткое время датасете. В отличие от ис- ходного формата, у участников гораздо меньше времени и попыток разработать решение, что мешает выявлять закономерности в тестовых данных. По той же причине недавно появились соревнования формата Code, где сдавать решение можно лишь с помощью блокнота Kaggle, но не загрузки готовых резуль- татов. Kaggle не устанавливает ограничений на выбор участником типа соревнова- ний, независимо от его опыта. Однако мы можем поделиться советами о том, какие категории и форматы стоит выбрать в зависимости от вашего уровня знаний и имеющихся ресурсов. • Абсолютным новичкам стоит начинать с конкурсов категорий Getting Started и Playground — на них вы сможете разобраться в работе Kaggle без супервысокой конкуренции. Тем не менее многие новички начинали и с кон- курсов категорий Featured и Research— конкуренция в их рамках только подстегивала учиться быстрее. Мы предлагаем ориентироваться на свой стиль обучения: кто-то предпочитает спокойно изучать платформу и совето- ваться с другими участниками (для чего идеально подходят категории Getting Started и Playground), другим для мотивации важен соревновательный азарт. • Стоит учесть, что соревнования категорий Featured и Research порой отно- сятся к переднему краю прикладного машинного обучения, так что вам нуж- ны либо глубокие знания, либо огромное желание самостоятельно разбирать- ся в предметной области. Наконец, имейте в виду, что львиная доля соревнований требует доступа к боль- шим вычислительным ресурсам, отсутствующим у основной массы исследователей
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 41 данных. Если вы используете какую-нибудь облачную платформу вне Kaggle, воз- можно, придется идти на дополнительные расходы. Наилучшим местом для при- ложения усилий могут стать соревнования формата Code либо те, где есть ограни- чение на время и ресурсы, поскольку они стремятся уравнять положение участников. Отправка решения и таблица результатов Общая схема работы Kaggle выглядит просто: тестовые данные скрыты от участни- ков, участники обучают модели, если ваша модель предсказывает ответы на тесто- вых данных лучше соперников, вы выигрываете. К сожалению, такое описание слишком упрощено. В нем не учитывается прямое и непрямое взаимодействие уча- стников, детали постановки задачи и особенности обучающих и тестовых данных. Парадигма каркаса для общих задач Более полное объяснение принципов работы Kaggle дано профессором статистики Стэнфордского университета Дэвидом Донохо (David Donoho, https:// web.stanford.edu/dept/statistics/cgi-bin/donoho/) в статье ”50 лет науки о данных” ("50 Years of Data science”), впервые появившейся в журнале Journal of Computational and Graphical Statistics, а затем опубликованной на сайте лаборатории Компьютерных наук и искусственного интеллекта Массачусетского технологиче- ского института (MIT Computer Science and Artificial Intelligence Laboratory, cm. http://courses.csail.mit.edu/18.337/2015/docs/50YearsDataScience.pdf). Профессор Донохо говорит не конкретно о Kaggle, но вообще о платформах для соревнований по науке о данных. Цитируя компьютерного лингвиста Марка Ли- бермана (Mark Liberman), он рассматривает соревнования и платформы как части парадигмы общей задачи, позволившей науке о данных в последние десятилетия внешне незаметно, но стремительно прогрессировать. Он утверждает, что, как по- казывает опыт, CTF (Common Task Framework, каркас для общих задач) может радикально улучшить решения задач науки о данных, и приводит в качестве при- меров конкурс Netflix и многие из конкурсов, устраивавшихся DARPA. Парадигма CTF поменяла методы решений во многих областях. Каркас для общих задач состоит из ’’ингредиентов” и ’’секретного соуса”. "Ин- гредиентами" будут: 1. Общедоступный датасет и связанная с ним задача предсказания. 2. Множество участников, взявшихся найти наилучшее решение этой общей задачи. 3. Честная и объективная система оценки предсказаний участников, не дающая им слишком конкретных подсказок. Такая система хорошо работает, если задача поставлена корректно и в данных нет проблем. В итоге качество решений постепенно улучшается, стремясь к некой асимптоте. Процесс можно ускорить, разрешив участникам кооперироваться (на Kaggle этому помогают форум и возможность делиться блокнотами и дополни-
42 Часть I. Знакомство с соревнованиями Kaggle тельными данными). Согласно парадигме CTF, конкуренция на соревнованиях по- зволяет находить лучшие решения. Когда она сочетается с некоторым уровнем кооперации, улучшения происходят еще быстрее — именно поэтому Kaggle всяче- ски поощряет обмен информацией. ’’Секретным соусом” в парадигме CTF является, собственно, соревновательность. Вместе с постановкой прикладной задачи, решение которой надо улучшить, она всегда приводит к появлению новых подходов к обработке данных, моделирова- нию, тестированию и в целом к применению машинного обучения в данной задаче. Таким образом, соревнования могут показать новые пути решать задачу предсказа- ния, строить признаки, модели и алгоритмы. Скажем, глубокое обучение, хотя и имеет корни в академических исследованиях, стало особенно бурно развиваться после того, как показало свою эффективность на соревнованиях (мы уже упомина- ли, например, конкурс компании Merck, где победила команда Джеффри Хинтона: https://www.kaggle.eom/c/MerckActivity/overview/winners). Вместе с движением за свободное программное обеспечение, позволившем каждо- му пользоваться мощными аналитическими инструментами (например, Scikit-leam, TensorFlow или PyTorch), парадигма CTF способствует достижению лучших ре- зультатов, поскольку все участники начинают в равных условиях. С другой сторо- ны, зависимость решений от мощного или специализированного железа ограничи- вает результативность, поскольку участники без доступа к подобным ресурсам не могут полноценно включиться в борьбу и помочь улучшению решений непосредст- венно или косвенно (созданием конкуренции). По этой причине Kaggle стал пред- лагать участникам бесплатный доступ к облачным вычислениям (о Kaggle Notebooks мы еще поговорим в разд. "Вычислительные ресурсы " далее в этой гла- ве). Это помогает сгладить неравенство в соревнованиях, требовательных к вычис- лительным мощностям (а к таким, например, относится большинство соревнований по глубокому обучению), и усилить конкуренцию. Что может пойти не так После нашего описания парадигмы CTF вы можете подумать, что достаточно соз- дать правильную соревновательную платформу для состязаний, и у вас автомати- чески появятся вовлеченные и мотивированные участники, а у компаний- спонсоров— прекрасные модели. Однако существует немало проблем, которые могут привести конкурс к итогам, разочаровывающим как участников, так и орга- низаторов: • утечка в данных; • зондирование результатов; • переобучение (приводящее к радикальным перестановкам в таблице резуль- татов); • скрытый обмен информацией между отдельными участниками. Утечкой в данных называют ситуацию, когда по части решения можно восстано- вить данные. Например, некоторые переменные могут зависеть от целевой пере-
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 43 менной и, соответственно, выдавать некоторую информацию о ней. Такая ситуация встречается при определении мошенничества (fraud detection), если использовать данные, обновленные уже после случая мошенничества, или при предсказании про- даж, когда используется информация об эффективном распределении товаров (где большие значения соответствуют большему количеству запросов на товар и, соот- ветственно, большим продажам). Другой проблемой может быть некая закономерность в порядке элементов обу- чающего и тестового датасетов либо связь значений идентификаторов с предсказы- ваемыми значениями. Например, идентификаторы могут присваиваться по порядку значений целевой переменной или же соответствовать времени измерения (а значе- ние целевой переменной — коррелировать со временем). Такие утечки в данных, порой называемые "золотыми" (поскольку заметившие их могут получить золотую медаль), ведут к решениям, которые невозможно исполь- зовать в реальности. Спонсор не получает желаемого результата, хотя и может уз- нать что-то новое о ’’протекающих” признаках, влияющих на решение. Другая проблема— зондирование (probing) решений лидеров. В этом случае можно воспользоваться знанием об их оценках и собрать решение по кусочкам из отосланного лидерами. Решение снова становится совершенно бесполезным на других данных. Примером может служить история с конкурса Don’t Overfit II. По- бедитель, Захари Мейерс (Zachary Mayers), отправлял каждую из переменных на тестирование отдельно, собрал информацию о ее возможном весе и таким образом подобрал коэффициенты модели (он подробно описал свое решение на https://www.kaggle.eom/c/dont-overfit-ii/discussion/91766). Обычно задачи на вре- менные ряды или другие задачи, содержащие некоторый постоянный сдвиг в дан- ных, легко поддаются зондированию — в них можно придумать некоторые спосо- бы постобработки, вроде умножения предсказаний на константу, подгоняющего решение под конкретное тестовое множество. Иногда участники, пытаясь получить информацию о тестовом множестве, полага- ются на публичную таблицу результатов больше, чем на собственные тесты. Это может привести к проваленному соревнованию и радикальным изменениям мест в итоговой таблице. Решение-победитель в таких случаях часто оказывается не столь оптимальным или даже случайным. Такие ситуации привели к распространению методов анализа возможных отличий между обучающим и тестовым множествами. Подобные техники ’’взлома” (adversarial testing) позволяют узнать, насколько можно полагаться на текущую таблицу результатов и не различаются ли какие-то признаки в обучающем и тестовом множествах настолько сильно, что их лучше не использовать вовсе. Пример можно найти в блокноте Бояна Тунгуза (Bojan Tunguz): https://www.kaggle.com/tunguz/adversarial-ieee. Существуют и другие стратегии защиты от переобучения на основе результатов из публичной таблицы. Например, поскольку обычно разрешается отправить для под- ведения итогов два решения, можно взять одно, показавшее наилучший результат на публичных тестовых данных, и одно, ставшее лучшим при кросс-валидации на обучающем множестве.
44 Часть I. Знакомство с соревнованиями Kaggle Для того чтобы избежать проблем, связанных с зондированием решений и переобу- чением, на Kaggle стали вводиться некоторые ограничения. Так, в соревнованиях типа Code оценивание, как мы ранее писали, разбито на две стадии, так что участ- ники не знают ничего об итоговых тестовых данных и должны полагаться на собст- венные методы валидации. Наконец, последняя из возможных проблем связана с обменом идеями и решения- ми в узком кругу из нескольких участников, а также с участием с нескольких ак- каунтов или за несколько команд. Все эти действия создают несправедливое пре- имущество для небольшого числа участников. Итоговое решение тоже может пострадать из-за отсутствия честной конкуренции. Если такие ситуации становятся известными (например, https://www.kaggle.eom/c/ashrae-energy-prediction/discussion/ 122503), они приводят к недоверию и отсутствию заинтересованности в этом или последующих конкурсах. Вычислительные ресурсы На некоторых соревнованиях вводятся ограничения, позволяющие получить при- годное для реального применения решение. Так, на конкурсе по оценке эффектив- ности производства компании Bosch (Bosch Production Line Performance, https://www.kaggle.eom/c/bosch-production-line-performance) были введены огра- ничения на время исполнения, задействованную память и выходной файл. Сорев- нования, где требуется проводить и обучение, и тестирование с помощью среды Kaggle Notebooks (Notebook-based, ранее также называемые Kernel-Only — ’’только ядро’’), позволяют участникам не думать о вычислительных ресурсах — их предос- тавляет Kaggle (что также способствует уравниванию шансов участников). Проблемы появляются, когда конкурс требует использовать блокноты Kaggle толь- ко для предсказаний на тестовом множестве. В таком случае обучение моделей участник может проводить на собственном компьютере, а ограничения касаются только времени работы готовой модели на тестовых данных. Так как на большин- стве соревнований сейчас приходится использовать глубокое обучение, в этом слу- чае для высокого результата возникает необходимость в установке специализиро- ванного аппаратного обеспечения (например, графического процессора). Даже на некоторых, редко встречающихся сейчас, ’’табличных” конкурсах вы быст- ро обнаружите, что вам для построения признаков, проведения экспериментов и обучения моделей нужен мощный многопроцессорный компьютер с большим объ- емом памяти. Сложно описать какую-то стандартную конфигурацию компьютера, с которой можно быть конкурентоспособным, — ситуация слишком стремительно меняется. Можно посмотреть, какие вычислительные ресурсы (свои или облачные) исполь- зуют другие участники. Так, компания HP в качестве рекламной акции выдавала некоторым кэгглерам ком- пьютеры HP Z4 или Z8. Модель Z8 имеет до 72 процессорных ядер, 3 Тбайт памя- ти, SSD на 48 Тбайт и две видеокарты NVIDIA RTX. Понятно, что подобные ком-
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 45 пьютеры доступны немногим, очень дорого даже использование подобных машин через облачные сервисы вроде GCP от Google или AWS от Amazon. Стоимость облачных вычислений, естественно, зависит от размера дан- ных, количества и типа моделей. Иногда участникам конкурсов предос- тавляется купон на 200-500 долларов на одной из облачных платформ (GCP или AWS). Мы предлагаем вам в начале пути на Kaggle пользоваться ресурсами, предостав- ленными самим Kaggle, — Kaggle Notebooks (ранее Kaggle Kernels). Kaggle Notebooks Kaggle Notebooks — среда, позволяющая писать и исполнять скрипты и блокноты на языках Python и R. Она основана на работающих в облаках контейнерах Docker и имеет следующие особенности: • интеграция с Kaggle (среда позволяет отправлять решения и отслеживать со- ответствие решений и блокнотов); • предустановленные библиотеки для науки о данных; • возможность настройки под себя (например, установка дополнительных биб- лиотек). В базовой версии вычисления производятся на обычных процессорах (central processing unit, CPU), расширенные используют NVIDIA Tesla P100 или TPU v3-8. TPU (tensor processing unit, тензорные процессоры) — устройства, специализиро- ванные для задач глубокого обучения. Хотя в Kaggle Notebooks существуют ограничения на время работы и на количество запускаемых блокнотов, это отличная среда как минимум для первой версии реше- ния конкурсных задач (табл. 1.1). Таблица 1.1. Базовые характеристики процессоров Тип процессора Количество ядер процессора Память, Гбайт Количество запущенных блокнотов одновременно Количество часов в неделю CPU 4 16 10 Не ограничено GPU 2 13 2 30 часов TPU 4 16 2 30 часов Кроме ограничений на общее время работы, каждая сессия для CPU- и GPU- блокнота может продолжаться не более 12 часов (а для TPU-блокнота— не более
46 Часть I. Знакомство с соревнованиями Kaggle 9 часов), и результаты, не записанные на диск, исчезнут. Доступное дисковое про- странство для моделей и их результатов— 20 Гбайт плюс дополнительное про- странство, выделяемое только на время работы скрипта. В некоторых случаях недостаточно использовать Kaggle Notebooks с GPU. Так, не- давний конкурс Deepfake Detection Challenge по распознаванию дипфейков (https://www.kaggle.eom/c/deepfake-detection-challenge) требовал обработки при- мерно 500 Гбайт видео. Это становится особенно сложной задачей из-за 30- часового недельного лимита и того, что более двух блокнотов одновременно запус- тить нельзя. Даже переход на использование TPU вместо GPU (руководство можно найти на https://www.kaggle.com/docs/tpu) может оказаться недостаточным для того, чтобы активно экспериментировать в конкурсах на очень больших данных, таких как Deepfake Detection Challenge. По этим причинам в главе 3 мы собираемся снабдить вас советами, как добиваться хороших результатов, несмотря на ограничения и без необходимости покупать сверхмощный компьютер. Мы также покажем, как интегрировать Kaggle Notebooks с GCP либо, в качестве альтернативы, как перенести свою работу на другую облач- ную платформу, Google Colab (об этом мы поговорим в главе 2). Создание команд и нетворкинг Хотя вычислительные ресурсы важны, решающую роль в соревнованиях играют знания и способности участников. Часто для успеха необходимы совместные уси- лия целой команды. На соревнованиях (кроме категории Recruitment, где компания может требовать только индивидуального участия) обычно нет ограничений на формирование команд. Как правило, в команде должно быть не более 5 человек. Преимущество создания команды — объединение усилий для поиска решений. Ко- манда единомышленников потратит на работу над задачей больше времени, чем один человек. Важно и то, что разные люди обладают различными навыками и зна- ниями в разных областях. Однако у объединения есть и недостатки. Координировать усилия для достижения общей цели непросто, и могут возникать различные проблемы. Самая частая из них — недостаточная вовлеченность или вовсе бездействие некоторых участников, но хуже всего ситуации, когда один из членов команды нарушает правила — в ре- зультате дисквалифицировать могут всех — или вовсе ’’шпионит” в пользу другой команды. Однако, несмотря на все возможные проблемы, объединение в команды — замеча- тельная возможность ближе познакомиться с другими исследователями данных, а также достичь больших результатов, т. к. правила Kaggle поощряют команды больше, чем индивидуальных участников. В малочисленных командах каждый уча- стник получает большую долю от приза, чем получил бы просто при делении его поровну. Объединение в команды не единственная возможность для общения и ус- тановления связей на Kaggle, но точно самая выгодная и интересная. Можно также
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 47 участвовать в дискуссиях на форуме, выкладывать свои датасеты и блокноты — все это позволяет познакомиться с другими исследователями данных и быть замеченным. Множество возможностей для нетворкинга кэгглеров есть и вне самой платформы. Например, существует несколько полезных каналов в Slack — в частности, множе- ство конкурсов обсуждалось в канале KaggleNoobs (https://www.kaggle.com/ getting-started/20577), созданном в 2016 г. Участники этого канала всегда готовы поддержать и помочь при проблемах в коде или в работе модели. Вообще, каналов, посвященных обсуждению Kaggle и других тем в науке о данных, довольно много. Некоторые объединяют участников из определенного региона или страны, как японский Kaggler-ja (http://kaggler-ja-wiki.herokuapp.com/) или рос- сийский Open Data Science Network (https://ods.ai/) (созданный в 2015 г. и позднее открытый и для нерусскоязычных пользователей). Сообщество Open Data Science Network не ограничивается каналом в Slack, оно предлагает также курсы о том, как побеждать на соревнованиях по науке о данных, и списки соревнований на разных платформах (см. https://ods.ai/competitions). Кроме каналов в Slack, проводится достаточно много локальных встреч и семина- ров, посвященных конкурсам Kaggle, как разовых, так и регулярных. Обычно на них один из участников делает презентацию, делясь своим опытом и идеями. Это один из лучших способов лично пообщаться другими кэгглерами, обменяться мне- ниями и договориться о совместном участии в конкурсах. Здесь стоит упомянуть о Kaggle Days (https://kaggledays.com/), сообществе, соз- данном Марией Парыш (Maria Parysz) и Павлом Янкевичем (Pawel Jankiewicz) и организовавшем несколько конференций в разных городах мира (https:// kaggledays.com/about-us/), чтобы собрать вместе экспертов Kaggle. Они проводят и довольно активные локальные семинары (https://kaggledays.commeetups/). Павел Янкевич https://wwvv.kaggle.com/paweljankiewicz Мы поговорили о Kaggle с Павлом Янкевичем, гроссмей- стером (в соревновательной категории Competitions) и со- основателем компании LogicAI. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я больше всего люблю соревнования типа Code благодаря тому, что в них необ- ходимо думать об ограничениях— на время, память, мощность процессора. Раньше мне слишком часто приходилось использовать на конкурсах до 3^4 мощ- ных виртуальных машин. Мне не нравилась необходимость задействовать для победы такие ресурсы, поскольку это ставит участников в очень неравные условия.
48 Часть I. Знакомство с соревнованиями Kaggle Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? К каждому конкурсу у меня свой подход. Я стараюсь всегда создавать схему, по- зволяющую проводить как можно больше экспериментов. Так, на одном из со- ревнований необходимо было строить глубокую сверточную нейросеть. Я при- думал способ строить нейросеть по ее описанию в формате С4-МР4-СЗ-МРЗ (где каждая буква обозначает один слой). Это было много лет назад, так что сейчас построение нейросети, скорее всего, делается выбором базовой модели. Но об- щий принцип остается прежним — создать каркас, позволяющий быстро менять наиболее сильно влияющие на результат части процесса. Ежедневная работа бывает похожа на соревнования, если говорить о моделиро- вании и тестировании. Соревнования показали мне важность тестирования и предотвращения утечек данных. Спросите себя сами: раз утечки данных случа- ются на столь многих конкурсах, где данные готовят лучшие специалисты, как часто они встречаются при тренировке реальных продуктовых моделей? Я бы предположил (хотя не стоит ссылаться на мою оценку), что процентах в восьми- десяти. Важное отличие ежедневной работы в том, что никто на самом деле не ставит за- дачу для твоей модели. Например, какую выбрать метрику— RMSE, RMSLE, SMAPE или МАРЕ? Если в задаче важен фактор времени, как наиболее реали- стичным образом разбить данные на обучающее и тестовое множество? И еще масса подобных вопросов. Кроме того, важно уметь обосновывать свой выбор. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, что ты вынес из участия в нем Самым захватывающим был конкурс по предсказанию цен Mercari Price Predic- tion. Он сильно отличался от других соревнований благодаря ограничениям в 1 час на время вычислений при всего 4 ядрах процессора и 16 Гбайт памяти. Спра- виться при таких ограничениях было самым интересным. После этого конкурса я стал больше верить в использование нейросетей для табличных данных. До того как мы объединились в одну команду с Константином Лопухиным (https://www.kaggle.com/lopuhin), у меня был целый набор сложных моделей — как нейросетевых, так и других, основанных на бустинге. Потом выяснилось, что Константин использовал только одну, но очень оптимизированную (в плане чис- ла эпох и скорости обучения) архитектуру сети. Особенностью данного конкурса было то, что усреднения решений команды не хватало. Мы были вынуждены создать единый план и написать одно общее решение, а не просто соединить фрагменты наших отдельных решений. Эта работа заняла три недели. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Наверное, сильно недооценены навыки разработчика. Каждый конкурс, каждая задача имеют свои особенности и требуют своих решений по организации кода, упрощающих работу над решением (как пример хорошей организации можно привести https://github.com/bestfitting/instance_Ievel_recognition). Хорошо ор- ганизованный код позволяет быстрее переходить к следующей версии и в итоге перебирать больше вариантов.
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 49 О чем важнее всего помнить, приступая к участию в соревновании? Главное — получить удовольствие. Уровни и рейтинг Кроме денег и прочих материальных призов — кружек, футболок, толстовок, на- клеек, Kaggle выдает и нематериальные. Кэгглеры тратят очень много времени и усилий на соревнованиях (и это еще не считая времени, во время которого они ос- ваивали необходимые для соревнований навыки, — вообще говоря, довольно ред- кие). Денежные призы служат компенсацией усилий лишь для нескольких лучших, если не для единственного победителя. Остальные, таким образом, добровольно потратили время и не получили вознаграждения. В долгосрочной перспективе уча- стие в конкурсах без ощутимого результата может приводить к разочарованию и потере интереса. Для того чтобы это предотвратить, Kaggle ввел систему медалей и рейтинг. Большее количество медалей и очков в рейтинге говорит об актуальности знаний и навыков, что помогает при поиске работы и в других ситуациях, где важна репутация специалиста. Во-первых, существует общий рейтинг, учитывающий результаты всех соревнова- ний (https://www.kaggle.com/rankings). На основании места в каждом соревнова- ний кэгглер получает определенное количество очков, в сумме дающих результат в общем рейтинге. Формула на первый взгляд кажется сложной1: [Rank“] - [1о8(1 + log(W. ))]>'"’] Однако на самом деле в ней присутствует очень немного параметров: • место на соревновании; • размер команды; • популярность соревнования; • давность соревнования. Вполне естественно, что высокое место на популярном конкурсе приносит много очков. Менее очевидна нелинейная зависимость от размера команды — благодаря делению на квадратный корень доля очков, полученных каждым участником, уменьшается с увеличением количества людей в команде. Тем не менее все еще выгодно объединяться в малочисленные команды по 2-3 че- ловека — из-за того, что ’’одна голова хорошо, а две лучше”, и больших вычисли- тельных ресурсов. Надо учесть, что очки тают со временем — также нелинейно, и примерно через год от набранного остается очень мало. Успех в рейтинге Kaggle, если не продолжать 1 Здесь Ny — количество участников в команде; N* — количество команд; Rank — рейтинг, место на соревновании. — Прим. ред.
50 Часть I. Знакомство с соревнованиями Kaggle соревноваться с такими же результатами, мимолетен. В качестве утешения, впро- чем, в профиле всегда указывается и наивысшее достигнутое место. Более долговечная награда — медали, которые получают чемпионы во всех четы- рех номинациях Kaggle — Competitions, Notebooks, Discussion и Datasets. В катего- рии Competitions медали выдаются в зависимости от занятого места на конкурсе, в трех остальных — на основании голосов других участников (что не всегда объек- тивно и может зависеть от популярности кэгглера). Чем больше у вас медалей, тем более высокое звание можно получить. Звания на Kaggle: Novice (новичок), Contributor (участник), Expert (эксперт), Master (мастер) и Grandmaster (гроссмей- стер). На странице https://www.kaggle.com/progression подробно объясняется, как получить медали и сколько их нужно для каждого звания. Помните, что все рей- тинги и звания относительны и меняются со временем — несколько лет назад сис- тема рейтинга была другой. Скорее всего, в будущем она также изменится, чтобы высокие звания оставались редким и ценным достижением. Критика и возможности Kaggle много критиковали с момента его появления. Участие в соревнованиях по науке о данных все еще остается предметом споров, существуют как положитель- ные, так и отрицательные мнения об этом. Критики говорят, что: • Kaggle зациклен на соревновательном аспекте и не дает представления о сфе- ре машинного обучения в целом; • Kaggle— всего лишь игра в оптимизацию гиперпараметров и объединение моделей для незначительного повышения точности (а на деле — просто пе- реобучения на тестовом множестве); • Kaggle переполнен неопытными энтузиастами, готовыми перепробовать все на свете ради рейтинга и попадания на радары рекрутеров; • как следствие, решения часто чересчур сложны и слишком завязаны на кон- кретные тестовые данные, чтобы быть применимыми. Многие воспринимают Kaggle и в целом платформы для соревнований по наукам о данных как далекие от реальной работы с данными. Критики напоминают, что на- стоящие задачи бизнеса не возникают из ниоткуда и, прежде всего, в них редко имеются качественные подготовленные данные. Обычно данные собираются по ходу дела с одновременным уточнением цели бизнеса и постановки задачи. Более того, многие критики подчеркивают, что кэгглеры не обязательно блистают в по- строении продуктовых моделей — решение победителя часто непригодно для ре- ального использования, поскольку не учитывает ограниченность вычислительных ресурсов или нуждается в доработке (впрочем, это верно не для всех соревнований). В конце концов, вся критика сводится к одному вопросу: как результаты на Kaggle соотносятся с остальным опытом (образованием, профессиональной деятельно- стью) в глазах работодателя? Устойчивым мифом является мнение, что соревнова-
Глава 1. Знакомство с Kaggle и другими соревнованиями по науке о данных 51 ния не помогут найти работу и не выделят вас из числа исследователей данных, не участвующих в них. Мы считаем, что якобы отсутствие ценности рейтинга Kaggle вне узкого круга кэгглеров — заблуждение. Так, для поиске работы Kaggle полезен приобретением важных навыков в построении и тестировании моделей, знакомством с различными методами и задачами из разных областей, лежащими вне привычной рабочей зоны комфорта. Разумеется, однако, Kaggle не даст абсолютно всех необходимых навы- ков для реальной работы. Kaggle, безусловно, стоит использовать для обучения (заметим, что на сайте есть в том числе раздел Courses (Курсы)) и для того, чтобы выделиться из массы канди- датов при поиске работы; однако восприятие этих достижений будет различным в разных компаниях. Но так или иначе, полученные на Kaggle навыки, бесспорно, окажутся полезными в карьере и обеспечат преимущество при построении моделей для сложных и нетривиальных задач. Участвуя в соревнованиях, вы научитесь уве- ренно строить модели и тестировать их, установите связи с другими исследователя- ми данных, которые могут вас порекомендовать, увидите другие подходы к задачам, с которыми раньше не встречались, сможете узнать много полезного от участников. Таким образом, мы считаем, что Kaggle помогает в карьере — многими способами, не только и не столько напрямую. Конечно, иногда сами по себе результаты стано- вятся поводом для приглашения на интервью, но чаще Kaggle дает навыки и опыт, необходимые для успеха на собеседовании и в работе. На самом деле, проведя некоторое время на Kaggle, вы сможете увидеть достаточно типов данных, задач и методов, с которыми приходится работать в условиях огра- ниченного времени, что, встретившись с подобными задачами в реальности, смо- жете прийти к решению быстро и эффективно. Возможность развить свои навыки — то, чему в первую очередь посвящена эта книга, то, о чем мы думали, когда работали над ней. Вы не найдете в чистом виде руководства, как побеждать в конкурсах, но точно обнаружите сведения, как со- ревноваться с большим успехом и большей пользой. И Kaggle, и другие соревновательные платформы надо использовать с умом. Это не волшебная палочка, открывающая все двери, победы не гарантируют вам высоко- оплачиваемую работу или славу за пределами сообщества. Однако регулярное уча- стие в соревнованиях — карта, которую можно с умом разыграть: показать увле- ченность своим делом, улучшить конкретные навыки, которые позволят вам не затеряться на фоне автоматических решений. Читайте эту книгу— мы покажем вам, как это сделать. Резюме В данной вводной главе мы рассказали о появлении и росте соревновательных платформ, о том, как они устроены с точки зрения участников и организаторов, в частности, о парадигме CTF, введенной Дэвидом Донохо.
52 Часть I. Знакомство с соревнованиями Kaggle Мы показали, как устроен Kaggle, не забыв упомянуть и о других платформах, и как участие в соревнованиях может быть полезно для целей вне самого Kaggle. Мы обсудили стадии соревнований, разные их типы и то, какие вычислительные и учебные ресурсы предоставляет Kaggle. В следующих главах мы поговорим о Kaggle подробнее и начнем с обсуждения данных. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
2 Организация данных В рассказе "Медные буки" Артура Конан Дойля Шерлок Холмс кричит: "Данные! Данные! Когда под рукой нет глины, из чего лепить кирпичи?" Этот подход, столь помогавший самому известному в мире сыщику, стоит принять на вооружение ка- ждому исследователю данных. Поэтому мы начнем самую техническую часть кни- ги с главы, посвященной данным, а именно с раздела Kaggle Datasets, и с того, как его использовать. В этой главе мы затронем следующие темы: • создание датасета; • сбор данных; • работа с датасетами; • взаимодействие Kaggle Datasets и Google Colab; • юридические вопросы. Создание датасета В принципе, вы можете загрузить на Kaggle любые используемые вами данные (о некоторых ограничениях скажем в разд. "Юридические вопросы" далее в этой главе). Ограничения на размер на данный момент — 100 Гбайт на один датасет и 100 Гбайт в целом. Размер учитывается в несжатом виде — сжатие ускорит за- грузку, но не поможет обойти ограничения. Актуальную документацию можно по- смотреть по адресу https://www.kaggle.com/docs/datasets. Лозунг Kaggle — "Здесь живет наука о данных", и впечатляющая коллекция дос- тупных на сайте данных служит тому подтверждением (рис. 2.1). Вы не только об- наружите здесь данные разной тематики, от цен на нефть до рекомендаций аниме, данные еще и попадают туда с впечатляющей скоростью. Когда в мае 2021 г. по Закону о свободе информации были опубликованы письма Энтони Фаучи
54 Часть I. Знакомство с соревнованиями Kaggle (https://www.washingtonpost.com/politics/interactive/2021/tony-fauci-emails/), они всего через 48 часов оказались загружены на Kaggle. Trending Datasets Python Course Discussion JSON Bruno Ferreira • Updated 2 hours ago Usability 10.0*80 KB 1 Ftt (JSON) See All Largest Cities in the World Rishi Damaria Updated 3 hours ago Usability 9.4-12 MB 1 File (other) Deforestation and Forest Loss Chittcanu Cnsttan 'Updated 7 hours ago Usability 7 1-4KB 1 File (CSV) Bitcoin Price ELoo Updated 9 hours ago Usability 10.0 -271 KB 1 Task 1 File {CSV) 0 Popular Datasets Heart Attack Analysis & Prediction Dataset Rashik Rahman • Updated a month ago Usability 10.0-4 KB 1 Task 2 Files (CSV) World Happiness Report 2021 А;аурд1 Singh Updated a month ago Usability 9 7 55 KB 1 Task • 2 Files (CSV) Stroke Prediction Dataset fedesonano Updated 3 months ago Usability 10.0-S7 KB 1 Task • 1 FU* (CSV) See All Reddit Vaccine Myths Gabriel Freds Updated a day ago Usability 10.0 *227 KB 2 Tasks -1 File (CSV) Рис. 2.1. Популярные датасеты на Kaggle Прежде чем загружать данные для своего проекта, проверьте, что выкладывали до вас. Возможно, ваши данные уже есть на Kaggle (особенно это касается популяр- ных тем вроде классификации изображений, обработки естественного языка и вре- менных рядов в финансовой сфере). Предположим, однако, что ваши данные прежде никто не выкладывал, и вам нужно создать новый датасет. Выйдите в меню (три полоски слева) и щелкните на пункте Datasets (Датасеты). Вы попадете на одноименную страницу (рис. 2.2). Datasets Explore, analyze, and share quality data Learn more about data types, creating, and collaborating. Г+ New Dataset^ Search datasets v Filters Ail datasets Computer Science Education Classification Computer Vision NLP Data Visualization Pre-Trained Model Puc. 2.2. Страница Datasets
Глава 2. Организация данных Нажмите кнопку + New Dataset. Вас попросят загрузить данные и дать им название (рис. 2.3). Q Enter Dataset Title X www.kaggle.com/konradb/ О о В Drag and drop files to upload Consider zipping large directories for faster uploads or Browse Files ® 6 Private Create Рис. 2.3. Ввод донных о дотасете Значки слева соответствуют источникам, из которых вы можете загрузить датасет. Перечислим их в порядке появления на странице: • загрузка с локального диска (см. рис. 2.3); • загрузка с заданного URL; • загрузка из репозитория GitHub; • вывод имеющегося блокнота; • загрузка из облака Google Cloud Storage. Важное замечание касательно загрузки с GitHub: это очень полезная опция при работе с экспериментальными библиотеками. Они обычно не включены в среду Kaggle, но часто предлагают недоступные иначе функции. Для того чтобы исполь- зовать такую библиотеку в своем коде, ее можно загрузить как датасет: 1. На странице Datasets нажать кнопку + New Dataset. 2. Выбрать значок GitHub. 3. Ввести ссылку на репозиторий и название датасета (рис. 2.4). 4. Нажать кнопку Create справа внизу.
56 Часть I. Знакомство с соревнованиями Kaggle Рис. 2.4. Загрузка датасета с GitHub Рядом с кнопкой Create есть еще одна, с надписью Private. По умолчанию все да- тасеты приватны: просматривать и изменять их может только создатель. Обычно при создании датасета имеет смысл оставить эту опцию и сделать датасет публич- ным (доступным всем либо заданному списку участников) позднее. Помните, что Kaggle — очень популярная платформа, на которую загружается мно- го данных, так что выбирайте не слишком общее название, это поможет вашим данным стать замеченными. Проделав все эти шаги и нажав кнопку Create, вы обнаружите, что — ура! — пер- вый датасет готов. Перейдите теперь на вкладку Data (рис. 2.5). Easy to understand and Includes Rich, machine readable file formats and Assurances the dataset is maintained essential metadata v' Add a subtitle Add tags s Add a description metadata О Add file information Help others navigate your dataset with a description of each file О Include column descriptors Specify provenance Specify update frequency О Publish a notebook Provide an example of the data in use so v' Upload an image Empowers others to understand your data by describing its features 'J Specify a license Use preferred file formats other users can get started quickly О Add a task Suggest an analysis users can do with this dataset Рис. 2.5. Вкладка Data
Глава 2. Организация данных На рис. 2.5 видно, какую информацию о датасете можно добавлять. Чем больше информации, тем выше индекс удобства использования (usability index). Он по- зволяет измерить, насколько хорошо описан датасет. Датасеты с большим индек- сом удобства использования стоят выше в поисковой выдаче. Индекс основан на нескольких факторах — уровне документации, доступности другого связанного с данными контента (например, блокнотов), типов файлов, указания ключевых мета- данных. Вообще, вы не обязаны заполнять все предложенные поля, можно использовать датасет без них (и в случае приватного датасета вы уж точно знаете, что за данные в нем содержатся). Однако этикет сообщества предписывает указывать информа- цию для публичных датасетов — чем она подробнее, тем проще будет использовать данные. Сбор данных На содержание датасетов нет других ограничений, кроме юридических. Вы можете хранить таблицы, изображения, тексты — что угодно в пределах допустимого ко- личества информации. Можно загружать данные, собранные из сторонних источ- ников. Так, популярны датасеты твитов с их хештегами или тематикой (рис. 2.6). Q. tweet^ Filters Datasets Tasks Computer Science Education Classification Computer Vision NLP Data Visualization 0 71 Tasks See All Sentiment! 40 dataset with 1.6 million tweets Maptcx; M^ggAtfirK KazAnova • Updated 4 years ago Usability 8.8 -1 File (CSV) * 81 MB -1 Task a1085 a Gold ... 1 / Kcai Twitter US Airline Sentiment Figure Eight Updated 2 years ago Usability 8 2-2 Files (SQLITE. CSV) * 3 MB * 747 • Gold «« 1 " 1 News Headlines Dataset For Sarcasm Detection Rishabh Misra • Updated 2 years ago * 667 Usability 10.0 - 2 Fites (JSON) 3 MB 1 Task • Gold Puc. 2.6. Датасеты с твитами — одни из самых популярных
58 Часть I. Знакомство с соревнованиями Kaggle Способы сбора данных из соцсетей (Twitter, Reddit и др.) не относятся к тематике нашей книги. Эндрю Мараньяно https://www.kaggle.com/andrewmvd Мы взяли интервью у Эндрю Мараньяно, также известного как Larxel, гроссмейстера в категории Datasets (занимаю- щего первую строчку рейтинга в этой категории на момент написания книги) и старшего исследователя данных в больнице им. Альберта Эйнштейна (Hospital Albert Ein stein) в Сан-Паулу. Мы поговорили о его пути к успеху, о советах по созданию датасе- тов и в целом об опыте на Kaggle. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Моя любимая тематика — медицинские изображения. Это и область моих про- фессиональных интересов, и в каком-то смысле моя миссия. Если говорить о со- ревнованиях, связанных с медициной, то соревнования по обработки естествен- ного языка (natural language processing, NLP) зависят от языка, табличные данные в разных больницах разные, но формат изображений обычно одинаков, и про- движения в этой области могут приносить пользу по всему миру. Мне нравится чувствовать свою полезность. Я люблю и NLP, и табличные данные, но это дос- таточно стандартно. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, что ты вынес из участия в нем На соревновании по обнаружению туберкулеза по рентгенограмме было дано около тысячи изображений — довольно мало для того, чтобы выявить все при- знаки заболевания. Для того чтобы справиться с этим, я предложил две идеи: 1. Предварительное обучение на примерно 20 тыс. изображений из датасета, по- священного выявлению пневмонии,— признаки пневмонии и туберкулеза иногда путают. 2. Предварительное обучение на примерно 600 тыс. изображений из датасета, посвященного классификации патологий в легких, с использованием алго- ритма grad-CAM (отображение активации классов) для разметки изобра- жений. В итоге простая комбинация двух этих подходов оказалась на 22% лучше, чем результат команды, занявшей второе место. Всего участвовало порядка 100 ко- манд, это было соревнование для специалистов в медицинской сфере.
Глава 2. Организация данных 59 Ты стал гроссмейстером в категории Datasets, занял первую строчку в рейтинге. Как ты выбираешь тему, собираешь и публикуешь данные? О, тут требуется длинный ответ, я разобью его на части. 1. Поставь себе цель. Первое, о чем я думаю при выборе темы: зачем это нужно? Когда есть обос- нование, хороший датасет становится результатом, а не самоцелью. Фей Фей Ли, руководитель лаборатории, создавшей ImageNet, в своем выступлении на TED рассказала, как мечтала о мире, где машины способны рассуждать и вос- принимать мир, как ее дети. Если у вас есть цель, вы будете прилагать больше усилий к сбору данных, улучшать их и сможете выделиться из толпы. Да, можно выкладывать таблич- ки по каким-то тривиальным темам, но вряд ли они принесут много пользы. 2. Хороший датасет рождается из важного вопроса. Если посмотреть на самые известные датасеты в современной литературе, та- кие как ImageNet, мы увидим между ними нечто общее: • за ними стоит важный вопрос, имеющий значение для всех нас (науч- ный или прикладной); • данные были тщательно собраны, прошли проверку качества и хорошо документированы; • количество и разнообразие данных соответствует текущим вычисли- тельным ресурсам; • есть некоторое активное сообщество, постоянно улучшающее и допол- няющее данные и/или занимающееся поставленным вопросом. Как я уже говорил, на мой взгляд, задавать вопросы — основная роль иссле- дователя данных, и она станет еще более важной с развитием автоматических решений в этой области. Именно сбор датасетов поможет развить этот уни- кальный навык. 3. Не ставьте успех самоцелью, создайте свой метод идти к нему. Качество важнее количества: чтобы стать гроссмейстером, достаточно 15 да- тасетов. Огромную роль во всем искусственном интеллекте играет небольшое количество высококачественных датасетов. Я отбросил не меньше датасетов, чем опубликовал. Сбор данных требует времени, но оно необходимо также для поддержания и улучшения датасета— не стоит, как многие, восприни- мать работу над набором данных по принципу ’’выложил и забыл". Часто забывают о том, чтобы поддерживать сообщество пользующихся твои- ми данными. Блокноты и датасеты — плод совместных усилий, поддерживать тех, кто тратит время на анализ твоих данных, очень полезно. Учитывая их трудности, их выбор методов анализа, проще решать, какие еще предпринять шаги по предобработке данных и как улучшить документацию. Итак, я рекомендую следующий алгоритм: определить свою большую цель, разбить ее на отдельные задачи и области, сформулировать вопросы, найти
60 Часть I. Знакомство с соревнованиями Kaggle источники данных, собрать данные, обработать, задокументировать, поддер- живать и улучшать. Допустим, вы хотите помочь в области социального благополучия. Вы выби- раете, например, задачу расового равенства, смотрите на связанные с ней те- мы и обнаруживаете движение Black Lives Matter. Теперь формулируем во- прос: как извлечь смысл из миллионов высказываний об этом движении? Теперь понятно, с каким типом данных нам придется иметь дело, — это зада- ча обработки естественного языка (NLP). Источниками данных могут стать новостные статьи, комментарии на YouTube, твиты (предположим, что вы вы- брали их из-за большей репрезентативности по интересующему вас вопросу и доступности для обработки). Вы проводите предобработку данных, убираете идентификаторы, документируете цели датасета и процесс сбора данных. Проделав все это, вы публикуете датасет, и кто-то из кэгглеров пытается по- строить модель, но не может, поскольку твиты написаны на разных языках и возникают проблемы с кодировкой. Вы должны поддержать их— советом, ссылкой на их работу и исправлением датасета (например, можно оставить только твиты на английском). Теперь анализ датасета, проведенный кэгглерами, отражает запросы, мотивы, страхи, относящиеся к изучаемому движению. Их усилия позволят превратить миллионы твитов в рекомендации того, как обществу прийти к равенству. 4. Все, что вы можете делать, — хорошо выполнять свою работу. Гроссмейстером в конечном счете вас делают другие. Голоса не всегда соот- ветствуют ни вашим усилиям, ни важности работы. На один из моих датасе- тов (Cyberpunk 2077) я потратил около 40 часов, и до сих пор у него едва ли не меньше всего голосов. Но это неважно. Я вложил усилия, я попробовал, я нашел новую информацию для себя — это то, что я могу контролировать, и я буду делать то же самое на следующей неделе. Делайте свое дело как можно лучше и двигайтесь вперед. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я сделаю странную вещь — дам одновременно рекомендации и антирекоменда- ции. Так, LightGBM — прекрасная библиотека для машинного обучения на таб- личных данных с фантастическим соотношением вычислительной эффективно- сти и качества результата. CatBoost иногда дает большую точность предсказаний, но ценой большего времени вычислений, а ведь время можно потратить на вы- движение и проверку новых идей. Порекомендую библиотеку Optuna для подбо- ра гиперпараметров, Streamlit для фронтенда, Gradio для создания прототипов, Fast API для микросервисов, Plotly и Plotly Express для диаграмм, PyTorch и его производные для глубокого обучения. Но хотя библиотеки — это прекрасно, я предлагаю в какой-то момент потратить время на то, чтобы реализовать все самостоятельно. Этот совет я впервые услы- шал от Эндрю Ына (Andrew Ng), а затем от многих других выдающихся специа- листов. Самостоятельная реализация алгоритмов дает глубокие знания и проли- вает свет на то, что делает ваша модель, как она работает с данными, как реагирует на шум в данных или изменение гиперпараметров.
Глава 2. Организация данных 61 По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? После всех лет я бы хотел раньше усвоить важность двух вещей: 1. Систематизировать все полученные знания в конце соревнований. 2. Воспроизводить решение победителя после подведения итогов. Когда конкурс подходит к концу, вы видите, как быстро меняется таблица ре- зультатов. Вы вряд ли захотите рисковать и медленно обдумывать все детали решения. Но после окончания можно без спешки проследить за логикой победи- телей, опубликовавших свои решения. При должной дисциплине такой подход творит чудеса, так что останавливайтесь, когда вы во всем разобрались, а не ко- гда закончился конкурс. Подобный совет давал и Эндрю Ын: чтобы стать спе- циалистом в области искусственного интеллекта, нужно воспроизводить резуль- таты статей. В конце конкурса вы обычно устаете и вам хочется остановиться. Это естествен- но, но учтите, что на форуме после окончания соревнования — самые большие залежи знаний на планете Земля, поскольку там публикуют множество идей и кода, относящихся к решениям победителей. Не поленитесь, прочитайте их и изучите, не поддавайтесь желанию перейти к другим делам — вы упустите уни- кальную возможность освоить новое. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle помог мне, дав огромное количество знаний и опыта, а также в создании портфолио. Я получил свою первую работу в качестве исследователя данных во многом благодаря соревнованиям на Kaggle и DrivenData. Всю свою карьеру я участвовал в конкурсах и изучал чужие решения. Категории Datasets и Notebooks также чрезвычайно полезны для изучения новых методов и развития навыка за- давать вопросы. На мой взгляд, именно умение задавать вопросы — главное для исследователя данных. Отвечать на вопросы — тоже неплохой навык, но я ду- маю, что в недалеком будущем все больше и больше моделей будут строиться автоматически. Какие-то ниши для навыков построения моделей останутся все- гда, но в целом эта часть работы будет поставлена на поток. Однако автоматизи- ровать постановку вопросов гораздо труднее, а даже лучшее решение бессмыс- ленно при некорректной постановке вопроса. Использовал ли ты свои результаты на Kaggle в портфолио для работодателя? Безусловно. Я получил свою первую работу в качестве исследователя данных в 2017 г., используя Kaggle как подтверждение знаний. Это до сих пор замечатель- ная часть резюме, т. к. формальное образование гораздо меньше говорит о знани- ях в науке о данных, чем твое портфолио с проектами. Наличие в нем соревнова- ний говорит не только о дополнительном опыте, но и о постоянном стремлении к развитию, в долгосрочной перспективе наиболее важном для успеха.
62 Часть I. Знакомство с соревнованиями Kaggle Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я использую DrivenData и AlCrowd. Мне нравится, что они позволяют организо- вывать соревнования организациям, не имеющим больших финансовых ресур- сов, — стартапам, исследовательским институтам. Для отличного конкурса нужны отличный вопрос и отличные данные, и то и дру- гое не зависит от размера компании. У Kaggle больше и активнее сообщество участников, доступ к вычислительным ресурсам и к данным делает его наилуч- шим выбором, но и DrivenData, и AlCrowd проводят не менее интересные кон- курсы и вносят разнообразие в общую картину. О чем важнее всего помнить, приступая к участию в соревновании? Если ваша цель — развитие, выбирайте конкурс на интересную вам тему с зада- чей, которую вы раньше не решали. Для того чтобы сформировать уверенность и критическое мышление, вам нужны глубина и разнообразие опыта. Умение сфо- кусироваться и показать свой максимум обеспечит глубину, а выбор новых тем — разнообразие. Работа с датасетами Создав датасет, вы наверняка захотите провести его анализ. В данном разделе мы расскажем о разных способах это сделать. Скорее всего, самый важный из них — создать блокнот, в котором ваш датасет бу- дет главным источником данных. Это можно сделать, зайдя на страницу датасета и нажав кнопку New Notebook. Make your dataset easy to use @ Usability 4.1 Puc. 2.7. Создание блокнота co страницы датасета После этого перед вами появится созданный блокнот (рис. 2.8). Мы увидим: • название из букв и цифр создается автоматически; его можно изменить, щелкнув на нем; • справа под надписью Data вы увидите список источников данных для блок- нота, выбранный мной файл можно найти по адресу ../input/ либо /kaggle/input/;
Глава 2. Организация данных 63 • стартовый блок кода с подключением библиотек, описанием и выводом спи- ска доступных файлов создается автоматически для каждого нового блокнота Python. tebook27227176cf + О X |Q П > ftur>A» Cocto ’ I > Output . ca Python • PtOfOfOAOM None • Puc. 2.8. Начало работы с блокнотом, использующим датасет Теперь можно начинать писать код, используя свой датасет как источник данных. Мы обсудим использование блокнотов Kaggle подробнее в главе 4. Kaggle Datasets и Google Colab Среда Kaggle Notebooks бесплатна, но имеет некоторые ограничения (подробнее о них можно прочитать в главе 4), и скорее всего первое, с чем вы столкнетесь, — это ограничение по времени работы. Популярная альтернатива— бесплатная среда Google Colab, позволяющая запускать в облаке блокноты Jupyter: https://colab.research.google.com. Перенеся вычисления в Google Colab, мы по-прежнему хотим иметь доступ к дата- сетам из Kaggle. Расскажем, как это сделать. Если мы уже зарегистрированы на Kaggle, первый шаг — зайти на страницу своей учетной записи, сгенерировать токен API token (токен доступа, служащий для идентификации пользователя): 1. Зайдите на страницу по адресу https://www.kaggle.com/tASE'lfAC4Affi'/account, нажмите кнопку Create New API Token (рис. 2.9). API Using Haggle's beta API, you can interact with Competitions and Datasets to download data, make submissions, and more via the command line. Read the docs Create Nev. API Token Expire API Token Puc. 2.9. Создание нового токена API Будет создан файл kaggle.json, содержащий имя пользователя и токен.
64 Часть I. Знакомство с соревнованиями Kaggle 2. Следующий шаг — создать папку Kaggle на Google Drive и загрузить в нее json- файл (рис. 2.10). 3. Теперь надо создать новый блокнот на Colab и дать ему доступ к своему диску: from google.colab import drive drive.mount(’/content/gdrive') 4. Получите код авторизации и введите его в появившееся поле. Запустите сле- дующий код: import os # content/gdrive/My Drive/KaggLe - путь к файлу kaggLe.json на GoogLe Drive os.environ[,KAGGLE_CONFIG_DIR*] = "/content/gdrive/My Drive/Kaggle" # смена рабочего каталога %cd /content/gdrive/Му Drive/Kaggle # проверяем текущий рабочий каталог с помощью команды pwd 5. Теперь можно скачать датасет. Зайдите на его страницу на Kaggle, щелкните на значке с тремя точками рядом с кнопкой New Notebook и выберите команду Copy API command (рис. 2.11). 6. Запустите команду API для скачивания датасета (подробнее об используемых командах можно прочитать на: https://www.kaggle.com/docs/api): ’kaggle datasets download -d ajaypalsinghlo/world-happiness-report-2021
Diaea 2. Организация данных 65 7. Датасет будет загружен в папку Kaggle как zip-архив. Осталось только распако- вать его. 336 Рис. 2.11. Копируем команду API Как видите, использование датасета Kaggle в среде Colab — процесс несложный; все, что вам нужно, — это токен API. Теперь вам будет доступно больше часов ис- пользования GPU, чем на Kaggle. Юридические вопросы На Kaggle возможно выложить любые данные, но не любые стоит туда выклады- вать. Примером может служить датасет пользователей Тиндера (People of Tinder). В 2017 г. один программист использовал Tinder API для поиска полузакрытых (semi- private) профилей и загрузил данные на Kaggle. Когда это стало известным, Kaggle удалил датасет. Полностью историю можно прочитать в статье https://www.forbes.com/sites/janetwburns/2017/05/02/tinder-profiles-have-been- Iooted-again-this-time-for-teaching-ai-to-genderize-faces/?sh=lafb86b25454. В целом, прежде чем выложить данные на Kaggle, задайте себе два вопроса: 1. Нет ли в этом нарушения авторских прав? Всегда проверяйте лицензии, а когда сомневаетесь — обратитесь к https://opendefinition.org/guide/data/ или в службу поддержки Kaggle. 2. Не выкладываете ли вы чьи-то персональные данные? Даже если публика- ция некоторой информации не является незаконной, она может причинить вред. Оба этих ограничения согласуются со здравым смыслом и вряд ли помешают ва- шим успехам на Kaggle.
66 Часть I. Знакомство с соревнованиями Kaggle Резюме В этой главе мы познакомились с разделом Datasets сайта Kaggle и стандартными способами хранить и использовать данные на этой платформе. Мы обсудили созда- ние датасетов, методы работы вне Kaggle и использование датасета в среде Kaggle Notebooks. Этой среде и будет посвящена следующая глава. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
3 Работаем и учимся с Kaggle Notebooks Kaggle Notebooks, до недавнего времени называвшиеся ядрами (Kernels),— это бесплатные браузерные блокноты Jupyter. С их помощью вы можете проводить эксперименты с любого подключенного к Интернету устройства (хотя вряд ли сто- ит делать это со смартфона). Технические характеристики среды на момент напи- сания книги указаны ниже, актуальную информацию всегда можно найти на https:// www.kaggle.com/docs/notebooks: • время исполнения: 12 часов для CPU/GPU, 9 часов для TPU; • 20 Гбайт дискового пространства с автоматическим сохранением (/kaggle/ working); • дополнительное дисковое пространство (вне папки /kaggle/working), доступ- ное только на время работы блокнота. Характеристики CPU: • 4 ядра; • 16 Гбайт RAM. Характеристики GPU: • 2 ядра CPU; • 13 Гбайт RAM. Характеристики TPU: • 4 ядра CPU; • 16 Гбайт RAM. В этой главе мы затронем следующие темы: • создание блокнота; • запуск блокнота;
68 Часть I. Знакомство с соревнованиями Kaggle • сохранение блокнотов на GitHub; • как получить максимум пользы от Kaggle Notebooks; • курсы из раздела Kaggle Learn. Без лишних слов перейдем к делу. Сначала поймем, как создать блокнот. Создание блокнота Существует два основных способа создания блокнотов: с главной страницы или со страницы датасета. При первом способе перейдем в раздел Code в меню, расположенном слева на главной странице (https://www.kaggle.com/), и нажмем кнопку + New Notebook (рис. 3.1). Этот метод предпочтителен, если вы хотите провести эксперимент на собственном датасете. Альтернативный способ, который мы описывали в предыдущей главе, — перейти на страницу интересующего вас датасета и нажать кнопку New Notebook (рис. 3.2). Какой бы способ вы ни выбрали, нажав кнопку New Notebook, вы увидите страни- цу со своим блокнотом (рис. 3.3). Справа на странице мы можем менять настройки (рис. 3.4). Вкратце опишем эти настройки. Первая из них — язык программирования (Language). На момент написания этой книги Kaggle поддерживает только Python и R. Языком по умолчанию является Python, если вы хотите использовать R, выбери- те его в выпадающем меню.
Глава 3. Работаем и учимся с Kaggle Notebooks 69 (€) Dataset Temperature Forecast Project using ML Predict Minimum and Maximum Temperature during a day based on various features . • Ayush Yadav • updated 12 hours ago (Version 1) New Notebook Data Tasks Code Discussion Activity Metadata Download (2 MB) & Usability 7.4 W Tags 1 stermediate, envirc-imen*, regression, oategor>cal data, korea Description Temperature Forecast Project using ML Problem Statement. Data Set Information This data is for the purpose of bias correction of next-day maximum and minimum air temperatures forecast of the LDAPS model operated by the Korea Meteorological Administration over Seoul, South Korea This data consists of summer data from 2013 to 2017 The input data is largely composed of the LDAPS model's next-day forecast data m-situ maximum and minimum temperatures of present-day, and geographic auxiliary variables There are two outputs (i.e. next-day maximum and minimum air temperatures) in this data. Hindcast validation was conducted for the period from 2015 to 2017. Attribute Information For more information, read [Cho et al 2020]. Рис. 3.2. Создание нового блокнота co страницы Dataset Puc. 3.3. Страница блокнота Следующий пункт в настройках — среда (Environment): вы можете всегда исполь- зовать последний Docker-образ среды (что рискованно: при обновлениях могут сломаться зависимости) или исходную версию от Kaggle (безопасный выбор). По- следний вариант используется по умолчанию, и обычно нет смысла его менять. Пункт Accelerator позволяет выбрать, исполнять ли код на CPU (без ускорения), GPU (что необходимо практически во всех серьезных приложениях глубокого обу- чения) или TPU. Учитывайте, что переход от CPU к одному GPU требует миниму- ма изменений в коде и может быть осуществлен с помощью поиска устройств (sys- tem device detection).
70 Часть I Знакомство с соревнованиями Kaggle сл Share >| • Data + Add data а Input Output ► D u working 0 Settings a Python ▼ Preferences None ▼ © Schedule a notebook run v Code Help a Search for examples of how to do things Рис. 3.4. Настройки блокнота Переход на TPU требует больше работы, начиная с этапа подготовки данных. Пом- ните, что вы можете переключаться между CPU/GPU/TPU при работе над блокно- том, но при каждом таком переключении необходимо снова запускать весь код с самого начала. Наконец, мы видим пункт Internet, позволяющий включить или отключить доступ в сеть. Если он включен, то при необходимости, скажем, подключить дополнитель- ную библиотеку она будет автоматически скачана и установлена. Отключать дос- туп к Интернету приходится, например, на некоторых соревнованиях, запрещаю- щих его во время отправки решения. Рис. 3.5. Ответвление от существующего блокнота
Глава 3. 'Работаем и учимся с Kaggle Notebooks 71 Важно, что вы всегда можете скопировать уже имеющийся блокнот (как свой, так и созданный другим кэгглером) и менять его для своих целей. Это осуществляется с помощью кнопки Copy and Edit в правом верхнем углу (рис. 3.5). На жаргоне кэгг- леров такое действие называют форкингом (forking), или ответвлением. Стоит помнить об этикете. Если вы раньше участвовали в конкурсах Kaggle, вы наверняка заметили, что таблица результатов просто кишит ответвлениями ответвлений блокнотов-лидеров. Ничего предосуди- тельного в использовании сделанного другими нет, но помните о том, чтобы отдать свой голос (upvote) за исходный блокнот и явно сослаться в своем коде на его автора. Созданный вами блокнот по умолчанию приватен (виден только вам). Если вы хо- тите дать доступ к нему другим, можете добавить только пользователей из опреде- ленного списка (collaborators) — им можно в том числе дать право редактировать код — или сделать блокнот публичным, чтобы его могли видеть все пользователи. Запуск блокнота Вы закончили писать код, и он выглядит неплохо. Попробуем запустить его. В пра- вом верхнем углу страницы найдите кнопку Save Version и нажмите ее (рис. 3.6). Рис. 3.6. Сохраните свой скрипт
72 Часть I. Знакомство с соревнованиями Kaggle Обычно для запуска скрипта используется опция Save & Run All, альтернатив- ная — Quick Save — полезна для сохранения промежуточных версий, не готовых к отправке на проверку (рис. 3.7). Рис. 3.7. Разные опции для сохранения just now Brain Tumor * - EDA with Animations an... Version #4 with GPU Running: just now Рис. 3.8. Отслеживание активных событий Titanic Survival Prediction : How I got to top 3% Python Notebook or Titanic - Machine Learning from Disaster X 6m to rue Edit leualtzations □ Stop Session w Brain Tumorw - EDA with Animations an... Version #4 with GPU 0 Open In Viewer Running; just now Pclass = 2 | Survived = 0 Pclass = Рис. 3.9. Отмена выполнения блокнота
Глава 3. Работаем и учимся с Kaggle Notebooks 73 Запустив свой скрипт, вы можете перейти в левый нижний угол и нажать Active Events (рис. 3.8). Таким образом, вы можете отслеживать, что происходит с вашими блокнотами (в том числе с несколькими одновременно запущенными). Нормальному исполнению соответствует сообщение Running, при ошибке вы увидите сообщение Failed. Если вы по каким-то причинам хотите остановить текущую сессию исполнения (напри- мер, вы вспомнили, что не используете последние данные), щелкните на значке с тремя точками справа от названия вашего скрипта, и тогда появится всплывающее окно, как на рис. 3.9. Сохранение блокнотов на GitHub Недавно (см. https://www.kaggle.com/product-feedback/295170) была добавлена возможность сохранять блокноты в репозитории GitHub (https://github.com/) — как публичные, так и приватные— с автоматическим обновлением версий. Это может быть крайне полезным как для совместной работы с сокомандниками на Kaggle, так и для того, чтобы продемонстрировать свою работу широкой публике. Для того чтобы связать блокнот с репозиторием, откройте его и в меню File выбе- рите команду Link to GitHub (рис. 3.10). [Tutorial] Feature selection with Boruta-SHAP File Edit View Run Add-ons Help + New Notebook All Markdown Я Upload Notebook Link to GitHub with Boruta-SHAP to in Download Notebook в Upgrade to Google Cloud Al Notebooks Feature Importance Set as Utility Script Add or upload data 1® Add utility scnpt Puc. 3.10. Связь c GitHub Теперь нужно привязать к блокноту аккаунт GitHub (рис. 3.11). В первый раз у вас явно запросят разрешения, с последующими блокнотами это будет происходить автоматически. После этого выберите репозиторий, и каждый раз при сохранении блокнота будет происходить синхронизация (рис. 3.12).
74 Часть I. Знакомство с соревнованиями Kaggle [Tutorial] Feature selection with Boruta-SHAP Ьч kj.1 W.w Run A<kl-i>r.;, нар + ® X 0.П t> N> Markdown Feature select'0” >,,;+u D”r"*” C1JAD Link to GitHub Kaggle needs to sync with your GitHub account for this feature to work You can review the specific authorization in the next step and can unbk from GitHub at any time О Link to GitHub Cancel Puc. 3.11. Связь c GitHub Save copy to GitHub Upload this ipynb to GitHub under your GitHub account Imassaron. This can only be undone directly on GitHub. Imassaron/kaggle_public_notebooks main s Include a link to Kaggle Puc. 3.12. Сохранение кода на GitHub Задав репозиторий и его ветку (что позволит сохранять код на разных стадиях раз- работки), вы можете изменить имя файла и сообщение при отправке.
Глава 3. Работаем и учимся с Kaggle Notebooks 75 Если вы хотите прекратить синхронизацию некоторого блокнота с GitHub, доста- точно в меню File выбрать пункт Unlink from GitHub. Наконец, если вы хотите вовсе отсоединить Kaggle от своей учетной записи на GitHub, это можно сделать в вашей учетной записи Kaggle (раздел Му linked accounts) или в настройках самого GitHub (https://github.com/settings/applications). Как получить максимум от Kaggle Notebooks Kaggle бесплатно предоставляет некоторые вычислительные ресурсы (не более оп- ределенного количества каждую неделю). Доступ к GPU и TPU ограничен по коли- честву часов — для TPU это 30 часов, для GPU квоты могут различаться в разные недели (официальное заявление об этом: https://www.kaggle.com/product-feedback/ 173129). Свой "баланс” можно увидеть в профиле (рис. 3.13). Д Konrad Banachewicz X @ Your Profile (•J Account -£] Sign Out Ф Your accelerator quota GPU available of 41h Tpu 30h available of 30h Puc. 3.13. Статистика использования вычислительных ресурсов Квоты на первый взгляд кажутся большими, но это впечатление может быть об- манчивым, истратить их полностью довольно легко. Контролировать использова- ние ресурсов помогут следующие подсказки. • Счетчик использования GPU или TPU начинает работу, как только вы запус- каете блокнот. • Поэтому сначала всегда проверяйте, что GPU отключен (см. рис. 3.6). Напи- шите сперва весь код, не требующий использования GPU, проверьте его пра- вильность, и лишь по мере необходимости подключите GPU. Не забудьте, однако, что при этом исполнение кода начнется с начала. • Обычно стоит сначала запустить код на малочисленном подмножестве дан- ных, чтобы оценить время выполнения. Таким образом вы минимизируете риск того, что ваш код исчерпает весь временной лимит и "упадет".
76 Часть I. Знакомство с соревнованиями Kaggle Иногда вычислительных ресурсов, которые бесплатно дает Kaggle, оказывается не- достаточно для поставленной задачи, и требуется более мощный компьютер. При- мером может служить недавний конкурс по классификации опухолей: https:// www.kaggle.com/c/rsna-miccai-brain-tumor-radiogenomic-classification/data. Если размер данных превышает 100 Гбайт, приходится либо менять разрешение изображений (downsampling), что негативно скажется на качестве классификации, либо обучать модель в той среде, которая способна работать с изображениями в высоком разрешении. Можно полностью перейти в другую среду (например, как описано в разд, "Kaggle Datasets и Google Colab" главы 2) или остаться внутри Kaggle Notebooks, но сменить компьютер, на котором будет исполняться код. Здесь на сцену выходят блокноты Google Cloud AL Переход на Google Cloud Platform Очевидное преимущество перехода на облачную платформу Google Cloud Platform (GCP) — доступ к более мощному аппаратному обеспечению: Kaggle предоставля- ет не самый высокопроизводительный (хотя и вполне достаточный для многих приложений) Tesla Р100 GPU, заметным ограничением могут стать и 16 Гбайт опе- ративной памяти (особенно в задачах обработки естественного языка или изобра- жений). Преимущество во времени очевидно (что позволяет быстрее улучшать свои модели), но в буквальном смысле не бесплатно. Время — деньги, особенно время работы мощного компьютера. Для того чтобы ваш блокнот исполнялся на GCP, в меню справа выберите пункт Upgrade to Google Cloud Al Notebooks (рис. 3.14). Рис. 3.14. Переход на платформу Google Cloud Al
Глава 3. Работаем и учимся с Kaggle Notebooks 77 Вы увидите следующее приглашение (рис. 3.15). Upgrade to Google Cloud Al Platform Notebooks a Google Cloud Access more compute power by exporting your notebook and its dependencies to Google Cloud Al Platform Notebooks where you can customize a virtual machine without quotas or runtime limits. This process is three steps: 1. Setup a billing-enabled Google Cloud Project 2. Setup your notebook instance and optionally customize your machine 3. Run your code without limits Puc. 3.15. Запрос на обновление do Google Cloud Al Platform Notebook Нажмите кнопку Continue, и вы будете перенаправлены на Google Cloud Platform, где придется настроить способ оплаты (увы, платформа GCP не бесплатна). Для того чтобы проделать это в первый раз, скорее всего, вам понадобится найти руко- водство. На шаг дальше Как мы уже обсуждали в этой главе, блокноты Kaggle — прекрасный инструмент для обучения и участия в соревнованиях, но кроме того, они крайне полезны как часть портфолио, показывающего ваши навыки в науке о данных. При построении портфолио нужно учитывать много факторов (например, целевую аудиторию), но главное — ваш код должен кто-то видеть. Так как Kaggle сейчас является частью Google, блокноты индексируются в самой популярной в мире по- исковой системе и, если чей-то запрос соответствует теме заинтересованных, будут показаны пользователям. Приведу пример из личного опыта. Несколько лет назад для одного из конкурсов я создал блокнот. Я занимался задачей, известной как adversarial validation (состяза- тельная проверка; вкратце ее постановку можно описать так: чтобы проверить, одинаково ли распределены обучающая и тестовая выборки, можно попробовать построить разделяющий их классификатор, подробнее об этом можно прочитать в главе 6). При написании данной главы я решил найти свой блокнот и обнаружил его на одном из первых мест в поисковой выдаче (заметим, что в запросе не упоми- нались ни Kaggle, ни мое имя (рис. 3.16). Перейдем к другим достоинствам использования блокнотов Kaggle: в категории Notebooks, как и в категориях Competitions, Datasets и Discussions, можно получать
78 Часть I. Знакомство с соревнованиями Kaggle голоса, медали и место в рейтинге. Можно вообще не участвовать в соревнованиях и при этом стать экспертом, мастером или даже гроссмейстером путем написания качественного кода, который оценят другие кэгглеры. adversarial validation code X Q, All Q Images □ Videos Щ News Q Maps • More Tools About 1.100.000 results (0.45 seconds) https://towardsdatascfence.com > adversanal-vahdatfon-ca... Learning the Adversarial Validation model - Towards Data ... Go there for better rendering of in-line code. Introduction. If you were to study some of the ccmpetmon-winning solutions on Kaggle, you might notice... 21 Jan 2020 ' Uploaded by WelcomeAIOverlords https://www.kdnuggets.com > 2016/10 > adversanal-val... < Adversarial Validation, Explained - KDnuggets This post proposes and outlines adversarial validation, a method for selecting training examples most similar to test... The code is available at GrtHub. People also ask What is adversarial validation? v What is the difference between cross-validation and holdout validation? s' What is the validation set in the 3 way cross-validation for? v What is cross-validation and validation machine learning? Feedback https://www.kaggle.com > konradb > adversarial-validat... Adversarial validation and other scary terms | Kaggle Explore and run machine learning code with Kaggle Notebooks | Using data from Sberbank hiiMiau — ii ...............—J Puc. 3.16. Блокнот Конродо в результатах поиска Google Актуальная версия требований для присвоения медалей и званий находится по ад- ресу https://www.kaggle.com/progression, на рис. 3.17 показан снимок экрана, от- носящийся к званиям эксперта и мастера. Добиться прогресса в категории Notebooks— задача интересная, но непростая (безусловно, легче, чем в категории Competitions, но сложнее, чем в Discussions). Самые популярные блокноты обычно относятся к одному из соревнований и со- держат разведочный анализ данных или полное решение с обоснованием. К сожа- лению, часто происходит погоня за местом в таблице: кто-то просто копирует блокнот с наилучшим значением метрики на тестовом множестве, немного меняет значения параметров, чтобы еще чуть-чуть улучшить метрику, и при бурном одоб- рении публики (если можно измерять его голосами) выкладывает результат своей работы. Нет, мы не хотим отговорить читателя от того, чтобы выкладывать на Kaggle хорошую работу,— в конечном счете качественные блокноты получают заслуженное одобрение, но стоит быть реалистами в своих ожиданиях.
Глава 3. Работаем и учимся с Kaggle Notebooks 79 Expert You’ve completed a significant body of work on Kaggle in one or more categories of expertise. Once you’ve reached the expert tier for a category, you will be entered into the site wide Kaggle Ranking for that category. Competitions Datasets Notebooks Discussions tef • 2 bronze medals 6? • 3 bronze medals ST > 5 bronze medals S? S 50 bronze medals Master You’ve demonstrated excellence in one or more categories of expertise on Kaggle to reach this prestigious tier Masters in the Competitions category are eligible for exclusive Master-Only competitions. Competitions ^®1 gold medal Sr 0 2 silver medals Datasets О 01 gold medal 004 silver medals Notebooks 8ГЭЮ silver medals Discussions S? 9 50 silver medals ST 200 medals in total Puc. 3.17. Требования для присвоения званий На ваш профиль Kaggle могут подписываться другие участники, к нему можно прикреплять ссылки на LinkedIn или GitHub (3.18). Konrad Banachewicz i interrogate data for a living at TNG Quant Consultancy Haarlem, North Holland, Netherlands Joined 11 years ago > last seen in the past day О * in Followers 642 Home Competitions (107) Datasets (23) Code (49) Discussion (1,240) Followers (642) Competitions eg» Master Current Rank Highest Rank 470 34 ©1162.835 9 29 16 Homesite Quote... 9 5 years ago TopIX Machinery Tube... years ago TopIX AMS 2013-2014... • 8 years ago Top 4% 3« of V55 5“ of 1320 5* of W0 Datasets Expert Notebooks Master Current Rank Highest Rank 76 59 Of 42,360 Э 9 • 0 1 14 Current Rank Highest Rank 152 54 of 177.997 9 9 • 4 10 24 Augmented trai... 0 2 months ago 25 votes Adversarial valid... • 4 years ago 116 votes Pytorch-Tabnet • 10 months ago 20 votes We need to go d... 0W days ago 84 votes Text recognition... 02 years ago 17 votes Linear baseline... 0 2 months ago 66 votes Discussion Grandmaster Edit Public Profile Discussion Grandmaster Current Rank Highest Rank 79 7 Of 206.287 9 9 • 60 88 586 Augmented dat.. 81 02 months ago votes Shrink the data... 75 0 3 years ago votes Minimalistic BER... 70 0 2 years ago votes Puc. 3.18. Профиль Конрада на Kaggle В наши дни слова о построении сообщества могут вызывать скептическую усмеш- ку, но в случае Kaggle они правдивы. У бренда Kaggle нет конкурентов по узнавае-
80 Часть I. Знакомство с соревнованиями Kaggle мости как среди исследователей данных, так и среди рекрутеров. Поэтому прилич- ный профиль на Kaggle поможет пройти как минимум первичный отбор, что зачас- тую, как мы знаем, сложнее всего. Мартин Хенце https://www.kaggle.com/headsortails Мы взяли интервью у Мартина Хенце (также известного как Heads or Tails), гроссмейстера в категориях Notebooks и Discussion и исследователя данных в компании Edison Software. Мартин — также автор еженедельной подборки лучших не замеченных публикой блокнотов Notebooks of the Week: Hidden Gems. Оповещения о новых постах из рубрики Hidden Gems можно получать, став подписчиком Мартина на Kaggle, Twitter или LinkedIn. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я долгое время был больше сосредоточен на блокнотах, посвященных разведоч- ному анализу данных (exploratory data analysis, EDA), чем на дающих итоговый результат и место в таблице. Большая часть моего опыта до Kaggle касалась таб- личных данных, так что я специализировался — да и сейчас специализируюсь — на поиске неочевидных закономерностей в табличных данных для только что за- пущенных конкурсов. Я потратил немало времени на создание структуры и ви- зуализацию данных для моих блокнотов и стремлюсь, чтобы они рассказывали некоторую историю. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Хотя сейчас на Kaggle стало мало табличных соревнований, я продолжаю счи- тать, что данные — самая важная часть любого состязания. Легко слишком рано сосредоточиться на типах моделей и подборе гиперпараметров. Но во многих конкурсах ключ к успеху по-прежнему основан на понимании данных и их осо- бенностей. Это верно и для изображений, и для обработки естественного языка, и для временных рядов — для любого типа данных. Поэтому я всегда начинаю с подробного изучения данных перед тем, как построить базовую модель, а уже за- тем усложняю ее. Главное отличие от моей работы в том, что базовые модели, которые опытные кэгглеры строят в первые недели конкурса, в реальном мере уже могли бы выйти в продакшен. В большинстве случаев за первые дни получается пройти около 80% пути к итоговому решению-победителю, если смотреть на значения метри- ки. Разумеется, самое сложное и интересное на Kaggle — найти способ добрать эти, скажем, несколько процентов точности. Но в индустрии часто более эффек- тивно провести время, работая над новым проектом.
Глава 3. Работаем и учимся с Kaggle Notebooks 81 Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle оказал очень большое влияние на мою карьеру. Опыт на Kaggle мотиви- ровал меня на переход из науки в индустрию. Сейчас я работаю исследователем данных в технологическом стартапе и постоянно развиваюсь и оттачиваю навыки на конкурсах Kaggle. В моем случае очень помогла специализация на подробных блокнотах — их лег- ко добавить в портфолио. Не знаю, насколько часто при найме действительно смотрят в твой код, но мне кажется, что звание гроссмейстера открыло мне больше возможностей, чем степень PhD. Хотя, возможно, свою роль сыграло их сочетание. В любом случае я очень рекомендую иметь портфолио из публичных блокнотов. Кроме того, при поиске работы я использовал стратегии, которые уз- нал на Kaggle, в тестовых заданиях, и они мне очень помогли. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Я думаю, все мы постоянно учимся, и сейчас мы умнее, чем были десять или пять лет назад — или даже год назад. Если отбросить это соображение, то очень важно иметь план действий, придерживаться его и отслеживать прогресс. Упус- кать из виду этот момент — очень понятная ошибка новичков: они оказываются в новой обстановке, в которой сложно сразу разобраться. Когда я зарегистриро- вался на Kaggle, я тоже был в растерянности — вокруг столько всего: форум, да- тасеты, конкурсы, курсы. У конкурсов даже названия могут звучать устрашающе: сегментация изображений нервных клеток {Neuronal Cell Instance Segmentation), предсказание волатильности рынка ценных бумаг {Stock Market Volatility Prediction). О чем это все? Тем не менее конкурсы— лучший способ начать. Ведь при запуске конкурса никто не знает, как решать эту задачу. Да, может най- тись человек, который писал диссертацию почти по той же самой теме, но таких мало. Все остальные более или менее начинают с нуля. Продираясь сквозь дан- ные, меняя функцию потерь, пробуя простые модели. Присоединяясь к соревно- ванию в его начале, вы двигаетесь по этой кривой обучения вместе с другими участниками и можете заимствовать их идеи. Но вам все равно нужен план. Это важно— легко провести несколько непродуманных экспериментов, исчерпать вычислительные ресурсы и на этом остановиться. Потом вы забываете, какая из версий вашей модели была лучшей, как связаны результаты в таблице и на ваших локальных тестах, проверяли ли вы такую-то комбинацию параметров... Поэтому запишите, что вы собираетесь делать, а потом зафиксируйте результаты. Суще- ствует множество инструментов для записи логов (и их количество растет), но можно написать и собственный скрипт. Машинное обучение остается по боль- шей части экспериментальной наукой, а рецепт эффективных экспериментов — тщательное планирование, запись, сравнение и анализ всех результатов. Какие ошибки ты допускал на соревнованиях? Я совершал множество ошибок, но, надеюсь, смог извлечь из них уроки. Напри- мер, одной из них было отсутствие надежной схемы кросс-валидации. Игнориро- вание различий между обучающим и тестовым множествами. Сосредоточение только на EDA и пренебрежение построением модели — вот, пожалуй, очень ха-
82 Часть I. Знакомство с соревнованиями Kaggle рактерная моя ошибка на первых соревнованиях. Хотя бывало и обратное — упущенные важные закономерности из-за недостаточно тщательного EDA. Еще я забывал выбрать два окончательных решения (что в итоге не особо повлияло на результат, но больше такого я не сделаю). Однако я повторю в отношении оши- бок то же самое, что раньше говорил про наличие плана. Ошибаться — нормаль- но, если вы учитесь на ошибках, если они помогают вам расти и развиваться. Да, стоит избегать тривиальных, легко предугадываемых ошибок. Но в машинном обучении, как и в науке, ошибки — часть процесса. Не все всегда работает, это нормально. Важно не повторять одних и тех же ошибок снова и снова. Так что единственная по-настоящему серьезная ошибка — не учиться на своих ошибках. Это правило годится не только для конкурсов Kaggle, но и для жизни в целом. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я знаю, что сейчас мир машинного обучения — это мир Python, но для работы с таблицами и для визуализации я все еще предпочитаю R и его библиотеки: dplyr, ggplot2, lubridate и т. д. Библиотека tidymodels — серьезный конкурент skleam. Даже если вы упертый фанат Python, стоит использовать не только самые попу- лярные библиотеки вроде pandas. Разные инструменты дают и различные точки зрения и в итоге больше простора для творчества. Что касается глубокого обуче- ния, я считаю PyTorch (с интерфейсом FastAI) самой интуитивно понятной биб- лиотекой. И, разумеется, сейчас все любят huggingface, и на это есть все основания. О чем важнее всего помнить, приступая к участию в соревновании? Главное— получать удовольствие и учиться. Во время и после соревнований участники делятся таким количеством идей и советов, что крайне обидно этим не воспользоваться. Даже если вас интересуют только победы, их не достичь без то- го, чтобы учиться, пробовать новое и опираться на опыт других. Но Kaggle — это не только конкуренция, и когда вы начнете делиться своими знаниями с другими, я обещаю, вы будете более полноценно развиваться. Курсы Kaggle Learn Kaggle позволяет получать знания многими способами. Вы учитесь, участвуя в конкурсах, изучая датасеты или код модели незнакомого вам ранее типа. Послед- ний по времени появления из способов учиться на Kaggle — это курсы из раздела Kaggle Learn (https://www.kaggle.com/learn). Эти микрокурсы позиционируются как "единственный быстрейший способ получить навыки для самостоятельных проектов". Каждый курс — это быстрое введение в одну из тем, разбитое на ма- ленькие главки с упражнениями. Каждая главка и каждый набор упражнений пред- ставляют собой блокнот. Теория и примеры кода чередуются с заданиями, в кото- рых код должны написать вы сами.
Глава 3. Работаем и учимся с Kaggle Notebooks 83 Ниже мы дадим краткий обзор самых полезных курсов. • Intro to ML/Intermediate ML (Введение в машинное обучение/Машинное обу- чение для продолжающих): https://www.kaggle.com/learn/intro-to-machine- learning и https://www.kaggle.com/learn/intermediate-machine-learning. Эти курсы можно рассмотреть как две части одного большого: в первом из них вводятся различные классы моделей и обсуждаются темы, общие для разных моделей, такие как недообучение, переобучение и валидация. Второй курс углубляется в построение признаков, работу с пропущенными значе- ниями и категориальными переменными. Эти курсы будут полезны для тех, кто только начинает знакомство с машинным обучением. • Pandas', https://www.kaggle.com/learn/pandas. Этот курс познакомит вас с одним из основных инструментов современной науки о данных. Вы научитесь создавать, читать и записывать данные, очи- щать их, работать с индексированием, выбирать нужные, группировать и т. д. Курс будет полезен как новичкам (во всех возможностях pandas легко запу- таться), так и специалистам (в качестве повторения или справочного мате- риала). • Game AI (Искусственный интеллект в играх): https://www.kaggle.com/learn/ intro-to-game-ai-and-reinforcement-learning. Этот курс служит прекрасным повторением и заключением для ’’техниче- ских” курсов Kaggle. Вы напишете ’’агента” для некоторой игры и настроите его, используя алгоритм минимакса. Можно рассматривать этот курс и как практическое введение в обучение с подкреплением. • Machine Learning Explainability (Интерпретируемость в машинном обучении): https://www.kaggle.com/learn/machine-learning-explainability. Строить модели очень увлекательно, но поскольку мир состоит не только из исследователей данных, вам может понадобиться объяснять окружающим свои результаты. Здесь вам пригодится этот курс. Вы научитесь определять важность признаков тремя методами: перестановками, SHAP (SHapley Addi- tive exPlanations, аддитивные объяснения Шепли) и графиками частичных за- висимостей. Этот курс будет очень полезен любому, кто работает с машин- ным обучением в бизнес-среде, где продолжение проекта зависит от того, насколько хорошо он объяснен. • AI Ethics (Этика искусственного интеллекта): https://www.kaggle.com/learn/ intro-to-ai-ethics. В этом очень интересном курсе обсуждаются вопросы морали в приложении к искусственному интеллекту (ИИ), Вы научитесь определять предвзятость в моделях, узнаете, что такое справедливый ИИ, и поймете, как повысить про- зрачность, сообщая информацию о модели. Это практический курс, посколь- ку слова об ’’ответственном искусственном интеллекте” звучат все чаще и чаще.
84 Часть I. Знакомство с соревнованиями Kaggle Кроме курсов, созданных Kaggle, некоторые пользователи предлагают свои обу- чающие блокноты, мы советуем вам искать и изучать их. Андрада Олтеану https://www.kaggle.com/andradaolteanu Андрада Олтеану — гроссмейстер Kaggle (в категории Notebooks), и она очень любит учиться. Андрада является глобальным послом HP в области науки о данных (HP Data Science Global Ambassador), исследователем данных в ком- пании Endava и экспертом по разработке в Weights & Biases. Мы поговорили с Андрадой о соревнованиях, ее карьере и многом другом. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я бы сказала, что моя специализация — визуализация данных, поскольку она по- зволяет мне привносить творчество в работу с данными. Не сказала бы, что у ме- ня есть любимый тип соревнований, скорее я люблю выбирать разные интерес- ные мне соревнования в различные моменты. Kaggle прекрасен тем, что позволяет освоить различные области внутри науки о данных (компьютерное зрение, обработку естественного языка, разведочный анализ данных, статистику, временные ряды и многое другое), знакомясь попутно с разными темами из ре- альной жизни (спортом, медициной, финансами, криптовалютами, событиями в мире...). Замечательно и то, что, например, если вы хотите узнать больше о рабо- те с текстовыми данными, почти всегда вы обнаружите актуальный конкурс, тре- бующий NLP. Если вы хотите научиться работать с аудиофайлами, найдется и такой конкурс. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шла к решению Самым сложным "конкурсом”, в котором я участвовала, был конкурс по анализу опроса Kaggle (Kaggle Data science and Machine Learning Annual Survey). Я пони- маю, что это не совсем "настоящее” соревнование, с таблицей результатов и ис- пользованием сложного машинного обучения, но для меня это было одно из са- мых сложных и многому меня научивших соревнований. Это конкурс блокнотов, и участники должны проявить нестандартное мышление, чтобы претендовать на один из пяти призов от Kaggle. Я участвовала в нем два года подряд. В первый раз, в 2020 г., было сложно обойтись базовыми навыками визуализации, и это стимулировало меня мыслить нестандартно. Я заняла третье место. В следую- щем, 2021 г., я 4 месяца готовилась, осваивая библиотеку D3 и стремясь перейти на новый уровень в визуализации данных. Итоги конкурса еще подводятся, но специальный приз Early Notebook Award я уже получила.
Глава 3. Работаем и учимся с Kaggle Notebooks 85 Могу дать следующие советы. • Во-первых, старайтесь не потеряться в массиве данных, создавайте диа- граммы, отражающие реальную картину. Проверяйте дважды, что ваше представление данных понятно и корректно. Нет ничего хуже, чем краси- вый график, из которого следуют неверные выводы. • Берите идеи из окружающего мира— природы, фильмов, своей работы. Рисуйте. Все это поможет вам находить нетривиальные способы визуали- зации. Помог ли тебе Kaggle в карьере? Если да, то как? Да, и очень. Я считаю, что большей частью я обязана Kaggle своей нынешней карьерой, и за это я навек благодарна данной платформе. Благодаря Kaggle я ста- ла глобальным послом HP в области науки о данных (HP Data Science Global Ambassador) и узнала о платформе для машинного обучения Weights & Biases, где теперь являюсь экспертом по разработке. Наконец, здесь я познакомилась со своим руководителем в Endava, который и позвал меня на работу в эту компа- нию. В общем и моя работа в Endava, и связь с двумя большими компаниями (HP и Weights & Biases) — непосредственный результат моей активности на Kaggle. На мой взгляд, самая недооцененная особенность Kaggle — наличие сообщества. На Kaggle собралось огромное количество людей, с которыми можно общаться и учиться у них новому. Лучший способ воспользоваться этим — взять, например, 100 первых участников в рейтинге по каждой из категорий (Competitions, Datasets, Notebooks и, если хотите, Discussions) и подписаться на их Twitter/ LinkedIn, если в профиле есть ссылка. Таким образом вы сможете регулярно взаимодействовать с этими потрясающими и столь много знающими людьми. Какие ошибки ты допускала на соревнованиях? Самая большая ошибка— не участвовать в них. Я считаю, что это основная ошибка, которую совершают новички. Они боятся (здесь я опираюсь на собст- венный опыт) и считают, что пока не готовы, или просто не знают, с чего начать. К счастью, есть довольно простой алгоритм, как приступить к любому конкурсу. • Запишитесь на любой конкурс, который кажется вам интересным. • Изучите страницы с описанием задачи и данных. • Если вы не знаете, с чего начать, не волнуйтесь! Откройте раздел Code и найдите блокноты с большим числом голосов либо созданные опытными участниками, скажем, гроссмейстерами. Создайте свой блокнот и посте- пенно переносите в него чужие наработки, стараясь улучшить их. Это, на мой взгляд, лучший способ обучения — вы учитесь на практике и никогда не застреваете в непонимании, как двигаться дальше. О чем важнее всего помнить, приступая к участию в соревновании? Помнить, что неудачи — это нормально, и это лучший способ научиться новому. Кроме того, ориентируйтесь на гроссмейстеров в соревновательной категории — они часто рассказывают о методах, о которых остальные не знают. Лучший спо-
86 Часть I. Знакомство с соревнованиями Kaggle соб учиться — смотреть на тех, кто уже пришел к успеху. Выберите двух-трех гроссмейстеров, которыми вы восхищаетесь, и учитесь у них, например изучайте и воспроизводите их блокноты. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Нет, я никогда не использовала других платформ, на Kaggle есть все, что мне нужно. Резюме В этой главе мы рассказали о бесплатной среде Kaggle Notebooks, которую удобно использовать для обучения и создания портфолио. Теперь вы можете создавать блокноты для соревнований или собственных проектов и эффективно использовать предоставленные вычислительные ресурсы. В следующей главе мы поговорим о форуме — главном способе обмена идеями и мнениями на Kaggle. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
4 Используем форумы Форумы — главное средство обмена информацией на Kaggle. Кэгглеры постоянно общаются — обсуждают текущее соревнование, датасет, блокнот с новым методом решения. В этой главе мы познакомимся с форумами, с тем, как они устроены, с правилами поведения. Мы обсудим следующие темы: • как работают форумы; • примеры дискуссий; • сетевой этикет. Как работают форумы Вы можете попасть на форумы несколькими способами. Самый очевидный — на- жать на название раздела Discussions на панели слева (рис. 4.1). Сверху вы видите список форумов, посвященных общим темам (Forums). Они по- лезны, когда вы участвуете в первом своем соревновании, когда у вас есть предло- жение или общий вопрос. Ниже вы видите все остальные обсуждения, большей частью они относятся к кон- курсам (как-никак, это основное занятие пользователей Kaggle), но иногда к блок- нотам или датасетам. По умолчанию они отсортированы по количеству участников и активности (Hotness). Здесь постоянно возникают новые обсуждения, относя- щиеся к различным разделам Kaggle. Их можно отфильтровать по нескольким кри- териям (рис. 4.2). Вы можете использовать фильтры, чтобы найти интересные вам обсуждения. Фильтровать можно по следующим параметрам (рис. 4.3): • RECENCY (время) — позволяет задать промежуток времени;
88 Часть I. Знакомство с соревнованиями Kaggle = kaggle 0 Home Competitions 63 Datasets <> Code Discussions ф Courses v More Q, Search Discussions Discuss the Kaggle platform A machine learning topics - this includes sharing feedback, asking questions and more. Your Discussions Ql Forums KVvWHiy tWWWH lb Explosive Violence Mo... 0 Kats by Facebook A n._. Д Practical time series - ». В Practical time series -... Ц TF/JAX Tutorials ~ Part3 Ж л» 1 Announcements, resources, ano interesting discussions ' Jest post 2 mtrurts» ago by Bembula Getting Started гпе first stop for new xaggters tost post 7 minutes ago by Emma Product Feedback Tea us whet you tovo beta and wish tor test post 2 hours ago by HuzafiaMS Questions A Answera Technical advice from other data sdentuts test post 2 hours ago by Jae-YuYm Se-S Recant topics by Bambute, Kaminadmon. HuxatfaMS •ii Recent topics by Emma, HuzaifaMS, AflB tGe Recent topics by HuzaifaMS, Bjim, Iboxorigin Ш Recent topics by Jae-Yu Yah, Oibbsss. dustinb Рис. 4.1. Переходим на страницу Discussions из главного меню Рис. 4.2. Обсуждения, относящиеся к различным разделам Kaggle
Глава 4. Используем форумы 89 • MY ACTIVITY (моя активность) — используйте, если хотите увидеть свои посты и комментарии на всех форумах. Эта опция особенно полезна, если вы участвуете одновременно в большом количестве обсуждений; • ADMIN — дает обзор всех объявлений от админов Kaggle; • TYPES (типы)— обсуждения могут относиться к общему форуму либо к конкретному соревнованию или датасету; • TAGS (теги) — некоторые, хотя и не все, дискуссии помечены тегами, и этим можно воспользоваться. На рис. 4.4 показан пример выдачи при фильтрации по тегу Beginner. Можно также сосредоточиться на конкретной тематике. Так как некоторые темы, зроде компьютерного зрения, чрезвычайно популярны, можно отсортировать об- суждения по активности в целом (Hotness), последним комментариям (Recent Comments), последним постам (Recently Posted), количеству голосов (Most Votes) и комментариев (Most Comments), рис. 4.5. На Kaggle приходят по разным причинам, но все же большинство привлечены уча- стием в соревнованиях. У каждого конкурса имеется свой отдельный форум, на ко- торый можно попасть, перейдя на страницу конкурса и щелкнув по ссылке Discussion (рис. 4.6).
90 Часть I. Знакомство с соревнованиями Kaggle ш Discussion from across Kaggle Q, Gear Шаг»loanable «eaten T Filters • Bagtoner X Hotness * ЦЦямоигсаас^ thaWtak:#12 \JFz Praajet^*™* to Genera .last comment 1h ago by Shasharik SmosUva ‘ 11 * S comments •»« Best Data Science Z Youtube Channels ЕЭ Ned to Getting Suned-L»t comment Shago by Uas Karri * 42 * 71 comments ••• More than 250 Awesome Public Datasets X^JZ PAVAN KumaP О ♦ И Genera - lest comment tOh ago by hastm • <2 ’ M comments » ►►Resources of the Weak : #12 xJFz PjanjKWrme to Qacmg Started Last comment 2h eg» by toxmen kueums *10 * 7<жттмш Everything about‘ GAN * Generative Adversarial Networks #3Reeources W «3 ShMft Rene 63 * to Genera Last comment 42m ago by Kaen BOKf • 11 * 23 comments *•* What is the secret behind random seed 42? JJ/ OKI MorA - to RSNA-MICCM frton Tumor Sa^ogenomic Cle^MHeh' test comment Th ago by Menu SMtowvie * 13 * 21 comments **« Common#t: Some Good things to learn Shthutaa to CommorO RaadabSty Prize Lett comment 1h ego by AraiK Temazian *!421 9 comments Рис. 4.4. Выдача результатов при фильтрации по тегу Beginner л Discussion from across Kaggle CiwtoM* to anabi» march Computer V»on X Whet it the secret behind random seed 42? Jf/ OW Mor* - in ItSNA-MCCJM few Tumor КщэугкгАс CUwttortw» tatt cemnwtt Л *90 Oy Menu SictohortM JK O^Resourcascf thaWaak:#11 \ у/ Rmm Wmm • w swim • Last eomwwM sw >00 ay hew Retrained 3D-CNN* and other resources AtweFrmewcBMWFerMnMi in RSNA-MCCAI BWft Tumor ItaMgew» СМкйсМоо - U« c-ommontSh Ma by 1меМП8 ’4 ©Re^urce*oftheWSek;#11 \Ду PwypWnm швепепй Le»cww»emJd»eoby «erMpopMSX Homes* 21c< Recent Comments Recently Posted }7ci Most Votes Most Comments 2ca Puc. 4.5. Темы, касающиеся компьютерного зрения, на общем форуме Сейчас (но так было не всегда) почти все соревнования имеют список часто зада- ваемых вопросов (frequently asked questions, FAQ), закрепленный сверху списка об- суждений на форуме этого конкурса.
Глава 4. Используем форумы 91 Т Гeatured Code Competition Optiver Realized Volatility Prediction Apply your data science skills to make financial markets better $100,000 Prize Money Optiver 1,051 teams 2 months to go (2 months to go until merger deadline) Overview Data Code Discussion Leaderboard Rules Team My Submissions New Topic Discussions Following ) Q, Search discussions ~ Filters All Owned Bookmarks Pinned topics Hotness * Competition data FAQ 9 Jiashen Liu • Last comment 2h ago by Gunes Evitan • New comments • 73 comments ••• seconds_in_bucket not starting from zero in some parts of the filler data Jiashen Liu - Last comment 3d ago by Jiashen Liu GW7) 23 comments ••• Puc. 4.6. Форум одного из конкурсов Jiashen Liu | Competition Host | 836th place Competition data FAQ Posted in opvvef-reaiized-voiatilily-prediction 21 days ego Hi ail, Again, welcome to our competition' Very excited to see so many Kaggiers participating alreadyl We have received a lot of questions about the competition data, here we would like to provide a list of FAQ to make everyone up-to-speed Most of below is already covered in the data page but good to mention here as well if helpful. Q: Is the same stock_ld representing same stocks In all competition dataset’ A: Yes, stock-id is a unique identifier of a stock in real fife, and the group of 112 unique stocked will be present in all datasets. Q: What does time ld mean and how the target-feature data are structured? Puc. 4.7. Добавление темы в закладки
92 Часть I. Знакомство с соревнованиями Kaggle Стоит начать с изучения этого списка, поскольку: • это экономит время — скорее всего, в списке уже есть ответы на самые час- тые вопросы; • вы не будете задавать вопросы, которые уже задал кто-то другой, и тем сде- лаете удобнее жизнь всех участников. Темы обсуждений, подобно блокнотам, можно добавлять в закладки (рис. 4.7). Список ваших закладок можно найти на странице профиля (рис. 4.8). Konrad Banachewicz I interrogate data for a living at TNG Quant Consultancy Haarlem, North Holland, Netherlands Joined 11 years ago - last seen in the past day О * in Home Competitions (113) Datasets (48) Code (62) Discussion (1,285) Followers (807) Followers 807 Discussion Grandmaster Edit Public Profile Discussion Summary Discussion Grandmaster Current»** Hlgmstftank 103 7 Of 269.397 ® о 71 91 609 Total Posts: 1285 Comments 1186 Topics. 99 Net Votes. 3357 Votes/Post: 2.61 3,357 upvoted Comments and topics Comments Topics Bookmarks pj Embeddings, Cosine Distance, and ArcFace Explained. Topic 10 months ago in Shopee - Pnce Match Guarantee Son by Most Votes What are These Strange Words? Puc. 4.8. Список закладок в пользовательском профиле Примеры обсуждений Абсолютно нормально в какой-то момент соревнований чувствовать себя расте- рянно. Предположим, вы приступили к конкурсу, опробовали пару идей, получили какой-то результат, но совершенно не понимаете, как двигаться дальше. В этот мо- мент полезно обратиться к обсуждениям на форуме. В качестве примера возьмем конкурс по предсказанию волатильности Optiver Realized Volatility Prediction (https://www.kaggle.eom/c/optiver-realized-volatility-prediction), описываемый организаторами так:
Глава 4. Используем форумы 93 В первые три месяца соревнования вы построите модели, предсказы- вающие в краткосрочной перспективе волатильность ценных бумаг разных секторов. Вы будете работать с сотнями миллионов записей с детальными финансовыми данными и с их помощью создадите мо- дели, предсказывающие волатильность в следующий 10-минутный период. Ваши модели будут протестированы на реальных данных рынка, собранных в следующие три месяца после обучающих данных. Здесь возникает очень много вопросов, пройдемся по главным из них и покажем, какую пользу можно извлечь из форума. Во-первых, участие в этом конкурсе тре- бует некоторых знаний в сфере финансов — может быть, не уровня опытного трей- дера, но мало кто из обычных людей (а в этом отношении большинство кэгглеров вполне обычны) понимает, какими способами вычисляется волатильность. К сча- стью, организаторы конкурса предоставили список источников, чтобы помочь ра- зобраться в предметной области: https://www.kaggle.eom/c/optiver-realized" volatility-prediction/discussion/273923. Если имеющихся сведений все еще недоста- точно, не стесняйтесь задавать вопросы, как здесь: https://www.kaggle.com/c/optiver- realized-volatility-prediction/discussion/263039, или здесь: https://www.kaggle.com/ sc/optiver-realized-volatility-prediction/discussion/250612. По ходу соревнования участники создают все более и более изощренные модели. Здесь приходится искать баланс: с одной стороны, вы сами многому раньше научи- лись у делившихся своими идеями ветеранов, с другой, не хочется, опубликовав весь свой код, терять возможное преимущество. Разумным компромиссом может быть пост с рассказом об основных идеях, например https://www.kaggle.com/ c/optiver-realized-volatility-prediction/discussion/273915. В последние годы всё больше соревнований уходят от формата с фиксированными тестовыми данными и тем или иным образом видоизменяют правила: некоторые требуют отправки решений с использованием Kaggle Notebooks, другие делят кон- курс на фазу обучения и фазу проверки на новых данных. Последний вариант отно- сился и к конкурсу от Optiver: После дедлайна на отправку решений таблица результатов будет периодически обновляться в соответствии с результатами блокно- тов на поступивших данных о рынке. Обновления будут происходить примерно раз в две недели с перерывом на рождественские каникулы.
94 Часть I. Знакомство с соревнованиями Kaggle Сформулировано просто, но как тогда обучать модели? Встретившись с подобной ситуацией, задавайте вопросы, как делали участники конкурса: https:// www.kaggle.com/c/optiver-realized-voIatility-prediction/discussion/249752. Схема валидации обученной модели — всегда важный вопрос в конкурсах Kaggle, приводящий к вечным спорам "кросс-валидация или таблица результатов"? (CV vs LB, cross-validation versus leaderboard). Конкурс от Optiver их также не избежал: https://www.kaggle.eom/c/optiver-realized-volatility-prediction/discussion/250650. Если кто-то уже не поднял эту тему до вас (советуем проверять это и не повторять- ся), можно задаться и таким вопросом, как качество отдельных моделей. Рано или поздно все приходят к ансамблям моделей, но они не будут эффективны, если не- эффективны их компоненты. Если вы считаете, что нашли лучший подход к задаче, стоит о нем рассказать — вы либо принесете пользу другим участникам, либо об- наружите свою ошибку и сэкономите силы и время. В обоих случаях вы в выигры- ше. В качестве примера можно привести обсуждение https://www.kaggle.eom/c/ optiver-realized-volatility-prediction/discussion/260694. Кроме очевидной пользы для вас (узнать, как справляются с задачей другие участ- ники), обсуждения в целом способствуют обмену информацией между участниками, объединению для решения задач и помощи новичкам. Пример такого обсуждения: https://www.kaggle.eom/c/optiver-realized-volatility-prediction/discussion/250695. Но даже изучив несколько тем вроде указанных выше, вы все еще можете задаваться вопросом, не упускаете ли что-нибудь важное. На Kaggle можно спросить и об этом: https://www.kaggle.eom/c/optiver-realized-volatility-prediction/discussion/262203. В завершение этого раздела посмотрим на другие соревнования. Мы уже обсужда- ли выше тему валидации, которая — по крайней мере для кэгглера — неразрывно связана с утечками информации и переобучением. Утечки подробно обсуждаются в главе 6, посвященной построению схем валидации. Здесь же мы поговорим о том, что имеет отношение к форумам. Так как кэгглеры — люди дотошные, при нали- чии утечки скорее всего кто-то поднимет этот вопрос. Так, названия файлов или идентификаторы записей могут содержать дату и время, что порой позволяет уз- нать будущие значения и получить нереалистично маленькую ошибку. Подобная ситуация произошла на конкурсе Two Sigma Connect (https://www.kaggle.com/ c/two-sigma-connect-rental-listing-inquiries/), о ней можно прочитать в посте https://www.kaggle.com/c/two-sigma-connect-rental-listing- inquiries/discussion/31870#176513. Другим примером может служить конкурс Airbus Ship Detection Challenge (https://www.kaggle.eom/c/airbus-ship-detection), задачей в котором было обнару- жение кораблей на спутниковых снимках. Как выяснилось, многие из тестовых изображений были случайным образом обрезанными изображениями из обучаю- щего множества, и поиск соответствий становился тривиальной задачей: https:// www.kaggle.com/c/airbus-ship-detection/discussion/64355#377037.
Глава 4. Используем форумы 95 Известной не с лучшей стороны оказалась серия конкурсов от компании Santander. В двух из трех конкурсов, организованных ею, присутствовала утечка данных: https://www.kaggle.eom/c/santander-value-prediction-challenge/discussion/61172. Подобные ситуации могут разрешаться по-разному: в некоторых случаях конкурс перезапускался с новыми либо вычищенными данными, но иногда влияние утечки считали незначительным и соревнование продолжалось. Пример того, как действо- вали в случае конкурса Predicting Red Hat Business Value, можно найти на https://www.kaggIe.eom/c/predicting-red-hat-business-vaIue/discussion/23788. Хотя утечки в данных могут стать серьезной проблемой, в последние 2-3 года они на Kaggle, к счастью, редки. Так что, скорее всего, раздел о них стоит прочитать, но вряд ли они будут играть важную роль в вашем соревновательном опыте. Ифань Се https://www.kaggle.com/yifanxie Ифань Се — мастер в категориях Discussions и Competitions, а также сооснователь Arion.ai. Мы попросили его расска- зать о соревнованиях и совместной работе с другими кэгг- лерами. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Пожалуй, любимого вида нет, мне нравятся разные задачи. Что касается подхо- дов, у меня уже выстроен процесс, позволяющий быстро применять стандартные методы. Наличие общей схемы дает мне преимущество на соревнованиях, позво- ляет быстрее переходить к новой версии и, соответственно, повышать качество результата. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Постепенно я создал свою систему работы с информацией, касающейся моих проектов по анализу данных — моей работы, конкурсов Kaggle, других сторон- них проектов. Обычно я фиксирую всю информацию, полезную для данного со- ревнования, — закладки, описание данных, списки задач, полезные команды, ре- зультаты экспериментов — в стандартном формате и, если работаю в команде, делюсь ей с товарищами. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Для меня всегда оказывалось полезным понимать контекст конкурса, например, какие социальные, технические или финансовые процессы стоят за появлением имеющихся данных. Если имеет смысл рассматривать отдельные записи или
96 Часть I. Знакомство с соревнованиями Kaggle объекты (data points) — как, например, в случае конкурса Deepfake Detection Challenge, где это были пары из настоящего и фейкового видео, — я буду изучать их. Я собираю и визуализирую основные характеристики данных, как статисти- ческие, так и относящиеся к отдельным записям, обычно с помощью библиотеки Streamlit. Все это позволяет мне лучше понять данные. Помог ли тебе Kaggle в карьере? Если да, то как? Я бы сказал, что Kaggle сыграл важнейшую роль в моем карьерном пути. В итоге я стал сооснователем компании, оказывающей консультации в области науки о данных. Kaggle позволил мне за несколько лет получить навыки, позволяющие решать задачи из разных областей. С некоторыми заказчиками и коллегами я по- знакомился, вместе участвуя в конкурсах. Хотя сейчас я уделяю Kaggle меньше времени, он всегда был для меня замечательным источником знаний. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Одна из ошибок, которые я замечаю за новичками, — не обращать внимания на важные аспекты, не относящиеся к науке о данных как таковой, — правила обра- зования команд, использования данных, публикации личной информации, ис- пользования нескольких аккаунтов без злого умысла и т. п. Ошибки такого рода могут свести на нет многомесячные усилия. Сам я хотел бы знать, что не стоит неотрывно следить за изменением своего места в таблице результатов. Это лишний стресс и источник переобученных решений. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Все стандартно: Scikit-leam, XGB/LGB, PyTorch и т. п. Единственный инстру- мент, который я бы советовал освоить на продвинутом уровне, — это библиотека NumPy, особенно полезная для нетривиальных способов сортировки и выбора части данных. То же самое можно делать и с помощью pandas, но NumPy обеспе- чивает большую эффективность. О чем важнее всего помнить, приступая к участию в соревновании? Как я писал в своей книге, все, что относится к науке о данных, можно делать по четырем причинам: для денег, для знаний, для развлечения и для принесения пользы. Для меня Kaggle всегда был важным источником знаний, а еще благода- ря ему мне есть что вспомнить. Так что советую всем помнить: рейтинг — это временное, а знания и воспоминания останутся с вами :) Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я активный участник на Numeral Если следовать моей классификации причин заниматься наукой о данных — скорее, для денег, поскольку они платят крипто- валютой. Это платформа, скорее, для индивидуальных участников, командная работа не запрещена, но и не особо поощряется — просто в трейдерских сорев- нованиях большее число участников не всегда способствует лучшему результату.
Глава 4. Используем форумы 97 Мне также проще регулярно поддерживать активность на Numerai, чем на Kaggle, в периоды загруженности на работе, поскольку в каждом раунде обу- чающие данные не меняются и после построения модели предсказание и отправ- ка решений могут быть автоматизированы. Numerai также лучше подходит для тех, кто хочет выстраивать процессы работы с табличными данными. Сетевой этикет Каждый, кто провел в Интернете больше 15 минут, знает: при обсуждении любой, самой невинной темы есть риск, что собеседников захлестнут эмоции, и они вый- дут за рамки цивилизованной дискуссии. Kaggle — не исключение из правил, по- этому были выработаны правила поведения: https://www.kaggle.com/community- guidelines. О них стоит думать не только на форуме, но и при других способах общения. Вот главные правила взаимодействия на Kaggle. • Не сваливайтесь в то, что Скотт Адамс называл иллюзией чтения мыслей: Kaggle состоит из людей со всех уголков света, английский для многих не яв- ляется родным языком, так что следить за его тонкими нюансами — для них непростая задача. Не делайте лишних предположений, что имел в виду собе- седник, и при возможности уточняйте это. • Не переходите на личности. Закон Годвина никто не отменял. Абсолютно за- прещенный прием — упоминать характеристики собеседника, на которые он не может повлиять. • Возможно, вы старожил Интернета и помните ’’сетевой Дикий Запад” 1990-х, когда послать собеседника было в порядке вещей. Но Интернет изменился, и сейчас грубость только оттолкнет окружающих. • Не пытайтесь перехитрить систему присвоения медалей. Не надо выпраши- вать голоса, а тем более устраивать сговоры и обманывать. Короче говоря, поступайте с другими так, как хотите, чтобы они поступали с вами, и все будет хорошо. Резюме В этой главе мы поговорили о форумах — главном средстве общения на платформе Kaggle. Мы разобрались в их устройстве, показали, как извлечь пользу из обсужде- ний при участии в соревнованиях, и перечислили основные правила этикета. На этом мы заканчиваем первую, вводную часть книги. Со следующей главы начи- нается более глубокое погружение в мир Kaggle и способы извлечь из него макси- мум. В ней мы обсудим постановку задач и метрики, с которыми вы встретитесь на соревнованиях.
98 Часть I. Знакомство с соревнованиями Kaggle Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
Часть II Опачивание соревновательных навыков

5 Задачи и метрики на соревнованиях Начинать участие в конкурсе нужно с изучения метрики, которую вы оптимизируе- те. Понимание, как оценивается ваша модель, критически важно для успеха на лю- бом конкурсе. Когда вы отправляете предсказания своей модели на Kaggle, они сравниваются с истиной именно по заданной метрике. Так, на конкурсе, посвященном выживанию пассажиров "Титаника" (https:// www.kaggle.eom/c/titamc/), все посылки оцениваются по доле правильных ответов (accuracy). Организаторы выбрали эту метрику, поскольку цель соревнования — найти модель, определяющую вероятность выживания пассажира. В другом учебном соревновании, посвященном предсказанию цен на недвижимость (House Prices — Advanced Regression Techniques, https://www.kaggle.com/c/house- prices-advanced-regression-techniques), ваше решение будут оценивать на основа- нии средней разности между предсказанными вами и реальными ценами. Формула будет содержать логарифмирование, возведение в квадрат и извлечение корня, т. к. от модели ожидается как можно более точный порядок цены на дом. В задачах реального мира метрики также играют ключевую роль для успеха проек- та, хотя отличия от конкурсов, несомненно, есть. Можно уверенно сказать, что в реальном мире все сложнее. В нем часто придется оценивать модель не по одной, а по нескольким метрикам. Зачастую некоторые из этих метрик даже не будут иметь отношения к соотношению предсказанных и истинных ответов. Предметная об- ласть в целом и конкретного проекта в частности, количество рассматриваемых признаков, расход памяти, требования к наличию специализированного аппаратно- го обеспечения (например, графического процессора), время работы модели, ее сложность и многие другие факторы могут оказаться важнее, чем само качество предсказаний.
102 Часть II. Оттачивание соревновательных навыков В задачах реального мира решающую роль — в гораздо большей степени, чем мо- жет подумать любой не имевший с ними дела, — играют соображения бизнеса и имеющейся технической инфраструктуры. Однако невозможно не признать, что базовый принцип одинаков на конкурсах Kaggle и в реальных проектах. Вашу ра- боту будут оценивать по некоторым критериям, и для успеха необходимо понять эти критерии и оптимизировать в соответствии с ними параметры модели. Так что разобраться, как оценивают модели на Kaggle, будет полезным и для вашей работы. В данной главе мы расскажем, как метрики оценивания для некоторых типов задач влияют на выбор моделей для соревнования. Мы рассмотрим различные исполь- зуемые метрики, чтобы вы могли сами их сравнить, и попутно обсудим их влияние на предсказательную способность моделей и то, как использовать их в своих про- ектах. Мы затронем следующие темы: • метрики оценивания и целевые функции; • основные типы задач: регрессия, классификация, ранжирование; • датасет Meta Kaggle; • как быть с незнакомыми метриками; • метрики для регрессии (обычной и в задачах ранжирования); • метрики для бинарной классификации (предсказание меток классов или их вероятностей); • метрики для многоклассовой классификации; • метрики для задач нахождения объектов; • метрики для многоклассовой классификации и задачи рекомендации; • оптимизация метрик оценивания. Метрики оценивания и целевые функции На конкурсах Kaggle метрику оценивания можно найти на вкладке Overview на странице конкурса. Выбрав раздел Evaluation, вы увидите описание метрики, ино- гда с формулой, кодом и комментарием. На той же странице будет сказано о фор- мате отправляемого файла и приведен пример из заголовка и нескольких строк. Метрика оценивания и описание отправляемого файла соседствуют неспроста: именно после того, как вы обучили модель и получили некоторые предсказания, к ним применяется метрика. Из этого следует, что сначала придется разобраться в разнице метрики и целевой функции. Вкратце, целевая функция (objective function) применяется при обучении модели для минимизации ошибки. Напротив, метрика (evaluation metric) применяется по- сле обучения и дает оценку модели. Она не может повлиять на процесс обучения напрямую, но помогает вам выбрать наилучшие модели из имеющихся и наилуч- шие гиперпараметры для них. Прежде чем перейти к обсуждению метрик на кон-
Гпава 5. Задачи и метрики на соревнованиях 103 курсах Kaggle и того, почему именно с их анализа стоит начинать, поговорим о не- которых терминах, которые вы, возможно, встретите на форумах. Вы часто будете слышать о целевых функциях, функциях стоимости и функциях потерь. Некоторые употребляют эти термины как синонимы, но, строго говоря, они означают разные вещи. • Функция потерь (loss function) определена на одном элементе (точке) дан- ных и вычисляет штраф, исходя из предсказания модели и истинного значе- ния в данной точке. • При вычислении функции стоимости (cost function) учитывается все обу- чающее множество либо его подмножество — пакет (batch) — для этого бе- рется сумма либо среднее арифметическое функций потерь на элементах. Функция стоимости может содержать и дополнительные ограничения (на- пример, L1- или Ь2-регуляризацию) и непосредственно влияет на ход обу- чения. • Целевая функция (objective function)— наиболее общий термин, относя- щийся к оптимизации при обучении. Так можно назвать функции стоимости, но не только их. Целевая функция способна учитывать другие требования, помимо качества предсказания, например, разреженности коэффициентов или минимальности их значений (как при L1- и Ь2-решуляризации). Кроме того, использование терминов ’’функция потерь” и ’’функция стоимости” под- разумевает их минимизацию, в то время как целевую функцию мы можем как минимизировать, так и максимизировать. Аналогично, при оценивании качества предсказаний вы встретитесь с оценочными функциями и функциями ошибок. Их легко различить: большие значения оценоч- ной функции (scoring function) говорят о более высоком качестве предсказаний (так что мы должны ее максимизировать). Функцию ошибки (error function), напротив, нужно минимизировать: чем меньше ее значения, тем выше качество предсказаний. Основные типы задач Не каждая целевая функция подходит для каждой задачи. Если обобщать, вы встре- тите на Kaggle два типа задач: задачи регрессии и задачи классификации. Недав- но стали появляться и задачи обучения с подкреплением (reinforcement learning, RL), но при оценке их решений вместо метрики используются состязания между решениями участников (если ваше решение выигрывает у чужого, ваша позиция улучшается, если проигрывает — ухудшается). Так как в обучении с подкреплени- ем нет метрик, мы продолжим придерживаться разделения на регрессию и класси- фикацию, хотя задачи ранжирования (где вы должны присвоить элементам выра- женный целым числом порядковый номер) могут ускользать от такого разделения: иногда их можно успешно решать методами, предназначенными для задач регрес- сии, иногда — для задач классификации.
104 Часть II. Оттачивание соревновательных навыков Регрессия В задачах регрессии требуется построить модель, предсказывающую вещественное значение (часто, но не всегда — положительное). Классический пример задачи рег- рессии — предсказание цен на дома (House Prices — Advanced Regression Techniques). Оценивание задачи регрессии строится на вычислении разности между вашими предсказаниями и истинными значениями. К разности могут применяться, например, возведение в квадрат, чтобы избегать больших по модулю ошибок, либо логарифм, чтобы избегать предсказаний неверного порядка. Классификация Встретившись на Kaggle с задачей классификации, необходимо учесть больше нюансов. Классификация бывает бинарной или многоклассовой, а еще классы мо- гут пересекаться (классификация со многими метками). В задачах бинарной классификации, по сути, вам нужно понять, попадает ли объ- ект в заданный класс (обычно называемый положительным). Объекты, не принад- лежащие положительному классу, образуют отрицательный класс. Требуемым форматом ответа может быть как сама принадлежность определенному классу, так и ее вероятность. Типичный пример — конкурс, посвященный гибели "Титаника", где требуется предсказать, выжил пассажир или нет. В этом случае требуется лишь ответ "да/нет", но зачастую нам нужна и вероятность: во многих областях, в част- ности в медицине, приходится сравнивать предсказания для разных вариантов (на- пример, диагноза или лечения) и разных обстоятельств. В задачах бинарной классификации кажется разумным подсчитывать количество верных предсказаний. Однако при несбалансированности положительного и отри- цательного классов, т. е. большой разнице в количестве примеров из них, этот под- ход работает плохо. Классификация в этом случае требует метрики, учитывающей несбалансированность, если мы хотим верно отслеживать улучшения в модели. Когда классов больше двух, говорят о задаче многоклассовой классификации. Она требует своих способов оценки качества, поскольку важно следить как за об- щим качеством предсказаний, так и за тем, чтобы оно было равномерным относи- тельно классов (а не проседало на каких-то из них, например). Здесь мы говорим о задачах, где каждый объект принадлежит ровно одному классу, примером может служить конкурс Leaf Classification (https://www.kaggle.eom/c/leaf-classification), где каждому изображению листа нужно правильно сопоставить вид растения. Наконец, если метки классов не взаимоисключающи и каждый объект может при- надлежать нескольким классам, говорят о задаче классификации с пересекаю- щимися классами. Для нее нужны способы оценки, учитывающие и количество классов для каждого объекта, и правильность их определения. Так, на конкурсе Greek Media Monitoring Multilabel Classification (WISE 2014) (https://www.kaggle.com/ c/wise-2014), посвященном греческой прессе, каждой статье надо было сопоставить затронутые в ней темы.
Глава 5. Задачи и метрики на соревнованиях 105 Задачи ранжирования В задачах ранжирования каждому примеру должно быть сопоставлено целое число (метка), и эти метки естественным образом упорядочены. Так, целым числом изме- ряется сила землетрясения. Данные маркетинговых опросов также часто имеют порядковый тип: степень согласия с каким-то утверждением, предпочтения при сравнении разных товаров. Поскольку задачи ранжирования предполагают упоря- доченные значения ответа, они могут быть рассмотрены как нечто среднее между регрессией и классификацией и решаться обоими способами. Самый распространенный способ решения задач ранжирования — представить их как задачи многоклассовой классификации. В этом случае предсказанием будет целочисленная метка класса, однако при этом не будет учитываться упорядочен- ность классов. Если посмотреть на вероятности различных предсказаний при таком подходе, возникнет подозрение, что с ним есть проблемы. Зачастую распределение этих вероятностей будет мультимодальным или асимметричным, когда следовало бы ожидать гауссова распределения с одним максимально вероятным классом. Другой способ работы с задачей ранжирования — представить ее как задачу рег- рессии, а потом преобразовать результат. Этот метод учитывает упорядоченность классов, однако по исходным предсказаниям нельзя сразу оценить их качество. Регрессия выдает в результате вещественное число, а не целочисленную метку класса, так что выходными значениями могут оказаться не только любые числа между возможными метками, но и числа, лежащие вне этого интервала (которые больше или меньше всех меток). Можно (разными способами) округлять получен- ные вещественные числа, но это ведет к неточностям и требует порой нетривиаль- ных преобразований (что мы далее обсудим в деталях). Вы можете задаться вопросом: с какими оценочными функциями необходимо по- знакомиться для успешных выступлений на Kaggle? Очевидно, необходимо пони- мать функцию, с помощью которой будет оцениваться результат на конкретном конкурсе. Однако некоторые метрики встречаются чаще прочих, и этим стоит поль- зоваться. Какие метрики наиболее популярны? Как выяснить, какие соревнования использовали аналогичную метрику, чтобы воспользоваться идеями из них? Отве- тить на эти вопросы поможет датасет Meta Kaggle. Датасет Meta Kaggle Датасет Meta Kaggle (https://www.kaggle.com/kaggle/meta-kaggle), содержащий большое количество данных о Kaggle, опубликован самой компанией. Он содержит таблицы в формате CSV, описывающие активность пользователей в разделах Competitions, Datasets, Notebooks и Discussions. От вас требуется только создать блокнот (как описано в главах 2 и 3), подключить к нему датасет и начать анализи- ровать данные. Таблицы обновляются ежедневно, так что вам понадобится часто проводить анализ заново, но полученная информация того стоит.
106 Часть II. Оттачивание соревновательных навыков Мы часто будем ссылаться на датасет Meta Kaggle в качестве источника интерес- ных и мотивирующих примеров хода соревнований, а также идей, касающихся стратегии обучения и участия в конкурсах. Здесь мы воспользуемся им, чтобы вы- яснить, какие метрики оценивания были наиболее популярны на соревнованиях в последние семь лет. Познакомившись с ними в этой главе, вы сможете уверенно приступать к конкурсам, а в дальнейшем уточнять свое понимание конкретной метрики на форумах. Ниже приведен код, создающий таблицу с метриками и количеством соревнований, когда они использовались, по годам: import numpy as пр import pandas as pd comps = pd.read_csv("/kaggle/input/meta-kaggle/Competitions.csv") evaluation = ['EvaluationAlgorithmAbbreviation', 'EvaluationAlgorithmName', 'EvaluationAlgorithmDescription'3] compt = ['Title', 'EnabledDate', 'HostSegmentTitle'] df = compsfcompt + evaluation].copy() df['year'] = pd.to_datetime(df.EnabledDate).dt.year.values df['comps'] = 1 time_select = df.year >= 2015 competition_type_select = df.HostSegmentTitle.isin(['Featured'3 'Research']) pd.pivot_table(df[time_select&competition_type_select], values='comps', index=['EvaluationAlgorithmAbbreviation'], columns=['year'], fill_value=0.0, aggfunc=np.sum, margins=True ).sort_values( by=( 'AH'), ascending=False) .iloc[l:,: ] .head(20) Мы загружаем таблицу формата CSV с данными о соревнованиях и используем столбцы с информацией о названии конкурса, дате начала и типе. Далее мы выби- раем строки, касающихся соревнований наиболее распространенных типов Featured и Research, проходивших не ранее 2015 г. В заключение мы создаем сводную таб-
Глава 5. Задачи и метрики на соревнованиях 107 лицу количества соревнований по используемому алгоритму оценки качества и го- ду, а затем выводим 20 наиболее популярных алгоритмов. На момент написания книги таблица выглядит так, как представлено в табл. 5.1. Таблица 5.1. Наиболее популярные алгоритмы Год 2015 2016 2017 2018 2019 2020 2021 Tot Алгоритм AUC 4 4 1 3 3 2 0 17 LogLoss 2 2 5 2 3 2 0 16 MAP@{K} 1 3 0 4 1 0 1 10 CategorizationAccuracy 1 0 4 0 1 2 0 8 MulticlassLoss 2 3 2 0 1 0 0 8 RMSLE 2 1 3 1 1 0 0 8 QuadraticWeightedKappa 3 0 0 1 2 1 0 7 MeanFScoreBeta 1 0 1 2 1 2 0 7 MeanBestErrorAtK 0 0 2 2 1 1 0 6 MCRMSLE 0 0 1 0 0 5 0 6 MCAUC 1 0 1 0 0 3 0 5 RMSE 1 1 0 3 0 0 0 5 Dice 0 1 1 0 2 1 0 5 GoogleGlobalAP 0 0 1 2 1 1 0 5 MacroFScore 0 0 0 1 0 2 1 4 Score 0 0 3 0 0 0 0 3 CRPS i 2 0 0 0 1 0 0 3 OpenlmagesObjectDetectionAP 0 0 0 1 1 1 0 3 MeanFScore 0 0 1 0 0 0 2 3 RSNAObjectDetectionAP 0 0 0 1 0 1 0 2 Используя те же самые переменные, что при создании этой таблицы, вы можете найти конкурсы, в которых использовалась выбранная метрика: metric = 'AUC metric_select = df['EvaluationAlgorithmAbbreviation']==metric print(df[time_select&competition_type_select&metric_select][['Title', 'year']])
108 Часть II. Оттачивание соревновательных навыков В приведенном выше фрагменте кода нас интересуют конкурсы, использовавшие метрику AUC. Достаточно поменять строку с названием метрики, и результат будет обновлен. Вернувшись к созданной нами таблице, рассмотрим самые популярные метрики оценивания в конкурсах Kaggle. • Две самые популярные метрики тесно связаны между собой и касаются задач бинарной классификации. Метрика AUC (area under curve— площадь под кривой) показывает, насколько точно предсказываемые вашей моделью веро- ятности отличают положительные примеры, а метрика Log Loss (логарифми- ческая потеря) позволяет измерить, насколько предсказанные вероятности близки к истине (оптимизация по Log Loss является также оптимизацией по AUC). • На третьем месте мы находим метрику МАР@{К} (Mean Average Precision at К), часто встречающуюся в рекомендательных системах и поисковиках. На конкурсах Kaggle она использовалась главным образом в задачах информа- ционного поиска, например на конкурсе Humpback Whale Identification (https://www.kaggle.eom/c/humpback-whale-ideiitification), целью которого было идентифицировать кита с пяти попыток. Другим примером конкурса с метрикой МАР@{К} может служить Quick, Draw! Doodle Recognition Challenge (https://www.kaggle.eom/c/quickdraw-doodle-recogmtioii/), целью которого было с трех попыток определить содержание рисунка. Если исполь- зуется метрика МАР@{К}, вы должны дать хотя бы один верный ответ из нескольких (их количество и имеется в виду под "К"). • Лишь на шестом месте мы находим первую метрику, используемую в задачах регрессии, RMSLE (root mean squared logarithmic error) — среднеквадра- тичную логарифмическую ошибку, и на седьмом— метрику Quadratic Weighted Карра (квадратично взвешенная каппа), особенно полезную для задач ранжирования. Просматривая список самых популярных метрик, мы видим, что все они часто встречаются в книгах по машинному обучению. В нескольких следующих разделах мы сначала обсудим, что делать, если вы встретили на конкурсе незнакомую мет- рику (что случается чаще, чем можно ожидать), а затем повторим известное о са- мых популярных метриках для задач классификации и регрессии. Как быть с незнакомыми метриками Прежде чем идти дальше, мы должны учесть, что не все соревнования используют метрики из топ-20 по популярности, а некоторые метрики и вовсе встречались по одному разу за несколько лет.
Глава 5. Задачи и метрики на соревнованиях 109 Продолжим использовать результаты приведенного ранее кода и выясним, много ли таких конкурсов: counts = (df[time_select&competition_type_select] .groupby('EvaluationAlgorithmAbbreviation')) total_comps_per_year = (df[time_select&competition_type_select] .groupby('year').sum()) single_metrics_per_year = (counts.sum()[counts.sum().comps==l] .groupby('year').sum()) table = (total_comps_per_year.rename(columns={'comps': 'n_comps'}) .join(single_metrics_per_year / total_comps_per_year)) print(table) Мы получили таблицу, в которой для каждого года указано число соревнований с метрикой, которая ни разу не использовалась после (n_comps), и их доля от всех со- ревнований в этом году (pct_comps): n__comps pct_comps year 2015 28 0.179 2016 19 0.158 2017 34 0.177 2018 35 0.229 2019 36 0.278 2020 43 0.302 2021 8 0.250 Мы видим, что доля соревнований с метрикой, которую после ни разу не использот вали, год от года растет и достигает 25-30% в последние годы, т. е. один конкурс из трех-четырех будет требовать от вас разобраться в новой метрике. Список таких метрик, появлявшихся в прошлом, можно найти так: В । print(counts.sum()[counts.sum().comps==l].index.values) Запустив этот код, вы получите, например, такой список: ['AHD@{Type}' 'CVPRAutoDrivingAveragePrecision' 'CernWeightedAuc' 'FScore_l' 'GroupMeanLogMAE' 'ImageNetObjectLocalization' 'IndoorLocalization' 'IntersectionOverUnionObjectSegmentationBeta' 'IntersectionOverllnionObjectSegmentationWithClassification' ' IntersectionOverllnionObjectSegmentationWithFl' ' Daccard' 'JaccardDSTLParallel' 'DigsawBiasAUC 'LaplaceLogLikelihood'
но Часть II. Оттачивание соревновательных навыков 'LevenshteinMean* 'Lyft3DObjectDetectionAP' 'M5_WRMSSE' 'MASpearmanR' 'MCRMSE' 'MCSpearmanR' 'MWCRMSE' 'MeanColumnwiseLogLoss' 'MulticlassLossOld' 'NDCG@{K}‘ 'NQMicroFl' 'NWRMSLE' 'PKUAutoDrivingAP' 'R2Score' 'Rvalue' 'RootMeanSquarePercentageError' 'SIIMDice' 'SMAPE' 'SantaResident' ’SantaRideShare' * SantaWorkshopSchedule2019' 'TrackML' 'TravelingSanta2’ 'TwoSigmaNews' 'WeightedAUC' 'WeightedMulticlassLoss' 'WeightedPinballLoss' 'WeightedRowwisePinballLoss' 'YT8M_ MeanAveragePrecisionAtK' 'ZillowMAE' 'football' 'halite' 'mab'] Внимательно рассмотрев его, вы обнаружите множество метрик, относящихся к глубокому обучению и обучению с подкреплением. Что делать, встретившись с ранее никогда не использовавшейся метрикой? Конеч- но, можно обратиться к форумам, где всегда можно найти идеи и помощь от других кэгглеров. Однако если вы хотите самостоятельно разобраться, кроме поиска в Ин- тернете, мы советуем вам самостоятельно реализовать оценочную функцию и про- верить, как она реагирует на разные типы ошибок. Можно также протестировать ее на части обучающих данных или на синтетических данных. Примеры этого похода описаны в следующих постах: • Карло Лепелаарс (Carlo Lepelaars) о метрике Spearman’s Rho: https:// www.kaggle.com/carlolepelaars/understanding-the-metric-spearman-s-rho; • Карло Лепелаарс о метрике Weighted Quadratic Карра: https://www.kaggle.com/ carlolepelaars/understanding-the-metric-quadratic-weighted-kappa; • Рохан Рао о лапласовском логарифме правдоподобия (Laplace Log Likelihood): https://www.kaggle.com/rohanrao/osic-understanding-laplace-log-likelihood. Такой метод даст вам лучше понять, как происходит оценивание, что будет пре- имуществом перед конкурентами, пользующимися только Google и форумами. Рохан Рао https://www.kaggle.com/rohanrao Прежде чем обсуждать различные метрики, мы поговорим с самим Роханом Рао (также известным как Vopani), гросс- мейстером во всех категориях и старшим исследователем данных в H20.ai, о его успехах на Kaggle и спросим, готов ли он поделиться с нами мудростью. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я люблю пробовать разные соревнования, но больше всего анализ временных рядов. Мне не очень нравятся типичные принятые в индустрии подходы к нему,
Глава 5. Задачи и метрики на соревнованиях 111 поэтому стараюсь мыслить нестандартно и изобретать собственные методы. В моем случае это оказалось успешной стратегией. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Для любого конкурса на Kaggle мой план действий будет выглядеть так. • Понять постановку задачи, прочитать всю информацию о правилах, фор- мате, сроках, датасетах, метриках и результатах. • Глубоко изучить данные. Копайтесь в них всеми возможными способами, исследуйте, визуализируйте, чтобы быть способным ответить на любой вопрос о них. • Построить простую модель и отправить полученные результаты, чтобы убедиться, что процесс работает. • Преобразовывать признаки, настраивать гиперпараметры, эксперименти- ровать с разными моделями, чтобы понять, что работает, а что — нет. • Постоянно возвращаться к анализу исходных данных, чтению форумов, всевозможной настройке моделей. Возможно, в какой-то момент стоит объединиться в команду. • Объединить несколько моделей и выбрать итоговые решения. В моей ежедневной работе присутствуют большинство из этих элементов, но также требуются два других, критически важных: • сбор и подготовка данных; • внедрение итоговой модели. Львиная доля моего времени на большинстве проектов раньше была посвящена именно им. Помог ли тебе Kaggle в карьере? Если да, то как? Большая часть моих знаний о машинном обучении получена на Kaggle. Плат- форма, сообщество и контент — это сокровища, и здесь вы можете научиться не- вероятному количеству вещей. Больше всего мне дало участие в соревнованиях, оно придало мне уверенности при понимании, структурировании и решении задач в разных областях, что я смог успешно применить в различных компаниях и проектах. Многие рекрутеры писали мне о своих вакансиях, увидев список моих достиже- ний на Kaggle, прежде всего соревновательных. Успех на Kaggle — достаточно хороший индикатор способности кандидата решать задачи наук о данных, так что это прекрасная платформа для того, чтобы показать свои навыки и собрать портфолио. Какие ошибки ты допускал на соревнованиях? Какие-нибудь ошибки я делал в каждом соревновании, но только так можно учить- ся и прогрессировать. Иногда речь о баге в коде, иногда о неправильном методе валидации, иногда об отправке не того решения. Важно учиться на своих ошибках и не повторять их. С каждым шагом ваши результаты будут становиться лучше.
112 Часть IL Оттачивание соревновательных навыков Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я считаю, что нельзя привязываться к одной технологии. Используйте то, что лучше всего работает, удобнее и эффективнее всего, но всегда будьте готовы к изучению новых инструментов. Метрики для задач регрессии Работая с задачами регрессии, т. е. с задачами, ответ которых является веществен- ным числом (в промежутке от минус бесконечности до плюс бесконечности), чаще всего используют метрики RMSE (root mean squared error, среднеквадратичная ошибка) и МАЕ (mean absolute error, средняя абсолютная ошибка), но могут быть полезны и чуть другие меры ошибки, такие как RMSLE или MCRMSLE. Средний квадрат и R-квадрат RMSE— метрика, являющаяся корнем из среднего квадрата ошибки (mean squared error, MSE), который представляет собой всего лишь среднее арифметиче- ское возведенных в квадрат ошибок — сумму возведенных в квадрат ошибок (sum of squared errors, SSE), деленную на количество примеров. С этими метриками вы наверняка уже знакомились, изучая регрессию. Вот формула для MSE: MSE =—SSE = —£(у,.-у,)2. Начнем с объяснения этой формулы. Прежде всего, п обозначает количество при- меров, у. — истинные значения целевой переменной, а у. — предсказанные. Сна- чала мы вычисляем разности между предсказаниями и настоящими значениями, затем возводим их в квадрат (так что они становятся неотрицательными) и получа- ем метрику SSE. Остается поделить ее на число примеров, чтобы получить среднее, MSE. Обычно все модели регрессии минимизируют SSE, так что не станет пробле- мой минимизация MSE или выводящихся из нее значений вроде И-квадрат (Л2, коэффициента детерминации), выраженного формулой: SSE <(у,-л)2 SST % (у,-у)2' Здесь SSE (сумма возведенных в квадрат ошибок) сравнивается с дисперсией от- ветов (sum of squares total, SST). В статистике SST определяется как сумма квадра- тов разностей между правильными ответами и их средним: SST = £(y,.-y)2.
Глава 5. Задачи и метрики на соревнованиях ИЗ Иными словами, Л-квадрат сравнивает сумму квадратов ошибок модели с суммой квадратов ошибок самой простой из возможных моделей, всегда выдающей сред- нее значение на всех примерах. Л-квадрат помогает определить, можно ли преобра- зовать значения для повышения качества. Важно помнить, что линейные преобразования признаков, такие как минимакс (https://scikit-learn.org/stable/modules/generated/sklearn. preprocessing.MinMaxScaler.html) или стандартизация (https://scikit- learn.org/stable/modules/generated/sklearn.preprocessing.StandardScal er.html), не меняют качество предсказаний никакой регрессионной мо- дели, т. к. линейно влияют на ответ. Однако нелинейные преобразо- вания — квадратный или кубический корень, логарифм, возведение в степень и их комбинации — качество определенно изменят, и при вы- боре правильного преобразования — к лучшему. MSE — замечательный инструмент для сравнения различных регрессионных моде- лей, примененных к одной задаче. Однако MSE редко используется на конкурсах Kaggle, предпочтение отдается RMSE. При извлечении квадратного корня резуль- тат будет величиной того же порядка, что и значения целевой переменной, так что станет легче быстро оценить качество работы модели. Если же вы сравниваете ра- боту одной и той же модели на разных задачах, предпочтительнее использовать R- квадрат — он прямо пропорционален MSE, но его значения лежат в промежутке от О до 1, что облегчает сравнение. Среднеквадратичная ошибка RMSE (root mean squared error, среднеквадратичная ошибка) — это квадратный ко- рень из MSE. RMSE = .fjJ^^- . Ш п В данной формуле п обозначает количество примеров, у. — истинные значения целевой переменной, а jX — предсказанные. При использовании MSE большие ошибки предсказания сильно штрафуются из-за возведения в квадрат. В случае RMSE этот эффект меньше, однако обращать вни- мание на выбросы необходимо при использовании любой метрики— они могут сильно влиять на качество предсказаний. Таким образом, можно улучшить качество предсказаний при использовании MSE в качестве целевой функции, применив к ответам извлечение квадратного корня (ес- ли оно возможно), а в конце снова возводя в квадрат.
114 Часть II. Оттачивание соревновательных навыков Такие функции, как TransformedTargetRegressor из библиотеки Scikit-leam, помогут при преобразовании ответов в задачах регрессии. Примеры недавних соревнований, использовавших RMSE: • конкурс по предсказанию спроса на Avito — Avito Demand Prediction Challenge (https://www.kaggle.eom/c/avito-demand-prediction); • Google Analytics Customer Revenue Prediction (https://www.kaggle.eom/c/ga-customer-revenue-prediction); • Elo Merchant Category Recommendation (https://www.kaggle.com/ c/elo-merchant-category-recommendation). Среднеквадратичная логарифмическая ошибка Другим типичным преобразованием MSE является среднеквадратичная логариф- мическая ошибка (root mean squared logarithmic error, RMSLE). MCRMSLE — ее вариант, ставший популярным благодаря конкурсу по предсказанию C0VID-19, он является средним от значений RMSLE по всем целевым переменным. Формула для RMSLE выглядит так: RMSLE = J-£(logCP,. +1) - log(y,. +1))2. V n 1=1 В данной формуле п обозначает количество примеров, у. — истинные значения целевой переменной, а у. — предсказанные. Так как к предсказаниям и истинным значениям целевой переменной перед осталь- ными операциями применяются логарифмические преобразования, большие откло- нения не столь сильно штрафуются, в особенности когда и предсказания, и настоя- щие значения велики. Иными словами, при использовании RMSLE вас больше всего волнует совпадение порядков предсказаний и истинных значений. Как и в случае RMSE, алгоритмы будут успешнее оптимизировать относительно RMSLE, если применить логарифмическое преобразование до обучения (а потом для обрат- ного эффекта применить экспоненту). Из недавних соревнований RMSLE использовалась на: • ASHRAE— Great Energy Predictor III (https://www.kaggle.eom/c/ ashrae-energy-prediction); • Santander Value Prediction Challenge (https://www.kaggle.eom/c/ santander-value-prediction-challenge):
Глава 5. Задачи и метрики на соревнованиях 115 Mercari Price Suggestion Challenge (https://www.kaggle.eom/c/ mercari-price-suggestion-challenge); Sberbank Russian Housing Market (https://www.kaggle.com/ olgabelitskaya/sberbank-russian-housing-market); Recruit Restaurant Visitor Forecasting (https://www.kaggle.eom/c/ recruit-restaurant-visitor-forecasting). На данный момент RMSLE — самая популярная метрика для задач регрессии на конкурсах Kaggle. Средняя абсолютная ошибка Метрика МАЕ (mean absolute error) — это среднее абсолютных значений разности предсказаний и истинных значений. Формула выглядит так: мае=-£|у,.-у,.|. п “ В данной формуле п обозначает количество примеров, у. — истинные значения целевой переменной, a у. — предсказанные. МАЕ не очень чувствительна к вы- бросам, в отличие от MSE, поэтому встречается на многих соревнованиях, где в данных присутствуют выбросы. Также многие алгоритмы могут напрямую исполь- зовать ее как целевую функцию, в остальных случаях можно извлекать квадратный корень из целевой переменной, а затем возводить предсказания в квадрат. К недостаткам использования МАЕ относится медленная сходимость, поскольку оптимизируется, по сути, предсказание медианы целевой переменной (оптимизация по L1-норме), а не среднего, как в MSE (Ь2-норма). Это приводит к более сложным вычислениям при оптимизации, так что зависимость времени работы от числа обу- чающих примеров может быть даже экспоненциальной (см., например, вопрос на Stack Overflow: https://stackoverflow.com/questions/57243267/why-is-training-a- random-forest-regressor-with-mae-criterion-so-slow-compared-to). Из недавних соревнований, использовавших МАЕ, примечательны: • конкурс по предсказанию землетрясений LANL Earthquake Prediction (https://www.kaggle.eom/c/LANL-Earthquake-Prediction); • How Much Did It Rain ? II (https://www.kaggle.com/c/how-much- did-it-rain-ii).
116 Часть II. Оттачивание соревновательных навыков Мы уже упоминали конкурс ASHRAE и должны заметить, что метрики для задач регрессии, в частности, используются в задачах финансового прогнозирования. Так, недавно прошел конкурс М5 (https://mofc.unic.ac.cy/m5-competition/), дос- тупны данные и с других конкурсов серии М. Если вам интересна данная область, прочитайте обзор этой серии и ценности Kaggle для получения новых теоретиче- ских и практических результатов: https://robjhyndman.com/hyndsight/forecasting- competitions/. В целом соревнования по прогнозированию не требуют принципиально новых мет- рик по сравнению с обычными соревнованиями на регрессию. Да, иногда в них встречаются необычные метрики, вроде Weighted Root Mean Squared Scaled Error (https://www.kaggle.eom/c/m5-forecasting-accuracy/overview/evaluation) или симметричная средняя абсолютная процентная ошибка (symmetric mean absolute percentage error), более известная как sMAPE (https://www.kaggle.com/c/demand- forecasting-kernels-only/overview/evaluation). Однако в конечном счете они явля- ются лишь вариациями RMSE или МАЕ, с которыми можно работать, преобразуя целевую переменную. Метрики для задач классификации Обсудив метрики для задач регрессии, перейдем к метрикам для задач классифика- ции. Мы начнем с бинарной классификации (когда классов два), перейдем к много- классовой классификации, а затем к классификации с пересечением классов (мно- жественными метками). Доля правильных ответов При измерении качества бинарной классификации самой простой и распространен- ной метрикой является доля правильных ответов (accuracy). Ошибкой классифи- кации является предсказание не того класса. Доля правильных ответов — это до- полнительная величина к доле ошибок классификации, и вычисляется она как отношение верных ответов к общему количеству ответов: верные ответы accuracy = —£---------. все ответы Эта метрика использовалась, например, на конкурсах Cassava Leaf Disease Classification (https://www.kaggle.eom/c/cassava-leaf-disease-classification) и Text Normalization Challenge— English Language (https://www.kaggle.com/ c/text-normalization-challenge-english-language), в котором правильным предсказанием считалось только точное совпадение вашего текста с на- стоящей строкой.
Глава 5. Задачи и метрики на соревнованиях 117 Данная метрика должна показывать, работает ли ваша модель так, как ожидалось. Однако ее стоит использовать аккуратно: при несбалансированности (разной часто- те) классов она может привести к ложным выводам. Так, если один класс составля- ет всего 10% данных, модель, всегда предсказывающая другой класс, будет иметь высокую долю правильных ответов 90%, будучи при этом довольно бесполезной. Как справиться с такой проблемой? Можно использовать матрицу несоответст- вий — таблицу, строки которой соответствуют истинным классам, а столбцы — предсказанным. Ее можно создать с помощью функции confusion_matrix() из Scikit- leam: sklearn.metrics.confusion_matrix( y_true, y_pred, *, labels=None, sample_weight=None, normalize=None ) Достаточно передать функции только векторы y_true и y_pred, однако можно также указать названия строк и столбцов и веса примеров, нормализовать по строкам, столбцам или всей таблице. Для идеального классификатора все примеры окажутся на главной диагонали матрицы. Если на главной диагонали мало примеров, это свидетельствует о серьезных проблемах. Для того чтобы лучше разобраться в этом, можно рассмотреть пример от Scikit- leam на https://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_ matrix. html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py (рис. 5.1). Ирис Ирис Ирис щетинистый разноцветный виргинский Предсказанный класс Рис. 5.1. Матрица несоответствий с нормализацией
118 Часть II. Оттачивание соревновательных навыков Более полезной долю правильных ответов можно сделать, посчитав ее для каждого класса и усреднив результаты, но полезней пользоваться другими метриками — точностью, полнотой, F\-мерой. Точность и полнота Для того чтобы вычислить метрики точности (precision) и полноты (recall), снова начнем с матрицы несоответствий. Сначала обозначим каждую из ячеек (табл. 5.2). Таблица 5.2. Матрица несоответствий с названиями ячеек Предсказание отрицательное положительное Действительное значение отрицательное истинноотрицательное (TN) ложноположительное (FP) положительное ложноотрицательное (FN) истинноположительное (ТР) Ячейки мы определим так: • TP (true positives, истинноположительные результаты)— правая нижняя ячейка, содержит примеры, которые были верно классифицированы как по- ложительные; • FP (false positives, ложноположительные результаты) — правая верхняя ячей- ка, содержит примеры, которые были классифицированы как положительные, но на самом деле отрицательны; • FN (false negatives, ложноотрицательные результаты) — левая нижняя ячейка, содержит примеры, которые были классифицированы как отрицательные, но на самом деле положительны; • TN (true negatives, истинноотрицательные результаты) — левая верхняя ячей- ка, содержит примеры, которые были верно классифицированы как отрица- тельные. Пользуясь матрицей несоответствий, вы можете более точно оценить, как работает ваш классификатор и как его улучшить. Сначала вспомним формулу для доли пра- вильных ответов: TP + TN доля правильных ответов =--------------. TP + TN + FP + FN Первая метрика — точность (специфичность, precision), представляет собой долю правильных ответов на положительном классе: ТР точность =------. TP + FP
Глава 5. Задачи и метрики на соревнованиях 119 При ее вычислении используются только количество истинноположительных и ложноположительных ответов. Таким образом, эта метрика показывает, насколько часто вы правы, когда предсказываете положительный класс. Очевидно, что модель может достичь высокой точности, предсказывая положительный класс лишь тогда, когда уверена в этом. Цель данной метрики — заставить модель предсказывать по- ложительный класс только при уверенности в правильности такого ответа. Однако если вы хотите найти как можно больше объектов положительного класса, вам нужно смотреть на полноту (она же чувствительность, recall): полнота = ТР TP + FN В этой формуле вам необходимо знать количество ложноотрицательных ответов. Заметим, что классификация основана на вероятностях классов — обычно с поро- гом 0,5, но этот порог можно изменить и улучшить одну из метрик за счет другой. Так, при увеличении порога точность повысится (классификатор будет более уве- рен в предсказании положительного класса), а полнота снизится. При уменьшении порога точность снизится, а полнота повысится. Таким образом, приходится искать компромисс. На сайте библиотеки Scikit-leam содержится простой и практически ориентированный обзор этого компромисса (https://scikit-learn.org/stable/auto_ examples/model_selection/plot_precision_recall.html), который поможет построить кривую (ломаную) точности/полноты и понять, что необходимо сделать для наи- лучшего в конкретной задаче результата (рис. 5.2). Рис. 5.2. Ломаная точности/полноты с характерными ступеньками Одна из метрик, связанных с точностью и полнотой,— это средняя точность (average precision). Для нахождения этой величины берется математическое ожида- ние точности по всем значениям полноты от 0 до 1 (по сути, по всем значениям по- рога вероятности от 0 до 1). Средняя точность очень популярна в задачах детекти-
120 Часть II. Оттачивание соревновательных навыков рования объектов, которые мы обсудим чуть позже, но весьма полезна и в класси- фикации на табличных данных. Ее ценность проявляется на практике, когда необ- ходимо тщательно следить за качеством классификации на очень несбалансиро- ванных данных, когда один из классов очень редок (например, при выявлении мошенничества). Подробнее об этом можно прочитать у Гаэля Вароко (Gael Varoquaux): http://gael-varoquaux.info/interpreting_ml_tuto/content/01_how_well/01_ metrics.html#average-precision. F-мера К этому моменту вы уже поняли, что выбор в качестве метрики точности либо пол- ноты не идеален, поскольку, улучшая одну из этих метрик, вы ухудшаете другую. Поэтому ни одно соревнование на Kaggle не использует лишь одну из них, а только их комбинации (например, среднюю точность). Наилучшим выбором среди этих комбинаций обычно считается F-мера (более точно называемая F\ -мерой), гармо- ническое среднее точности и полноты: _ точность • полнота — 2 . точность -h полнота Большие значения F-меры говорят об улучшениях в точности, полноте или обеих этих метриках. Примером использования F-меры может быть конкурс по классификации вопросов на Quora (Quora Insincere Questions Classification, https://www.kaggle.com/cZquora- insincere-questions-classification). В некоторых конкурсах используется Fp-мера — взвешенное гармоническое сред- нее точности и полноты, где Р — вес полноты: /я п2\ точность • полнота Fp = (1 + Р I • у—-----Г---------. 7 (р точность)-»-полнота Так как мы уже ввели понятия вероятности классификации и ее порога, теперь мы готовы обсуждать очень распространенные метрики Log Loss и ROC-AUC. Log Loss и ROC-AUC Начнем с метрики Log Loss, в моделях глубокого обучения также известной как кросс-энтропия. Она представляет собой разность предсказанной и истинной веро- ятностей: Log Loss = -£[у, log (у,) + (1 - у,) log (1 - у,)]. п 1=1 В данной формуле п обозначает количество примеров, у, — истинные значения целевой переменной, a у. — предсказанные.
Глава 5. Задачи иметрики на соревнованиях 121 Если конкурс использует метрику Log Loss (а таких конкурсов довольно много), это означает, что целью является как можно точнее оценить вероятность принад- лежности объекта к положительному классу. Можно привести в качестве примера, лажем, недавний конкурс по распознаванию дипфейков Deepfake Detection Challenge (https://www.kaggle.eom/c/deepfake-detection-challenge) или более ста- рый конкурс Quora Question Pairs (https://www.kaggle.eom/c/quora-question-pairs). ROC-кривая, или кривая рабочей характеристики приемника (receiver operating characteristic curve),— это график, используемый для оценки качества бинарных классификаторов и сравнения их между собой. С его помощью определяется мет- рика ROC-AUC — это просто площадь под ROC-кривой. ROC-кривая— это график зависимости доли истинноположительных ответов на объектах положительного класса (полноты, true positive rate) от доли ложнополо- жительных ответов на объектах отрицательного класса (false positive rate). Послед- ия величина равна единице минус доля истинноотрицательных ответов (на объек- тах отрицательного класса). Приведем несколько примеров (рис. 5.3). ответы ответы Рис. 5.3. ROC-кривые и площади под ними Ложноположительные ответы 100%
122 Часть II. Оттачивание соревновательных навыков В идеале, ROC-кривая хорошего классификатора круто идет вверх и дает большие значения полноты при маленьких значениях доли ложноотрицательных ответов. Очень хорошими считаются значения ROC-AUC от 0,9 до 1,0. Плохой классификатор можно узнать по ROC-кривой, близкой к диагонали (кото- рая будет графиком полностью случайного классификатора, как на правом верхнем рисунке); о почти случайной классификации говорят значения ROC-AUC в районе 0,5. Если вы используете площадь под кривой (AUC) для сравнения различных класси- фикаторов, наилучшим является классификатор с наибольшей AUC. Если классы сбалансированы (либо, по крайней мере, несбалансированность не сильно выраже- на), увеличение AUC происходит пропорционально эффективности модели, и мож- но думать об этом как об увеличении вероятности истинноположительных ответов либо о лучшей упорядоченности примеров от положительных к отрицательным. Однако, если объекты положительного класса редки, метрика AUC сразу будет большой, и ее увеличение может очень мало говорить о том, насколько лучше мы предсказываем редкий класс. В этом случае, как мы уже говорили, средняя точ- ность будет более полезной метрикой. Метрика AUC использовалась в большом количестве конкурсов. Сове- туем обратить внимание на следующие из них • lEEE-CZS' Fraud Detection (https://www.kaggle.eom/c/ieee-fraud-detection); • Riiid Answer Correctness Prediction (https://www.kaggle.eom/c/riiid-test-answer-prediction); • Jigsaw Multilingual Toxic Comment Classification (https://www.kaggle.com/c/jigsaw-multilingual-toxic-comment- classification/). Можно найти подробный рассказ об этой метрике в статье У. Су, Ю. Юань, М. Чжу ’’Взаимосвязь между средней точностью и площадью под кривой ROC’’1. Коэффициент корреляции Мэтьюса Мы завершим наш обзор метрик для бинарной классификации коэффициентом корреляции Мэтьюса (Matthews correlation coefficient, МСС), появившемся на конкурсах VSB Power Line Fault Detection (https://www.kaggle.com/c/vsb-power- line-fault-detection) и Bosch Production Line Performance (https://www.kaggle.com/ c/bosch-production-line-performance). 1 Su W., Yuan Y., Zhu M. A relationship between the average precision and the area under the ROC curve И Proceedings of the 2015 International Conference on The Theory of Information Retrieval. — 2015.
Глава 5. Задачи и метрики на соревнованиях 123 Формула для него выглядит так: TPTN-FPFN мсс = ^(ТР + FP) • (TP + FN) • (TN + FP) • (TN + FN) где ТР — количество истинноположительных ответов; TN — истинноотрицатель- ных; FP — ложноположительных; FN — ложноотрицательных (те же обозначения мы использовали при обсуждении точности и полноты). Эта метрика ведет себя как коэффициент корреляции, принимая значения от +1 (когда все предсказания верны) до -1 (когда все они противоположны истине), и может служить мерой качества классификации даже при довольно сильной несба- лансированности классов. Формула выглядит сложной, но ее можно преобразовать и упростить, как было по- казано кэгглером под ником Neuron Engineer (https://www.kaggle.com/ratthachat) в блокноте www.kaggle.com/ratthachat/demythifying-matthew-correlation- coefficients-mcc. Его объяснения крайне полезны для понимания. Преобразованная формула для МСС выглядит как: МСС = (PosTO4HOCTb + NegTO4HOCTb -1) • PosNegRatio, где используются следующие обозначения: т. ТР Pos =--------------; точность ТР _|_ рр TN NegTO4Hocrb =TN + FN’ „ _ „ . /PosPredictionCount • NegPredictionCount PosNegRatio = 4--------------------------------------; \ PosLabelCount • NegLabelCount PosPredictionCount = TP + FP; NegPredictionCount = TN + FN, где PosPredictionCount — общее количество положительных предсказаний; NegPredictionCount — общее количество отрицательных предсказаний2. Такое преобразование гораздо яснее исходной формулы и позволяет понять, что лучшее качество достигается при улучшении предсказаний на обоих классах, но кого недостаточно: доля положительных и отрицательных предсказаний должна быть близка к истинной доле этих классов, иначе метрика сильно ухудшается. Метрики для многоклассовой классификации При переходе к многоклассовой классификации используют уже известные нам метрики для бинарной классификации, а затем усредняют в соответствии с одной * Что такое PosLabelCount и NegLabelCount, автор, к сожалению, не объясняет. — Прим. ред.
124 Часть II. Оттачивание соревновательных навыков из нескольких возможных стратегий. Так, если вы хотите оценить решение с по- мощью F-меры, вам придется выбирать из трех способов усреднения. • Макроусреднение. Для каждого класса вычисляется F-мера (где класс берет- ся за положительный), а затем она усредняется. При этом способе вклад каж- дого класса одинаков вне зависимости от того, насколько часто он встречает- ся и насколько важен для вашей задачи, поэтому и потери качества одинаковы при ошибках на любом классе: МакрО (класс 1) + ^*1 (класс 2) + + ^*1 (класс Л/) • Микроусреднение. При этом подходе вычисляется общая F-мера для всех классов, поэтому он подходит для несбалансированных классов: МИКрО FJ (класс_1+класс_2+...+класс_ЛО’ • Взвешенное среднее. Как и при макроусреднении, сначала вычисляется F- мера для каждого класса, а затем берется среднее с весами, зависящими от количества истинных меток каждого класса. При таком выборе весов учиты- вается частота каждого класса или его релевантность для задачи. Такой под- ход, очевидно, отдает предпочтение более часто встречающимся классам, присваивая им больший вес: взвешенное среднее = FJ (юисс1) • w, + F} (И1асс_2) • w2 +... + Ft (IcraccJV) • wN; Wl + W2 + ••• + WN =1,0. Часто встречаются на конкурсах Kaggle следующие метрики для многоклассовой классификации: • доля правильных ответов (взвешенная) — например, на конкурсе Bengali.AI Handwritten Grapheme Classification (https://www.kaggle.com/c/bengaliai- cvl9); • многоклассовый Log Loss (средний по столбцам Log Loss)— на конкурсе Mechanisms of Action (MoA) Prediction (https://www.kaggle.eom/c/lish-moa/); • F-мера с макро- и микроусреднением (NQMicroFl) — например, на конкур- сах University of Liverpool— Ion Switching (https://www.kaggle.eom/c/ liverpool-ion-switching), Human Protein Atlas Image Classification (https://www.kaggle.eom/c/human-protein-atlas-image-classification/), TensorFlow 2.0 Question Answering (https://www.kaggle.com/c/tensorflow2- question-answering); • средняя F-мера (Mean-Fl)— на конкурсе Shopee— Price Match Guarantee (https://www.kaggle.eom/c/shopee-product-matching/). Здесь F-мера вычис- ляется для каждой строки в данных и затем усредняется, в то время как мак- роусреднение усредняет по классу и метке. Еще одну метрику— квадратичную взвешенную каппу (Quadratic Weighted Карра) — мы рассмотрим далее как метрику качества для задач ранжирования. В
Глава 5. Задачи и метрики на соревнованиях 125 своей простейшей разновидности (каппа Коэна, Cohen Карра) она показывает со- гласованность предсказаний и истинных значений. Исходно она создавалась как метрика согласованности аннотаций, но с тех пор нашла новые применения. Что значит согласованность аннотаций? Представим, что вам нужно классифици- ровать фото, присвоить им метки в зависимости от того, изображена ли на них кошка, собака или ни то, ни другое. Если вы попросите группу людей поставить метки, то получите некоторое количество ошибок: кто-то из размечавших мог пе- репутать кошку с собакой, и наоборот. Стоит поэтому распределить, работу так, чтобы одно и то же фото размечали разные люди, а затем измерить согласован- ность их меток с помощью каппы Коэна. Таким образом, каппа Коэна определена как мера согласованности тех, кто ставил метки в задаче классификации: к = (ро-ре)1(\ -ре). В данной формуле ро обозначает наблюдаемую согласованность, а ре— вероят- ность случайной согласованности. В обозначениях матрицы несоответствий 2(TPTN-FNFP) - (tp+fp)-(fp+tn)+(tp+fn)(fn+tn) В этой формуле интересно, что она учитывает возможность случайного совпадения :еток. Метрика принимает значения от 1 (при полном совпадении меток) до -1 при полном несовпадении). Значения, близкие к нулю, говорят о том, что расхож- дения случайны. Таким образом, метрика обычно позволяет вам понять, работает : ваша модель лучше случайной. Андрей Лукьяненко https://www.kaggle.com/artgor Наше второе интервью в этой главе — с Андреем Лукья- ненко, гроссмейстером в категориях Notebooks и Discussions и мастером в категории Competitions. В обыч- ной жизни Андрей— специалист по машинному обуче- нию, техлид в компании МТС. Ему есть что рассказать вам о Kaggle! Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я предпочитаю соревнования, решения которых достаточно общие, чтобы быть переносимыми на другие данные или другие области. Мне интересно пробовать различные архитектуры нейросетей, новые подходы, различные способы постоб- работки ответов. Мне не нравятся те конкурсы, в которых требуется реверс- инжиниринг или придумывание некоторых объясняющих всё признаков, т. к. эти подходы перестанут работать на других данных.
126 Часть II. Оттачивание соревновательных навыке* Ты не только участвовал в соревнованиях, но и стал гроссмейстером в категориях Notebooks (заняв первое место в рейтинге) и Discussions. Насколько много ты работал для достижения этих целей? Я потратил много времени и усилий на написание блокнотов, а вот звание гросс- мейстера в Discussions случилось как бы само собой. Начнем с категории Notebooks. В 2018 г. прошел конкурс DonorsChoose.org Application Screening. DonorsChoose — это фонд, поддерживающий учителей государственных школ при закупке необ- ходимого оборудования, учебников, канцтоваров и прочих необходимых мате- риалов. Фонд организовал конкурс, победитель которого определялся числом го- лосов, набранных решением. Идея показалась мне интересной, я создал свой блокнот и, подобно многим другим участникам, рассказал о нем в соцсетях. В ре- зультате я занял второе место и выиграл Pixelbook, который до сих пор исполь- зую. Я был очень мотивирован этим успехом и продолжил писать блокноты. По- началу я просто хотел поделиться результатами своего анализа, получить обратную связь, сравнить свои навыки аналитики и визуализации с навыками ок- ружающих, понять, что я умею. Многие отдавали свои голоса за мои блокноты, это мотивировало продолжать. Мне также хотелось научиться быстро создавать минимальный рабочий продукт (minimum viable product, MVP). Когда запускает- ся новый конкурс, ты хочешь опередить других и должен быстро реализовывать решение, не теряя качества. Это сложно, но очень увлекательно. Я достиг звания гроссмейстера в категории Notebooks в феврале 2019г., через некоторое время занял первое место в рейтинге и удерживал его более года. Те- перь я реже создаю блокноты, но все еще люблю это делать. Что касается категории Discussions, все случилось как бы само собой. Я отвечал на комментарии к своим блокнотам, участвовал в обсуждении конкурсов, в кото- рых принимал участие, и так повышал свой рейтинг. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Расскажу о конкурсе Molecular Properties, о котором уже подробно писал в посте https://towardsdatascience.com/a-story-of-my-first-gold-medal-in-one-kaggle- competition-things-done-and-lessons-learned-c269d9c233dl. В нем требовалось предсказывать взаимодействие между атомами в молекулах. Технология ядерно- го магнитного резонанса (ЯМР) позволяет узнать структуру и динамику взаимо- действия белков и молекул. Исследователи всего мира используют ЯМР в таких областях, как фармацевтика и материаловедение. В этом конкурсе мы пытались предсказать магнитное взаимодействие (скалярную константу спин-спинового взаимодействия) между двумя атомами в молекуле. Современные методы кван- товой механики позволяют вычислять эту константу, зная только 3 D-структуру молекулы, но эти вычисления крайне ресурсоемки и поэтому не всегда могут быть проведены. Если мы сможем предсказывать значения константы спин- спинового взаимодействия с помощью машинного обучения, это поможет фар- макологам быстрее и с меньшими затратами понимать структуру вещества.
Глава 5. Задачи и метрики на соревнованиях 127 Обычно я провожу разведочный анализ данных, приступая к новому конкурсу, так я поступил и в этот раз. Типичный подход к конкурсам с табличными данны- ми на Kaggle — преобразования признаков в сочетании с методами градиентного бустинга. При первых попытках я также использовал LGBM, но уже думал, что должны быть и более удачные методы для работы с графами. Обнаружив, что знание предметной области дает серьезное преимущество, я стал искать любую доступную информацию. Разумеется, я обратил внимание на нескольких актив- ных экспертов на форуме, изучал все их комментарии и блокноты. А потом я по- лучил письмо от одного эксперта в предметной области, который считал, что наши навыки хорошо дополняют друг друга. Обычно на конкурсах я предпочи- таю сначала работать самостоятельно, но в этом случае объединиться показалось хорошей идеей — и я не ошибся. Мы смогли постепенно собрать отличную ко- манду. Через некоторое время мы обнаружили возможности для нейронных се- тей: известный кэгглер Хенг привел пример модели типа MPNN (Message Passing Neural Network). Я смог ее запустить, но результаты были хуже, чем у нашей мо- дели. Однако наша команда знала, что нам придется работать с этими нейронны- ми сетями, чтобы претендовать на высокое место. Кристоф создавал новые сети с удивительной скоростью. Скоро мы сфокусировались только на них. Я проводил эксперименты, меняя гиперпараметры, архитектуру, расписание обучения. Я также проводил разведочный анализ данных, чтобы обнаружить интересные примеры или те примеры, на которых модель делала ошибки, что помогало нам улучшаться. Мы заняли восьмое место, и я очень многому научился благодаря этому конкурсу. Помог ли тебе Kaggle в карьере? Если да, то как? Безусловно, помог, особенно с приобретением навыков и с построением личного бренда. Создание и публикация блокнотов на Kaggle научили меня не только разведочному анализу данных и машинному обучению, но и гибкости, способно- сти быстро схватывать новое и менять свой подход. Кроме того, это дало мне не- которую известность. В моем первом портфолио (https://erlemar.github.io/) было множество различных блокнотов, и половина из них была основана на соревно- ваниях Kaggle, что несомненно помогло получить первую работу. Достижения на конкурсах привлекали рекрутеров из хороших компаний, которые часто предла- гали даже пропустить некоторые этапы отбора, несколько раз я становился кон- сультантом разных компаний. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Я думаю, начинающих кэгглеров стоит разделить на две группы: те, кто в целом имеет мало опыта в науке о данных, и те, кто просто не имел дела с Kaggle. Но- вички в науке о данных как таковой делают множество ошибок (что нормально, все когда-то были начинающими): • одна из самых серьезных проблем — недостаток критического мышления и неумение проводить собственные исследования; • непонимание, какие существуют инструменты и методы и когда они при- менимы;
128 Часть II. Оттачивание соревновательных навыков • использование чужих блокнотов без понимания их работы; • зацикливание на одной идее, даже если она не работает; • склонность отчаиваться и терять мотивацию при неудачах. Если же говорить о тех, кто имеет опыт в науке о данных, но впервые знакомится с Kaggle, то их главная ошибка — недооценивать сложность соревнований. Они не ожидают такого уровня конкуренции, необходимости пробовать различные методы, типичных чисто соревновательных приемов, существования профессио- нальных ’’спортсменов”. Они также зачастую переоценивают знание предметной области. Да, на некоторых соревнованиях выигрывали команды, в составе кото- рых были эксперты в данной области, но в большинстве случаев побеждают про- сто опытные кэгглеры. Не раз я видел людей, утверждавших, что победить на Kaggle легко, и претендент или его команда совсем скоро будут увешаны золо- тыми медалями. Обычно после мы ничего о них не слышим. Какие ошибки ты допускал на соревнованиях? • Недостаточно изучал данные. Иногда можно было бы придумать признаки получше или лучше предобработать данные. Отдельная тема— реверс- инжиниринг и "золотые признаки". • Тратил слишком много времени, пытаясь заставить работать один выбран- ный подход и попадая в то, что называют ловушкой невозвратных затрат. • Недостаточно экспериментировал. Усилия окупаются, а если вы не потра- тили на конкурс достаточно времени и сил, вы не займете высокое место. • Участвовал не в тех соревнованиях. В некоторых мешали утечки данных или возможность реверс-инжиниринга. Иногда слишком сильно различа- лись обучающие и тестовые данные, так что перестановка в таблице ре- зультатов была гарантирована. Иногда конкурс просто не был достаточно интересен для меня. • Объединялся в команду не с теми людьми. Порой сокомандники оказыва- лись менее активными, чем я ожидал, и результат был хуже. О чем важнее всего помнить, приступая к участию в соревновании? Думаю, важно помнить о своих целях, знать, насколько вы сейчас готовы вкла- дываться в участие в этом конкурсе, и просчитывать возможные исходы. Участ- вовать в конкурсах можно с разными целями: • получить медаль или денежный приз; • получить новые навыки или улучшить имеющиеся; • поработать в новой области или над новой задачей; • установить связи с другими людьми; • прорекламировать себя ит. д. Разумеется, мотивов может быть несколько. Что касается готовности вкладываться — обычно речь идет о количестве време- ни и сил, которое вы готовы потратить на задачу, а также об имеющихся у вас
Глава 5. Задачи и метрики на соревнованиях 129 вычислительных ресурсах. Говоря об исходах, я имею в виду то, что происходит после окончания конкурса. Быть может, потратив время и силы, вы выиграете, быть может, проиграете. Готовы ли вы к этому? Критично ли для вас одно про- игранное соревнование? Возможно, стоит прикладывать больше усилий, но, с другой стороны, один проигранный конкурс может и не быть столь важен для ваших долгосрочных целей. Метрики для задач детектирования объектов В последние годы на Kaggle становится всё больше соревнований по глубокому обучению. Большинство из них касаются распознавания изображений или обработ- ки естественного языка, и метрики для них не сильно отличаются от уже обсуж- давшихся. Однако некоторые специфические задачи требуют и своих метрик — это задачи нахождения (детектирования) объектов и сегментации. Классификация + локализация (кошка) Детектирование объекта (собака, кошка) Рис. 5.4. Задачи компьютерного зрения (источник: https://cocodataset.org/#explore?id=68717, https://cocodataset.org/#explore?id=38282) В задачах нахождения объектов нужно не классифицировать изображение, а най- ти на нем релевантные участки и присвоить им метки. Так, на рис. 5.4 алгоритм должен найти на фото участки, содержащие собаку или кошку, и верно классифи- цировать каждый из таких участков. На фото слева местонахождение кошки пока- зано с помощью ограничивающей рамки (bounding box). На фото справа такими рамками выделены несколько кошек и собак, которые затем корректно классифи- цированы (синие рамки соответствуют собакам, красные — кошкам). Для того чтобы описать местонахождение объекта, используются пря- моугольные ограничивающие рамки. Они обычно задаются двумя па- рами координат (х, у), соответствующими левому верхнему и правому нижнему углам.
130 Часть II. Оттачивание соревновательных навыков Говоря языком машинного обучения, нахождение координат ограничи- вающих рамок — это задача регрессии с многомерной целевой функци- ей. Однако, скорее всего, вы будете не решать эту задачу с нуля, а пола- гаться на уже построенные и зачастую предобученные модели, такие как Mask R-CNN (https://arxiv.org/abs/1703.06870), RetinaNet (https://arxiv.org/abs/2106.05624vl), FPN (https://arxiv.org/abs/ 1612.03144v2), YOLO (https://arxiv.org/abs/1506.02640vl), Faster R- CNN (https://arxiv.org/abs/1506.01497vl) или SDD (https://arxiv.org/ abs/1512.02325). Задачу сегментации можно рассмотреть как классификацию на уровне пикселов, так что, если имеется изображение размера 320 х 200, придется классифицировать 64 000 пикселов. В зависимости от конкретной задачи сегментация может быть се- мантической, когда необходимо классифицировать каждый пиксел изображения, либо сегментацией экземпляров (instance segmentation), когда нужно классифици- ровать только пикселы, относящиеся к объектам определенного типа (например, кошке на рис. 5.5). Семантическая сегментация (кошка, диван) Сегментация экземпляра (кошка) Рис. 5.5. Семантическая сегментация и сегментация экземпляров на одном изображении (источник: https://cocodataset. org/#explore?id=338091) Начнем с обзора специальных метрик для задач детектирования объектов и сегмен- тации, общих для обеих этих задач, т. к. и там и там вам нужно обнаружить на изо- бражении некоторые области (прямоугольные при детектировании объектов, мно- гоугольные при сегментации) и сравнить свои предсказания с истиной (опять же заданной как области изображения). Простейшая метрика для задач сегментации — доля верно классифицированных пикселов (pixel accuracy). Эта метрика не слишком хороша; как и доля правильных ответов в обычных задачах (бинарной и многоклассовой) классификации, она может давать очень высокие значения, когда классификатор всегда предсказывает самый распространенный класс (т. е. когда интересующая нас область изображения мала, сегментация фактически не произво-
Глава 5. Задачи и метрики на соревнованиях 131 дится). Поэтому гораздо чаще используются две другие метрики: отношение пло- щадей ограничивающих рамок (intersection over union) и коэффициент Дайса (Dice coefficient). Отношение площадей ограничивающих рамок Отношение площадей ограничивающих рамок (intersection over union, IoU) так- же называют индексом Жаккара. В задачах сегментации он применяется в сле- дующей ситуации: у вас есть два изображения, одно соответствует вашему пред- сказанию, другое — истине (обычно это матрица-"маска" со значениями 0 и 1, где 1 соответствует нужным нам пикселам). В случае когда на изображении нужно найти несколько объектов разных классов, "масок" будет несколько, каждая из них соот- ветствует одному из классов. В задачах детектирования объектов вам даны две прямоугольные области (соответ- ствующие предсказанию и истине), заданные координатами вершин. Для каждого класса вычисляется площадь пересечения предсказанной и истинной областей, а затем делится на площадь их объединения (рис. 5.6). Такой показатель ухудшается как в том случае, если предсказанная вами область больше истинной (поскольку увеличится знаменатель), так и в том случае, когда она меньше (поскольку умень- шится числитель). Область перекрытия Объединенная область Рис. 5.6. Вычисление IoU На рис. 5.6 показаны области, задействованные в этом вычислении. Представив се- бе подобные картинки, вы, например, поймете, как метрика штрафует предсказа- ния, которые затрагивают лишнюю по отношению к истине часть изображения (по- скольку увеличивается площадь пересечения). Примеры соревнований, на которых использовалась метрика IoU: • TGS Salt Identification Challenge (https://www.kaggle.com/cZtgs- salt-identification-challenge/); • iMaterialist (Fashion) 2019 at FGVC6 (https://www.kaggle.eom/c/ imaterialist-fashion-2019-FGVC6);
132 Часть II. Оттачивание соревновательных навыков • Airbus Ship Detection Challenge (https://www.kaggIe.com/cZairbus- ship-detection). Коэффициент Дайса Другая полезная метрика— коэффициент Дайса (Dice coefficient), удвоенная площадь пересечения предсказанной и истинной областей, деленная на сумму пло- щадей этих областей (рис. 5.7). Область перекрытия Сумма областей Рис. 5.7. Вычисление коэффициента Дайса В отличие от индекса Жаккара, в знаменателе при этом не учитывается пересечение предсказанной и истинной областей. Ожидается, что, максимизируя площадь пере- сечения, вы правильно предскажете размер интересующей вас области. Впрочем, если предсказанная вами область окажется слишком большой, значение метрики также уменьшится. На деле индекс Жаккара и коэффициент Дайса не только поло- жительно коррелируют между собой, но и практически совпадают для задач одно- классовой классификации. Различия начинаются в случае нескольких классов. При использовании обеих метрик вы вычисляете их значения для всех классов и берете среднее. Однако при этом метрика IoU приводит к большему штрафу за ошибки на одном из классов, в то время как коэффициенту Дайса важнее средний результат. Примеры конкурсов, использующих коэффициент Дайса (заметим, что он очень часто встречается в задачах, связанных с медициной, хотя и не только в них): • НиВМАР — Hacking the Kidney (https://www.kaggle.eom/c/hubmap-kidney-segmeiitatioii); • Ultrasound Nerve Segmentation (https://www.kaggle.eom/c/ultrasound-nerve-segmentation); • Understanding Clouds from Satellite Images (https://www.kaggle.eom/c/understanding_cloud_organization); • Carvana Image Masking Challenge (https://www.kaggle.eom/c/carvana-image-masking-challenge).
Глава 5. Задачи и метрики на соревнованиях 133 IoU и коэффициент Дайса являются базовыми метриками для задач сегментации и детектирования объектов, все более сложные метрики основаны на них. Выбрав подходящий порог для значения одной из этих метрик (обычно 0,5), вы определяе- те, найден ли нужный объект (задача классификации). Для классификации можно использовать одну из уже обсуждавшихся метрик — точность, полноту или F-меру, как происходит на популярных конкурсах по нахождению объектов и сегментации, например Pascal VOC (http://host.robots.ox.ac.uk/pascaWOC/voc2012) или СОСО < https://cocodataset.org). Метрики для многоклассовой классификации и построение рекомендаций Рекомендательные системы являются одним из самых популярных приложений анализа данных и машинного обучения, и задача многих конкурсов Kaggle, напри- мер конкурса по распознаванию дудлов Quick, Draw! Doodle Recognition Challenge, сформулирована как задача построения рекомендаций. В некоторых других кон- курсах целью действительно было построения эффективной рекомендательной сис- темы (примером может служить конкурс Expedia Hotel Recommendations: https://www.kaggle.eom/c/expedia-hotel-reconiniendations) и, более того, однажды на Kaggle проходил ежегодный конкурс конференции RecSYS, посвященной реко- мендательным системам (RecSYS 2013: https://www.kaggle.com/c/yelp-recsys-2013). Mean Average Precision at К (MAP@{K}) — метрика, обычно используемая для оценки качества рекомендательных систем, и чаще всего на конкурсах Kaggle, свя- занных с построением рекомендаций, вы встретитесь именно с ней. Другие метри- ки, Р@К и АР@К, являются функциями потерь и вычисляются для каждого пред- сказания отдельно. Разобравшись в их работе, вы сможете лучше понять метрику МАР@К и то, как она ведет себя в задачах выдачи рекомендаций и многоклассовой классификации. Сходство этих двух типов задач в том, что модель выдает некото- рый набор предсказаний, относящихся к отдельным классам. Оценить подобный результат можно, вычислив среднее от значений метрик для бинарной классифика- ции (как на конкурсе Greek Media Monitoring Multilabel Classification, WISE 2014, где использовалось среднее значение F-меры: https://www.kaggle.com/c/wise-2014) или используя метрики вроде МАР@{К}, типичные для рекомендательных систем. Можно рассмотреть и задачи выдачи рекомендаций, и задачи многоклассовой клас- сификации как задачи ранжирования (в рекомендательной системе упорядочены предлагаемые варианты, в задаче многоклассовой классификации имеется набор меток, но их порядок не важен). МАР@{К} МАР@{К} — довольно сложная метрика. Для того чтобы понять ее, начнем с precision at к (Р@К). Так как результат работы системы, ее предсказание — это упорядоченный список рекомендуемых объектов, от наиболее вероятного к найме-
134 Часть II. Оттачивание соревновательных навыков нее вероятному, то можно взять к первых элементов списка, найти число совпаде- ний с истиной и поделить на к. Иначе говоря, это точность на первых к элементах списка. Метрика, требующая чуть больше вычислений, но идейно столь же про- стая — это average precision at к (АР@К), среднее значение Р@К для длин верх- ней части списка от 1 до к. Сначала мы смотрим на качество предсказания, рас- сматривая только первую рекомендацию, затем — две первые рекомендации и так далее до к первых рекомендаций. Наконец, МАР@К— это среднее значений АР@К для всех выданных предсказаний. Так выглядит формула для МАР@5, взя- тая из описания конкурса Expedia Hotel Recommendations (https://www.kaggle.com/ c/expedia-hotel-recommendations): i |(/| min(5,w) MAP@5 = ^j£ £ В этой формуле | СТ] — количество пользователей, которым были выданы рекоменда- ции; Р(Л) — точность для первых к элементов списка; п — количество предсказанных кластеров отелей (в каждой рекомендации может быть до 5 отелей). Формула выгля- дит немного страшнее, чем наше объяснение, но на деле говорит всего лишь о том, что метрика МАР@К — это среднее значений АР@К для всех пользователей. Закончив с обзором конкретных метрик для различных задач регрессии и класси- фикации, обсудим, как работать с ними в конкурсах Kaggle. Оптимизация метрики Мы уже говорили о том, что целевая функция — это функция, измеряющая, на- сколько хорошо результат вашей модели соответствует данным. Она дает алгорит- му обучения ’’обратную связь’’, позволяющую ему улучшаться. Кажется очевид- ным, что если алгоритм обучения нацелен на оптимизацию целевой функции, то лучшие результаты будут достигаться при совпадении этой функции с метрикой оценивания конкурса. К сожалению, зачастую это не так. Нередко метрика оцени- вания может быть только приближена существующей целевой функцией, и секре- том хорошего вычисления будет выбор наилучшего приближения. В случае когда целевая функция не совпадает с метрикой оценивания, вы можете действовать не- сколькими способами: 1. Модифицировать алгоритм обучения так, чтобы его целевая функция совпадала с метрикой оценивания, что, к сожалению, возможно не для всех алгоритмов (так, LightGBM и XGBoost позволяют выбрать произвольную целевую функ- цию, но для большинства моделей из Scikit-leam это невозможно). 2. Выбрать такие гиперпараметры модели, что при использовании метрики оцени- вания достигается наилучший результат. 3. Произвести постобработку результатов так, чтобы они лучше соответствовали критериям оценивания. Скажем, можно написать оптимизатор, преобразующий ваши предсказания (примером могут служить алгоритмы калибровки вероятно- стей, которые мы обсудим в конце главы).
Глава 5. Задачи и метрики на соревнованиях 135 Наиболее эффективным является первый метод — использование конкурсной мет- рики в алгоритме обучения, однако лишь немногие алгоритмы допускают его. По- этому чаще всего используется второй подход, и большинство соревнований сво- дятся к борьбе за наилучшие гиперпараметры. Если у вас есть код, вычисляющий значение метрики, то правильное проведение кросс-валидации обеспечивает про- хождение половины пути к успеху. При самостоятельном написании такой функ- ции пользуйтесь формулой, указанной на странице Kaggle. Всегда применяйте сле- дующую схему действий. • Найдите как можно больше информации о метрике оценивания. • Поищите готовые реализации в популярных библиотеках, таких как Scikit- leam (https://scikit-learn.org/stable/modules/model evaluation.html#model- evaluation) или TensorFlow (https://www.tensorflow.org/api_docs/python/tf/ keras/losses). • Затем обратитесь к репозиториям на GitHub (например, к проекту Бена Хам- мера: https://github.com/benhamner/Metrics). • Задавайте вопросы и ищите готовый код на форумах и в блокнотах Kaggle (относящихся как к текущему конкурсу, так и к похожим на него). • Помимо этого, стоит изучить датасет Meta Kaggle (https://www.kaggle.com/ kaggle/meta-kaggle) и найти в таблице Competitions соревнования, использо- вавшие ту же самую метрику. Вы сразу сможете найти множество полезных идей и готового кода. Обсудим подробнее, что делать, когда метрика оценивания не совпадает с целевой функцией алгоритма. Начнем с обсуждения нестандартных метрик. Нестандартные метрики и целевые функции Мы говорили, что первая опция при несовпадении целевой функции с метрикой оценивания— поменять целевую функцию на новую, нестандартную, но не все алгоритмы машинного обучения допускают это. К счастью, некоторые алгоритмы, для которых это возможно, чрезвычайно эффективны. Конечно, написание собст- венной целевой функции может казаться сложной задачей, но улучшение результа- та на соревновании стоит того. Так, целевую функцию можно поменять для алго- ритмов градиентного бустинга (XGBoost, CatBoost, LightGBM), как и для всех моделей глубокого обучения из библиотек TensorFlow или PyTorch. Прекрасные руководства, касающиеся нестандартных метрик и целевых функций в TensorFlow и PyTorch, можно найти по ссыпкам: • https://towardsdatascience.com/custom-metrics-in-keras-and-how-simple- they-are-to-use-in-tensorflow2-2-6d079c2ca279; • https://petamind.com/advanced-keras-custom-loss-functions/; • https://kevinmusgrave.github.io/pytorch-metric-learning/extend/losses/.
136 Часть II. Оттачивание соревновательных навыков Вы найдете заготовки кода и подсказки, как реализовать нестандартную целевую функцию. Если вы хотите найти готовый код для нужной вам функции, стоит обра- ч । z титься к блокноту автора RNA (https://www.kaggle.com/bigironsphere): https://www.kaggle.com/bigironsphere/loss-function-library-keras-pytorch/ 5 notebook, содержащему множество функций потерь для TensorFlow и PyTorch, появлявшихся на различных конкурсах. Если вы хотите создать нестандартную функцию потерь для использования с LightGBM, XGBoost или CatBoost, согласно их документации вам нужна функция, принимающая на вход предсказанные и истинные значения и возвращающая гради- ент и матрицу Гессе. Что представляют собой градиент и матрица Гессе, можно понять из поста на Stack Overflow: https://stats.stackexchange.com/questions/231220/ how-to-compute-the-gradient-and-hessian-of-logarithmic-loss-question- is-based. С точки зрения реализации, если вам нужно использовать больше параметров, чем предсказанные и истинные метки, можно прибегнуть к анонимным функциям. Приведем в качестве примера функцию потерь, известную как focal loss (присваи- вающую большой вес редким классам и описанную в статье Ти-Йи Лин и др. "По- теря фокуса при обнаружении плотных объектов"3). Вы можете использовать этот код как образец: from scipy.misc import derivative import xgboost as xgb def focal_loss(alpha, gamma): def loss_func(y_pred, y_true): a, g = alpha, gamma def get_loss(y_pred, y_true): p = 1 / (1 + np.exp(-y_pred)) loss = (-(a * y-true + (1 - a)*(l - y_true)) * ((1 - (y_true * p + (1 - y_true) * (1 - p)))**g) * (y-true * np.log(p) + (1 - y_true) * np.log(l - p))) return loss 3 Lin T-Y. et al. Focal loss for dense object detection. — URL: https://arxiv.org/abs/1708.02002.
Глава 5. Задачи и метрики на соревнованиях 137 partial_focal = lambda y_pred: get_loss(y_pred, y_true) grad = derivative(partial-focal, y_pred, n=l, dx=le-6) hess = derivative(partial-focal, y_pred, n=2, dx=le-6) return grad, hess \ return loss-func i xgb = xgb.XGBClassifier(objective=focal_loss(alpha=0.25, gamma=l)) В данном коде мы определили новую функцию потерь, focal_loss, и передали ее в гачестве параметра объекту класса XGBoost. Пример достоин внимания, поскольку данная функция потерь требует дополнительных параметров (alpha и gamma). Про- стейший способ явно задать их внутри функции не слишком хорош, поскольку при настройке модели эти параметры должны меняться. Вместо этого параметры, пере- данные функции focal_loss, сохраняются и используются в функции loss_func, ко- торую и передают алгоритму XGBoost. Таким образом, возвращаемая функция стоимости использует заданные значения alpha и gamma. Другой интересной особенностью нашего примера является простота вычисления градиента и матрицы Гессе для функции стоимости с помощью взятия производной из библиотеки SciPy. Если функция стоимости дифференцируема, вам не нужны вычисления вручную. Однако придумывание нестандартной целевой функции тре- бует математических знаний и некоторых усилий для доказательства того, что она соответствует вашим задачам. Так, о сложностях, с которыми столкнулся Макс Халфорд (Max Halford) при реализации focal loss для LightGBM, и об их преодоле- нии можно прочитать здесь: https://maxhalford.github.io/blog/lightgbm-focal-loss/. Тем не менее реализация нестандартной функции потерь зачастую определяет ваш успех на конкурсе. Если, однако, не удается реализовать собственную целевую функцию, можно снизить планку и использовать эту функцию только как метрику оценивания. В этом случае ваша модель не будет непосредственно оптимизиро- ваться относительно этой функции, однако вы все еще можете подбирать гиперпа- раметры, используя второй из подходов, описанных в предыдущем разделе. Впро- чем, если вы пишете метрику с нуля, для ее правильной работы вам порой все равно придется подчиняться неким стандартам написания кода. Так, при использо- вании Scikit-leam вам придется применять к своим функциям обертку make_scorer, делающую их пригодными для работы с Scikit-leam API. Обертка учитывает неко- торую дополнительную информацию, например, использовать ли предсказанные метки классов или их вероятности, введен ли какой-то порог и хотим ли мы макси- мизировать или минимизировать возвращаемое значение: from skleam. metrics import make_scorer from sklearn.metrics import average_precision_score scorer = make_scorer(average_precision_score, average='weighted', greater_is_better=True, needs_proba=False)
138 Часть II. Оттачивание соревновательных навыков В данном^ примере кода вы создаете оценивающую функцию на основе средней точности, использующую веса для задач многоклассовой классификации. Для оптимизации параметров вашего алгоритма относительно оцени- вающей метрики (даже если внутри он использует другую функцию стоимости) можно применять поиск по сетке, случайный поиск или бо- лее продвинутые методы вроде байесовской оптимизации. Мы еще об- судим, как наилучшим способом оптимизировать параметры, после то- го, как поговорим о валидации моделей, и особенно в главе, касающейся работы с табличными данными. Постобработка предсказаний Постобработка подразумевает, что ваши предсказания преобразуются с помощью некоторой функции. Построив собственную функцию стоимости или проведя оп- тимизацию относительно метрики оценивания, вы можете преобразовать свои предсказания так, чтобы они давали лучший результат относительно метрики. Рас- смотрим, например, квадратичную взвешенную каппу (Quadratic Weighted Карра) — метрику, полезную при работе с задачами ранжирования. Вспомним, что исходно коэффициент каппа показывает согласованность предсказаний с истиной с поправкой на вероятность (т. е. немного похож на долю правильных ответов, но с учетом возможности случайных совпадений). Формула, которую мы уже видели: к = (р0 ~Ре)/(1 -РеУ В этой формуле ро — доля совпадающих ответов, ре — вероятность случайного совпадения. Здесь вам нужны две матрицы: одна с наблюдаемыми оценками, дру- гая — с ожидаемыми. Для того чтобы вычислить взвешенный коэффициент каппа, потребуется также матрица весов: к=(р0-ре)/(1 -Рр). Матрица рр задает различные веса для штрафов за ошибку — что очень полезно в задачах ранжирования, поскольку тогда можно сильнее штрафовать за более силь- ные отклонения от истины. Использование квадратичных форм (в данном случае — возведение к в квадрат) — делает эти штрафы еще более жесткими. Однако опти- мизировать относительно такой метрики непросто, т. к. ее сложно реализовать как функцию стоимости. Помочь может постобработка. Примером может служить конкурс PetFinder.my Adoption Prediction (https:// www.kaggle.com/c/petfinder-adoption-prediction), посвященный взятию животных из приютов. Задачу этого соревнования можно было решать как задачу классифи- кации или как задачу регрессии (поскольку возможными значениями предсказаний были целые числа от 0 до 4). При использовании регрессии постобработка улучша-
Глава 5. Задачи и метрики на соревнованиях 139 ла качество модели по метрике Quadratic Weighted Карра, превосходя результаты, полученные методами классификации. Она заключалась в том, что результаты рег- рессии преобразовывались в целые числа, исходно использовались в качестве поро- говых значения [0.5, 1.5, 2.5, 3.5], а затем они настраивались для наилучших ре- зультатов. Поиск оптимальных пороговых значений требовал использования, например, функции optimize.minimize из SciPy, основанной на методе Нелдера — Мида, а затем кросс-валидации. Подробно о таком способе постобработки можно прочитать в посте, написанном во время конкурса Абхишеком Такуром (Abhishek Thakur): https://www.kaggle.eom/c/petfinder-adoption-prediction/discussion/76107. На множестве других конкурсов также было показано, что грамотная постобработка ведет к улучшению результатов. В качестве примеров приведем: • https://www.kaggle.com/khoongweihao/post-processing- technique-c-f-lst-place-jigsaw; • https://www.kaggle.com/tomooinubushi/postprocessing-based-on- leakage; https://www.kaggle.com/saitodevel01/indoor-post-processing-by- cost-minimization. К сожалению, способ постобработки часто сильно зависит не только от используе- мой метрики (собственно, без ее понимания провести хорошую постобработку не- возможно), но и от данных, например, в случае временных рядов и при утечках в данных. Поэтому выработать некоторую общую процедуру, подходящую для лю- бого конкурса, практически невозможно. Однако о возможности постобработки стоит помнить всегда и следить за малейшими признаками, что она окажется по- лезной (в частности, искать информацию о прошедших похожих конкурсах). Предсказание вероятностей и их корректировка В завершение разговора об оптимизации метрики (постобработке предсказаний) мы поговорим о задачах предсказания вероятностей. Как мы уже говорили, вероятно- сти могут встречаться в задачах бинарной и многоклассовой классификации, и они обычно оцениваются с помощью функции Log Loss в ее бинарном или многоклас- совом варианте (подробнее можно прочитать в разделах, посвященных метрикам для классификации). Однако оптимизация с использованием Log Loss может ока- заться недостаточной. К возможным проблемам относятся такие: модель на самом деле возвращает не оценку вероятности; классы несбалансированы; распределение классов различно для обучающих и тестовых данных.
140 Часть II. Оттачивание соревновательных навыков В первом случае стоит проверить, действительно ли предсказания моделируют не- определенность. Хотя, например, многие алгоритмы из библиотеки Scikit-leam имеют метод predict_proba, это не гарантирует, что он действительно вернет веро- ятность. Рассмотрим деревья принятия решений, являющиеся основой для множе- ства эффективных методов работы с табличными данными. Вероятность, возвра- щаемая деревом классификации (https://scikit-learn.org/stable/modules/generated/ sklearn.tree.DecisionTreeClassifier.html), основана на распределении классов на листе дерева, содержащем тестовый пример. Обычно в случае полностью постро- енного дерева эта вероятность очень высока (поскольку лист содержит мало при- меров из других классов). Меняя параметры дерева, например max_depth, max_leaf_nodes или min_samples_leaf, вы можете сильно варьировать эту вероятность. Решающие деревья являются базовой моделью случайных лесов, бэггинга и бус- тинга (в частности, XGBoost, LightGBM и CatBoost). Однако ненадежность оценки вероятностей касается и других методов, таких как метод опорных векторов и ме- тод ближайших соседей. Кэгглеры в основном не знали об этой проблеме до кон- курса Otto Group Product Classification Challenge (https://www.kaggle.com/c/otto- group-product-classification-challenge/overview/), когда ее озвучили несколько участников, в частности, Кристоф Бургина (Christophe Bourguignat) — прочитать об этом можно на https://www.kaggle.com/cbourguignat/why-calibration-works. Тогда проблема решилась использованием функций калибровки, недавно добавленных в Scikit-leam. Кроме используемой модели, проблемы с оценкой вероятностей может вызывать и дисбаланс классов. Удачным решением может служить уменьшение или увеличе- ние классов (undersampling, oversampling) либо введение весов при вычислении функции потерь. Хотя эти методы и улучшают качество модели, они почти всегда искажают вероятности, и для дальнейшего улучшения результатов их необходимо еще корректировать. Наконец, третий источник проблем — различие распределений обучающего и тес- тового множеств. Его обычно скрывают, но существует масса способов его вы- явить, например, методом проб и ошибок на основе таблицы результатов (о чем мы уже говорили в главе /). В качестве примеров приведем конкурсы iMaterialist Furniture Challenge (https:// www.kaggle.com/c/imaterialist-challenge-furniture-2018/) и Quora Question Pairs (https://www.kaggle.eom/c/quora-question-pairs). Оба они породили много обсуж- дений, как проводить постобработку, чтобы вероятности соответствовали ожида- ниям (можно почитать об этом подробнее на https://swarbrickjones.wordpress.com/ 2017/03/28/cross-entropy-and-training-test-class-imbalance/ и https://www.kaggle.com/ dowakin/probability-calibration-0-005-to-lb). В целом, если вы не знаете распреде- ления тестовых данных, разумной идеей по-прежнему является предсказание на основе распределения тестовых данных (пока не появятся свидетельства, что тесто- вое распределение отличается; но даже в этом случае проще начинать с вероятно- стей, полученных на основе обучающего множества, а затем корректировать их).
Г,пава 5. Задачи и метрики на соревнованиях 141 Справиться с несовпадением между предсказанными вероятностями и распреде- лением ответов на обучающем множестве поможет функция калибровки CalibratedClassif ierCV из Scikit-leam: sklearn.calibration.CalibratedClassifierCV(base_estimator=None, *, method='sigmoid', cv=None, n_Jobs=None, ensemble=True) Функция калибровки применяется к предсказанным вероятностям, чтобы прибли- зить их к эмпирическим вероятностям на обучающем множестве. Если вы поль- зуетесь моделями из Scikit-leam (либо ведущими себя аналогично), эта функция представляет собой обертку, направляющую предсказания модели на постобра- ботку. Для постобработки возможно выбрать один из двух методов — метод сиг- моиды (калибровка Плата), представляющий собой на деле логистическую рег- рессию, или изотоническую регрессию. Последний метод является непарамет- рическим и при небольшом числе примеров склонен к переобучению. Также необходимо выбрать метод обучения. Поскольку постобработка применяется уже к результатам вашей модели, во избежание переобучения необходимо менять предсказания. Можно использовать кросс-валидацию (о чем мы подробнее пого- ворим в главе 6) и, построив несколько моделей, усреднять их предсказания (ensemble=True). Обычно же используют так называемые out-of-fold-предсказания (о которых мы подробнее поговорим потом) и проводят калибровку, учитывая все имеющиеся данные (ensemble=False). Суд ал ай Раджкумар https://www.kaggle.com/sudalairajkumar Последнее наше интервью в этой главе — с Судалаем Радж- кумаром, гроссмейстером в категориях Competitions, Datasets и Notebooks и мастером в категории Discussions. Он занимает первое место в рейтинге платформы Analytics Vidhya и работает консультантом по AI и ML для различ- ных стартапов. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Больше всего я люблю соревнования, требующие преобразования признаков. Умение делать его я считаю своей сильной стороной. Мне в целом интересно анализировать имеющиеся данные и разбираться в них как можно лучше (поэто- му у меня имеется ряд блокнотов, посвященных разведочному анализу данных: https://www.kaggle.com/sudalairajkumar/code), а затем придумывать на основа- нии узнанного новые признаки.
142 Часть II. Оттачивание соревновательных навыков Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? На соревнованиях приходится анализировать имеющиеся данные, выбирать ме- тод валидации, преобразовывать признаки, строить модели, объединять их. Все эти задачи присутствуют и в моей обычной работе, но, кроме того, в ней я дол- жен общаться с заказчиками, собирать и размечать данные, следить за качеством уже работающей модели и объяснять сделанные выводы. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты действовал Мне запомнился конкурс Santander Product Recommendation. Рохану и мне при- шлось много преобразовывать признаки и строить различные модели. Объединяя эти модели, мы присваивали продуктам веса, причем порой они не давали в сумме 1. Эти веса мы подбирали вручную. Так мы поняли, насколько важно понимать предметную область и данные и насколько наука о данных близка к искусству. Помог ли тебе Kaggle в карьере? Если да, то как? Да, Kaggle сыграл большую роль в моей карьере. Во многом благодаря ему я по- лучил свою текущую и предыдущую работу. Кроме того, успехи на Kaggle по- зволили мне общаться с другими энтузиастами науки о данных и учиться у них, а также дали мне возможность приобрести авторитет, что помогает в роли кон- сультанта стартапов. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Участники нередко не уделяют время глубокому пониманию данных и сразу на- чинают строить модели. Разведочный анализ данных играет огромную роль в ус- пехе на любом соревновании. Он поможет создать схему кросс-валидации, по- строить удачные признаки и в целом более эффективно использовать данные. Какие ошибки ты допускал на соревнованиях? Их список огромен, но ошибки — это возможность для роста. На каждом соревно- вании я пробую 20-30 идей, а срабатывает порой всего одна. Ошибки и неудачи позволяют научиться большему, чем успехи. Так, я на собственном горьком опыте узнал о переобучении, свалившись из верхней части таблицы глубоко вниз на од- ном из первых своих соревнований. Зато этот опыт я запомнил на всю жизнь. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Для табличных данных я в первую очередь применяю XGBoost/LightGBM. Кроме того, в качестве отправной точки для сравнения я использую результаты AutoML-библиотек с открытым кодом и Driverless AL Для глубокого обучения я пользуюсь Keras, Transformers и PyTorch. О чем важнее всего помнить, приступая к участию в соревновании? Главное— упорство и последовательность. На каждом конкурсе будут свои взлеты и падения, дни без малейшего прогресса, но важно не сдаваться и про- должать идти. Думаю, этот совет применим не только к конкурсам Kaggle.
Глава 5. Задачи и метрики на соревнованиях 143 Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я участвовал в конкурсах на других платформах, например Analytics Vidhya DataHack, Driven Data, CrowdAnalytix. Они тоже очень хороши, но Kaggle гораз- до более известен во всем мире, так что число соревнований на Kaggle сущест- венно больше. Резюме В этой главе мы обсудили метрики оценивания на конкурсах Kaggle. Сначала мы объяснили, как метрика оценивания может отличаться от целевой функции. Мы также указали на разницу между задачами классификации и регрессии. Для каждо- го типа задач мы рассказали о наиболее часто встречающихся метриках. После этого мы поговорили о метриках, которые раньше на конкурсах не встреча- лись и которые вы вряд ли увидите снова. Наконец, мы изучили различные распро- страненные метрики и привели примеры их использования на соревнованиях. Затем мы предложили пути оптимизации относительно метрики, в частности реализацию собственной функции стоимости и постобработку. Теперь вы понимаете роль метрики в конкурсах. Вы также понимаете, как действо- вать, столкнувшись со знакомой или незнакомой метрикой, как обращаться к про- шлым конкурсам и разбираться в работе метрики. В следующей главе мы обсудим, как оценить качество вашего решения с помощью кросс-валидации. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
6 Построение схемы валидации Во время участия в соревновании, в спешке строя модели и отправляя предсказа- ния, вы можете думать, что вам достаточно просто следить за результатом в табли- це, и значение имеет только место. Это типичная ошибка. На самом деле настоящей (приватной) таблицы результатов вы не увидите до окончания конкурса, а слепая вера в результаты из публичной таблицы часто приводит к неверным выводам. В данной главе мы познакомим вас с важностью валидации на соревнованиях. Со- держание главы: • что такое переобучение и почему не стоит верить публичной таблице резуль- татов; • страшные перетасовки в таблице; • типы стратегий валидации; • adversarial validation; • как обнаружить и использовать утечки в данных; • как выбрать итоговые решения. Не только на соревнованиях, но и в целом в науке о данных важно следить за каче- ством модели и не допускать переобучения. Грамотная валидация — один из клю- чевых навыков, которому можно научиться на конкурсах Kaggle, а затем применить его в профессиональной среде. Подглядывание Как мы уже говорили, тестовые данные на каждом конкурсе Kaggle делятся на публичную часть, результаты на которой видны в текущей таблице результатов, и приватную часть, которая будет использоваться для подведения итогов конкурса. Разделение на две части обычно проводится случайно (хотя для задач, связанных с
'зава 6. Построение схемы валидации 145 феменными рядами, оно проводится по времени) и тестовые данные выкладыва- ются целиком. Недавно, чтобы избежать подстройки решения под тестовые данные, Kaggle на некоторых конкурсах перестал выкладывать эти данные, при- водя лишь несколько примеров. На таких конкурсах (Code competitions) участник отправляет не сами предсказания, а генерирующий их код. Таким образом, при отправке решения предсказания строятся для всего тестового множества, но только публичная часть будет оцениваться сразу, в то время как приватная — после завершения соревнования. 3 связи с этим возникают три соображения. • Для того чтобы конкурс проходил без проблем, обучающие и тестовые дан- ные должны иметь одинаковое распределение. Более того, публичная и приватная части тестовых данных также должны иметь одинаковое распреде- ление. • Даже если обучающие и тестовые данные относятся к одному распределе- нию, при недостатке примеров в одном из них будет сложно получить согла- сованные результаты. • Публичные тестовые данные стоит рассматривать как отложенные (holdout) контрольные данные в реальном проекте, т. е. использовать только для окон- чательной валидации. Однако не стоит слишком часто обращаться к ним, чтобы не получить эффект переобучения (и снижение качества на других тестовых данных). Эти три соображения являются ключевыми для понимания соревновательной ди- замики. В рамках большинства конкурсов на форуме много обсуждается соотно- ление обучающих, публичных тестовых и приватных тестовых данных, но при этом сотни решений отправляются, будучи оцененными только по результатам в публичной таблице. Часто обсуждаются и радикальные перестановки в таблице результатов при под- зедении итогов, разочаровывающие многих из занимавших высокие позиции. Обычно их связывают с различиями между обучающими и тестовыми данными ли- бо публичными и приватными тестовыми данными. Эти различия можно измерить ю подведения итогов сравнением локальных значений метрики и результата в таб- лице, а после него — двумя характеристиками: • общим ’’индексом перемешивания” mean(abs(private_rank-public_rank)/ number_of_teams), где private_rank и public_rank— соответственно позиция в приватной и публичной таблицах, number_of_teams — число команд; • ’’индексом перемешивания” для верхней части таблицы (верхних 10% в пуб- личной таблице).
146 Часть II. Оттачивание соревновательных навыков ’’Индексы перемешивания” были впервые придуманы Стивом Донохо (Steve Donoho, https://www.kaggle.com/breakfastpirate), составившим "хит-парад" самых беспощадных перемешиваний (https://www.kaggle.com/ c/recruit-restaurant-visitor-forecasting/discussion/49106#278831). Сейчас подобные рейтинги воспроизводятся во множестве блокнотов, исполь- зующих датасет Meta Kaggle, обсуждавшийся нами в главе 5 (посмотрите, например, https://www.kaggle.com/jtrotman/meta-kaggle-competition- shake-up). Взглянув на цифры, вы поймете, например, как страшен для многих был конкурс RSNA Intracranial Hemorrhage Detection из-за пол- ного перетряхивания таблицы результатов, в особенности в верхней части. Однако и без подобных вычислений мы можем извлечь из перестановок в результа- тах прошлых соревнований уроки на будущее. Так думали и исследователи из Ка- лифорнийского университета в Беркли. В статье, представленной на конференции NIPS 2019, Р. Релофс, С. Фридович-Кейл и др. изучали динамику результатов в конкурсах Kaggle. Хотя они рассмотрели лишь ограниченное множество соревно- ваний (120 конкурсов, посвященных бинарной классификации, на каждом из кото- рых было отправлено хотя бы 1000 решений), но смогли обнаружить следующие интересные факты. • Переобучение на соревнованиях выражено слабо, иначе говоря, обычно при- ватная таблица результатов похожа на публичную. • Большая часть перестановок в результатах— это случайные флуктуации, происходящие из-за большой плотности результатов. В этом случае даже не- значительные отличия в значениях метрики на приватных тестовых данных отражаются на распределении мест. • Сильное перемешивание может происходить при маленькой обучающей вы- борке или в случае, когда обучающие данные не являются независимыми и одинаково распределенными. Полный текст статьи— Roelofs R., Fridovich-Keil S. et al. A meta- analysis of overfitting in machine learning И Proceedings of the 33rd International Conference on Neural Information Processing Systems. — 2019. — lip. — можно найти по адресу: https://papers.nips.cc/paper/2019/file/ee39e503b6bedf0c98c388b7e8589a ca-Paper.pdf. На собственном опыте участия в конкурсах Kaggle, однако, мы встречали немало случаев переобучения. Можно, например, прочитать пост Грега Пака (Greg Park) с анализом одного из первых наших соревнований: http://gregpark.io/blog/Kaggle-
Глава 6. Построение схемы валидации 147 Psychopathy-Postmortem/. Так как проблема переобучения обычна для многих «эгглеров, мы предлагаем пользоваться более продвинутой стратегией, чем просто следить за публичной таблицей. • Всегда стройте надежную систему кросс-валидации, которую будете приме- нять локально (на своем компьютере). • Всегда старайтесь выявить отклонения данных от независимых одинаково распределенных, используя наилучшую возможную в имеющейся ситуации схему валидации. Обнаружить такие отклонения, если о них прямо не сказано в условии,— задача нетривиальная, однако некоторые идеи на этот счет можно обнаружить на форуме либо проведя эксперименты со стратифициро- ванной схемой валидации (например, при стратификации по некоторому при- знаку могут сильно улучшаться результаты модели). • Следите за корреляцией между локальными оценками качества и публичной таблицей результатов, чтобы понять, согласованы ли они. • Используйте при тестировании метод adversarial validation, чтобы понять, совпадают ли распределения обучающих и тестовых данных. • Стройте ансамбли моделей для большей устойчивости решения, особенно при работе с небольшими датасетами. В последующих разделах мы обсудим некоторые из этих идей (кроме построения ансамблей, которое будет темой следующей главы) и расскажем вам об инструмен- тах и стратегиях для достижения наилучших результатов, в особенности на приват- ном датасете. Почему важна валидация Участие в конкурсе можно представить как систему экспериментов. Выигрывает тот, кто придумает самый последовательный и эффективный путь их провести. Ка- кими бы теоретическими знаниями вы ни обладали, вашими соперниками будут сотни или тысячи профессионалов в науке о данных примерно того же уровня. Они будут использовать те же самые данные и примерно те же самые инструменты iTensorFlow, PyTorch, Scikit-leam и т. д.). Некоторые из них, безусловно, будут иметь доступ к большим вычислительным ресурсам, но наличие среды Kaggle Notebooks и снижающиеся цены на облачные вычисления делают этот разрыв не столь существенным. Таким образом, различия в результатах между вами и конку- рентами вряд ли можно будет объяснять разными знаниями, данными, моделями или компьютерами — однако некоторые участники раз за разом опережают других. Значит, имеются еще какие-то факторы успеха. В интервью и выступлениях многие кэгглеры называют ключевым фактором упор- ство. Некоторые описывают его как готовность перепробовать все методы или даже ’вложить всего себя в соревнование”. Последнее звучит слишком туманно, поэтому назовем такой подход систематическим экспериментированием. На наш взгляд, ключ к успеху — в количестве проведенных вами экспериментов и стратегии их
148 Часть II. Оттачивание соревновательных навыков проведения. Чем больше вы экспериментируете, тем больше у вас шансов решить задачу лучше остальных. Конечно, количество экспериментов будет зависеть от имеющегося времени, вычислительных ресурсов (чем быстрее компьютер, тем лучше — хотя, как мы уже говорили, это не столь существенный фактор), количе- ства участников в команде и их вовлеченности — что вполне согласуется со слова- ми об упорстве и мотивации как ключе к успеху. Тем не менее на результат влияют и другие факторы. Необходимо учитывать, что важна и схема проведения экспериментов. На соревнованиях важно быстро пони- мать, что текущий метод не работает, и переходить к следующему. Разумеется, обдумывать результат и делать выводы нужно как после успехов, так и после не- удач, иначе участие в конкурсах превращается в череду беспорядочных попыток наткнуться на нужный метод. Таким образом, при прочих равных хорошая стратегия валидации отличает тех, кто добивается успеха на соревнованиях, и тех, кто просто переобучается на пуб- личных тестовых данных и в итоге оказывается на более низком месте, чем ожидал. —Валидация — способ узнать об ошибках, допускаемых моделью, и из- мерить повышение или понижение качества результатов при проведе- нии экспериментов. В целом влияние схемы валидации слишком часто недооценивают в сравнении с более легко сравнимыми факторами вроде мощного компьютера или количества участников команды. Тем не менее рассчитывать только на число экспериментов и публичный резуль- тат— значит действовать по принципу "что тут думать, трясти надо". Советуем почитать о проблемах такого подхода на http://gregpark.io/blog/Kaggle- Psychopathy-Postmortem/. Да, порой эта схема оправдывает себя, но чаще прова- ливается, поскольку вы пропустите правильное направление экспериментов и не отличите алмаз от мусора. Если слепо и несистематически гнаться за удачей в пуб- личной таблице, то даже при наличии отличных решений вы не выберете их в каче- стве итоговых и получите низкий результат на приватных тестовых данных. Наличие хорошей стратегии валидации поможет вам выбрать модель и отправить ее для оценки на приватных данных. Велик соблазн выбрать ту, которая показала наилучший результат на публичных тестовых данных, но нужно всегда учитывать и итог валидации. Стратегия будет зависеть от ситуации, например, от того, дове- ряете ли вы публичным результатам. Можно выбрать одну модель на основании публичной таблицы и одну на основании итогов валидации, либо (если вы не дове- ряете публичным результатам, например, из-за маленького обучающего множества или того, что данные не являются независимыми одинаково распределенными) две лучшие модели по итогам валидации. Таким образом, вы снизите риски выбрать решение, плохо работающее на приватных данных.
Глава 6. Построение схемы валидации 149 Мы указали на важность стратегии проведения экспериментов, но остаются прак- тические детали валидации. При построении модели вы, по сути, принимаете ряд связанных друг с другом решений: I. Как обрабатывать данные. 2. Какую модель выбрать. 3. Какие изменения внести в архитектуру модели (особенно это относится к моде- лям глубокого обучения). 4. Как выбрать гиперпараметры. 5. Как провести постобработку предсказаний. Даже при идеальной корреляции между публичной и приватной таблицами резуль- татов из-за существующих на всех конкурсах ограничений на число отправленных за день решений вы не сможете, опираясь только на публичную таблицу, протести- ровать все методы на всех перечисленных шагах. Качественная система валидации □одскажет вам, может ли выбранный метод принести результат. https://www.kaggle.com/dinitrylarko Дмитрий Ларько — гроссмейстер Kaggle в категории Competitions и главный исследователь данных в H20.ai. У Дмитрия более десяти лет опыта в науке о данных и ма- шинном обучении. С Kaggle он познакомился в декабре 2012 г. и через несколько месяцев в первый раз участвовал в конкурсе. Как мы узнаем из интервью, он всегда настаи- вает на важности валидации на соревнованиях. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? В основном я участвовал в конкурсах с табличными данными, но также люблю и соревнования по компьютерному зрению. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я всегда стараюсь сначала построить общий процесс отправки решений и начи- нать с небольших простых моделей. Важный шаг — продумать схему валидации, позволяющую надежно оценивать решения. Всегда стоит также тщательно изу- чать и анализировать данные. Моя обычная работа — построение AutoML-платформы, и многое из того, что я пробовал на Kaggle, я переношу в работу над ней.
150 Часть II. Оттачивание соревновательных навыков Расскажи о каком-нибудь сложном и интересном конкурсе и о том, какие идеи ты использовал в нем Не могу вспомнить ничего конкретного, но это и неважно — сложное для меня может быть легким для других. Технические сложности не так важны, как пони- мание, что конкурс Kaggle — марафон, а не спринтерский забег (ну или, может быть, это много спринтерских забегов подряд). Поэтому важно не выматываться, высыпаться, заниматься спортом, гулять, чтобы мозг оставался в состоянии гене- рировать новые идеи. Для того чтобы победить, вам понадобятся все ваши зна- ния, творческое мышление и немного удачи. Помог ли тебе Kaggle в карьере? Если да, то как? Свою нынешнюю работу я получил благодаря званию гроссмейстера — для ра- ботодателя оно было достаточным доказательством моего профессионализма. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? В основном они не уделяют внимания валидации и ориентируются на публичную таблицу результатов. Обычно это заканчивается плохо и ведет к перетасовке ре- зультатов. Новички также склонны пропускать стадию разведочного анализа и сразу пере- ходить к построению моделей, что приводит их к слишком упрощенным решени- ям и средненьким результатам. Какие ошибки ты допускал на соревнованиях? Моя главная ошибка была типичной для неопытных участников — я ориентиро- вался на таблицу, а не на результаты валидации. Каждый раз это стоило мне не- скольких мест на конкурсе. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Здесь все ожидаемо. Для табличных данных: LightGBM, XGBoost, CatBoost; для глубокого обучения: PyTorch, PyTorch-Lightning, timm; и Scikit-leam для всего. О чем важнее всего помнить, приступая к участию в соревновании? Начинайте с простого, всегда применяйте валидацию, верьте ее результатам, а не таблице. Смещение и разброс Хорошая система валидации дает вам более надежные метрики, чем меры ошибки на обучающем множестве. На значения метрик на обучающем множестве влияют емкость (capacity) и сложность (complexity) модели. Можно думать о емкости как о "памяти" модели, которую она может использовать для обучения. Каждая модель имеет внутренние параметры, позволяющие ей (собственным спо- собом) фиксировать закономерности в данных. Отдельные модели выявляют одни
Глава 6. Построение схемы валидации 151 типы закономерностей, другие модели— иные закономерности. Закономерности гранятся в "памяти" модели. Емкость, или выразительность, модели, также описывают с помощью понятий смещения (bias) и разброса (variance). Сами эти термины относятся к предсказани- ям модели, но лежащие за ними принципы тесно связаны с выразительностью мо- дели. Модель можно рассматривать как математическую функцию, сопоставляющую «оду (наблюдаемым данным) предсказание. Функции разнятся по своей сложно- сти — по количеству параметров и тому, как они используются в вычислениях: • если функция, соответствующая модели, недостаточно выразительна, чтобы учесть сложность решаемой задачи, говорят о смещении— предсказания будут ограничены (смещены) из-за недостаточной выразительности модели; • если эта функция слишком сложна для решаемой задачи, мы имеем дело с проблемой разброса — модель будет учитывать ненужные детали и шум в обучающих данных, что приведет к ошибкам в предсказаниях. Сейчас, с учетом прогресса в машинном обучении и в вычислительных ресурсах, проблемой практически всегда становится именно разброс— самые популярные подели, глубокие нейронные сети и модели градиентного бустинга часто более вы- разительны, чем нужно для решаемых задач. Если учтены все полезные закономерности, которые умеет выявлять данная мо- хль, а емкость модели не исчерпана, модель начинает запоминать не относящиеся I делу характеристики данных (обычно называемые шумом). В то время как зако- юмерности, извлеченные поначалу, обобщаются на тестовые данные и помогают лелать правильные предсказания, затем модель запоминает информацию об обу- «ющем множестве, которая бесполезна и даже портит качество предсказаний. Процесс заучивания закономерностей, которые не обобщаются за пределы обу- вющего множества, называют переобучением (overfitting). Главная цель валидации — определить оценку или значение функции потерь, отде- ющее улучшение обобщающей способности модели от переобучения. За это от- «чает функция потерь при валидации (validation loss), которую вы можете ви- летьнарис. 6.1. Если вы будете отмечать значения функции потерь на оси у и время обучения мо- дели (например, число эпох для нейросетей) на оси х, вы заметите, что результат на йучающих данных постоянно улучшается, но для всех данных в целом это обычно «верно. Го же самое произойдет при других гиперпараметрах, другой предобработке дан- шх или даже другом выборе модели. Форма графиков будет разниться, но всегда яндется та точка, где начинается переобучение. Ее местоположение будет зависеть гт модели и других сделанных вами выборов. Если благодаря хорошей стратегии «лидации вы верно определите эту точку, качество вашей модели будет коррели- ровать с результатами в таблицах — как публичной, так и приватной, и метрики жтидации позволят вам оценить свое решение еще до его отправки.
152 Часть IL Оттачивание соревновательных навыков Рис. 6.1. Улучшение результатов на обучающем множестве не всегда приводит к лучшим предсказаниям Переобучение может происходить на нескольких уровнях: • на уровне обучающих данных, когда модель слишком сложна для данной за- дачи; • на уровне валидационных данных, когда модель слишком активно подстраи- вается под них; • на уровне публичной таблицы результатов, когда результаты не соответству- ют тому, чего вы ожидали при обучении; • на уровне приватной таблицы результатов, когда, несмотря на хорошую по- зицию в публичной таблице, итоговый результат разочаровывает. Во всех этих, хотя и немного разных, случаях ваша модель плохо обобщается на новые данные. Стратегии разделения данных Как мы уже говорили, функция потерь при валидации вычисляется на тех данных, на которых не происходило обучение. Это эмпирический показатель того, насколь- ко хороши предсказания вашей модели, и он более точен, чем оценка на обучаю- щем множестве (большей частью говорящая о том, насколько хорошо модель за- помнила закономерности в обучающих данных). Выбор данных, которые вы будете использовать для валидации, задает валидационную стратегию.
. лдва 6. Построение схемы валидации 153 Для валидации вашей модели вы можете использовать один из двух подходов. • Работать с отложенными данными (hold-out), рискуя отложить нерепрезен- тативную выборку или переобучиться под эти отложенные данные. • Использовать вероятностный подход, случайно выбирая для валидации ряд подмножеств в данных. К разновидностям этого подхода относятся кросс- валидация, контроль по отдельным объектам (leave-one-out, LOO) и бутстрэп (bootstrap). Детали стратегии кросс-валидации зависят от того, как вы выби- раете (семплируете) данные для валидации (простое случайное семплирова- ние, стратифицированное семплирование, кластерное семплирование, сем- плирование по времени). Все эти стратегии основаны на семплировании. В них общая характеристика (ка- чество модели) вычисляется на основании результата на случайно выбранной не- большой части данных. Семплирование лежит в основе статистики, но не является некоторой однозначно заданной процедурой — в зависимости от метода, данных и случая могут происходить ошибки. Так, если вы опираетесь на смещенную выбор- ку, ваша метрика оценивания может принимать значения, большие или меньшие истинного. Однако хорошо продуманная и качественно реализованная стратегия семплирования обычно дает надежные оценки. Кроме того, все эти стратегии основаны на разделении данных — каждый пример относится либо к обучающему множеству, либо к множеству валидации. Так как большинство моделей обладают "памятью", использование одних и тех же приме- ров для обучения и валидации привело бы к завышенным оценкам качества, в то время как мы хотим оценить обобщающую способность модели, качество ее рабо- ты на ранее не виденных примерах. Контроль на отложенных данных Первая стратегия— разбить данные на две части, отложив часть обучающих данных (holdout), и использовать ее для контроля качества моделей, обученных на оставшихся данных. Преимущество этой стратегии — в ее простоте: вы отложили часть данных и проверяете на них свое решение. Обычно разбиение проводят в пропорции 80/20 (обучающих данных, конечно, должно быть больше). В библиотеке Scikit-leam данный метод реализован в функции train_test_split. Об- ратим ваше внимание на следующие ее особенности: • На больших объемах данных вы вправе ожидать, что распределение отло- женных вами данных такое же, как и всего датасета (т. е. контрольная выбор- ка репрезентативна). Однако, т. к. процесс формирования контрольной вы- борки случаен, некоторая вероятность, что она репрезентативной не будет, присутствует всегда. В частности, эта вероятность возрастает при малом ко- личестве данных. Убедиться в правильности своих оценок можно с помощью метода adversarial validation, о котором мы еще поговорим.
154 Часть II. Оттачивание соревновательных навык • Для того чтобы убедиться, что контрольная выборка репрезентативна, осо- бенно в части зависимости целевой переменной от остальных признаке г можно применить стратификацию (чтобы доли значений некоторого при- знака в контрольной выборке соответствовали таковым в данных в целом1 Для этого можно использовать параметр stratify функции train_test_split. значением которого должен быть массив. Важно заметить, что даже при репрезентативной контрольной выборке простое разбиение на обучающую и контрольную выборки не всегда хорошо работает. По- сле многочисленных проверок на контрольной выборке модель может переобу- читься точно так же, как и при следовании за результатами в публичной таблице. По этой причине вероятностные стратегии валидации, хотя и требуют больше вы- числительных ресурсов, работают лучше. Вероятностные методы оценки качества Вероятностное оценивание качества моделей основано на статистических свойст- вах выборки из распределения. Семплирование дает вам подмножество исходных данных, от которого мы ожидаем тех же самых характеристик. Не вошедшие в это подмножество данные также должны иметь то же распределение, что и исходное множество. Обучая и проверяя модель на семплированных данных много раз, вы получаете статистическую оценку качества модели. Каждый семпл может быть не вполне репрезентативным, но при большом их количестве средняя оценка сойдется к истинному среднему той меры, значение которой мы хотим найти (по теореме, известной как закон больших чисел). Вероятностные методы валидации требуют большего количества вычислений, чем одно разбиение на обучающее и контрольное множество, но приводят к более на- дежным оценкам качества модели. Контроль по к блокам Самый распространенный из вероятностных методов валидации — контроль по к блокам (k-fold cross-validation). Он способен достаточно успешно оценивать каче- ство модели на новых данных с тем же распределением. Объяснение можно найти в статье S. Bates, Т. Hastie, R. Tibshirani ’’Cross-validation: what does it estimate and how well does it do it?” (https://arxiv.org/pdf/2104.00673.pdf). Контроль по к блокам может успешно применяться как при сравнении разных мо- делей, так и при выборе гиперпараметров. Он имеет довольно много вариантов, но простейший из них, реализованный в функции KFold библиотеки Scikit-leam, осно- ван на разбиении обучающего множества на к частей. После этого в течение к ите-
Глава 6. Построение схемы валидации 155 раций одна из частей берется в качестве контрольного множества, а остальные ис- пользуются для обучения. Оценка скользящего контроля будет средним от к значе- ний оценки качества. Стандартное отклонение этих оценок будет мерой неопреде- ленности. На рис. 6.2 показана схема контроля по 5 блокам. Блок 1 валидация обучение Блок 2 обучение валидация обучение БлокЗ обучение валидация обучение Блок 4 обучение валидация обучение Блок 5 обучение валидация Рис. 6.2. Схема контроля по 5 блокам Один из важных моментов, касающихся оценки качества по к блокам, — это сред- нее качество моделей, обученных на Л - 1 блоках. Если в дальнейшем вы обучите модель на всех имеющихся данных, эта оценка не будет верной. По мере того, как к приближается к числу примеров п, оценки качества модели будут становиться всё ближе к результату для модели, обученной на всех данных, однако будет расти и корреляция между ними. В итоге вы получите число, характеризующее качество модели на обучающих данных, — все еще полезное при сравнении моделей, но ни- чего не говорящее об их обобщающей способности. При к = п мы получаем метод контроля по отдельным объектам (LOO), полезный при малом числе примеров. Большей частью он дает несмещенную оценку качества ва обучающих данных, поскольку использует для обучения почти все имеющиеся тайные, а для контроля — всего один объект. Тем не менее он плохо предсказывает качество на ранее не встречавшихся данных, т. к. его итерации сильно коррелируют друг с другом. Количество блоков к стоит выбирать, исходя из следующих факторов: • чем меньше к (минимальное возможное значение равно 2), тем больше будет каждый из блоков, и тем большим смещением будет обладать модель, обу- ченная на к - 1 из них, ее качество будет хуже, чем у модели, обученной при большем к, • чем больше к, тем больше данных используется каждый раз при обучении, но тем сильнее корреляция между полученными оценками качества, полезные вероятностные свойства, позволяющие оценить качество на новых данных, больше не будут верны. Обычно к выбирают равным 5, 7 или 10, реже берут 20 блоков. Мы обычно считаем хорошим выбором на соревнованиях к=5 или к= 10— в последнем случае при □бучении каждый раз используется больше данных (90% всех имеющихся), а зна- чит, можно точнее оценить качество модели после обучения на всем датасете.
156 Часть II. Оттачивание соревновательных навыков Когда вы решаете, какое к выбрать для конкретных данных, предлагаем учесть два соображения. Во-первых, выбор количества блоков должен соответствовать вашим целям: • если цель — оценка качества, вам нужно низкое смещение, что достигается большим количеством блоков (обычно от 10 до 20); • если вы хотите подбирать параметры, вам нужен компромисс между значе- ниями смещения и разброса, поэтому обычно используют от 5 до 7 блоков; • если вы просто хотите осуществить отбор признаков в данных, вам нужны низкие значения разброса, поэтому достаточно маленького количества блоков (обычно от 3 до 5). Когда данных достаточно много, можно выбирать нижнюю границу предлагаемых диапазонов. Во-вторых, если вы хотите только оценивать качество, чем больше у вас блоков, тем меньше каждый раз будет множество валидации и тем больше будут коррели- ровать оценки качества при каждом разбиении. После некоторого момента увели- чение к делает итоговую оценку качества менее способной предсказывать результат на новых данных и больше оценивающей качество работы модели на обучающем множестве. Из этого также следует, что при большем числе блоков удобно приме- нять стэкинг (как мы узнаем в главе 9). На конкурсах Kaggle контроль по к блокам нередко используют не только для ва- лидации своих методов и оценки качества модели, но и для построения предсказа- ний. При кросс-валидации вы строите подмножества данных, а усреднение резуль- татов множества моделей, построенных по таким подмножествам, является эффективным способом борьбы с разбросом предсказаний — часто более эффек- тивным, чем обучение на всех имеющихся данных (об этом мы подробнее погово- рим в главе 9). По этой причине многие кэгглеры используют модели, построенные при кросс-валидации, для получения набора предсказаний на тестовом множестве, а затем берут среднее от них. Варианты контроля по к блокам Так как контроль по к блокам основан на случайном семплировании, он может ге- нерировать ’’плохие” разбиения, если: • вам нужно сохранить долю небольших классов как относительно целевой пе- ременной, так и относительно признаков — типичная проблема для несба- лансированных данных. Классическим примером являются данные о спаме (поскольку он составляет небольшую часть от нормальных писем) или о кре- дитных рисках (поскольку дефолт случается относительно редко); • вам нужно сохранить распределение численной переменной (целевой либс одного из признаков) — типичная проблема для задач регрессии с несиммет- ричным распределением либо тяжелыми хвостами. Примером может служить задача предсказания цен на недвижимость (некоторые дома стоят намногс больше среднего);
Глава 6. Построение схемы валидации 157 • ваши примеры не являются независимыми и одинаково распределенными — типичная проблема для задач на временные ряды. В первых двух ситуациях нам поможет стратифицированный контроль по к Спокам, при котором семплирование контролируется таким образом, чтобы сохра- нять нужное распределение. Если необходимо сохранять распределение одной пе- ременной (чаще всего целевой), можно использовать stratifiedKFold из Scikit-leam. Эта функция возвращает набор индексов, помогающий разбить данные. То же са- мое для численной переменной, после ее дискретизации, можно сделать с помощью функции pandas.cut или KBinsDiscretizer из Scikit-leam. Чуть сложнее задача стратификации по нескольким переменным или в случае пере- сечения классов. Решение можно найти в библиотеке Scikit-multileam (http://scikit.ml/). В частности, команда IterativeStratification поможет сохранить поли значений для нескольких переменных (http://scikitml/api/skmultilearn.model_ adection.iterative_stratification.html). Она реализует алгоритм, описанный в статьях: • Sechidis К., Tsoumakas G., Vlahavas I. On the stratification of multi-label data // Machine Learning and Knowledge Discovery in Databases.— 2011.— P. 145— 158. — URL: http://lpis.csd.auth.gr/publications/sechidis-ecmlpkdd-2011.pdf; • Szymanski P., Kajdanowicz T. Proceedings of the First International Workshop on Learning with Imbalanced Domains: Theory and Applications // PMLR. — 2017. — № 74. — P. 22-35. — URL: http://proceedings.mlr.press/v74/szyma% C5%84ski 17a.html. Стратификация может быть полезной не только в задачах классификации, но и в адачах регрессии. Она поможет алгоритму обучаться на том же распределении признаков или целевой переменной, которое встречается в датасете в целом. В этом случае, чтобы StratifiedKFold работал корректно, необходимо ввести вспомогатель- ую дискретную целевую переменную вместо непрерывной. Проще всего это сде- лать с помощью функции cut из библиотеки pandas, взяв достаточно большое коли- чество значений дискретной целевой переменной (например, 10 или 20): i import pandas as pd | y_proxy = pd.cut(y_train, bins=10, labels=False) Для того чтобы определить количество таких значений ("ячеек", bins), передавае- мое в функцию, Абхишек Такур советует использовать правило Стерджеса, осно- ванное на количестве примеров (см. https://www.kaggle.com/abhishek/step-l- create-folds): ’ import numpy as пр | bins = int(np.floor(l + np.log2(len(X_train)))) Альтернативный подход заключается в том, чтобы сосредоточиться на распределе- яи признаков в обучающем множестве и стремиться его воспроизвести. Эта задача требует применения кластерного анализа (относящегося к методам обучения без
158 Часть II. Оттачивание соревновательных навыков учителя) на признаках обучающих данных (исключив целевую переменную и иден- тификаторы). Полученные кластеры используются в стратификации. Пример мож- но увидеть в блокноте https://www.kaggle.com/lucamassaron/are-you-doing-cross- validation-the-best-way, где сначала применяется метод главных компонент, чтобы убрать корреляцию признаков, а затем проводится кластеризация методом к сред- них (k-means). Количество кластеров можно найти эмпирически. Продолжим обсуждение случаев, когда разбиение может оказаться ’’плохим”. Сложности возникают в третьем из описанных выше случаев — когда данные не являются независимыми одинаково распределенными, а, например, образуют груп- пы. В этом случае возникает проблема корреляции признаков и целевой перемен- ной между примерами. Так, если одна и та же группа окажется и в обучающем, и в тестовом множестве, модель может научиться определять группу, а не значение целевой переменной. При этом валидация может показывать хороший результат, но после отправки решения место будет низким. Решение предоставляет GroupKFold: указав группирующую переменную, вы гарантируете, что каждая из групп окажет- ся либо только в обучающем, либо только в контрольном множестве. Обнаружение групп примеров, делающих данные не независимыми одинаково распределенными,— задача нетривиальная. Если в описа- нии конкурса нет явных указаний на наличие таких групп, приходится полагаться на свои способности анализировать данные (используя ме- тоды обучения без учителя, такие как кластерный анализ) и знания о предметной области. Так, если вы анализируете данные об использова- нии мобильных телефонов, по совпадению части значений вы можете догадаться, что некоторые примеры относятся к одному пользователю. При анализе временных рядов мы сталкиваемся с той же проблемой: поскольку данные не являются независимыми одинаково распределенными, вы не можете ис- пользовать простое случайное семплирование (т. к. более поздние данные могут нести ’’следы’’ более ранних — явление, называемое в статистике автокорреляци- ей). При самом простом подходе к валидации для временных рядов вы разбиваете данные на обучающие и контрольные по времени, как на рис. 6.3. обучение валидация тестирование тестирование (публичные данные) (приватные данные) время Рис. 6.3. Разбиение данных на обучающие и контрольные по времени Тем не менее этот способ ограничивает возможности валидации. Для более про- двинутого подхода можно использовать TimeSeriesSplit из библиотеки Scikit-leam
- лава 6. Построение схемы валидации 159 sidearn.model_selection.TimeSeriesSplit). TimeSeriesSplit позволяет установить вре- менные рамки для обучающих и контрольных частей временного ряда. 1>ункция TimeSeriesSplit поможет взять в качестве обучающих данных все данные ж контрольного отрезка времени либо только фиксированный предшествующий зериод (например, три месяца до контрольного отрезка). На рис. 6.4 вы видите схему стратегии валидации с растущим обучающим множе- лвом и сдвигающимся контрольным. тестирование (публичные данные) тестирование (приватные данные) тестирование (публичные данные) тестирование (приватные данные) тестирование (публичные данные) тестирование (приватные данные) время Рис. 6.4. Обучающее множество растет с течением времени обучение валидация тестирование (публичные данные) тестирование (приватные данные) обучение валидация тестирование (публичные данные) тестирование (приватные данные) обучение валидация тестирование (публичные данные) тестирование (приватные данные) время Рис. 6.5. Обучающее и тестовое множества постепенно смещаются На рис. 6.5 вы видите схему, при которой продолжительность периода, соответст- вующего обучению, фиксирована. До нашему опыту, фиксированное окно обучения (и, соответственно, одинаковый ххьем обучающих данных) помогает более точной оценке качества модели. Ис- юльзуя вместо этого растущее обучающее множество, вы не можете отличить, жйствительно ли модель хорошо работает или просто с ростом обучающего мно- жества уменьшается смещение. Наконец, стоит помнить, что TimeSeriesSplit может устанавливать зазор между вре- менем, соответствующим обучающим и контрольным данным. Эта опция особенно жлезна, если известно, что тестовые данные собраны спустя некоторое время (на- пример, месяц) после обучающих, и вы хотите проверить, умеет ли модель загля- дывать настолько далеко.
160 Часть II. Оттачивание соревновательных навыке* Вложенная кросс-валидация Теперь важно упомянуть про вложенную кросс-валидацию. До сих пор мы обсу- ждали только тестирование моделей на их итоговое качество, но зачастую хочето немедленно проверить качество модели при подборе гиперпараметров. Вы не мо- жете проверять выбор параметров, а затем оценивать итоговое качество модели hi одних и тех же контрольных данных. Так как вы нашли именно те параметры, ко- торые лучше всего работают на этих контрольных данных, итоговая оценка на ню же будет чересчур оптимистичной. В этом случае необходимо различать кон- трольное множество, на котором вы сравниваете качество различных моделей i значений гиперпараметров, и тестовое множество, позволяющее оценить итоговое качество модели. Если использовать метод отложенных данных, это достигается разбиением данньг на три части — обучающую, контрольную и тестовую. Обычно соотношение ю размеров 70/20/10 соответственно, но вы можете выбрать и другое. При использо- вании кросс-валидации она будет вложенной (т. е. вы делаете разбиение разбиенш. когда нужно оценивать разные модели с различными параметрами). Пример на рис. 6.6 показывает схему "внутренней" и "внешней" кросс-валидацив Внешняя часть отделяет тестовые данные, используемые для итоговой оценки ks- чества. Во внутренней части обучающие данные внешней части разбиваются к собственно обучающую и контрольную части, помогающие выбрать модель и гв- перпараметры. V валидация обучение обучение валидация обучение обучение валидация Рис. 6.6. Внутренний и внешний циклы вложенной кросс-валидации
Глава 6. Построение схемы валидации 161 Этот подход позволяет надежно подбирать гиперпараметры, но имеет две проблемы: • из-за двух разбиений уменьшается размер обучающего множества; • он требует больших вычислительных ресурсов на построение моделей: если использовать вложенный контроль по 10 блокам, необходимо запустить 100 моделей. В особенности по последней причине некоторые кэгтлеры не пользуются вложен- ной кросс-валидацией и идут на риск переобучения, используя кросс-валидацию одновременно как для подбора модели и параметров, так и для итоговой оценки качества либо используя одни и те же отложенные данные. По нашему опыту, та- кой подход может работать, хотя и приводит к завышенным оценкам качества мо- дели и переобучению, когда одни и те же отложенные данные используются по- вторно (об этом мы еще поговорим в следующем разделе). Мы всегда советуем вам использовать метод, который подходит именно для вашей ситуации. Если вы хоти- те корректно оценить качество модели, использование по возможности вложенной кросс-валидации приведет к меньшему переобучению, что важно в некоторых со- ревнованиях. Предсказания на контрольном множестве При кросс-валидации, помимо оценивания качества, вы делаете предсказания на тестовом и контрольном множествах. Вы обучаетесь на части обучающих данных и делаете предсказания на оставшихся. При этом вы можете получить: • предсказания на тестовом множестве. Среднее предсказание всех моделей часто лучше, чем результат модели, обученной на всех данных. Это одна из разновидностей ансамблевых методов, которые мы будем обсуждать в главе 9; • предсказания на контрольном множестве. После кросс-валидации таким образом вы получите предсказания для всех обучающих примеров, их часто называют out-of-fold (OOF) predictions. Они могут оказаться очень полез- ными. Первый способ использования OOF-предсказаний— применение их для оценки качества модели (метрика оценивания вычисляется на OOF-предсказаниях). Полу- ченная оценка качества будет отличаться от таковой при кросс-валидации (и осно- занной на семплировании); она не обладает теми же вероятностными свойствами, поэтому не является корректным способом измерить обобщающую способность модели, но может служить мерой качества на конкретном обучающем множестве. Второй способ — изобразить графически предсказания и истинные значения либо предсказания различных моделей. Это поможет понять, как работают различные модели и как коррелируют их предсказания. О последнем способе — создании метапризнаков — мы подробно поговорим в гла- « 9, сейчас же только заметим что OOF-предсказания — побочный продукт кросс- валидации и работают потому, что при кросс-валидации модель строит предсказа- ния на тех объектах, которые не видела во время обучения. Так как каждое OOF- тредсказание сделано моделью, обученной на своем множестве данных, они будут
162 Часть IL Оттачивание соревновательных навыков несмещенными и их можно использовать, не боясь переобучения (хотя свои нюан- сы, которые мы обсудим в следующей главе, есть и здесь). OOF-предсказания можно получить двумя способами: • реализовать процедуру, которая собирает сделанные при валидации предска- зания в один вектор, при этом расставляя их в порядке, соответствующем по- рядку примеров в обучающих данных; • использовать функцию cross_yal_predict из библиотеки Skikit-leam. Второй подход мы увидим дальше в этой главе, когда будем рассматривать прием adversarial validation. Случайные разбиения Существуют и другие стратегии валидации, кроме контроля по к блокам, однако они не обладают той же обобщающей способностью. Мы уже обсуждали контроль по отдельным объектам (LOO), являющийся частным случаем контроля по к бло- кам при к = п (где п — число объектов). Другой метод — случайное разбиение — отличается тем, что данные много раз разбиваются в случайной пропорции, часть используется для обучения, а оставшаяся часть — для контроля. Усредняя метрики оценивания по всем таким разбиениям, вы получите оценку качества валидации. Как и при контроле по к блокам, мы хотим, чтобы каждый пример в какой-то мо- мент оказался в контрольном множестве. Для того чтобы такая ситуация имела вы- сокую вероятность, мы должны сделать довольно много попыток разбиения. Кроме того, при недостаточном числе таких попыток одни примеры могут чаще оказы- ваться контрольными, чем другие. Для валидации методом случайных разбиений предназначена функция ShuffleSplit из Scikit-leam. Бутстрэп Наконец, еще одной опцией для оценки качества моделей является применение ме- тода бутстрэпа, придуманного статистиками для исследования распределения ошибок. При бутстрэпе из имеющихся данных генерируется семпл того же размера (возможно, с повторами). Метод бутстрэпа можно применять двумя путями. • Как обычно делают статистики, вы можете семплировать много раз, обучать модель на этом семпле и вычислять значение метрики на исходных обучаю- щих данных. Итоговой оценкой будет среднее этих значений. • Вы также можете использовать сгенерированный семпл для обучения, а ос- тавшиеся примеры — в качестве контрольных данных. По нашему опыту первый путь, часто используемый в статистике для поиска коэф- фициентов линейных моделей и их распределений ошибок, в машинном обучении не столь уж полезен. Причина в том, что многие алгоритмы склонны к переобуче- нию, поэтому даже с бутстрэпом невозможно получить корректное значение мет-
Глава 6. Построение схемы валидации 163 рики на обучающем множестве. По этой причине Эфрон и Тибширани в статье "Улучшения в перекрестной проверке: метод начальной загрузки 632+" предложи- ли в качестве метрики итоговой валидации так называемую метрику 632+1. Поначалу они ввели простой показатель, называемый "бутстрэп 632": Егг^ = 0,368 • егг„, + 0,632 • err, 1тт. ,632 ’ jit ’ bootstrap В этой формуле мы обозначаем метрику качества как err, errfit — ее значение на обучающем множестве, а еггьооип-ар — значение на взятом семпле. При переобуче- нии errf,t, однако, будет стремиться к нулю, делая этот показатель не слишком по- лезным. Поэтому авторы предложили вторую версию бутстрэпа 632+: Егг,632 = (1 - w) • errfil + w • errbootstrap, где 0,632 w =------------; 1-0,632/? R^errbootstrap-errfit Новый параметр у, уровень ошибок при отсутствии информации, оценивается как качество модели на всех возможных комбинациях признаков и целевых пере- менных. Его вычисление, как говорят сами разработчики Scikit-leam, практически невозможно: https://github.com/scikit-learn/scikit-learn/issues/9153. С учетом ограничений и вычислительной невозможности использования "класси- чески-статистического” бутстрэпа в машинном обучении, стоит использовать вме- сто него второй подход — оценивать качество модели на примерах, не попавших в семпл. В таком виде бутстрэп является альтернативой кросс-валидации, но, как и случай- ные разбиения, он требует построения и контроля гораздо большего числа моделей, чем кросс-валидация. Тем не менее о таких альтернативах имеет смысл знать на случай, когда кросс-валидация показывает слишком большой разброс метрики оце- нивания и требуется более тщательная проверка. Этот метод раньше присутствовал в Scikit-leam (https://github.com/scikit-learn/ irikit-learn/blob/0.16.X/sklearn/cross_validation.py#L613), но затем был исключен. Поэтому мы приводим нашу собственную реализацию: import random def Bootstrap(n, n_iter=3, random_state=None): Случайная выборка с заменяющим генератором кросс-валидации. Efron, В., Tibshirani R. Improvements on cross-validation: the 632+ bootstrap method 11 J. Am. Stat. Asso- hation. — 1997. — № 92.438. — P. 548-560.
164 Часть II. Оттачивание соревновательных навыков Для каждого значения iter генерируется семпл бутстрэпа с индексом [0, п), а функция возвращает полученную выборку и список всех исключенных индексов. IIIIII if random_state: random.seed(random_state) for j in range(n_iter): bs = [random.randint(0, n-1) for i in range(n)] out_bs = list({i for i in range(n)} - set(bs)) yield bs, out_bs Итак, бутстрэп действительно является альтернативой кросс-валидации, хотя его гораздо больше используют в статистике и финансах, а в машинном обучении ’’зо- лотым стандартом” является контроль по к блокам. Тем не менее мы советуем не забывать про бутстрэп в ситуациях, когда из-за наличия выбросов или некоторой группы примеров, непохожей на данные в целом, метрика кросс-валидации имеет большое стандартное отклонение. В этом случае бутстрэп окажется более подхо- дящим для валидации. Райан Чеслер https://www.kaggle.com/ryches Второе интервью в этой главе— с Райаном Чеслером, гроссмейстером в категории Discussions и мастером в кате- гориях Notebooks и Competition. Он работает исследовате- лем данных в H20.ai и является одним из организаторов San Diego Machine Learning group в Meetup (https://www.meetup.com/San-Diego-Machine-Learning/). В ответах на несколько вопросов он говорил о важности валидации. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я люблю пробовать совершенно разные конкурсы. Гораздо интереснее решать непохожие друг на друга задачи, чем специализироваться в узкой области вроде компьютерного зрения или обработки естественного языка. Самые интересные дня меня конкурсы — те, где можно делать нетривиальные выводы из данных и ошибок предсказаний. Для меня анализ ошибок — один из самых полезных про- цессов для решения задачи. Нужно понять, где модель работает не так, и попро- бовать найти способ с этим справиться— изменив модель или представление данных.
Глава 6. Построение схемы валидации 165 Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Мой подход и там и там одинаков. Многие предпочитают проводить разведоч- ный анализ данных до моделирования, но на мой взгляд, подготовки данных для построения модели обычно достаточно. Мой типичный подход — вручную про- смотреть данные и предварительно определить модели и методы, которые стоит попробовать. После этого я строю модель, оцениваю ее качество, а затем анали- зирую ошибки и на основании этого анализа продумываю следующие шаги в мо- делировании. Помог ли тебе Kaggle в карьере? Если да, то как? Да, благодаря Kaggle я получил свою нынешнюю работу. Я работаю в компании Н2О, где очень ценятся достижения на Kaggle. На прошлой работе тоже были довольны моими успехами на соревнованиях. Ты также организуешь в Сан-Диего встречи, посвященные машинному обучению, в вашей группе более 2 тыс. участников. Связано ли это с твоим опытом на Kaggle? Да, безусловно. Начиная участвовать в конкурсах, я знал очень мало и поначалу выступал не слишком удачно. Я сходил на местную встречу увлеченных машин- ным обучением и там нашел тех, у кого мог учиться и с кем мог объединиться в команду. Я смог поработать с людьми гораздо более высокого уровня и вместе мы стали третьими среди более чем четырех с половиной тысяч команд — дейст- вительно прекрасный результат. Потом группа перестала регулярно собираться, а мне хотелось, чтобы встречи продолжались. Поэтому я собрал собственную команду и стал организовывать свои мероприятия, и сейчас я делаю это уже почти четыре года. Теперь уже я учу других и помогаю им начать свой путь. Сначала мы только обсуждали конкурсы Kaggle и искали сокомандников, но потом стали организовывать лекции и книж- ные клубы по различным темам. Думаю, своими успехами я в большой мере обя- зан этому времени, каждую неделю выделяемому на обучение. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? По моему опыту, многие переоценивают важность компромисса между смеще- нием и разбросом и переобучения. Я регулярно вижу людей, которые слишком об этом беспокоятся. Между тем стоит стремиться не к тому, чтобы качество на обучении и контроле совпадало, а к тому, чтобы качество на контроле было как можно лучше. Какие ошибки ты допускал на соревнованиях? Моей постоянной ошибкой было не пробовать все варианты. Иногда я слишком рано отказывался от хороших идей. Зачастую я с первой попытки получал доста- точно приличный результат, но его дальнейшее постепенное улучшение требует немного других навыков, над которыми я еще работаю.
166 Часть IL Оттачивание соревновательных навыку Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я использую многие из стандартных инструментов: XGBoost, LightGBM, Pytorch, TensorFlow, Scikit-leam. Однако я не привязываюсь к одному любимому инстру- менту или библиотеке, а использую то, что подходит к данной задаче. О чем важнее всего помнить, приступая к участию в соревновании? Думаю, важнее всего помнить о валидации. Очень часто я вижу людей, убедив- ших себя, что качество их модели выросло, а затем, после отправки решения, уз- навших, что это не так. Очень важно понимать, какие предположения о новых данных допустимы, и строить модель, надежно на них работающую. Настройка системы валидации К этому моменту вы знаете о всех стратегиях валидации. На соревновании вы вы- бираете и реализуете одну из них. Затем нужно проверить свой выбор. При построении стратегии валидации стоит руководствоваться следующей идеен попробуйте воспроизвести подход, по которому организаторы делили данные ш обучающее и тестовое множества. Подумайте, как они могли осуществлять это раз- биение. Брали случайный семпл? Стремились сохранить некоторое распределение' Совпадают ли распределения обучающих и тестовых данных? В реальных проектах вы не будете задаваться такими вопросами. В отличие от ре- альных задач, для которых главнейшее— обобщающая способность модели, вг соревнованиях вы должны построить модель, которая работает как можно лучше на тестовом множестве (в особенности его приватной части). Помня об этом с самок начала, вы с большей вероятностью найдете наилучшую стратегию валидации е сможете занять более высокое место. Выбор стратегии валидации происходит путем проб и ошибок, и в нем стоит сис- тематически проверять два условия. 1. Во-первых, результаты валидации должны быть согласованы между собой — ошибки кросс-валидации при выборе различных контрольных блоков или раз- ных отложенных подмножеств должны быть близки. 2. Во-вторых, они должны быть согласованы с результатами в публичной таблице. Первое условие может не выполняться по следующим причинам: • слишком мало обучающих данных; • данные слишком разнородны и при каждом разбиении обучающие множества сильно различаются по свойствам (например, если есть много признаков с большим количеством различных значений, вроде почтовых индексов, или при наличии выбросов по разным признакам).
Diaea 6. Построение схемы валидации 167 В обоих случаях вашей модели, по сути, не хватает данных. Даже если кажется, что дело просто в их разнородности, если нарисовать кривую обучения, станет ясно, что модели нужно больше данных. Возможно, выяснится, что переход к более простой модели (при котором мы жерт- вуем маленьким смещением в обмен на маленький разброс) не ухудшает качество решения. Если же такого не происходит, стоит потратить больше ресурсов на вали- дацию, например: • брать большее количество блоков к (в пределе это метод LOO с к = и). Хотя тогда результаты валидации будут хуже оценивать обобщающую способ- ность модели, но из-за больших размеров обучающих множеств станут более согласованными между собой; • усреднять результаты многократного контроля по к блокам (с разной инициа- лизацией генератора случайных чисел, чтобы получить разные разбиения на блоки); • применить повторный бутстрэп. Надо учесть, что вы наверняка не единственный, кто столкнулся с нестабильными результатами валидации, обычно это общая проблема, связанная с природой дан- ных. Вы можете найти на форуме идеи, как с ней справиться. Так, различные мето- ды целевого кодирования решают проблему признаков с большим числом значе- ний, стратификация поможет при наличии выбросов и т. д. Другое дело, если выполняется первое из условий, но не выполняется второе, т. е. локальная кросс-валидация дает согласованные между собой значения, но они не согласуются с таблицей результатов. Для того чтобы обнаружить такую проблему, необходимо аккуратно записывать все свои эксперименты, методы валидации, на- чальные состояния (seeds) генератора случайных чисел и результатов в таблице по- сле отправки решения. После этого можно построить диаграмму рассеивания (scatterplot) локальных результатов валидации и соответствующих результатов в публичной таблице и попробовать построить линейную регрессию или просто най- ти корреляцию. Такой анализ требует времени и терпения, но позволяет делать важные выводы о своих соревновательных результатах. Если расхождение между итогом валидации и результатом в таблице системати- ческое — один из этих показателей все время оказывается больше другого — мож- но сделать вывод, что в вашей стратегии валидации есть проблемы, но они не ме- шают улучшать модель. Фактически, вы можете продолжать работу над моделью и ожидать, что повышение ее качества отразится в таблице результатов, хотя, быть может, и не пропорционально локальным изменениям. Тем не менее систематиче- ское расхождение всегда будет знаком того, что ваш способ контроля качества от- личается от предполагавшегося организаторами. Гораздо хуже, если локальные результаты валидации вообще не коррелируют с ре- зультатом в таблице. Это серьезный звоночек, что что-то пошло не так и необходи-
168 Часть II. Оттачивание соревновательных навыков мо немедленно выяснить, в чем проблема, потому что независимо от того, насколь- ко она общая, она может сильно повлиять на вашу итоговую позицию. Вариантов может быть несколько. • Тестовые и обучающие данные имеют разное распределение. Помочь в этой ситуации может метод adversarial validation (который мы обсудим в следую- щем разделе). • Данные не являются независимыми одинаково распределенными, но это не ука- зано явно. Так, на конкурсе по определению видов рыб The Nature Conservancy Fisheries Monitoring (https://www.kaggle.com/c/the-nature-conservancy-fisheries- monitoring) изображения из обучающего множества были сняты на одних и тех же рыболовецких судах, и необходимо было понять, как идентифициро- вать рыбу, а не окружающую обстановку (советуем обратить внимание на блокнот пользователя Anokas: https://www.kaggle.com/anokas/finding-boatids). • Многомерное распределение признаков одинаково, но некоторые группы в тестовом множестве распределены иначе. Если вы обнаружите эти различия, то можете соответствующим образом поделить данные на обучающее и кон- трольное множества. Для этого пригодится зондирование таблицы резуль- татов. • Тестовые данные имеют некоторое смещение по отношению к обучающим или продолжают некий тренд (обычно эта ситуация встречается в задачах временных рядов). В этом случае опять же стоит зондировать таблицу ре- зультатов в поисках идей для постобработки, например умножения ваших ре- зультатов на некоторое число, тем самым имитируя имеющийся тренд. Как мы уже говорили, зондирование таблицы — это отправка решений, специально ориентированных на выявление информации о публичном тестовом множестве. Оно приносит хорошие результаты, если публичное и приватное тестовые множе- ства обладают одинаковыми свойствами. Для зондирования нет универсальных ме- тодов, так что вам придется придумать собственную стратегию, подходящую для конкретного конкурса. Так, в статье ’’Climbing the Kaggle Leaderboard by Exploiting the Log-Loss Oracle” (https://export.arxiv.org/pdf/1707.01825) рассказывается, как занять на конкурсе четвертое место, даже не скачав обучающие данные. Что касается задач регрессии, в недавно организованной программе "30 дней ма- шинного обучения" (30 Days of ML) Хун Хой (Hung Khoi) рассказывал, как зонди- рование таблицы помогло ему выявить разницу в средних значениях и дисперсии целевой переменной между обучающими и публичными тестовыми данными (см. https://www.kaggle.eom/c/30-days-of-ml/discussion/269541). Для этого он использовал уравнение2: RMSE2 = MSE = variance + {mean - guessedvalue )2. 2 RMSE— среднеквадратичная ошибка, MSE— средний квадрат ошибки, variance— дисперсия. mean — среднее значение, guessedvaiue — предполагаемое значение. — Прим. ред.
Глава 6. Построение схемы валидации 169 По сути, у вас есть две неизвестных величины (среднее и дисперсия), поэтому для решения системы уравнений необходимы всего две отправки решений. Также можно почерпнуть некоторые идеи по зондированию таблицы у Криса Деот- та (Chris Deotte, https://www.kaggle.com/cdeotte) в посте https://www.kaggle.com/ cdeotte/lb-probing-strategies-0-890-2nd-place, относящемся к конкурсу Don 7 Overfit II (https://www.kaggle.eom/c/dont-overfit-ii). У зондирования, однако, есть и оборотная сторона. Так, Захар Чикишев, *—применяя его на конкурсе по предсказанию землетрясений LANL Earthquake Prediction, занимал первое место в публичной таблице ре- зультатов, но в итоге опустился на 87-е: https://towardsdatascience.com/ how-to-lb-probe-on-kaggle-c0aa21458bfe. Применение adversarial validation Как мы уже говорили, кросс-валидация позволяет вам протестировать обобщаю- щую способность модели (если новые данные взяты из того же распределения, что и обучающие). Так как на конкурсах Kaggle цель — создание модели, хорошо рабо- тающей на публичных и приватных тестовых данных, обычно можно надеяться, что эти тестовые данные имеют то же распределение, что и обучающие. К сожале- нию, это происходит не всегда. Даже избежав переобучения, при котором ваша модель подстраивается под тесто- вые данные (для чего необходимо опираться не только на результаты в таблице, но и на итоги кросс-валидации), вы все равно можете столкнуться с сюрпризами при подведении итогов. Это может произойти даже при небольших различиях между обучающими и тестовыми данными. Распределение целевой переменной в обу- чающем множестве и то, как ее значения соотносятся со значениями признаков, задает модели некоторые ожидания, которые при другом распределении тестовых данных не будут выполняться. Таким образом, недостаточно избежать подстройки под таблицу результатов, надо перед этим выяснить, похожи ли обучающие и тес- товые данные. Если они различаются, необходимо понять, можно ли как-то умень- шить воздействие этих различий и создать модель, способную работать на тестовых данных. Для того чтобы оценить различия между обучающими и тестовыми данными, и был придуман метод adversarial validation. Долгое время кэгглеры рассказывали о нем друг другу лично, для широкой же аудитории его опубликовал Зыгмунт Заяц iZygmunt Zaj^c, https://www.kaggle.com/zygmunt) в своем блоге FastML Идея метода проста: возьмите обучающее множество, удалите целевую перемен- ную, объедините его с тестовым множеством и попробуйте построить бинарный
170 Часть II. Оттачивание соревновательных навыков классификатор, отличающий элементы тестового (положительный класс) и обу- чающего множеств. Оцените полученный классификатор по метрике ROC-AUC, которую мы обсуждали в предыдущей главе. Если получилось значение, близкое к 0,5, это означает, что обучающие и тестовые примеры различить сложно и, по-види- мому, они происходят из одного распределения. Значения, приближающиеся к 1,0, сообщают нам, что различить два множества легко, они, видимо, происходят из разных распределений, и в этом случае не приходится ожидать легкого обобщения обученной модели на тестовое множество. Примером может служить блокнот, созданный для конкурса Сбербанка Sberbank Russian Housing Market (https ://www.kaggle.com/c/sberbank- russian-housing-market), посвященного рынку жилья. В нем на практике / konradb/adversarial-validation-and-other-scary-terms. Так как данные могут относиться к разным типам (численные или категориальные, последние часто записаны в строковом виде) и, кроме того, содержать пропущен- ные значения, перед запуском классификатора обычно требуется их обработка. Мы советуем использовать в качестве алгоритма классификации случайный лес, по- скольку: • его результаты, не являясь настоящими вероятностями, интерпретируются как порядковые значения, что пригодится при вычислении ROC-AUC; • это очень гибкий алгоритм, основанный на деревьях принятия решений. Он способен проводить отбор признаков и работать с их разными типами, устой- чив к переобучению и не требует длительной настройки гиперпараметров; • из-за своей ’’древесной” природы он требует минимальной предварительной обработки данных. Вы можете, в частности, просто заменить отсутствующее значение отрицательным числом вроде -999, не встречающимся в нормаль- ных данных, и закодировать строки числами (например, используя sklearn.preprocessing.LabelEncoder). Этот способ кодирования обычно работает несколько хуже, чем one-hot encoding, но он хорош для ’’древесных" алгорит- мов и, кроме того, очень быстр. Хотя построение классификатора — самый простой из способов adversarial validation, существуют и другие. В частности, можно найти отображение как обу- чающих, так и тестовых данных в пространство меньшей размерности (как в посте https://www.kaggle.com/nanomathias/distribution-of-test-vs-training-data) от Nano- Mathias (https://www.kaggle.com/nanomathias). Хотя этот подход (основанный на таких алгоритмах, как t-SNE и РСА) требует большего времени для настройки, он обладает большим преимуществом— представимостью в красивом и понятном
Гпава 6. Построение схемы валидации 171 графическом виде. Стоит помнить, что наш мозг лучше приспособлен для работы с визуальными образами, чем с числами (подробное обсуждение этих его способно- стей можно найти на https://onlinelibrary.wiley.com/doi/full/10.1002/qua.24480). РСА и t-SNE не единственные инструменты, которые могут уменьшить размерность ваших данных и позволить их визуализировать. Так, UMAP (https://github.com/lmcinnes/umap) зачастую способен быстро дать решение небольшой размерности с четко выделенными кластера- ми. Вариационные автокодировщики (которые мы обсудим в главе 7) могут производить нелинейное понижение размерности, давая часто более полезное представление данных, чем РСА. При этом, однако, их сложнее обучить и настроить. Пример реализации Хотя вы можете найти примеры adversarial validation в статье Зыгмунта и в Notebook, на которые мы ссылались, мы также создали для вас новый пример на основе зада- чи с конкурса Tabular Playground Series— Jan 2021 (https://www.kaggle.eom/c/ tabular-playground-series-j an-2021). Сначала мы импортируем библиотеки и загружаем данные: import numpy as пр import pandas as pd from sklearn.ensemble import RandomForestClassifierDesigning Good Validation from sklearn.model_selection import cross_val_predict from sklearn.metrics import roc_auc_score train = pd.read_csv("../input/tabular-playground-series-jan-2021/train.csv") test = pd.read_csv("../input/tabular-playground-series-jan-2021/test.csv") Подготовка данных не занимает много кода. Так как все признаки являются число- выми, их не нужно кодировать в каком-то ином виде, однако придется заменить пропущенные значения отрицательными числами (подойдет -1), удалить целевую переменную и идентификаторы (при последовательных идентификаторах мы полу- чили бы большое значение ROC-AUC): train = train.fillna(-l).drop(["id", "target"], axis=l) test = test.fillna(-l).drop(["id", axis=l]) X = train.append(test) у = [0] * len(train) + [1] * len(test)
172 Часть II. Оттачивание соревновательных навыков Теперь достаточно получить предсказания RandomForestClassifier с помощью функ- ции cross_val_predict, автоматически создающей схему кросс-валидации и сохра- няющей предсказания на контрольном множестве: model = RandomForestClassifier() cv_preds = cross_val_predict(model, X, у, cv=5, n_jobs=-l, method='predict_proba') В итоге вы получите несмещенные предсказания без переобучения (поскольку вы не делаете предсказания на тех же данных, на которых обучались), которые можно использовать для оценки ошибок. Заметим, что cross_val_predict не обучает модель на всех данных, так что вы не узнаете, например, какие признаки использует ваша модель. Это можно сделать с помощью функции model.fit(х, у). Наконец, вы можете вычислить показатель ROC-AUC: print (гос_аис_5соге(у^гие=ул y_score=cv_preds[: 31])) Вы должны получить значение в районе 0,49-0,50 (если вы не задаете начальное значение случайного генератора, функция cross_val_predict работает недетермини- рованно). Это означает, что вы не можете легко отличить обучающие и тестовые примеры, и, значит, они происходят из одного распределения. Различные распределения обучающих и тестовых данных Значения ROC-AUC от 0,8 и выше говорят вам, что тестовое множество весьма своеобразно и отличается от обучающего. Что делать в этом случае? Существует несколько стратегий: • подавление (suppression); • обучение на примерах, наиболее схожих с обучающим множеством; • валидация с имитацией тестового множества. Метод подавления состоит в том, что вы удаляете признаки, наиболее помогшие классификатору при adversarial validation, до тех пор, пока не приходите к одинако- вым распределениям. Делается это итеративно. Вы обучаете модель на всех имею- щихся данных, смотрите на важность признаков (с помощью, например, метода feature_importances_ классификатора RandomForest из Scikit-leam) и показатель ROC- AUC. Вы удаляете самый важный признак и повторяете все заново — обучение, измерение ROC-AUC и удаление самого важного признака— до тех пор, пока ROC-AUC не станет близок к 0,5. Единственная проблема этого метода состоит в том, что вы можете быть вынужде- ны удалить большинство важных признаков, так что любая построенная по остав- шимся признакам модель будет неспособна давать сколь-нибудь точные прогнозы.
Глава 6. Построение схемы валидации 173 При обучении на примерах, похожих на тестовое множество, вы выбираете не часть всех признаков, а часть (подмножество) всех объектов — такую, что ее рас- пределение совпадает с распределением тестовых данных. Модель, обученная на таком подмножестве, будет хорошо работать на тестовых данных (но ее обобщаю- щая способность будет низкой). Применимость этого подхода ограничена из-за то- го, что размер обучающего множества сокращается и из-за недостатка примеров предсказания могут быть сильно смещенными. В нашем предыдущем примере вы- бор только тех объектов обучающего множества, которым классификатор при adversarial validation присвоил вероятность положительного класса более 0,5 (’’при- нял их за тестовые”), дает всего 1495 таких объектов (поскольку обучающие и тес- товые данные различаются не сильно): print(np.sum(cv_preds[:len(X), 1] > 0.5)) Наконец, при валидации с имитацией тестового множества вы обучаетесь на всех имеющихся данных, но в качестве контрольного множества берем только те объекты, которым классификатор при adversarial validation присвоил вероятность положительного класса более 0,5 (а иногда выбирают и более высокий порог, такой как 0,9). Это позволит выбрать модель и гиперпараметры, способные достичь наи- лучшего конкурсного результата. В нашем примере наиболее отличающимися признаками в обучающем и тестовом множествах окажутся признаки feature_19 и feature_54: model.fit(X, у) ranks = sorted(list(zip(X.columns, model.feature_importances_))j key=lambda x: x[l], reverse=True) for feature, score in ranks: print(f"{feature:10} : {score:0.4f}") В завершение сделаем еще несколько замечаний об adversarial validation. Во- первых, хотя использование этого метода часто помогает на соревнованиях, иногда он бесполезен. В первую очередь это относится к соревнованиям типа Code и к другим случаям, когда у вас нет доступа ко всему тестовому множеству. Кроме то- го, данный метод может дать вам информацию о тестовых данных в целом, но не об их разбиении на публичные и приватные, которое чаще всего является причиной переобучения и перестановок в таблице результатов. Наконец, хотя метод adversarial validation разработан специально для соревнований, ему можно найти и применение в реальных задачах: вспомните, сколько раз вы вы- бирали не то контрольное множество для вашей модели. Данный метод поможет понять, правильно ли вы пользуетесь контрольными данными. Кроме того, иногда данные меняются, и без повторного обучения имеющиеся модели начинают давать плохие предсказания (явление, известное как concept drift). С помощью adversarial validation можно быстро понять, необходимо ли повторное обучение.
174 Часть II Оттачивание соревновательных навыков Джулиано Янсон https://www.kaggle.com/adjgiulio Джулиано Янсон — гроссмейстер в категории Competitions и старший научный сотрудник в области машинного обу- чения и обработки естественного языка в компании Zillow Group. Мы поговорили с ним о победах на соревнованиях, важности кросс-валидации и утечках в данных (которые станут темой следующего раздела). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Идеальное соревнование, на мой взгляд, имеет три составляющих: а) интересную задачу; б) датасет среднего размера — достаточно большой, чтобы можно было избежать переобучения, но не настолько большой, чтобы не влезть в память, и в) возможность творческого преобразования признаков. Такие конкурсы дают мне возможность показать свои лучшие результаты, поскольку позволяют про- явить логику и творческие способности, но не давят чисто техническими ограни- чениями. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Любой конкурс на Kaggle— это марафон. Регистрируясь на соревнования, я знаю, что от 90 до 95% итогового результата будет достигнуто за пару дней ра- боты, но затем необходимо упорное медленное продвижение дальше. Единст- венное мерило успеха — результат в таблице. Моя ежедневная работа скорее похожа на серию спринтерских забегов, в кото- рых я должен учитывать не только и не столько качество работы модели. Может играть роль скорость работы, интерпретируемость, масштабируемость, усилия по поддержке. На каждом этапе могут пересматриваться приоритеты, так что ко- нечный продукт может разительно отличаться от изначально задуманного. Более того, создание моделей занимает лишь небольшую часть моего рабочего дня. Го- раздо больше времени я провожу, разговаривая с людьми, расставляя приорите- ты и думая о том, как превратить прототип в успешно работающее продуктовое решение. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Один из двух выигранных мною конкурсов — Genentech Cancer, посвященный проведению скрининга на рак шейки матки. Данные были предоставлены в сы- ром неструктурированном виде, не было красивой общей таблицы, но я как раз люблю работу по выделению и преобразованию признаков. Так как к моменту своего участия в конкурсе я уже десять лет работал в сфере здравоохранения, я многое понимал про имеющиеся данные и, кроме того, про технические нюансы работы с неструктурированными данными. Последнее оказалось ключом к побе-
Глава 6. Построение схемы валидации 175 де — одна из сразу появившихся гипотез о возможной утечке в данных оказалась верной. После этого конкурса я понял, как важно быть аккуратным при преобра- зовании признаков и валидации. Утечки в данных очень сложно отследить, и обычный подход к валидации моделей в этом не помогает — в итоге модель пло- хо работает в реальности. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle помог мне в двух аспектах. Во-первых, это удобная точка входа в совре- менное машинное обучение, позволяющая познакомиться с самыми передовыми техниками моделирования и разобраться в науке (а отчасти искусстве) валидации моделей. Во-вторых, на Kaggle собираются лучшие умы прикладного машинного обучения. Я очень ценю уроки, извлеченные из совместной работы с топовыми кэгглерами, и стараюсь делиться ими. Ты создавал портфолио с помощью Kaggle? Kaggle не повлиял напрямую на мою карьеру в том смысле, что я не получал предложения о работе или приглашения на интервью из-за своих результатов на конкурсах. Я начал участвовать в соревнованиях, будучи уже старшим исследо- вателем данных, хотя в основном занимался не машинным обучением. Благодаря изученному на Kaggle я смог перейти на работу, сфокусированную именно на этой области. Многие из моих коллег интересуются соревновательным машинным обучением и спрашивают меня о моем опыте на Kaggle, но правда и то, что многие специали- сты по ML даже не знают, что такое Kaggle. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Новички часто недооценивают важность кросс-валидации. Хорошая стратегия кросс-валидации позволяет надежно и объективно отслеживать изменение каче- ства модели. На соревнованиях, отдельные из которых длятся до полугода, луч- шие модели обычно получаются не у тех, у кого с самого начала была лучшая идея, а у тех, кто готов дорабатывать и настраивать их в соответствии с эмпири- ческими результатами. Основой для этого служит валидация. Какие ошибки ты допускал на соревнованиях? Один из уроков, которым я всегда делюсь с новичками, — не увлекаться слиш- ком сложными идеями. Столкнувшись с новой и сложной задачей, легко под- даться соблазну искать сложное решение. Однако такие решения требуют много времени и, главное, часто не сильно превосходят более простые и базовые. Пред- ставьте, что вам нужно предсказать результат выборов и вы начинаете думать о признаках, которые бы учитывали сложное взаимодействие между явными и скрытыми географическими, социально-экономическими и временными факто- рами. Вы можете провести так недели, считая, что столь тщательно обдуманные признаки действительно окажутся важными. Однако они могут не давать пре- имущества в сравнении с более простыми признаками и моделью, способной улавливать взаимодействие между ними. Поэтому я советую придерживаться бритвы Оккама и пробовать простые подходы до того, как переходить к сложным.
176 Часть II. Оттачивание соревновательных навыков Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я постоянно пользуюсь pandas и Scikit-leam. Мне нравится то, как pandas позво- ляет легко работать с данными, и то, как благодаря Scikit-leam можно за считан- ные минуты создавать прототипы моделей. Большая часть моей работы над про- тотипами происходит с использованием этих двух библиотек. Тем не менее итоговые модели часто основаны на XGBoost. Для глубокого обучения мне нра- вится Keras. Работа с утечками в данных Нередкая ситуация на конкурсах Kaggle, влияющая на результаты, — утечка в дан- ных. Это явление, иногда выступающее под более вычурными названиями (напри- мер, ’’золотые признаки”), заключается в наличии при обучении информации, кото- рая будет недоступна при реальном тестировании. Утечка позволяет модели показывать очень хорошее качество при обучении и тестировании на конкурсе, за- нимать высокие места, но с точки зрения спонсора решение на основе такой модели будет бесполезным или по крайней мере неоптимальным. Утечку можно определить как ситуацию, когда ’’информация, раскры- вающая правильный ответ, искусственно и ненамеренно внесена в при- знаки обучающих данных или в метаданные обучающего множества”. Такое определение было введено Майклом Кимом (Michael Kim, https://www.kaggle.com/mikeskim) на конференции Kaggle Days в Сан- Франциско в 2019 г. Несмотря на проверки, проводимые как спонсорами, так и командой Kaggle, утечки в данных обнаруживаются довольно часто. Поймать утечку сложно, но то и дело кто-то из большого количества кэгглеров, ищущих все пути улучшить свой резуль- тат, находит ее. Не путайте утечки в данных (data leakage) с протекающей (leaky) стра- тегией валидации. Протекание стратегии валидации — проблема, при которой благодаря наличию дополнительной информации завышены оценки на контрольном множестве. Это проблема не данных конкурса как таковых, а конкретной стратегии валидации, и может происходить, например, при предобработке данных (нормализации, понижении раз- мерности, заполнении пропусков в данных) перед разделением на обу- чающие и контрольные данные.
шва 6. Построение схемы валидации 177 Для того чтобы предотвратить протекание валидации, при использова- нии Scikit-leam необходимо исключать контрольные данные перед применением операций, связанных с изменением параметров модели (fitting)— fit() и fit_transform(). Лучше всего это делать с помощью конвейеров (Scikit-leam pipelines, https://scikit-learn.org/stable/modules/ generated/sklearn. pipeline.Pipeline.html), объединяющих обработку данных и модель, что позволяет избегать применения к данным ’’проте- кающих” преобразований. Утечка в данных же не обязательно связана с валидацией, но оказывает воздействие на ее результат. Хотя эта глава в основном посвящена стратегиям валидации, мы все же сочли необходимым поговорить здесь об утечках, поскольку они могут очень сильно влиять на оценку качест- ва модели и на способность модели к обобщениям. Вообще говоря, утечки могут возникать на уровне признаков или на уровне объ- ектов. Первый вариант более распространен. Он может возникать из-за того, что некоторый признак однозначно определяет целевую переменную (target proxy) или, наоборот, зависит от нее. Так, от значений целевой переменной может зависеть присвоение идентификаторов, что значительно упрощает работу модели. Более тонкая причина утечек — совместная предобработка обучающего и тестового мно- жеств организаторами. В истории Kaggle известны утечки по следующим причинам: 1. Организаторы допустили ошибки при предобработке данных (например, работая совместно с обучающими и тестовыми данными). Примером может служить конкурс Loan Default Prediction (https://www.kaggle.eom/c/loan-default-prediction), организаторы которого поначалу включили в число признаков сводные данные за все время. 2. Порядок строк в таблице связан с течением времени или с разбиением объектов на группы. Так, на конкурсе Telstra Network Disruptions (https://www.kaggle.com/ c/telstra-recruiting-network) порядок записей зависел от местоположения и ока- зался очень важным для предсказаний. ?. Порядок признаков связан с течением времени. 4. Признаки повторяются в идущих друг за другом строках, поскольку эти приме- ры могут быть связаны, как на конкурсе Bosch Production Line Performance (занявшее первое место решение участника Beluga можно посмотреть на https://www.kaggle.eom/c/bosch-production-line-performance/discussion/25434). 5. Нужная информация содержится в метаданных изображений, как на конкурсе Two Sigma Connect: Rental Listing Inquiries (https://www.kaggle.com/cZtwo-sigma- connect-rental-listing-inquiries). 5. Применяется один из легко взламываемых способов хеширования, анонимиза- ции или присвоения идентификаторов.
178 Часть II. Оттачивание соревновательных навыков Проблема апостериорной информации возникает из-за того, что мы не учитываем течение времени и причинно-следственные связи между различными признаками. Работая с информацией о прошлом, мы часто забываем, что некоторые известные нам на данный момент величины не были известны на тот момент. Так, если вы хотите вычислить кредитный рейтинг компании, информация о задержках плате- жей является важным индикатором риска, но вы не сможете узнать об этом до вы- дачи кредита. Анализируя базы данных о разных компаниях, вы также зачастую обнаружите, что имеете данные о текущей, а не прошлой ситуации. Восстановле- ние информации, имевшейся в прошлом, может оказаться сложной задачей. Поэто- му стоит тщательно проверять наличие протекающих признаков и исключать их из рассмотрения либо корректировать до построения модели. Аналогичные проблемы возникают и на соревнованиях с подобными источниками данных (например, банковскими или страховыми), хотя, благодаря усилиям орга- низаторов по подготовке данных, они более трудноуловимы. В обычной жизни протекающие признаки обнаружить легко, поскольку они сильно коррелируют с целевой переменной, и эксперт в предметной области часто может объяснить при- чину (зная, например, когда данные попадают в базу). На соревнованиях такие оче- видные протекающие признаки не встречаются, однако могут остаться их ускольз- нувшие от контроля организаторов производные. Они порой теряются среди остальных признаков, анонимизированных для защиты информации. Участники стремятся, комбинируя имеющиеся признаки, вытащить на свет эти "золотые", или "волшебные", признаки. В посте Кори Левисона (Corey Levison, https://www.linkedin.com/pulse/ winning-13th-place-kaggles-magic-competition-corey-levinson/) можно прочитать, как конкурс Santander Customer Transaction Prediction для его команды превратился в охоту за "волшебными" признаками. Другой хороший пример рассказан пользователем dune_dweller в посте https://www.kaggle.com/c/telstra-recruiting- network/discussion/19239#l09766. Обратив внимание на порядок дан- ных, dune dweller понял, что, скорее всего, они упорядочены по време- ни. Сконструировав новый признак, он смог улучшить свой результат. Другая разновидность утечек в данных связана с так называемыми протекающими примерами, особенно часто встречающимися при нарушении условий независимо- сти и одинакового распределения. Таким образом, некоторые примеры относятся к одному периоду или одной группе и коррелируют между собой. Если все они не принадлежат только к обучающему либо только к тестовому множеству, а распре- делены между ними, с большой вероятностью алгоритм машинного обучения будет выявлять такие случаи, а не выводить общие правила. В качестве примера часто приводят ситуацию, произошедшую с группой профессора Эндрю Ына (Andrew Ng): https://twitter.com/nizkroberts/status/931121395748270080). В 2017 г. вышла
- лава 6. Построение схемы валидации 179 и статья, основанная на датасете из 100 000 рентгеновских снимков, принадлежа- лих 30 000 пациентов. Разбив данные на обучающее и тестовое множества, иссле- дователи не подумали, что снимки одного и того же пациента могут попасть в оба множества. На возможную утечку, приводящую к завышенным оценкам качества модели, обратили внимание специалисты по практическому машинному обучению, 1 частности Ник Робертс (Nick Roberts). Благодаря их замечаниям статья была герьезно переработана. Что происходит в случае обнаруженной на конкурсе утечки? Kaggle предусматри- зает несколько вариантов действий: • оставить все как есть и продолжать соревнование (особенно в случаях, когда утечка не оказывает большого влияния на результат); • перезапустить соревнование, удалив из данных причину утечки; • создать новые тестовые данные, не содержащие утечки. Kaggle рекомендует публично рассказывать о найденных утечках, хотя и не делает это обязательным и никак не наказывает не рассказавших. Однако наш опыт гово- рит, что при наличии утечек они быстро станут явными и активно обсуждаемы- ми — так что, если вы следите за форумом, вы узнаете о них. Однако учтите, что некоторые участники могут использовать обсуждение ’’волшебных” признаков для отвлечения соперников. Знаменитым стал случай на конкурсе Santander Customer Transaction, когда некоторые кэгглеры специально подогревали интерес конкурен- тов к таким признакам, на деле оказавшимся не особо полезными (о чем можно прочитать по ссылке https://www.kaggle.com/c/santander-customer-transaction- prediction/discussion/87057#502362). Мы советуем внимательно прочитать обсуждение утечки и решать, стоит ли она изучения, на основе своих интересов и целей участия в конкурсе. Решение не использовать утечку может повредить итоговому результату, решение использовать не полезно с точки зрения обучения (поскольку из-за нее вы не узнае- те настоящего качества модели). Если ваша основная цель не в том, чтобы приоб- рести репутацию или получить работу в компании-спонсоре, совершенно нормаль- зо использовать любые утечки, в противном случае лучше сосредоточиться на работе над своей моделью (возможно, Kaggle перезапустит соревнование или ис- правит тестовые данные, к разочарованию многих воспользовавшихся утечкой). Утечки бывают разными, и чтобы составить некоторое представление об их типах, можно рассмотреть следующие примеры: • https://www.kaggle.com/c/predicting-red-hat-business- value/discussion/22807 — обсуждение утечки на конкурсе Predicting Red Hat Business Value (https://www.kaggle.eom/c/ predicting-red-hat-business-value), где проблема была вызвана некорректным разбиением данных на обучающие и тестовые;
180 Часть II. Оттачивание соревновательных навыков • https://www.kaggle.eom/c/talkingdata-mobile-user-demographics/ discussion/23403 — обсуждение утечки на конкурсе TalkingData Mobile User Demographics (https://www.kaggle.com/c/talkingdata- mobile-user-demographics), где данные не удовлетворяли усло- вию независимости и одинакового распределения; • https://www.kaggle.com/c/two-sigma-connect-rental-listing- inquiries/discussion/31870 — обсуждение утечки на конкурсе Two Sigma Connect: Rental Listing Inquiries (https://www.kaggle.com/ c/two-sigma-connect-rental-listing-inquiries), где дело было в ме- таданных (времени создания папок). Резюме В конце этой главы мы повторим основные данные ранее советы по стратегии ва- лидации, которые помогут вам к концу соревнования иметь хорошо работающие модели. Сначала мы поговорили об изменениях в публичной таблице результатов, о пере- становках в ней, о проблеме переобучения. Затем мы обсудили важность валида- ции, построения надежной стратегии, соответствие ее результатов таблице и то, как важно отслеживать прогресс. Мы также познакомились с таким методом подбора гиперпараметров и проверки тестовых данных (либо разбиений на обучающее и контрольное множество), как adversarial validation. В конце мы обсудили утечки в данных на соревнованиях и работу с ними. В итоге мы можем дать следующие советы. • Всегда начинайте с построения надежной схемы валидации, при этом обычно контроль по к блокам благодаря своим вероятностным свойствам предпочти- тельнее простого контроля на отложенных данных, поскольку обладает большей обобщающей способностью. • Если результаты валидации нестабильны, стоит увеличить число блоков или сделать больше разбиений. Проверяйте тестовое множество методом adver- sarial validation. • Отслеживайте как результаты в таблице, так и итоги локальной валидации. Вторым стоит больше доверять при поиске возможностей для оптимизации или возможных утечек. • При выборе итоговых решений опирайтесь не только и не столько на резуль- таты в таблице, сколько на итоги валидации. Теперь мы готовы к разговору о конкурсах с табличными данными (численными или категориальными данными, представленными в виде матриц, где строки соот-
Глава 6. Построение схемы валидации 181 ветствуют объектам, а столбцы — признакам). В следующей главе мы обсудим орга- низуемые Kaggle и конкретно автором inversion (https://www.kaggle.com/inversion) ежемесячные конкурсы Tabular Playground Series (’’табличная песочница”). Мы по- знакомим вас с такими полезными при работе с табличными данными приемами, как преобразование признаков и целевое кодирование, с применением автокоди- ровщиков для удаления шума, а также с использованием нейросетей как альтерна- тивы наиболее часто используемым в табличных задачах методам градиентного бустинга (XGBoost, LightGBM, CatBoost). Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
7 Моделирование для табличных данных До 2017 г. не было необходимости различать соревнования по их типу данных, т. к. подавляющее большинство конкурсов было основано на табличных данных. Даже само выражение ’’табличные конкурсы’’ на форумах не встречалось. Внезапно что- то изменилось, и после некоторого периода почти без новых соревнований (https://www.kaggle.com/general/49904) на конкурсах начали преобладать задачи глубокого обучения, а табличные, к разочарованию многих, стали редки. Настолько редки, что недавно понадобилось запускать отдельную серию табличных конкурсов на основе синтетических данных. Что же произошло? К 2017-2018 гг. наука о данных стала зрелой областью, и к ней начали обращаться очень многие компании. Хотя она оставалась сверхпопулярной темой, но уже не была чем-то необычным. Решение задач, похожих на ранее встречавшиеся на Kaggle, стало стандартной практикой многих компаний. В этих условиях спонсоры были не слишком заинтересованы в запуске новых табличных конкурсов, посколь- ку уже справлялись с подобными задачами своими силами. Глубокое обучение, с другой стороны, — тема не столь хорошо изученная и останется такой еще некото- рое время. Поэтому имеет смысл проводить конкурсы в этой области в надежде на новые идеи. В данной главе, однако, мы поговорим о табличных конкурсах. Мы расскажем о некоторых знаменитых соревнованиях прошлого, но больше сосредоточимся на серии конкурсов Tabular Playground. Табличные задачи часто встречаются в работе большинства исследователей данных, и Kaggle позволяет научиться многим полез- ным методам для работы с ними. Мы начнем с обсуждения разведочного анализа данных (exploratory data analysis, EDA) и преобразования признаков. Познакомив вас с основными стратегиями преобразования признаков, мы перейдем к связанным с ним темам, таким как кодирование категорий, отбор признаков, преобразование целевой переменной и присвоение псевдометок. В конце мы затронем применение
Глава 7. Моделирование для табличных данных 183 глубокого обучения для табличных данных, приведем примеры специализирован- зых нейросетей, таких как TabNet, и автокодировщика для удаления шума. Мы расскажем, почему автокодировщики в последнее время стали столь полезны для гонкурсов Kaggle, оставаясь редкими в реальных приложениях. Темы этой главы: • Tabular Playground Series; • начальное состояние случайного генератора и воспроизводимость; • разведочный анализ данных; • уменьшение размера данных; • преобразование признаков; • псевдометки; • удаление шума с помощью автокодировщиков; • нейросети в табличных конкурсах. Эта глава не сможет рассказать обо всех аспектах табличных конкурсов, но вы лег- £0 найдете недостающую информацию в других книгах. Вместо этого она предста- вит вам ряд методов и подходов, специфичных для таких конкурсов на Kaggle и обсуждаемых почти исключительно на форумах. Tabular Playground Series Так как многие участники ждали табличных задач, в 2021 г. Kaggle в качестве экс- перимента запустил серию ежемесячных конкурсов Tabular Playground Series. Кон- 1урсы этой серии были основаны на синтетических датасетах, подобных публич- ным данным или данным старых соревнований и созданных генеративной нейросетью CTGAN. Код для CTGAN вы можете увидеть на https://github.com/sdv-dev/ CTGAN. Существует также статья, объясняющая ее работу, о том, как она моделирует распределение данных и генерирует новые данные (https://arxiv.org/pdf/1907.00503v2.pdf). Технологии, лежащие в основе CTGAN и связанных с ней инструментов, были созданы благодаря проекту Synthetic Data Vault (https://sdv.dev/), зародившемуся в MIT. Результатом их работы стали программы с от- крытым кодом, предназначенные для создания синтетических данных по реальным образцам. С их помощью можно как создавать новые да- тасеты, не содержащие чувствительной информации о конкретных лю- дях или компаниях, так и дополнять имеющиеся.
184 Часть II. Оттачивание соревновательных навыков В 2021 г. Kaggle провел 13 конкурсов, которые прошли довольно успешно и при- влекли немало участников, хотя не приносили рейтинговых очков и медалей, а при- зы ограничивались сувенирами. Перед вами список конкурсов 2021 г. (табл. 7.1). вы можете искать в нем интересные вам типы задач или метрики и затем обращать- ся к форумам и блокнотам. Таблица 7.1. Конкурсы Tabular Playground Series 2021 г. Месяц, год Задача Переменные Метрика Пропущенные данные Январь 2021 Регрессия Числовые RMSE Нет Февраль 2021 Регрессия Числовые и категориальные RMSE Нет Март 2021 Бинарная класси- фикация Числовые и категориальные AUC Нет Апрель 2021 Бинарная класси- фикация Числовые и категориальные Доля правиль- ных ответов Да Май 2021 Многоклассовая классификация Категориальные Log Loss Нет Июнь 2021 Многоклассовая классификация Числовые и категориальные Log Loss Нет Июль 2021 Многомерная рег- рессия (загрязне- ние воздуха) Числовые, время RMSLE Да Август 2021 Регрессия (потери от дефолта по вкладу) Числовые RMSE Нет Сентябрь 2021 Бинарная класси- фикация (страхо- вание) Числовые AUC Да Октябрь 2021 Бинарная класси- фикация (биологи- ческая активность молекул) Числовые и категориальные AUC Нет Ноябрь 2021 Бинарная класси- фикация (иденти- фикация спама) Числовые AUC Нет Декабрь 2021 Многоклассовая классификация (тип леса) Числовые и категориальные Доля правиль- ных ответов Нет
Глава 7. Моделирование для табличных данных 185 Серия Tabular Playground продолжалась и в 2022 г., с более сложными задачами (табл. 7.2). Таблица 7.2. Конкурсы Tabular Playground Series 2022 г. Месяц, год Задача Переменные Метрика Пропущенные данные Январь 2022 Прогнозирова- ние продаж Даты, категори- альные SMAPE Нет Февраль 2022 Классификация (виды бактерий) Числовые Доля правиль- ных ответов Нет Большая часть этой главы основана на коде и обсуждениях, относящихся к пере- численным в табл. 7.1 и 7.2 соревнованиям, а не к знаменитым конкурсам прошло- го. Как мы уже говорили, ситуация в мире машинного обучения изменилась, таб- личные конкурсы навсегда ушли с ’’переднего края”, и стоит давать советы, жтуальные для настоящего, а не прошлого. Как и на серьезных соревнованиях с присвоением очков и медалей, мы советуем применять на табличных конкурсах простую, но эффективную схему действий (собственно, мы будем рекомендовать ее на всем протяжении книги): • разведочный анализ данных (EDA); • подготовка данных; • моделирование (и контроль качества методом кросс-валидации); • постобработка; • отправка результатов. Как правило, вам также нужно позаботиться о воспроизводимости результатов и сохранить модели (при выборе каждого блока в качестве контрольного), их пара- метры, предсказания на каждом блоке и предсказания моделей, обученных на всех даных. Всю эту информацию необходимо хранить в удобном виде, позволяющем ^произвести результаты (для чего можно использовать метки и хеши, например, MD5 — об этом можно прочитать на https://stackoverflow.com/questions/16874598/ taw-do-i-calculate-the-md5-checksum-of-a-file-in-python), записывать результаты убличных тестов и кросс-валидации. Большинство кэгглеров пользуются просты- ш инструментами вроде текстовых файлов или таблиц Excel, но есть и более про- жинутые: • DVC (https://dvc.org/); • Weights and Biases (https://wandb.ai/site); • MLflow (https://mlflow.org/); • Neptune (https://neptune.ai/experiment-tracking). В итоге, однако, важен результат, а не инструменты. Стремитесь даже в пылу борь- бы под держивать порядок в своих экспериментах и записях о них.
186 Часть II. Оттачивание соревновательных навыков Прежде чем продолжать, мы предлагаем вам подумать о методах генерации дан- ных, которые Kaggle использует для табличных конкурсов, их понимание даст вам серьезное преимущество. Понимание устройства синтетических данных может по- мочь вам и в реальном мире, позволяя получить больше данных для обучения. Так, рассмотрим соревнование Google Brain — Ventilator Pressure Pre- diction (https://www.kaggle.eom/c/ventilator-pressure-prediction), по- священное использованию машинного обучения для управления аппа- ратом искусственной вентиляции легких. Хороших результатов можно Л было добиться с помощью имеющихся данных и нейросетевой модели, но благодаря синтетической природе данных можно было также приме- нить реверс-инжиниринг к их генерации и оказаться в числе лидеров. Поступивший так Джун Кода (Jun Koda, https://www.kaggle.com/ junkoda) описал свои действия в посте https://www.kaggle.eom/c/ ventilator-pressure-prediction/discussion/285278. Генерация собственных искусственных данных и понимание того, как генериру- ются чужие, — задача непростая, как можно понять из блокнота https:/ www.kaggle.com/lucamassaron/how-to-use-ctgan-to-generate-more-data — моди- фикации блокнота, принадлежащего Дариушу Бахрами (Dariush Bahrami. https://www.kaggle.com/dariushbahrami). Начальное состояние случайного генератора и воспроизводимость Прежде чем обсуждать схему действий на табличных конкурсах и используемые модели, полезным будет вернуться к уже упомянутой теме воспроизводимости ре- зультатов. Многие функции, которые вы встретите в блокнотах Kaggle, принимают в качестве параметра число, задающее начальное состояние генератора случайных чисет (seed). Этот параметр нужен именно для воспроизводимости, т. к. многие алгорит- мы не являются детерминированными и основаны на случайности. Задавая началь- ное состояние генератора случайных чисел, вы делаете генерируемую им последо- вательность предсказуемой — иными словами, получаете один и тот же результат при каждом запуске кода. Именно для этого параметр начального состояния генератора присутствует в алго- ритмах из библиотеки Scikit-leam и совместимых с ней (из наиболее популярных — XGBoost, LightGBM, CatBoost). Воспроизводимость результатов важна не только на конкурсах Kaggle, но и в ре- альных проектах, где она позволяет лучше отслеживать изменения в качестве мо- дели и согласованность ее результатов. На соревнованиях воспроизводимость по-
Глава 7. Моделирование для табличных данных 187 могает при проверке гипотез, поскольку исчезают случайные отклонения. Так, при введении нового признака вы можете понять, дает ли он преимущество, и быть уверенными, что изменение качества модели обусловлено введением этого призна- ка, а не случайностью. Воспроизводимость важна и для работы с публичными блокнотами. Обычно в них выставлено начальное состояние генератора, равное 0, 1 или 42. Значение 42 попу- лярно как отсылка к роману Дугласа Адамса ’’Автостопом по Галактике”, в котором это число является ответом на ’’Главный вопрос жизни, Вселенной и всего такого”, полученным в результате 7,5 млн лет непрерывных вычислений на специально соз- данном компьютере— ’’Думателе” (Deep Thought). Заметим, что использование всеми участниками конкурса одинакового начального состояния (random seed) мо- жет привести к двум эффектам: • к переобучению, если данное значение слишком хорошо подходит для тесто- вых данных; • к большому количеству одинаковых результатов. Изменение начального состояния генератора устраняет обе эти проблемы и может дать вам преимущество. Заметим, что в случае победы в конкурсе вам нужно будет показать, как было получено победившее решение. Так что для беспроблемного получения приза важно позаботиться о воспроизводимости. Модели из библиотек TensorFlow и PyTorch не используют явно начальное состоя- ние генератора, так что обеспечить полную воспроизводимость для них — не столь простая задача. Следующий код задает одинаковое начальное состояние для этих моделей: def seed_everything(seedj tensorf low_init=True_> pytorch_init=True): Основные параметры для воспроизводимости результатов IIIIII random.seed(seed) os.environ["PYTHONHASHSEED"] = str(seed) np.random.seed(seed) if tensorflow_init is True: tf.random.set_seed(seed) if pytorch_init is True: torch.manual_seed(seed) torch.cuda.manual_seed(seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False
188 Часть II. Оттачивание соревновательных навыков При работе с Scikit-leam рекомендуется (если класс или функция это допускают) напрямую задавать начальное состояние генератора с помощью параметра random_state. Разведочный анализ данных Термин ’’разведочный анализ данных” (exploratory data analysis, EDA) появился благодаря Джону Тьюки (John W. Tukey), одному из крупнейших статистиков со- временности. ’’Exploratory Data Analysis” — название его книги, изданной в 1977 г. Тьюки представляет EDA как способ исследования данных, выявления закономер- ностей и выдвижения гипотез, которые потом должны быть подтверждены стати- стическими тестами. Согласно Тьюки, процесс выдвижения гипотез основан скорее на наблюдении и рассуждении, чем на вычислениях. Эта мысль полезна не только в статистике, но и в машинном обучении (в частности, данные могут быть предобработаны так, чтобы алгоритмы машинного обучения работали эффективнее). Проводя разведочный анализ данных для конкурса, ищите: • пропущенные значения и, главное, корреляцию отсутствия значений с целе- вой переменной; • численные признаки с перекошенным распределением и их возможные пре- образования; • редкие значения категориальных признаков и группы, в которые их можно объединить; • возможные выбросы (как по одному, так и по нескольким признакам); • признаки, сильно коррелирующие друг с другом (или даже дублирующиеся). В случае категориальных признаков обратите внимание на пересекающиеся категории; • признаки, сильнее всего влияющие на значение целевой переменной. Все это делается с помощью описательных статистик, графиков, диаграмм, изуче- ния отдельных признаков, соотношений между парами признаков (например, с по- мощью диаграмм рассеивания) или большим числом признаков. Если у вас мало времени или вы не знаете, с чего начать, можно для начала обра- титься к автоматическим инструментам, таким как AutoViz (https://github.com/ AutoViML/AutoViz), популярной свободно распространяемой программе для EDA. Использовать ее в своем блокноте можно, выполнив команду pip install git+git://github.com/AutoViML/AutoViz.git
Глава 7. Моделирование для табличных данных 189 Получить более полное представление о возможностях AutoViz можно, прочитав статью Дэна Рота (Dan Roth) на https://towardsdatascience.com/ autoviz-a-new-tool-for-automated-visualization-ec9c!744a6ad или про- смотрев несколько интересных блокнотов, например, https:// www.kaggle.com/gvyshnya/automating-eda-and-feature-importance- detection от Георгия Вишни (https://www.kaggle.com/gvyshnya). Георгий также упоминает и другой инструмент— Sweetviz (https:// github.com/fbdesignpro/sweetviz). Обзорную статью о нем и пример работы с данными о пассажирах ’’Титаника" можно найти по ссылке https://towardsdatascience.com/powerful-eda-exploratory-data-analysis- in-just-two-lines-of-code-using-Sweetviz-6c943d32f34. Еще один популярный и потенциально полезный инструмент — Pandas Profiling (https://github.com/pandas-profiling/pandas-profiling). Он лучше всего пригоден для классической описательной статистики и визуали- зации. Рассказ о нем можно найти в статье https://medium.com/ analytics-vidhya/pandas-profiling-5ecd0b977ecd. Можно также подождать, пока другие кэгглеры опубликуют блокноты с разведоч- ным анализом данных. Вообще следить за разделом Notebooks очень полезно — это иожет дать отличные идеи, помочь в выборе модели и в целом в понимании того, иго стоит, а что не стоит делать. Однако в тех случаях, когда EDA действительно люсобен принести прорывные идеи, вы не получите их с помощью автоматизиро- ванных решений и вряд ли найдете в публичных блокнотах — придется исследовать змостоятельно. /как, наш совет— начать с автоматизированных инструментов, которые просто хвоить и просто применить. Они сэкономят много времени, которое вы провели 5ы в раздумьях над диаграммами. Однако затем стоит обратиться к Matplotlib или Seaborn и попробовать менее стандартные способы визуализации, подходящие для юнкретной задачи и конкретных данных. Так, если вам дан ряд измерений, произведенных в разные моменты времени, полезно строить как непрерывный график, так и отмечать от- g дельные точки наблюдений, чтобы, например, видеть промежутки меж- ду ними.
190 Часть II. Оттачивание соревновательных навыков Понижение размерности методами t-SNE и UMAP При проведении EDA можно строить множество разных типов графиков и диа- грамм, и мы не собираемся перечислять их все. Однако о некоторых методах по- строения диаграмм с понижением размерности стоит упомянуть, поскольку оне могут дать очень много информации. Это t-SNE (https://lvdmaaten.github.io/tsne/ и UMAP (https://github.com/lmcinnes/umap)— часто используемые методы, по- зволяющие проецировать сложно устроенные данные в пространство меньшей раз- мерности (чаще всего равной 2). Двумерные диаграммы, получаемые с помощью UMAP и t-SNE, позволяют обна- ружить выбросы и определить кластеры. Если представить результат проекции в двумерное пространство в виде диаграммы- рассеивания (где цвет соответствует значению целевой переменной), можно понять возможные способы работы с подгруппами. Хорошим примером того, как UMAP и t-SNE позволяют лучше разобраться в дан- ных (хотя и относящимся к анализу изображений), является работа Криса Деотта (Chris Deotte) для конкурса SIIM-ISIC Melanoma Classification (https://www.kaggle.com c/siim-isic-melanoma-classification/discussion/168028). Крис спроецировал как обу- чающие, так и тестовые данные в двумерное пространство и выделил области, где присутствовали только тестовые примеры. UMAP и t-SNE крайне полезны для выявления неочевидных законо- мерностей в данных, а также для построения новых признаков. Приме- А ром последнего служит конкурс Otto Group Product Classification Chai- lenge, на котором Майк Ким (Mike Kim) использовал t-SNE в качестве признаков проекции (https ://www.kaggle.com/c/otto-group-product- classification-challenge/discussion/14295). Однако, как замечено в статье ”How to t-SNE Effectively” (https://distill.pub/2016 misread-tsne/), эти методы нужно использовать с осторожностью, поскольку можнс ’’обнаружить” несуществующие кластеры и закономерности. Это же предостере- жение касается и UMAP. Советы по использованию этих методов для реальных данных можно найти в таких руководствах, как https://pair-code.github.io understanding-umap/. Тем не менее, несмотря на потенциальные опасности, наш опыт говорит о пользе UMAP и t-SNE для выявления закономерностей, больших, чем у классических ме- тодов (РСА или SVD). UMAP и t-SNE позволяют понизить размерность до допус- кающей визуализацию, при этом сохраняя структуру в данных. За это приходите* платить долгим временем работы. Впрочем, NVIDIA выпустила набор библиотег RAPIDS (https://developer.nvidia.com/rapids), основанный на CUDA и позволяю-
Глава 7. Моделирование для табличных данных 191 щий при работе на GPU получить результаты UMAP и t-SNE за разумное время, что делает их пригодными для разведочного анализа данных. Пример применения UMAP и t-SNE с использованием RAPIDS для EDA (относящийся к конкурсу 30 Days of ML) можно найти по ссылке https://www.kaggle.com/lucamassaron/interesting-eda-tsne-umap/. На рис. 7.1, являющемся результатом работы этого блокнота, можно заметить кла- стеры, но ни один из них не показывает связи с целевой переменной. Рис. 7.1. Кластеры на диаграмме t-SNE Рис. 7.2. На диаграмме t-SNEлегко выделить области, где преобладает положительный класс В другом блокноте (https://www.kaggle.com/lucamassaron/really-not-missing-at- random) те же самые методы применяются к индикаторам пропущенных значений, что позволяет выделить отдельные области с преобладанием определенных клас- сов. Пропущенные значения в этой задаче распределены неслучайным образом и юзволяют предсказывать ответы (рис. 7.2). Уменьшение размера данных Ъботая с блокнотами Kaggle, вы быстро обнаружите их неприятные и трудно об- водимые ограничения. В частности, при нехватке памяти (out-of-memory error) вы- жишение блокнота прекращается, и он должен быть запущен сначала. Такая ситуа- жя часто встречается на соревнованиях, однако в отличие от задач глубокого Лучения, связанных с текстами или изображениями, в которых вы можете загру- жать данные с диска и обрабатывать их небольшими порциями, большинство таб- шчных алгоритмов требуют загрузки в память всех данных сразу.
192 Часть II. Оттачивание соревновательных навыков Чаще всего проблема возникает при попытке загрузить данные из файла CSV с по- мощью функции read_csv библиотеки pandas, когда получившаяся таблица (DataFrame) оказывается слишком большой для среды Kaggle Notebooks. Проблему можно решить, сжав таблицу без потерь информации (lossless compression), на- пример, с помощью следующего скрипта, основанного на блокноте Гильома Мар- тена (Guillaume Martin, https://www.kaggle.com/gemartin/load-data-reduce-memory- usage): def reduce_mem_usage(df, verbose=True): numerics = ['int!6\ 'int32', 'int64', 'floatl6', 'float32', 'float64'] start_mem = df.memory_usage().sum() / 1024**2 for col in df.columns: col_type = df[col].dtypes if col_type in numerics: c_min = df[col].min() c_max = df[col].max() if str(col_type)[:3] == 'inf: if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max: df[col] = df[col].astype(np.int8) elif c_min > np.iinfo(np.intl6).min and cjnax < np.iinfo(np.intl6).max: df[col] = df[col].astype(np.intl6) elif c_min > np.iinfo(np.int32).min and cjnax < np.iinfo(np.int32).max: df[col] = df[col].astype(np.int32) elif c_min > np.iinfo(np.int64).min and cjnax < np.iinfo(np.int64).max: dffcol] = df[col].astype(np.int64) else: if c_min > np.finfo(np.float32).min and cjnax < np.finfo(np.float32).max: df[col] = df[col].astype(np.float32) else: df[col] = df[col].astype(np.float64) end_mem = df.memory_usage().sum() / 1024**2 if verbose: print('Mem. usage decreased to {:5.2f} Mb ({:.lf}% reduction)'.format(end_mem, 100 * (start_mem - end_mem) / start_mem)) return df
Глава 7. Моделирование для табличных данных 193 Гильом Мартен был не первым кэгтлером, предложившим сжимать А таблицы. Пионером был Аржан Гроен (Aijan Groen), написавший сжи- мающую функцию на конкурсе от компании Zillow (https:// www.kaggle.com/arjanso/reducing-dataframe-memory-size-by-65). Этот скрипт использует тот факт, что значения всех численных признаков принад- лежат определенному интервалу. В Python существуют различные типы численных данных (целых и с плавающей точкой), занимающие разное число байтов в памяти, и скрипт сравнивает интервал значений каждого признака с интервалом, допусти- мым для каждого типа данных. После этого каждый признак приводится к типу, включающему все его значения и занимающему меньше всего памяти. Это очень полезный способ, но он имеет свои подводные камни. Приведя каждый признак к оптимальному типу, вы больше не сможете применять такие преобразо- вания, результаты которых могут выйти за пределы этого типа. Мы предлагаем применять сжатие уже после преобразований признаков (либо перед ними, если они точно не меняют масштаб данных). Также в работе с памятью вам поможет библиотека gc, предназначенная для сборки мусора, и конкретно метод gc.collect(). Уменьшать размер данных можно также с помощью преобразований признаков (в частности, их отбора либо сжатия). Преобразования признаков В реальном мире корень разницы между хорошей и посредственной моделью ма- шинного обучения часто лежит не в самой модели, а в данных. Далее, главное, что отличает хорошие данные от плохих, не отсутствие пропущенных значений, не их надежность и не число примеров; информационная ценность заключается в типах признаков. Именно признаки объектов являются материалом, они используются для разделе- ния классов или предсказания численных ответов. Модели обладают разной выра- жтельностью, разной способностью превращать признаки в предсказания, но если • вас недостаточно признаков, никакая модель не даст вам хороших предсказаний. Модели выявляют лишь те закономерности, что заложены в данных. На Kaggle, как правило, у всех участников с самого начала датасет одинаков (очень хдко разрешается искать дополнительные). Основную роль играет их обработка. Частой ошибкой кэгглеров является игнорирование того, что данные можно улуч- шать. Преобразование признаков (feature engineering), безусловно, очень важно хжя достижения результатов на конкурсах. Даже самые мощные модели часто нуж- даются в более понятном представлении исходных данных. С помощью преобразования признаков вы также можете учесть ваши априорные ания о задаче и предметной области, например, получив с помощью арифмети- ческих операций некоторые новые полезные характеристики. Оно применяется и
194 Часть II. Оттачивание соревновательных навыков для других целей, реже нужных на конкурсах, но часто важных в реальном мире. Первая — уменьшение размера обучающих данных (впрочем, оно может быть по- лезно и на конкурсах из-за ограничений на память в Kaggle Notebooks). Вторая — интерпретируемость полученной модели, ее понятность человеку. В каждой области существуют свои методы преобразований, часто неочевидные, но хорошо известные экспертам. Так, при работе с финансовыми данными для от- деления сигнала от шума применяются фильтры Калмана и вейвлеты. Мы не будем углубляться в конкретные предметные области и их методы преобразований — их слишком много и они часто весьма сложны. Вместо этого мы познакомим вас с са- мыми общими методами, применимыми практически на любом табличном конкурсе. Простые производные признаки Получать новые признаки, преобразуя старые, — простой, но часто очень эффек- тивный путь. Так, вычисление отношений признаков (т. е. деление значений одного признака на значения другого) может быть весьма полезно, поскольку многие алго- ритмы либо вообще не могут совершать деление (градиентный бустинг), либо вы- полняют его с трудом (глубокие нейронные сети). Вот самые распространенные преобразования. • Преобразования временных признаков. Разбиение даты на год, месяц и день, вычисление номера недели в году и дня недели, вычисление разностей дат, сравнение с некоторыми важными датами (например, праздниками). Выделение часов, минут, секунд. Непрерывные циклические преобразования (использующие функции синуса и косинуса) для получения периодических признаков: cycle = 7 df['weekday_sin'] = np.sin(2 * np.pi * df['coll'].dt.dayofweek/cycle) df['weekday_cos'] = np.cos(2 * np.pi * df['coll'].dt.dayofweek/cycle) • Преобразования численных признаков. Изменение масштаба (scaling), нормализация, логарифмирование, возведение в степень, выделение целой и дробной частей, сложение, вычитание, умножение, деление признаков. При- знаки приводятся к одному интервалу с помощью стандартизации (вычисле- ния z-оценки) или нормализации (min-max scaling), что может быть полезным при использовании алгоритмов, чувствительных к порядку величин (а это, например, все нейросети). • Дискретизация численных признаков (binning) с помощью разбиения всего интервала их значений на части (bins). Дискретизация помогает избавиться от шума и ошибок в данных и легко моделировать нелинейные зависимости ме- жду дискретизированным признаком и целевой переменной (в связке с пря- мым кодированием, в качестве примера можно рассмотреть https://scikit- learn.org/stable/modules/generated/sklearn.preprocessing.KBinsDiscretizer.html).
Глава 7. Моделирование для табличных данных 195 • Кодирование категориальных признаков — прямое кодирование (one-hot encoding) или целевое кодирование (о котором мы поговорим дальше), объе- динение категорий. • Разделение или объединение категориальных признаков — например, на конкурсе, посвященном гибели "Титаника" (https://www.kaggle.com/ c/titanic), можно разбить имя пассажира на собственно имя и фамилию. • Возведение численных признаков в степень (получаем так называемые по- линомиальные признаки). Пример: https://scikit-learn.org/stable/modules/ generated/sklearn.preprocessing.PolynomialFeatures.html. Работа с пропущенными значениями и с выбросами относится не столько к преоб- разованию признаков, сколько к очистке данных, но тем не менее это некоторое изменение признаков, которое может помочь выявлению закономерностей. • Работа с пропущенными значениями. Часто полезно ввести бинарную пе- ременную, говорящую о наличии пропуска, поскольку порой пропуски не случайны и имеют какую-то важную причину. Обычно эта причина касается способа сбора данных и имеет некоторое объяснение. Так, если при проведе- нии переписи человек отказывается говорить о своем доходе, обычно он либо очень беден, либо очень богат. Если алгоритм обучения требует отсутствия пропусков в данных, их можно заменить средним, медианой или модой (из- редка применяются и более сложные способы). О работе с пропусками рассказывает Парул Пандей (Parul Pandey, VY https://www.kaggle.com/parulpandey) в посте ZY4 https://www.kaggle.com/parulpandey/a-guide-to-handling- missing-values-in-python. Стоит, однако, помнить, что некоторые модели сами справляются с пропус- ками и дают результаты лучше, чем при стандартных способах заполнения. К таким относятся модели градиентного бустинга: XGBoost (https://xgboost.readthedocs.io/en/latest/faq.html); LightGBM (https://lightgbm.readthedocs.io/en/latest/Advanced-Topics.html); CatBoost (https://catboost.ai/docs/concepts/algorithm-missing-values- processing.html). • Работа с выбросами. Выбросы можно удалять из данных, заменить на ми- нимальное или максимальное значение в основном массиве данных либо иным образом модифицировать. Для этого можно использовать сложные мо- дели, работающие с множеством признаков, например, из библиотеки Scikit- leam (https://scikit-learn.org/stable/modules/outlier_detection.html). Можно определять выбросы только по одному признаку, вычисляя, насколь- ко значения отличаются от среднего (в стандартных отклонениях) или от гра-
196 Часть II. Оттачивание соревновательных навыков ниц межквартильного интервала (interquartile range, IQR). В последнем случае можно просто исключить из рассмотрения точки, превосходящие 1,5 • IQR + 2з (выбросы сверху) либо меньшие Q\ - 1,5 • IQR (выбросы снизу). Также, обнаружив все выбросы, можно отметить их бинарным индикатором. Все описанные преобразования могут улучшить предсказательную способность вашей модели, но редко играют решающую роль на соревнованиях. Базовых преоб- разований недостаточно, хотя знать их необходимо. В следующих разделах мы об- судим более сложные методы извлечения полезной информации из данных. Метапризнаки на основе строк и столбцов Для того чтобы быть конкурентоспособными, вы должны освоить более сложные преобразования данных. Начать стоит с рассмотрения признаков, относящихся к каждому объекту отдельно, например: • вычислить среднее, медиану, сумму, стандартное отклонение численных зна- чений признаков (возможно, некоторого подмножества); • найти пропущенные значения; • посчитать частоту общих значений (например, для бинарных признаков — частоту положительных значений); • отнести каждый объект к одному из кластеров (полученных, например, с по- мощью метода к средних). Такие метапризнаки (основанные на подмножестве признаков) помогают разде- лить объекты из ваших данных на разные типы и указать на это вашему алгоритму. Метапризнаки могут быть основаны и на столбцах. Операции агрегации и сумми- рования на отдельных признаках говорят, например, о том, является ли данное зна- чение признака редким или часто встречающимся. Сама модель машинного обуче- ния не может, например, посчитать количество значений данного категориального признака. В качестве метапризнаков можно использовать любую стандартную статистику (моду, медиану, сумму, стандартное отклонение, минимум, максимум, асимметрию и эксцесс). С метапризнаками, вычисляемыми по столбцам, можно работать одним из следующих способов. • Частотное кодирование. Посчитать частоту встречаемости значений катего- риального признака и заменить значения на эту частоту. Тот же метод можно применять и к численным признакам с повторяющимися значениями. • Вычисление частот и статистик по группам. Вы разбиваете данные на группы и можете создавать новые признаки из старых как категориальных, так и численных. Группы можно получить методом кластерного анализа либо определить по значениям одного из признаков (так, можно разбить людей по возрастам, по месту проживания и т. д.). Метапризнаки, описывающие всю группу, затем применяются к каждому из ее элементов. Так, с помощью
Глава 7. Моделирование для табличных данных 197 функции groupby из библиотеки pandas можно добавить в данные новые мета- признаки на основе группирующей переменной. Сложнее всего здесь выде- лить осмысленные группы в данных, на основе которых будут вычисляться метапризнаки. • Объединение нескольких групп также даст новые частоты и статистики. Разумеется, это не полный список того, как можно получать новые признаки мето- дами подсчета частот и статистик по строкам либо столбцам. Рассмотрим простой пример, основанный на данных конкурса Amazon Employee Access Challenge о сотрудниках Amazon. Сначала применим к признаку ROLE_TITLE частотное кодирование: import pandas as pd train = pd.read_csv("../input/amazon-employee-access-challenge/train.csv") , # Подсчет частоты объекта i feature__counts = train, groupby ('ROLE__TITLE').size() * print(train['ROLE_TITLE'].apply(lambda x: feature_counts[x])) Названия классов будут заменены на частоты их встречаемости. Теперь закодируем признак role_title на основе количества раз, когда он встреча- ется в группе с одинаковым признаком role_deptname (мы ожидаем, что некоторые роли будут чаще встречаться в определенных отделах). В итоге мы получаем новый признак, основанный на значениях двух старых: 1 feature_counts = train.groupby([' ROLEJDEPTNAME', 'ROLE-TITLE']).size() print(trainf['ROLE_DEPTNAME', 'ROLE__TITLE']] .apply (lambda x: feature^ I counts[x[0]][x[l]], axis=l)) i ___Весь исходный код и результаты его запуска можно найти в блокноте https://www.kaggle.com/lucamassaron/meta-features-and-target- encoding/. Целевое кодирование Ъботать с категориальными признаками обычно несложно благодаря простым функциям, предлагаемым библиотекой Scikit-leam: • LabelEncoder; OneHotEncoder; OrdinalEncoder.
198 Часть IL Оттачивание соревновательных навыке* Данные функции могут преобразовывать категориальные признаки в числовые, г затем в бинарные, удобные для алгоритмов машинного обучения. Заметим, однако, что при большом количестве категорий применение прямого кодирования (one-hot encoding) приводит к огромной очень разреженной (большинство значений в ней будут нулями) таблице, для работы с которой может не хватать памяти и мощности процессора. Такие признаки с большим числом значений (признаки большой мощ- ности, high-cardinality feature) требуют специального обращения с ними. Начиная с первых конкурсов Kaggle, для них использовалось кодирова- JT""^ ние, описанное в статье Micci-Barreca D. A preprocessing scheme for high-cardinality categorical attributes in classification and prediction prob- lems И ACM SIGKDD Explorations Newsletter 3.1. — 2001. — 27-32. Идея состоит в том чтобы преобразовать значения категориального признака в со- ответствующее им ожидаемое значение целевой переменной. Для регрессии это среднее значение на объектах данной категории, для бинарной классификации — вероятность положительного класса при условии принадлежности объекта к данной категории, для многоклассовой классификации — также условная вероятность, нс уже каждого из классов. Так, на конкурсе, посвященном гибели "Титаника" (https://www.kaggle.com competitions/titanic), где нужно было предсказать вероятность выживания каждогс пассажира, целевое кодирование категориального признака (например, пола) за- ключается в замене значений этого признака на среднюю вероятность выживания для каждого из полов. Таким образом, категориальный признак превращается в числовой без разбухания данных. Целевое кодирование полезно во многих ситуациях. Его принцип немногс напоминает стэкинг (метод, при котором в качестве признака используется выхо* другой модели — в данном случае такой признак вычисляется по high-cardinalib feature) и, подобно стэкингу, целевое кодирование подвержено риску переобуче- ния. Для очень редких категорий фактически нет разницы между использованием целевого кодирования и предоставлением значения целевой переменной. Однакс эту проблему можно обойти. Перед тем как мы посмотрим на реализацию, которую вы можете включать в соб- ственный код, посмотрим на реальный пример целевого кодирования. Одно из пер- вых мест на конкурсе PetFinder.my Adoption Prediction было занято с использовани- ем следующего кода: import numpy as пр import pandas as pd from sklearn.base import BaseEstimator, TransformerMixin
Глава 7. Моделирование для табличных данных 199 class TargetEncode(BaseEstimator, TransformerMixin): def __init__(self, categories='auto', k=l, f=l, noise_level=0, random_state=None): if type(categories)==str and categories!='auto1: self.categories = [categories] else: self.categories = categories self.к = к self.f = f self.noise_level = noise_level self.encodings = dict() self.prior = None self.random_state = random_state def add_noise(self, series, noise_level): return series * (1 + noise_level * np.random.randn(len(series))) def fit(self, X, y=None): if type(self.categories)=='auto': self.categories = np.where(X.dtypes == type(object()))[0] temp = X.loc[:, self.categories].copy() temp['target'] = у self.prior = np.mean(y) for variable in self.categories: avg = (temp.groupby(by=variable)['target'].agg(['mean', 'count'])) # Вычислить сглаживание smoothing = (1 / (1 + np.exp(-(avg['count'] - self.k) / self.f))) # Чел» больше значение> тем меньше учитывается fuLL_avg self.encodings[variable] = diet(self.prior * (1 - smoothing) + avg['mean'] * smoothing) return self def transform(self, X): Xt = X.copy()
200 Часть IL Оттачивание соревновательных навыков for variable in self.categories: Xt[variable].replace(self.encodings[variable], inplace=True) unknown_value = {value:self.prior for value in /[variable].unique() if value not in self.encodings[variable].keys()} if len(unknown_value) > 0: Xt[variable].replace(unknown_value, inplace=True) Xt[variable] = Xt[variable].astype(float) if self.noise_level > 0: if self.random_state is not None: np.random.seed(self.random_state) Xt[variable] = self.add_noise(Xt[variable], self.noise_level) return Xt def fit_transform(self, X, y=None): self.fit(X, y) return self.transform(X) Опишем параметры функций: • categories — названия столбцов, которые вы хотите закодировать; при значе- нии по умолчанию ('auto') берутся все строковые признаки; • к — целое; минимальное число примеров, при котором для категории вычис- ляется среднее значение; • f — целое; параметр сглаживания, позволяющий сбалансировать среднее по данной категории и по всем обучающим примерам (последнее соответствует априорной вероятности); • noise_level — уровень шума, добавляемого к результату кодирования во из- бежание переобучения (начинайте с очень маленьких значений); • random_state— начальное состояние случайного генератора, обеспечивает воспроизводимость при noise_level > 0. Обратите внимание на параметры к и f. По сути, для уровня i категориального при- знака мы хотим найти способ кодирования, который позволит лучше предсказывать значения целевой переменной. Замена этого уровня на эмпирическую условную вероятность не слишком хорошо работает при малом числе наблюдений. Решением служит "смешивание" наблюдаемой апостериорной вероятности и априорной веро- ятности (вычисленной по всей выборке) с параметром лямбда. Такой подход назы- вают эмпирическим байесовским. Иначе говоря, в нашей функции для данного уровня категориальной переменной мы можем использовать условную вероятность на данной категории, вероятность
Глава 7. Моделирование для табличных данных 201 на всех данных либо их смесь. Выбор задается значением лямбда для фиксирован- ного параметра к (обычно равного единице), зависящего от f. Как показано на графике рис. 7.3 (значения на оси х соответствуют числу примеров для данного, значения на оси у — весу условной вероятности), при малых f проис- ходит резкий переход от априорной вероятности к апостериорной. При больших f учитываются оба значения, за исключением случаев с очень большим числом при- меров. lambda(n) 20 40 100 Рис. 7.3. График значений лямбда (на оси у) в зависимости от fu количества примеров (на осих) Таким образом для фиксированного к большие значения f соответствуют меньшему доверию к эмпирической вероятности для данной категории и большему — к эмпи- рической вероятности для всех данных. Оптимальное значение f обычно подбира- ется экспериментально (с помощью кросс-валидации), поскольку f можно рассмат- ривать как гиперпараметр. Теперь использование нашего класса стало понятным. Создайте его экземпляр, за- дав имена кодируемых признаков и выбранные вами параметры, и обучите на дан- ных. Затем вы можете преобразовать данные: te = TargetEncode(categories='ROLE-TITLE') te.fit(train, train['ACTION']) te.transform(train[['ROLE_TITLE']])
202 Часть IL Оттачивание соревновательных навыке* Этот пример работает с теми же данными из конкурса Amazon Employee Access Challenge, которые мы использовали ранее, и кодирует только признак role_title. Вместо написания собственного кода вы можете использовать библио- ч । z теку https://github.com/scikit-learn-contrib/category_encoders и класс “ ОРч" Target Encoder (http ://contrib.scikit-learn.org/category_encoders/ - targetencoder.html). Он работает "из коробки" в точности так же, как код из этого раздела. Важность признаков и оценка качества Слишком активное применение преобразований признаков имеет побочные эффек- ты. Если создать слишком много коррелирующих друг с другом признаков или признаков, неважных для решения задачи, модели могут обучаться слишком долге и давать худшие результаты. Это кажется парадоксальным, но объясняется просто: каждая переменная содержит некоторый шум (случайные ошибки измерения или записи), и чем больше количество переменных, тем выше вероятность, что модель примет шум за закономерность (сигнал). Поэтому нужно стараться оставлять только релевантные признаки, т. е. применять отбор признаков. Их определение довольно сложно: с увеличением количества признаков растет и количество их возможных комбинаций. Есть разные способы отбора признаков, но прежде всего необходимо решить, на какой стадии подготовки данных это делать. По нашему опыту это стоит делать в конце. Так как признаки изменяются совместно, вы не можете проверять их пооди- ночке, а только вместе. Затем стоит проверить ваш выбор признаков с помощью кросс-валидации. После того как вы получили набор признаков, работающую модель и схему обуче- ния и валидации (модель не обязательно должна быть полностью оптимизирована, но должна корректно работать и давать приемлемое качество), вы готовы к отбор} признаков. Это можно делать несколькими способами. • Классические статистические подходы основаны на добавлении или удале- нии признаков по одному. Это достаточно медленный подход, поскольку для него на каждом шаге необходимо вычислять метрику качества. • Для регрессионных моделей использование метода лассо может указать на важные, но коррелирующие между собой признаки. Процедура стабильно- го отбора (stability selection) заключается в многократном отборе признаков методом лассо и последующем проведении голосования — сохранятся только те признаки, которым чаще всего соответствовали ненулевые коэф- фициенты.
Глава 7. Моделирование для табличных данных 203 Об этой процедуре можно почитать на https://github.com/scikit- learn-contrib/stability-selection. • Для древесных моделей (случайных лесов, градиентного бустинга) улучше- ние метрики при ветвлении по данному признаку задает важность признаков. Можно установить порог, отсекающий наименее важные признаки. • Рандомизация признаков (либо сравнение со случайными признаками) помо- гает отличить полезные признаки от шума или избыточных признаков в слу- чае древесных моделей (но этот метод обобщаем и на другие типы моделей). Пример отбора через рандомизацию на конкурсе Ventilator Pressure Prediction при- водил Крис Деотт: https://www.kaggle.com/cdeotte/lstm-feature-importance. Его блокнот производит отбор признаков для LSTM-нейросети. Сначала строится мо- дель и записывается базовое значение качества. Затем значения каждого признака до очереди перемешиваются, и модель снова выдает предсказания. Если качество предсказаний падает, значит, был затронут важный признак. Если оно остается та- ким же или улучшается, значит, признак был неважен или даже вреден. При оценке важности признаков также верен принцип отсутствия бес- платных завтраков. Перемешивание значений признака не требует по- вторного обучения, что является большим преимуществом. Однако в .—некоторых ситуациях оно вызывает проблемы — например, иногда соз- । дает бессмысленные входные комбинации, качество на которых оцени- вать бессмысленно, либо при наличии сильно коррелирующих призна- ков считает один важным, а другой — нет. В последнем случае вместо перемешивания значений признака стоит удалять его, повторно обучать модель и сравнивать ее качество с базовым. Другой подход, основанный на перемешивании признаков, реализует процедура Bonita (реализация: https://github.com/scikit-learn-contrib/bonita_py), используя случайные признаки для итеративного контроля качества модели. Альтернативная крепя такой процедуры отбора, BorutaShap (https://github.com/Ekeany/Boruta- Shap), использует так называемый метод SHAP (основанный на векторах Шепли) ия интерпретируемого отбора признаков. Такой метод обычно более надежен, чем просто последовательное удаление или рандомизация, поскольку в нем признаки фавниваются со случайными многократно, пока не докажут свою важность стати- лически. Bonita и BorutaShap производят до 100 итераций и работают только с февесными алгоритмами машинного обучения. При отборе признаков для линейной модели использование Bonita может дать вппние признаки, поскольку этот метод учитывает как основные эффекты призна- а так и все их взаимодействия (но в линейной модели не все взаимодействия важ-
204 Часть II. Оттачивание соревновательных навыке* ны). Эффективно использовать Boruta для отбора признаков линейных моделей можно, если применять градиентный бустинг с максимальной глубиной в одно де- рево (так что взаимодействие между признаками не учитывается). Можно обратиться к блокноту-руководству, представленному во время конкура 30 Days of ML, чтобы увидеть, насколько просто и быстро можно произвести отбор признаков с BorutaShap: https://www.kaggle.com/lucamassaron/tutorial-feature- selection-with-boruta-shap. Боян Тунгуз https://www.kaggle.com/tunguz Боян Тунгуз — тот кэгглер, который точно понимает важ- ность преобразований признаков (а еще он очень любит библиотеку XGBoost). Мы с удовольствием поговорили с ним о работе в качестве специалиста по моделям машинно- го обучения (Machine Learning Modeler) в NVIDIA, а также о его опыте на Kaggle (Боян является гроссмейстером во всех четырех категориях). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Мне нравятся все соревнования не из категории Code. В целом мои предпочтения менялись с течением времени. Я очень сильно увлекался анализом изображений, но сложность используемых в них техник очень сильно возросла за эти годы. Не- которое время я любил конкурсы по обработке естественного языка, но они все- гда были редки на Kaggle. Неизменным, однако, оставался мой интерес к конкур- сам с табличными данными. Они были главным типом соревнований на Kaggle, но сейчас почти исчезли. Тем не менее я все еще заинтересован в этой области машинного обучения и начал свои исследования в ней. По сравнению с другими областями машинного обучения, в частности с глубоким обучением, прогресс в применении машинного обучения к табличным данным незначительный, так что остается еще много возможностей. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я всегда подходил к Kaggle как к игре. Я начинаю с отправки простых решений, странных решений, измененных чужих решений, их комбинаций и т. д. Это по- могает почувствовать задачу, то, какие методы работают, как далеко можно про- двинуться с простыми идеями, и т. д. Кое-что из этого относится и к моей обыч- ной работе, но в ней не хватает важного аспекта — поддержки от сообщества и обратной связи от таблицы результатов. Работая самостоятельно или в маленькой группе, вы никогда не знаете, строите ли вы лучшее из возможных решений или есть куда расти.
Глава 7. Моделирование для табличных данных 205 Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Самым сложным и важным для меня соревнованием был конкурс Ноте Credit Default Risk. Это второе по числу участников соревнование на Kaggle за всю ис- торию, и оно пришлось на довольно сложный период в моей жизни. Кредитное страхование — очень нетривиальная задача науки о данных, требую- щая умных преобразований признаков и надежной схемы валидации. Моей идеей было использование простой линейной модели для отбора признаков, что очень помогло решению нашей команды. Мы выиграли этот конкурс, и до сих пор я считаю ту победу самой важной в своей соревновательной карьере. Помог ли тебе Kaggle в карьере? Если да, то как? Да, Kaggle сыграл важнейшую роль. Три из четырех моих мест работы я получил благодаря успехам на Kaggle. Трудно переоценить, насколько важен может быть профиль на Kaggle для карьеры. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Во всех задачах машинного обучения, в частности на соревнованиях, есть два ас- пекта, которым я очень долго не уделял достаточного внимания: преобразования признаков и надежная валидация. Я люблю алгоритмы и библиотеки и склонен сразу, как только могу, строить алгоритм. Однако наибольшее влияние на ре- зультат вашей модели оказывают хорошие признаки. К сожалению, преобразова- ние признаков — это больше искусство, чем наука, и оно сильно зависит от дан- ных и модели. Большинство интересных методов в нем редко упоминаются в стандартных курсах и других источниках по машинному обучению. Многие та- кие методы вообще придумываются под конкретную задачу, и им невозможно научить. Однако стоит говорить о преобразовании признаков как о необходимой части работы. Для того чтобы стать в нем специалистом, тем не менее, понадо- бятся годы. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Все, что вам нужно, — это XGBoost! Псевдометки На конкурсах, где критически важно количество обучающих примеров, ваш ре- зультат могут сильно улучшить псевдометки. Идея состоит в добавлении приме- ров из тестового множества, в предсказаниях на которых вы уверены, в обучающее множество. Первый раз этот метод был использован на конкурсе Santander Customer Transac- tion Prediction командой Wizardry (о чем можно прочитать по ссылке: https:// www.kaggle.com/c/santander-customer-transaction-prediction/discussion/89003). Введение псевдометок может помочь нахождению коэффициентов модели, увели-
206 Часть II. Оттачивание соревновательных навыков чив количество обучающих примеров. Однако этот подход работает не всегда. Во- первых, на некоторых соревнованиях он не нужен вовсе, введение псевдометок не улучшит, а порой и ухудшит (из-за внесения дополнительного шума) результат. К сожалению, заранее узнать, помогут ли псевдометки в данном кон- курсе, невозможно, это приходится проверять опытным путем. Постро- УУ ив кривую обучения, вы можете предположить, поможет ли в принципе z g 4 увеличение количества данных (советуем ознакомиться с примером от Scikit-leam: https://scikit-learn.org/stable/auto_examples/model_selection/ plot_learning_curve.html). Во-вторых, непросто понять, какие тестовые примеры добавить для улучшения ре- зультатов. Обычно план действий выглядит так: 1. Обучить модель. 2. Получить предсказания на тестовом множестве. 3. Установить, насколько мы в них уверены. 4. Выбрать элементы тестового множества, которые добавим в обучающее. 5. Построить новую модель по объединенным данным. 6. Получить предсказания этой модели и отослать их на проверку. Хороший пример работы с псевдометками принадлежит Крису Деотту и относится к конкурсу Instant Gratification (https://www.kaggle.com/cdeotte/pseudo-labeling- qda-0-969). Для того чтобы им воспользоваться, почти не нужно специальных знаний. Тем не менее при использовании псевдометок есть несколько подводных камней. • У вас должна быть очень хорошая модель, чтобы ее предсказания годились для использования при обучении. Иначе вы только добавите шум в данные. • Так как добиться полностью безошибочных предсказаний на тестовом мно- жестве нереально, нужно отличать хорошие предсказания от плохих. Если делаете предсказания по блокам кросс-валидации, проверяйте стандартное отклонение (как для задач регрессии, так и для классификации) и берите только примеры с наименьшим стандартным отклонением. При предсказании вероятностей берите лишь примеры с очень маленькой или очень большой вероятностью (в которых модель наиболее уверена). • При объединении обучающего множества и части тестового не добавляйте бо- лее 50% тестовых примеров. Идеальное соотношение — 70% примеров из ис- ходного обучающего множества и 30% примеров с псевдометками. Если доба- вить слишком много примеров с псевдометками, ваша новая модель рискует обучиться не столько по исходным данным, сколько по наиболее простым тес- товым примерам. На самом деле модель должна обучаться работать в том чис- ле с шумом в данных, но в примерах с псевдометками такого шума нет.
Глава 7. Моделирование для табличных данных 207 Не забывайте, что псевдометкам нельзя полностью доверять, и вы частично портите данные добавлением тестовых примеров в обу- j4 чающее множество. Тем не менее иногда пользы от этого больше, чем вреда. • Если вы опираетесь на результаты валидации, чтобы определить, стоит ли ос- танавливать обучение, менять гиперпараметры, да и просто для оценки каче- ства модели, не используйте в процессе валидации псевдометки — они могут увести вас по ложному следу. Используйте только исходные обучающие дан- ные, причины мы уже объяснили выше. • По возможности используйте разные типы моделей для получения псевдоме- ток и для последующего обучения. Таким образом вы можете получить из псевдометок новую информацию, а не только подтвердить уже выведенное предыдущей моделью. Конечно, использование псевдометок — скорее искусство, чем наука. Оно может помочь на некоторых соревнованиях, но для этого должно быть проведено с боль- шим умением. Тем не менее помните об этом методе и пробуйте хотя бы одно ре- шение на его основе. Удаление шума с помощью автокодировщиков Автокодировщики, когда-то более известные как инструмент для нелинейного сжатия данных (нелинейный аналог РСА) и удаления шума с изображений, стали рассматриваться как интересный инструмент и для табличных конкурсов после то- го, как Михель Ярер (Michael Jahrer, https://www.kaggle.com/mjahrer), применив их, выиграл конкурс Porto Seguro’s Safe Driver Prediction (https://www.kaggle.com c/porto-seguro-safe-driver-prediction) — популярное соревнование по оценке стра- ховых рисков (более чем 5000 участников) с очень зашумленными признаками. Михаэль обнаружил более удачное представление численных данных для после- дующей подачи на вход нейросети, получаемое с помощью удаляющих шум авто- кодировщиков neural (denoising autoencoders, DAEs). Такой автокодировщик даст вам новый датасет с большим числом признаков, основанным на активации скры- тых слоев. В своем знаменитом посте (https://www.kaggle.com/c/porto-seguro-safe-driver- prediction/discussion/44629) Михаэль описывает, как автокодировщик способен не только убирать шум, но и создавать новые признаки, так что обучение представле- нию признаков происходит тем же способом, что при работе с изображениями. Он говорит, что секрет работы с DAE — в шуме, добавляемом к данным, а также в том, что его метод предусматривает объединение обучающих и тестовых данных (что делает его непригодным для использования вне соревнований). После этого победного появления метод долго не упоминался на форумах, пока не появился в серии Tabular Playground.
208 Часть II. Оттачивание соревновательных навыков DAEs состоят из кодирующей и декодирующей частей. Кодирующая принимает обучающие данные и пропускает их через несколько полносвязных слоев (dense layers). В идеале имеется скрытый средний слой, который при активации кодирует всю обучающую информацию. Если количество нейронов этого слоя меньше числа входов, происходит сжатие. При этом мы надеемся на то, что будет обнаружена скрытая размерность, лежащая за процессом порождения входных данных. В про- тивном случае мы только избавимся от избыточности в данных и шума (что тоже неплохо). В декодирующей части слои снова увеличиваются в размере, пока не достигают размера входа. Выход сравнивается со входом, и вычисляется функция ошибок для обратного распространения. Можно понять, что типов DAE будет два. • Первый тип — "бутылочное горлышко" (bottleneck DAEs). Как и при обра- ботке изображений, в качестве новых признаков берутся значения активации среднего слоя, разделяющего кодирующую и декодирующую части. Форма такой нейросети напоминает песочные часы — количество нейронов умень- шается от входа до среднего слоя, затем снова увеличивается (рис. 7.4). Ко- личество скрытых слоев всегда нечетно. Вход Реконструкция Рис. 7.4. "Бутылочное горлышко". Признаками становятся только веса среднего слоя Вход Реконструкция Рис. 7.5. Г.лубокий стек. Признаками становятся веса всех скрытых слоев
Глава 7. Моделирование для табличных данных 209 • Второй тип — глубокий стек (deep stack DAEs) — имеет слои одинакового размера, их число может быть как четным, так и нечетным (рис. 7.5). В каче- стве признаков берутся значения активации для всех скрытых слоев. Как мы уже обсуждали, важная и часто обсуждаемая тема — добавление шума в автокодировщик. Для лучшего обучения любого из типов DAE необходимо доба- вить к обучающим данным шум, чтобы не происходило переобучения (т. е. просто запоминания входов нейросетью). На конкурсе Porto Seguro Михаэль Ярер добав- лял шум (swap noise) следующим способом: Я семплирую признаки с вероятностью, обозначенной в таблице как "inputSwар Noise”. 0,15 означает, что 15% значений признака замене- ны признаками из других строк. По сути, это метод аугментации, известный как смешивание (mixup) и используе- мый также для аугментации изображений: https://arxiv.org/abs/1710.09412. Для табличных данных вы определяете вероятность смешивания и заменяете некоторые исходные значения значениями из тех же обучающих данных. В своем обзоре (https://www.kaggle.com/springmanndaniel/lst-place-turn-your- data-into-daeta) кэгглер Danzel описывает три подхода к добавлению шума по строкам, по столбцам и случайный. • При добавлении шума по строкам вы заменяете на шум значения в опреде- ленных столбцах. Доля таких столбцов зависит от вероятности смешивания (mixup probability). • При добавлении шума по строкам вы заменяете на шум определенное коли- чество значений в каждой строке; доля измененных значений во всех строках одинакова, но замененные признаки разные. • При случайном добавлении шума вы фиксируете число заменяемых значе- ний на основании вероятности смешивания и выбираете их случайно из всего массива данных (итог похож на добавление шума по строкам). Как и использование псевдометок, использование DAE сводится к методу проб и ошибок. Этот метод срабатывает не всегда, и те приемы, которые полезны в одной задаче, окажутся бесполезны в другой. Для того чтобы успешно использовать DAE, стоит помнить о следующих моментах: • архитектура DAE (deep stack обычно работает лучше, но требуется задавать число слоев и число нейронов в слое); • скорость обучения и размер пакета; • функция потерь (стоит также различать потери для категориальных и число- вых признаков);
210 Часть II. Оттачивание соревновательных навыке* • момент остановки (не всегда стоит останавливаться при наименьшем значе- нии функции потерь, пользуйтесь валидацией и ранней остановкой). Вы должны быть готовы к трудностям при выборе архитектуры сети и ее настрой- ке, но усилия могут окупиться местом среди лидеров в приватной таблице. На не- давних табличных конкурсах многие выигрышные решения использовали DAE. • Danzel (https://www.kaggle.com/springmanndaniel) рассказывает в посте https://www.kaggle.eom/c/tabular-playground-series-jan-2021/discussion/216037 о том, как использовал веса трех слоев по 1500 нейронов, превратив исход- ную таблицу с 14 столбцами в таблицу с 4500 столбцами. Эти новые данные были использованы как входы других нейросетей и моделей градиентного бустинга. • Рен Чзан (Ren Zhang, https://www.kaggle.com/ryanzhang) рассказывает о сво- ем решении по ссылке https://www.kaggle.com/c/tabular-playground-series- feb-2021/discussion/222745. Код его решения можно найти на https:/ github.com/ryancheunggit/Denoise-Transformer-AutoEncoder. Он использо- вал стек преобразующих кодировщиков (stacked transformer encoders) с акти- вацией скрытых слоев ReLU. При таком подходе обучение DAE может зани- мать до 20 часов. Он также предложил добавлять к данным случайный шум е вычислять потери не только по ошибкам при определении данных, но и пс этому шуму. При этом сходимость происходит быстрее. Изучив код на GitHub и граф на форуме, вы поймете и сможете воспроизвести этот новый подход. • JianTT (https://www.kaggle.com/jiangtt) заметил, что некоторые ключевые подходы к автокодировщикам, например добавление шума, могут помочь при обучении моделей без необходимости создавать полный DAE: https:/ www.kaggle.com/c/tabular-playground-series-apr-2021/discussion/235739. Если вы не желаете тратить время на построение собственного DAE, но хотите проверить, как нечто подобное может работать на интересую- щем вас конкурсе, можно попробовать частично готовые решения. Во- первых, можно обратиться к блокноту Хунг Хоя (Hung Khoi), содержа- —щему написанную с использованием PyTorch нейросеть: https:// www.kaggle.com/hungkhoi/train-denoise-transformer-autoencoder, и адаптировать ее под свои цели или использовать библиотеку от Чжона Юна Ли (Jeong-Yoon Lee, https://www.kaggle.com/jeongyoonlee). В од- ном из своих блокнотов Чжон Юн Ли демонстрирует ее работу на зада- че из серии Tabular Playground: https://www.kaggle.com/jeongyoonlee/ dae-with-2-lines-of-code-with-kaggler. Нейросети для табличных конкурсов Обсудив автокодировщики, мы должны закончить эту главу рассказом о том, как нейронные сети в целом могут быть полезны на табличных конкурсах. Для таблич-
. лава 7. Моделирование для табличных данных 211 вых конкурсов (как и для табличных задач реального мира) чаще всего используют модели градиентного бустинга, но порой нейросети могут выделять сигнал там, где модели градиентного бустинга не справляются. Нейросети могут использоваться гак поодиночке, так и в ансамбле. Многие гроссмейстеры настоящего и прошлого говорят, что объедине- ние разных моделей (например, нейросети и модели градиентного бус- тинга) всегда даст на табличных данных результаты лучше, чем одна модель. Оуэн Чзан (Owen Zhang), в прошлом лидер рейтинга, подробно расска- зывает, как нейросети и модели градиентного бустинга можно исполь- зовать вместе: https://www.youtube.com/watch?v=LgLcfZjNF44. Быстро построить нейросеть для табличного соревнования больше не является пу- гающе трудным делом. Такие библиотеки, как TensorFlow/Keras и PyTorch, и нали- чие в них готовых сетей упрощают задачу. Есть множество источников, рассказывающих, как построить нейросеть. Мы предлагаем нашу книгу "Machine Learning Using TensorFlow Cookbook" (https:// www.packtpub.com/product/machine-learning-using-tensorflow-cookbook/ ♦781800208865), в одной из глав которой (глава 7) подробно разбирается использо- зание глубоких нейросетей для табличных задач. В этой книге вы также найдете много других советов по использованию TensorFlow на Kaggle. Зы также можете обратиться к следующим онлайн-ресурсам, ссылки на которые 5ыли даны на конкурсе 30 Days of ML'. • видео о применении TensorFlow для табличных данных; • (https://www.youtube.com/watch?v=nQgUt_uADSE); • руководство с кодом на GitHub (https://github.com/lmassaron/deep_learning_ for_tabular_data); • руководство в формате блокнота для конкурса (https://www.kaggle.com/lucamassaroii/tutorial-tensorflow-2-x-for-tabular-<iata). Ключевые моменты, которые нужно учитывать: • используйте функции активации GeLU, SeLU, или Mish вместо ReLU; во многих статьях они упоминаются как лучше подходящие для табличных дан- ных, что подтверждается и нашим личным опытом; • пробуйте разный размер пакета; • используйте аугментацию методом смешивания (mixup), который мы обсуж- дали в разделе про автокодировщики;
212 Часть II. Оттачивание соревновательных навыков • приводите числовые признаки к равномерному или гауссовскому распреде- лению (преобразования квантилей); • используйте встраиваемые слои (embedding layers), но помните, что они не учитывают взаимодействие между встраиваемым признаком и остальными (поэтому его придется учитывать вам, конструируя новые признаки). Помните, что слои встраивания можно использовать повторно. По сути, они вы- полняют умножение матриц, превращающее входной разреженный вектор (прямое кодирование признака большой мощности) в вектор меньшего размера. Сохранив результат встраивания, мы можем использовать его в других алгоритмах, от гради- ентного бустинга до линейных моделей. Посмотрите на рис. 7.6, чтобы лучше понять схему процесса. На нем показано, как значения категориальной переменной с 24 уровнями преобразуются из текстового либо целочисленного формата в вектор, с которым может работать нейросеть. Пред подготовка Текст в переменной: ID_8080 Кодирование меток: 3/24 Один "горячий" вектор кодирования (размер = 24) [0 010000000000000000 00 00 0] Встраивание tf.keras. layers. Embedding) input-dim, output_dim) Весовая матрица (размер: вход х выход, т. е. 24 х 4) [[0.48 0.997 0.706 0.475] <--------------------- [0.794 0.922 0.086 0.921]] Полностью подключенный Вектор на выходе (размер = 4) [0.283,0.34,0.789,0.876] Плотные слои Обратное распространение Цель Рис. 7.6. Как работает слой встраивания Сначала необходимо выяснить, сколько различных значений признака существует В нашем примере их 24, поэтому прямым кодированием будет создан вектор длины 24. Затем мы умножаем его на матрицу, число строк в которой равно длине векто- ра, а столбцов — размерности выхода. Таким образом категориальный признак на входе преобразуется в многомерный числовой на выходе. Эффективность умноже- ния достигается благодаря алгоритму обратного распространения ошибок. Если вы не хотите строить собственную глубокую нейросеть на TensorFlow иле PyTorch, можно положиться на имеющиеся готовые решения, входящие в состав библиотек или написанные другими кэгглерами на основе научных статей.
Глава 7. Моделирование для табличных данных 213 Можно попробовать использовать на табличных конкурсах следующие из них, уже успевшие хорошо себя зарекомендовать. • TabNet— нейросеть, придуманная исследователями из Google (Ank S. О., Pfister Т. Tabnet: Attentive interpretable tabular learning // arXiv. — 2020. — URL: https://www.aaai.org/AAAI21Papers/AAAI-1063.ArikS.pdf), позволяю- щая выбирать и обрабатывать релевантные признаки и работать как с катего- риальными, так и с текстовыми данными. Она обладает небольшим числом гиперпараметров, хотя все равно необходимо потратить некоторое время на их подбор: качество результатов сети с хорошо подобранными гиперпара- метрами и сети с плохо подобранными может разительно отличаться. Суще- ствует несколько реализаций, в частности превосходная библиотека pytorch- tabnet (https://github.com/dreamquark-ai/tabnet), а также реализации от Ирана Чзана (Yirun Zhang, https://www.kaggle.com/gogo827jz): https://www.kaggle.com/ludovick/introduction-to-tabnet-kfold-10-training и https://www.kaggle.com/ludovick/introduction-to-tabnet-kfold-10-inference, созданные для конкурса Mechanism of Action (МоА) Prediction. • Neural Oblivious Decision Ensembles (NODE, "нейросетевые забывчивые ре- шающие ансамбли") — архитектура, пытающаяся воспроизвести нейросете- выми методами схем работы решающего дерева (Popov S., Morozov S., Babenko A. Neural oblivious decision ensembles for deep learning on tabular data // arXiv preprint arXiv: 1909.06312.— 2019.— URL: https://arxiv.org/abs/ 1909.06312). Можно использовать реализацию Ируна Жанга на TensorFlow (https://www.kaggle.com/gogo827jz/moa-neural-oblivious-decision-ensembles- tf-keras) или на PyTorch (https://www.kaggle.com/gogo827jz/moa-public- pytorch-node). • Можно также использовать различные модели (Wide & Deep, DeepFM, xDeepFM, Autolnt и многие другие), основанные на так называемых машинах факторизации и разработанные в основном для нахождения показателя кли- кабельности. Их опять же не обязательно реализовывать самостоятельно, можно — как показывает пример занявших второе и первое место соответст- венно на конкурсе Categorical Feature Encoding Challenge II Чангхао Ли (Changhao Lee, https://www.kaggle.com/leechh) и Чжан Янга (Jian Yang, https://www.kaggle.com/jackguagua) — положиться на такие библиотеки, как DeepCTR (https://github.com/shenweichen/DeepCTR) или DeepTables (https://github.com/DataCanvasIO/deeptables). Итак, вы можете построить собственную нейросеть для табличных данных, комби- нируя уровни встраивания для категориальных признаков и полносвязные слои для числовых. Но если этот путь не оправдывает себя, можно всегда положиться на од- но из большого количества готовых решений. Всегда следите за появлением новых библиотек, которые могут помочь вам как на конкурсах Kaggle, так и в реальных проектах. По нашему опыту, однако, не стоит ожидать, что нейросеть станет луч- шей моделью на табличном конкурсе, такое происходит редко. Вместо этого стоит
214 Часть II. Оттачивание соревновательных навыков использовать ансамбли из нейросетевых и классических (например, основанных на градиентном бустинге) моделей. Жан-Франсуа Пюже https ://www.kaggle.com/cpmpml Мы поговорили с Жаном-Франсуа Пюже, также известным как СРМР, о том, как работать с данными, о важности вос- производимости, об его лучших результатах и многом дру- гом. Жан — гроссмейстер в категориях Competitions и Dis- cussions, а также ведущий инженер (Distinguished Engineer) в RAPIDS, NVIDIA, поэтому у него есть что рассказать. Редактору особенно по- нравился его рассказ про научный метод. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я люблю соревнования, связанные с наукой или с задачей, которая мне близка. Я не люблю анонимные и синтетические данные, если они не сгенерированы с по- мощью точной физической симуляции. В целом я люблю соревнования, касаю- щиеся незнакомых мне областей, поскольку на них я узнаю больше нового. Это не слишком эффективно с точки зрения рейтинга, но зато очень интересно. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Сначала я изучаю данные и стараюсь в них как можно лучше разобраться. Я ищу в них закономерности, особенно позволяющие делать предсказания. Часто я строю диаграмму рассеяния для двух признаков (имеющихся или производных), на которой цвет соответствует третьему признаку. Один из этих трех признаков должен быть значением целевой переменной. Вообще я активно пользуюсь ви- зуализацией, т. к. считаю зрение человека лучшим инструментом анализа данных. Затем я думаю над оценкой качества модели, поскольку ее необходимо делать как можно более точной. Что неудивительно, часто я пользуюсь одним из вари- антов контроля по к блокам. Разделение на блоки может зависеть от соревнова- ния (быть основанным на времени для соревнований по прогнозированию, со- держать не отдельные примеры, а группы связанных примеров, например действий одного и того же пользователя, и т. д.). Затем я создаю базовую реализацию всего пути от исходных данных до их отправ- ки. На соревнованиях категории Code ее тщательное тестирование критически важно. Затем я пробую использовать более сложные модели (в случае глубокого обучения) либо больше признаков (при применении XGBoost или других моделей из RAPIDS или skleam). Затем я отправляю результаты и проверяю наличие корре- ляции между моей локальной оценкой качества и результатом в таблице. Если на- блюдается корреляция, можно отправлять результат на такую проверку реже.
Глава 7, Моделирование для табличных данных 215 Через несколько недель я настраиваю гиперпараметры. Я делаю это раз или два за соревнование, ближе к его концу, поскольку боюсь переобучения. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Один из конкурсов, которыми я больше всего горжусь, — TalkingData AdTrack- ing Fraud Detection Challenge, на котором был дан огромный массив данных с кликами пользователей и надо было предсказать, какие из них приведут к уста- новке приложения. Признаков было очень мало, а примеров — много (примерно полмиллиарда). На тот момент я имел только 64 Гбайт памяти и должен был придумывать очень эффективный способ создавать и оценивать новые признаки. Я пользовался несколькими идеями. Во-первых, скорее всего, скачивание при- ложения осуществляется последним для этого пользователя кликом на странице. Таким образом, важным признаком становится время до следующего клика того же пользователя на странице того же приложения. Во-вторых, для одного и того же пользователя и приложения, если несколько кликов сделано почти в одно время, скачиванию соответствует последний из них (либо никакой). Третьей иде- ей было использование разложений матриц, чтобы представить совместное появ- ление значений признаков. Я реализовал на Keras модель libFM и добавил в каче- стве признаков скрытые векторы. Единственная команда, сделавшая то же самое, стала победителем, я же в одиночку занял шестое место в окружении гроссмей- стеров (я тогда гроссмейстером не был). Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle помог мне дважды. Во время моей работы в IBM Kaggle стал для меня важным источником знаний о современном машинном обучении, которые я ис- пользовал при разработке IBM Watson Studio и IBM Watson Machine Learning. Например, благодаря мне IBM стал поддерживать библиотеки Python в 2016 г,, хотя всегда использовал в основном Java/Scala. Без меня они сделали бы ставку на Spark и Scala для машинного обучения и пропустили бы всплеск популярно- сти Python. Я также настоял на поддержке XGBoost, а не только Spark ML и TensorFlow. Во второй раз Kaggle помог мне при получении моей нынешней ра- боты. Компания NVIDIA искала гроссмейстеров Kaggle с активным профилем в соцсетях, чтобы продвигать свои продукты, включая библиотеку RAPIDS GPU. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Кэгглеров от остальных исследователей данных отличает оценка качества моде- ли. Кэгглеры обязаны освоить этот навык, иначе они выберут для отправки ре- шения, отлично выглядящие в публичной таблице, но плохо работающие на при- ватных данных. Кэгглер, знающий, как строить модели, хорошо работающие на приватных данных, знает, как строить модели, хорошо работающие на новых, ранее не виденных данных. Неопытные кэгглеры часто спрашивают: может ли данный метод или данная мо- дель сработать на этом конкурсе? Я всегда отвечаю, что это нужно проверять са- мому. Начинающие часто забывают, что машинное обучение — наука эксперимен- тальная.
216 Часть II. Оттачивание соревновательных навыке* Для того чтобы строить хорошие модели, надо следовать научному методу: • сформулируйте гипотезу (например: добавление этого признака или этого слоя нейросети повысит качество решения); • проведите эксперимент, чтобы протестировать гипотезу (внесите измене- ния и проведите обучение); • проанализируйте результаты эксперимента. Стало ли качество лучше? На каких примерах результаты улучшаются, на каких ухудшаются? Каждый эксперимент должен позволять подтвердить или опровергнуть гипотезу, поэтому менять следует только одну деталь за раз. Новички часто меняют многое сразу и потом не могут понять, что сработало, а что — нет. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Для разведочного анализа данных я в основном использую диаграммы Matplotlib. Обрабатываю сами данные я в pandas, если датасет маленький, или в cuDF из RAPIDS, если большой. Для собственно обучения — cuML из RAPIDS, XGBoost с GPU-ускорением и PyTorch. По возможности я использую предобученные мо- дели, например модели для NLP от компании Hugging Face или модели класси- фикации изображений из библиотеки timm. О чем важнее всего помнить, приступая к участию в соревновании? Убедитесь, что вы потратили на задачу достаточно времени. Резюме В этой главе мы обсудили табличные конкурсы на Kaggle. Так как большая часть применимых на них знаний и навыков является стандартной, мы сосредоточились на методах, специфичных для Kaggle. Мы начали с недавно запущенной серии конкурсов Tabular Playground и коснулись воспроизводимости, разведочного анализа данных, преобразования и отбора при- знаков, целевого кодирования, псевдометок и использования нейросетей в приме- нении к табличным данным. Разведочный анализ данных является необходимым этапом на соревновании. Тем не менее он сильно зависит от конкретных данных. Мы дали некоторые общие со- веты касательно EDA, а также обратили внимание на такие методы, позволяющие визуализировать данные, как t-SNE и UMAP. Следующая стадия — преобразование признаков — также сильно зависит от ваших данных. Мы перечислили несколько возможных идей по преобразованиям, из которых вы должны выбрать работающие в вашей конкретной задаче. Мы дали краткий обзор темы отбора признаков и обра- тили внимание на методы, основанные на важности признаков и рандомизации. Мы рассказали о целевом кодировании, подчеркнув, что его невозможно провести полностью автоматически, и перешли к методам, которые вы вряд ли будете ис-
Глава 7. Моделирование для табличных данных 217 пользовать в реальных проектах с табличными данными, но которые могут отлично сработать на соревнованиях: псевдометки и удаление шума с помощью автокоди- ровщиков. Наконец, после обсуждения работы с категориальными признаками че- рез слои встраивания мы дали обзор готовых нейросетевых архитектур для работы с табличными данными. В следующей главе мы завершим обзор методов, которые нужны на табличных конкурсах, обсудив оптимизацию гиперпараметров. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
8 Оптимизация гиперпараметров Качество решения зависит не только от типа алгоритма обучения, данных и при- знаков, но и от гиперпараметров алгоритма, т. е. тех параметров, которые долж- ны быть определены до обучения. Выбор правильных данных и признаков наиболее эффективен в табличных конкурсах, в то время как оптимизация гиперпараметров нужна всегда. На самом деле, при фиксированных данных и алгоритме она явля- ется единственным гарантированным способом улучшить результат. Ансамбли настроенных моделей также работают лучше, чем ансамбли ненастроенных. Воз- можно, вы слышали, что при понимании влияния гиперпараметров на алгоритм можно подбирать их вручную. Многие гроссмейстеры и мастера говорили, чтс поступают так. Они пользуются при этом идеей бинарного поиска, т. е. берут один из наиболее важных гиперпараметров и пробуют меньшие и меньшие егс значения, пока не найдут наилучшее по качеству результатов. Затем они перехо- дят к следующему гиперпараметру. Эта схема отлично работает, если для каждо- го гиперпараметра существует единственное оптимальное значение и параметры независимы друг от друга. В этом случае поиск проводится на основе опыта и по- нимания алгоритма. Однако на большинстве соревнований ситуация другая. Сложность задач и используемых алгоритмов требует систематического подхода, который можно реализовать только с помощью алгоритмов поиска. Поэтому мы взялись за эту главу. В данной главе мы расскажем, как расширить кросс-валидацию на поиск наилуч- ших гиперпараметров. При этом необходимо учитывать конкуренцию и нехватку времени, обычные на конкурсах, поэтому мы сосредоточимся на методах байесов- ской оптимизации, успешно зарекомендовавших себя при оптимизации сложных моделей в условиях ограниченных ресурсов. Мы не только обсудим поиск опти- мальных значений для предопределенных гиперпараметров, но и поговорим об ар- хитектуре нейросетей.
Глава 8. Оптимизация гиперпараметров 219 Мы затронем следующие темы: • базовые методы оптимизации; • ключевые параметры и их использование; • байесовская оптимизация. Поехали! Базовые методы оптимизации Главные алгоритмы для оптимизации гиперпараметров, содержащиеся в библиоте- ке Scikit-leam,— это поиск по сетке (grid search) и случайный поиск (random search). Недавно составители этой библиотеки добавили также алгоритм сокра- щения вдвое (halving algorithm), позволяющий повысить эффективность обоих ти- пов поиска. В данном разделе мы обсудим все эти основные методы. Освоив их, вы получите не только эффективные инструменты оптимизации для конкретных задач (так, маши- ны опорных векторов обычно оптимизируют поиском по сетке), но и познакоми- тесь с общими принципами оптимизации гиперпараметров. Для начала следует перечислить необходимые компоненты: • модель, гиперпараметры которой мы хотим оптимизировать; • пространство поиска — заданные границы, между которыми мы ищем значе- ния гиперпараметров; • схема кросс-валидации; • метрика оценивания. Все эти компоненты подаются на вход методу поиска, чтобы можно было найти оптимальное решение. Поиск по сетке Поиск по сетке — это полный перебор для гиперпараметров, поэтому он вычисли- тельно неосуществим в многомерном пространстве. Для каждого из параметров вы задаете множество значений, которые хотите протестировать, а затем проверяете зсе (полный перебор!) возможные комбинации значений. Этот алгоритм очень прост, но сильно страдает от "проклятия размерности". С другой стороны, он чрез- вычайно параллелен (определение этого термина можно узнать на https:// www.cs.iusb.edu/~danav/teach/b424/b424_23_embpar.html), что позволяет при дос- таточном числе процессоров получать оптимальную комбинацию параметров очень быстро. В качестве примера возьмем задачу классификации и метод опорных векторов support-vector machine classification, SVC). Машины опорных векторов (support- vector machines, SVM) используются как для классификации, так и для регрессии,
220 Часть II. Оттачивание соревновательных навыков и, скорее всего, вы часто будете применять поиск по сетке именно для них. С по- мощью функции make_classification из библиотеки Scikit-leam можно быстро соз- дать датасет: from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, у = make_classification(n_samples=300, n_features=50, n_informative=10, n_redundant=25, n_repeated=15, n_clusters_per_class=5, flip_y=0.05, class_sep=0.5, random_state=0) Затем мы определим базовый алгоритм классификации с использованием опорных векторов (SVC) и пространство поиска. Так как набор гиперпараметров отличается в зависимости от ядра SVC (функции, преобразующей данные внутри SVM), мы создаем список из двух словарей, задающих разные пространства поиска в зависи- мости от выбранного ядра. Мы также задаем метрику качества (т. к. датасет сба- лансирован, мы берем долю верных ответов, accuracy): from sklearn import svm svc = svm.SVC() svc = svm.SVC(probability=TrueJ random_state=l) from sklearn import model_selection search_jgrid = [ {’C’: [1, 10, 100, 1000], ’kernel’: ['linear’]}, {’C: [1, 10, 100, 1000], ’gamma': [0.001, 0.0001], 'kernel': ['rbf']} ] scorer = 'accuracy' В нашем примере линейное ядро не требует настройки параметра gamma, зато этот параметр очень важен для ядра радиального базиса. Поэтому мы задаем два слова- ря: первый — с параметрами для линейного ядра, второй — для ядра радиального базиса, каждый из которых содержит только нужные для своего ядра параметры. Важно заметить, что метрика оценивания может отличаться от функции стоимости, оптимизируемой алгоритмом. Как мы уже говорили в главе 5, бывают ситуации, когда вы не можете изменить функцию стоимости алгоритма, а метрика конкурса
.лава 8. Оптимизация гиперпараметров 221 отличается от нее. В этих обстоятельствах помочь в выборе лучшей модели все еще может выбор оптимальных гиперпараметров относительно метрики оценивания. Найденный оптимальный набор гиперпараметров, соответствующий лучшему зна- чению метрики оценивания при имеющихся ограничениях, возможно, не будет да- мть лучшее теоретически возможное качество, но может приблизиться к нему. Объекту класса GridSearchev передаются модель, пространство поиска, метрика оце- нивания, схема кросс-валидации, а затем происходит обучение модели: search_func = model_selection.GridSearchCV(estimator=svc, paramjgrid=searchjgrid, scoring=scorer, n_jobs=-l, cv=5) search_func.fit(X, y) print (search_func. best_params_) print (search_func.best_score_) Через некоторое время (зависящее от вычислительных ресурсов) вы получите наи- хучшую комбинацию гиперпараметров по итогам кросс-валидации. Итак, поиск по сетке — очень простой алгоритм оптимизации, к тому же легко рас- тараллеливаемый. Он хорошо работает с алгоритмами машинного обучения, не требующими многочисленных настроек (например, SVM, гребневой регрессией и регрессией лассо), но в других случаях его применение довольно ограничено. Во- жрвых, он позволяет проверять только значения гиперпараметров из конечного жскретного множества. Во-вторых, он не слишком эффективен при большом ко- жчестве гиперпараметров, поскольку в этом случае усложняется пространство по- кка и поскольку данный метод бездумно перебирает комбинации параметров, большая часть которых не работает для данной задачи. Случайный поиск Случайный поиск, берущий случайные комбинации параметров из пространства юиска, осуществим даже в многомерных пространствах и широко используется на практике. Недостаток этого метода в том, что он не использует информацию от федыдущих экспериментов при выборе следующей комбинации параметров «прочем, этого не делает и поиск по сетке). Кроме того, в вопросе, как быстро вы зайдете нужную комбинацию, вы можете надеяться только на свое везение. Ча практике, однако, случайный поиск работает очень хорошо и прост для понима- яя. Дело не только в везении, как может показаться поначалу. Как и при семпли- ювании, суть метода в том, что при достаточном количестве случайных тестов вы- хка вероятность найти правильную комбинацию параметров.
222 Часть II. Оттачивание соревновательных навыке» Многие системы автоматического машинного обучения (AutoML) при большое количестве гиперпараметров полагаются на случайный поиск (см. Golovin D. et al Google Vizier: A Service for Black-Box Optimization. — 2017). Эвристическое прави- ло: стоит обращаться к случайному поиску, когда размерность задачи оптимизации гиперпараметров велика (скажем, превосходит 16). Повторим предыдущий пример с заменой поиска по сетке на случайный: import scipy.stats as stats from sklearn.utils.fixes import loguniform search_dict = {'kernel’: [’linear', ’rbf’], ’C: loguniform(l, 1000), ’gamma’: loguniform(0.0001, 0.1) } scorer = ’accuracy’ search_func = model_selection.Random!zedSearchCV (estimatorsvc, param_distributions=search_dict, n_iter=6, scoring=scorer, n_Jobs=-l, cv=5) search_func.fit(X, y) print (search_func.best_params_) print (search_func. best_score_) Заметим, что теперь нам не надо запускать поиск на разных пространствах для раз- личных ядер. В отличие от поиска по сетке, который систематически тестирует ка- ждое возможное значение параметра, даже неэффективное (на что нужно время : случайный поиск не зависит от нерелевантных параметров. Поиск является вероят- ностным, и каждая из попыток полезна. Поиск сокращением вдвое Как мы уже говорили, как поиск по сетке, так и случайный не используют полу- ченную ранее информацию (например, о том, что некоторые гиперпараметры ж влияют на результат или что некоторые интервалы значений неэффективны). По- этому недавно в библиотеку Scikit-leam были добавлены алгоритмь HalvingGridSearchCV и HalvingRandomSearchCV, которые помогут производить поиск I пространстве параметров последовательным сокращением вдвое (при этом страте- гией в целом может быть как случайный поиск, так и поиск по сетке). При сокращении вдвое на первом этапе оценивается качество большого числа ком- бинаций гиперпараметров, но на небольшом числе примеров. Маленький размет обучающего множества требует меньшего количества вычислительных ресурсоь
Глава 8. Оптимизация гиперпараметров 223 но ценой меньшей точности в оценке качества. Этот первый этап позволяет вы- дать подмножество значений-кандидатов для гиперпараметров (показавших наи- лучшие результаты), которые будут проверяться на втором этапе, на большем обу- чающем множестве. Следующие этапы проходят аналогично, вовлекая всё большие подмножества обу- чающего множества, в то время как количество тестируемых значений каждый раз сокращается (любая проверка теперь требует больше времени, но дает более точ- ную оценку качества). Пример кода, решающий ту же задачу, что и предыдущие: from sklearn.experimental import enable_halving_search_cv from sklearn.model_selection import HalvingRandomSearchCV search_func = HalvingRandomSearchCV(estimator=svc, param_distributions=search_dict, resource=’n_samples’3 max_resources=100, aggressive_elimination=T rue, scoring=scorer, n_Jobs=-l, cv=5, random_state=0) search_func.fit(X, y) print (search_func.best_params_) print (search_func.best_score_) Сокращение вдвое передает информацию следующему шагу оптимизации, отбирая юзможные значения гиперпараметров. В следующих разделах мы обсудим еще эолее продвинутые методы поиска в пространстве гиперпараметров, более точные I эффективные. Казуки Онодера https://www.kaggle.com/onodera Прервемся для интервью с еще одним кэгглером. Казуки Онодера — гроссмейстер в категории Competitions и мас- тер в категории Discussions, за плечами у которого более 7 лет соревновательного опыта. Он также является стар- шим исследователем данных по глубокому обучению.
224 Часть II. Оттачивание соревновательных навыке* (Senior Deep Learning Data Scientist) в компании NVIDIA и членом команды NVIDIA KGMON (Kaggle Grandmasters of NVIDIA — гроссмейстеры Kaggle из NVIDIA). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Соревнования, похожие на Instacart Market Basket Analysis. Этот конкурс оказал- ся сложным для многих кэгглеров. В нем по анонимизированным данным заказов покупателей надо было предсказать, какие продукты будут в следующем заказе. Мне конкурс понравился, т. к. я люблю преобразования признаков и смог приду- мать несколько хороших и интересных признаков, до которых не додумались другие. Так я занял второе место. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я стараюсь представить, как работает модель, и понять причину ложноположи- тельных и ложноотрицательных результатов — все как и в обычной работе. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Это конкурс Human Protein Atlas — Single Cell Classification. Задача выглядела как задача сегментации, но на деле это была скорее задача многоклассовой клас- сификации с ненадежной разметкой (weakly supervised). Я создал двухступенча- тую схему удаления шума из меток. Помог ли тебе Kaggle в карьере? Если да, то как? Да, сейчас я работаю в команде NVIDIA KGMON (Kaggle Grandmasters of NVIDIA). Kaggle проводит множество конкурсов по машинному обучению, раз- личающихся по типу данных (таблицы, изображения, тексты, сигналы) и области (промышленность, финансы, астрономия, медицина, спорт, продажи и т. д.). Ду- маю, никто, кроме кэгглеров, не имеет опыта со всеми этими типами задач. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Анализ целевой переменной (target analysis). Также недооценено усреднение по начальным состояниям (seed averaging) — простой, но мощный метод. Какие ошибки ты допускал на соревнованиях? Ошибки в анализе целевой переменной. Лидеры всегда превосходят в этом ос- тальных, поэтому я всегда после неудач читал разбор лучших решений и пони- мал, что в данных я упустил. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Просто Python и Jupyter Notebooks.
Глава 8. Оптимизация гиперпараметров 225 О чем важнее всего помнить, приступая к участию в соревновании? Если проигрыш позволяет научиться новому, это не проигрыш. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Да, KDD Сир и RecSys. Обе удовлетворяют минимальным требованиям — инте- ресные и непростые задачи. Ключевые параметры и их использование Следующая задача— использовать правильный набор гиперпараметров для каж- дой модели. В частности, чтобы эффективно проводить оптимизацию, необходимо для каждого гиперпараметра знать, какие значения имеет смысл проверить. В этом разделе мы рассмотрим самые распространенные на конкурсах Kaggle, в особенности табличных, модели и гиперпараметры, которые необходимо подобрать для наилучшего результата. Мы выясним разницу между классическими моделями машинного обучения и моделями градиентного бустинга. Что касается нейронных сетей, мы вкратце расскажем о параметрах для стандарт- ных моделей (например, для TabNet). Однако в основном на конкурсах приходится оптимизировать не стандартные модели, а построенные под конкретную задачу. Таким образом, помимо основных параметров, таких как скорость обучения и раз- мер пакета (batch), оптимизация нейронных сетей зависит от архитектуры. В конце главы мы обсудим пример так называемого NAS (neural architecture search, поиск нейронной архитектуры) с использованием KerasTuner (https://keras.io/keras_tuner/). Линейные модели Обычно это модели линейной или логистической регрессии с регуляризацией: • С— стоит проверять значения из np.logspace(-4, 4, 10); меньшие значения соответствуют более сильной регуляризации; • alpha — стоит проверять значения из np.logspace(-2, 2, 10); большие значения соответствуют более сильной регуляризации и требуют больше времени при использовании метода лассо; • ll_ratio — стоит проверять значения из [.1, .5, .7, .9, .95, .99, 1]; исполь- зуется только для метода elastic net. В Scikit-leam в зависимости от алгоритма вы ищете либо гиперпараметр с (логисти- ческая регрессия), либо alpha (лассо, гребневая регрессия, elastic net). Машины опорных векторов Машины опорных векторов (SVM) — семейство мощных методов обучения с учи- телем для классификации и регрессии, подходящих как для линейных, так и для
226 Часть II. Оттачивание соревновательных навыков нелинейных моделей. Библиотека Scikit-leam предлагает реализацию, основанную на LIBSVM (библиотеке с полным набором реализаций SVM для регрессии и клас- сификации) и LIBLINEAR (библиотеке для линейной классификации, идеальной для больших данных, в особенности разреженных текстовых). При оптимизации машины опорных векторов стремятся разделить классы такой границей, чтобы ши- рина разделяющей полосы была максимальной. Хотя SVM неплохо работает и с параметрами по умолчанию, они все же зачастую не оптимальны, так что вам нужно искать наилучшую комбинацию значений с по- мощью кросс-валидации. Вам необходимо выставить следующие параметры (в по- рядке убывания важности). • с — штраф. Уменьшение с делает шире разделяющую полосу между класса- ми, игнорируя шум и повышая обобщающую способность модели. Опти- мальное значение обычно лежит в np.logspace(-3, 3, 7). • kernel— определяет, как SVM справляется с нелинейностью. Возможные значения: ’linear’, ’poly’, ’rbf’, ’sigmoid’ или ваше собственное ядро. Чаще всего, безусловно, используется ядро радиального базиса. • degree— относится к kernel='poly’, задает степень многочлена, при другом выборе ядра игнорируется. Оптимальное значение обычно от 2 до 5. • gamma— относится к типам ядра ’rbf’, ’poly’ и ’sigmoid’. Большие значения дают лучшее соответствие данным, но могут привести к переобучению. Можно представлять себе этот параметр как степень влияния одного примера на модель. Маленькие значения говорят, что влияние каждого примера про- стирается дальше. Разделяющая кривая, построенная SVM, будет более глад- кой и менее сложной формы, не будет подстраиваться под каждую отдель- ную точку. Большие значения gamma, напротив, означают, что кривая учитывает каждую из точек и приобретает более неправильную и извилистую форму. Мы предлагаем искать этот гиперпараметр в пр.logspace(-3, з, 7). • пи — для регрессии и классификации с использованием nuSVR и nuSVC этот параметр задает степень толерантности к примерам, классифицированным неправильно либо близким к границе. Помогая игнорировать такие примеры, он делает разделяющую кривую более гладкой. Этот параметр имеет смысл для доли обучающих данных, поэтому должен лежать в промежутке [0, 1]. По итогу он действует аналогично с, большие его значения увеличивают разде- ляющую полосу. • epsilon — этот параметр задает допустимую ошибку для регрессии, т. е. ин- тервал, в котором не накладывается штраф. Мы советуем искать его в пр.logspace(-4, 2, 7). • penalty, loss, dual — применяются к LinearSVC и допускают комбинации зна- чений (’ll’, ’squared_hinge', False), (’12’, ’hinge’, True), (’12’, ’squared_hinge’. True), (’12’, ’squared_hinge’, False). Комбинация (’12’, ’hinge’, True) эквива- лентна использованию алгоритма SVC (kernel=*linear’).
Глава 8. Оптимизация гиперпараметров 227 Может показаться, что у SVM очень много параметров, однако часть их относится только к конкретным реализациям или ядрам. Случайные леса и экстремально рандомизированные деревья Основную идею алгоритма случайного леса придумали (и зарегистрировали как торговую марку, хотя сам алгоритм доступен открыто) Лео Брейман (Leo Breiman) и Адель Катлер (Adele Cutler). Случайные леса реализованы в Scikit-leam в классах RandomForestClassifier и RandomForestRegressor. Случайные леса работают аналогично бэггингу, также придуманному Лео Брейма- ном, но используют только бинарные деревья принятия решений, которые при этом растят до конца. При этом каждое дерево использует случайный семпл примеров (полученный с помощью бутстрэппинга). Набор переменных, по которому проис- ходит каждое из ветвлений, также выбирается случайно. Главная идея алгоритма случайного леса: благодаря разным семплам и различным наборам переменных для ветвления мы получаем очень разные деревья, не связан- ные друг с другом. Это дает преимущество: при объединении результатов случай- ные отклонения в основном компенсируют друг друга. Иными словами, алгоритмы бэггинга гарантируют разнообразие предсказаний и позволяют заметить законо- мерности, которые не заметит, например, одно дерево. Таким образом, мы строим набор предсказаний, среднее которых будет лучше, чем каждое в отдельности. Экстремально рандомизированные деревья (extremely randomized trees, extra Tees) представлены в библиотеке Scikit-leam классами ExtraTreesClassifier/ ExtraTreesRegressor. Это более рандомизированная версия случайного леса, дающая эценки с меньшим разбросом, но большим смещением. Так как экстремально ран- домизированные деревья работают быстрее случайных лесов, они могут идеально подойти для больших (как по количеству примеров, так и по количеству признаков) данных. Причина большей скорости и большего смещения оценок в том, как произ- водится разбиение. Случайный лес, выбрав подмножество признаков, по которым может производиться разбиение, ищет среди них оптимальный. В экстремально рандомизированном дереве, однако, случайно определяется как набор признаков- хандидатов, так и выбор среди них. Это позволяет избежать большого количества вычислений, но может привести к неоптимальному выбору. Ключевые гиперпараметры для обоих алгоритмов: • max_features — количество признаков, которые рассматриваются при каждом разбиении. Параметр влияет на скорость работы: чем он меньше, тем алго- ритм быстрее, но тем больше смещение ответов; • min_samples_leaf — признак, влияющий на глубину дерева. Большие значения уменьшают разброс и увеличивают смещение; • bootstrap — булево значение, разрешающее бутстрэппинг;
228 Часть II. Оттачивание соревновательных навыков • n_estimators — количество деревьев. Чем их больше, тем лучше, но с опреде- ленного момента приращение качества будет несущественным. Надо учиты- вать и имеющиеся вычислительные ресурсы. Экстремально рандомизированные деревья являются хорошей альтернативой слу- чайному лесу, особенно в случае сильно зашумленных данных. Так как они отли- чаются меньшим разбросом и большим смещением, они менее, чем случайные ле- са, склонны к переобучению и принятию шума за закономерности. Градиентный бустинг над деревьями Градиентный бустинг над решающими деревьями (gradient tree boosting, gradient boosting decision trees, GBDT) — это один из вариантов общей схемы бустинга (по- следовательного применения ряда слабых алгоритмов). Как и алгоритм AdaBoost, GBDT основан на алгоритме градиентного спуска. Он показал себя одним из самых мощных ансамблевых методов, хотя и отличается большим разбросом оценок и чувствительностью к шуму (обе проблемы можно смягчить использованием под- выборок в данных), а также довольно большим временем работы (т. к. не может быть полностью распараллелен). Кроме алгоритмов глубокого обучения, градиентный бустинг считается самым продвинутым методом машинного обучения. С момента появления алгоритма AdaBoost и первой реализации градиентного бустинга, принадлежащей Джерому Фридману (Jerome Friedman), появилось много других вариантов, самыми совре- менными из которых являются XGBoost, LightGBM и CatBoost. LightGBM Высокопроизводительный алгоритм LightGBM (https://github.com/Microsoft/ LightGBM) может работать на нескольких компьютерах и быстро обрабатывать большие объемы данных. Он был разработан группой сотрудников Microsoft как открытый проект на GitHub (и был описан ими в статье https:// papers.nips.ee/paper/2017/hash/6449f44al02fde848669bdd9eb6b76fa-Abstract.html). LightGBM, как и XGBoost, основан на деревьях принятия решений, но следует дру- гой стратегии. В то время как XGBoost растит дерево по уровням, LightGBM растит его по листьям или, говоря языком алгоритмов, на графах; XGBoost осуществляет поиск в ширину, a LightGBM — поиск в глубину. Это позволяет LighGBM быстро получить хорошее соответствие с данными. Дерево выходит иным, чем при исполь- зовании XGBoost (поэтому можно соединить два решения и уменьшить разброс оценок). Настройка гиперпараметров LightGBM кажется пугающей задачей, поскольку их более сотни (как можно узнать на https://github.com/Microsoft/LightGBM/ blob/master/docs/Parameters.rst или https://lightgbm.readthedocs.io/en/latestz Parameters.html).
Глава 8. Оптимизация гиперпараметров 229 Ча практике обычно больше всего влияют на результат следующие из них: • n_estimators — целое число от 10 до 10000, задающее количество деревьев; • learning^rate— вещественное число от 0.01 до 1.0, обычно случайно выбран- ное из логарифмически равномерного распределения, представляет собой шаг алгоритма градиентного спуска (вычисляющего веса для ансамбля всех предшествующих итераций алгоритма); • max_depth — целое число от 1 до 16, задающее максимальное количество ветв- лений в дереве. Отрицательные значения этого параметра означают макси- мальное возможное число разбиений (обычно приводящее к переобучению); • num_leaves — целое число от 2 до 2Amax_depth, задающее максимальное число листьев в каждом дереве; • min_data_in_leaf — целое число от 0 до 300, задающее минимальное количест- во примеров в одном листе; • minjgain_to_split — вещественное число от 0 до 15, задающее минимальную информативность ветвления. Этот параметр позволяет избежать ненужных ветвлений и тем избежать переобучения (соответствует параметру gamma в XGBoost); • max_bin— целое число от 32 до 512, задающее максимальное число групп (bins), на которые будут поделены значения признака. Значения, большие значения по умолчанию (255), несут больший риск переобучения; • subsample— вещественное число от 0.01 до 1.0, задающее долю выборки, ис- пользуемую при обучении каждого из деревьев; • subsample_freq — целое число от 0 до 10, задающее частоту, с которой алго- ритм будет случайно выбирать примеры; При нулевом значении этого параметра (которое является значе- нием по умолчанию!) будет игнорироваться параметр subsample. • feature_fraction— вещественное число от 0.1 до 1.0, задающее долю призна- ков, используемую при обучении каждого из деревьев. Такой механизм по- зволяет добавить в обучение случайности, уменьшить влияние шума и муль- тиколлинеарности в признаках; • subsample_for_bin — целое число от 30 до количества обучающих примеров, задает количество примеров для построения разбиения для гистограммы; • regJLambda— вещественное число от 0 до 100.0, параметр Ь2-регуляризации. Важен скорее порядок, чем точное значение этого параметра. Обычно берет- ся из логарифмически равномерного распределения;
230 Часть II. Оттачивание соревновательных навыка* • reg_alpha— вещественное число от 0 до 100.0, параметр L1-регуляризации Обычно берется из логарифмически равномерного распределения; • scale_pos_weight — вещественное число от le-б до 500, обычно берется из ло- гарифмически равномерного распределения и борется с дисбалансом классов, изменяя размер положительного класса относительно отрицательного (взято- го за 1). Хотя количество гиперпараметров алгоритма LightGBM может пугать, на деле важны лишь немногие из них. При заданных количестве итераций и скорости обу- чения влияют на результат только некоторые (feature_fraction, num_leaves, subsample reg_lambda, reg_alpha, min__data_in_leaf), объяснение чему можно найти в посте гросс- мейстера Кохея Озаки (Kohei Ozaki): https://medium.com/optuna/lightgbm-tuner- new-optuna-integration-for-hyperparameter-optimization-8b7095e99258. Кохев Озаки использует этот факт для быстрой настройки параметров фреймворка Optima (о котором мы поговорим в конце главы). XGBoost Название алгоритма XGBoost (https://github.com/dmlc/XGBoost) расшифровывает- ся как extreme Gradient Boosting— "экстремальный градиентный бустинг". Эк проект с открытым исходным кодом, не являющийся частью Scikit-leam (хотя не- давно в Scikit-leam был добавлен класс-обертка). XGBoost приобрел известность в 2015 г. благодаря соревнованиям по науке о дан- ных, в частности, Kaggle и KDD Сир 2015. Как писали в своих статьях его создате- ли, Тяньци Чен (Tianqui Chen), Тонг Хе (Tong Не) и Карлос Гестрин (Carlos Guestrin), из 29 конкурсов Kaggle 2015 г. 17 решений-победителей использовалк XGBoost как единственный подход или в комбинации с другими алгоритмами. С тех пор алгоритм всегда пользовался популярностью у исследователей данных, хо- тя ему и приходилось конкурировать с другими моделями градиентного бустинга. например LightGBM and CatBoost. Кроме высокого качества результатов и скорости работы, XGBoost отличаете! масштабируемостью, по максимуму используя многопроцессорность и распреде- ленные системы. По сравнению с исходной идеей градиентного бустинга на де- ревьях XGBoost, как алгоритм нового поколения, добавляет следующие улучшения: • более эффективную (как по памяти, так и по времени) работу с разреженны- ми матрицами); • возможность приближенного обучения (более быстрого, чем обычное); • возможность параллельных и распределенных вычислений; • возможность вычислений вне ядра (out-of-core) с помощью так называемых столбцовых блоков (column blocks). XGBoost также может эффективно работать с пропущенными данными. Другие ан- самблевые методы на обычных деревьях принятия решений требуют заполнения пропусков специальными (например, отрицательными) значениями.
лава 8. Оптимизация гиперпараметров 231 Мы опишем несколько ключевых параметров XGBoost (https://xgboost.readthedocs.io/ en/latest/par ameter.html): • n_estimators — целое число, обычно от 10 до 5000; • learning_rate— вещественное число от 0.01 до 1.0, обычно берется из лога- рифмически равномерного распределения; • min_child_weight — целое число, обычно от 1 до 10; • max_depth — целое число, обычно от 1 до 50; • max_delta_step — целое число, обычно от 1 до 20, задает максимальный шаг дельта для каждого листа; • subsample— вещественное число от 0.1 до 1.0, задающее долю выборки, ис- пользуемую при обучении каждого дерева; • colsample_bytree— вещественное число от 0.1 до 1.0, задающее долю столб- цов, используемую при обучении каждого дерева; • colsample_bylevel — вещественное число от 0.1 до 1.0, задающее долю подвы- борки по уровням; • reg_lambda— вещественное число от 1е-9 до 100.0, параметр Ь2-регуля- ризации. Обычно берется из логарифмически равномерного распределения; • reg_alpha — вещественное число от 1е-9 до 100.0, параметр L1-регуляризации. Обычно берется из логарифмически равномерного распределения; • gamma — задает минимальное уменьшение функции потерь при ветвлении де- рева, вещественное число от 1е-9 до 0.5, обычно берется из логарифмически равномерного распределения; • scale_pos_weight— вещественное число от 1е-6 до 500.0, обычно берется из логарифмически равномерного распределения и борется с дисбалансом клас- сов, изменяя размер положительного класса относительно отрицательного. Многие гиперпараметры XGBoost аналогичны гиперпараметрам LightGBM, поэто- му сказанное выше про этот алгоритм применимо и к XGBoost. CatBoost 3 июле 2017 г. российский поисковик Яндекс опубликовал еще один интересный Алгоритм градиентного бустинга — CatBoost (https://catboost.ai/), название которо- го представляет собой аббревиатуру из слов category и boosting. Сильной стороной этого алгоритма является работа с категориальными признаками, зачастую состав- тяющими большую часть информации в базах данных. Для этого применяется лратегия, совмещающая прямое и целевое (о котором мы говорили в главе 7) ко- тирование. *1дея кодирования категориальных признаков, заложенная в CatBoost, не является полностью новой, но раньше такой способ преобразования признаков применялся в основном на соревнованиях. Целевое кодирование (target encoding, также likelihood encoding, impact coding, mean encoding) — это способ преобразования признаков в
232 Часть II. Оттачивание соревновательных навыков число на основе их связи с целевой переменной. В задаче регрессии, например, можно преобразовать признак в среднее значение целевой переменной, соответст- вующее этому значению признака, в задаче классификации — в вероятность поло- жительного класса при данном значении признака. Этот простой и оригинальный прием, тем не менее, имеет некоторые побочные эффекты (в основном касающиеся переобучения), поскольку при предсказаниях используется информация об ответах. CatBoost имеет довольно много параметров (https://catboost.ai/en/docs/reference& training-parameters/), но мы поговорим только о восьми самых важных: • iterations — целое число, обычно от 10 до 1000, иногда больше (зависит от за- дачи); • depth — целое число от 1 до 8, обычно большие значения дают большее время обучения, но не лучший результат; • learning_rate— вещественное число от 0.01 до 1.0, обычно берется из лога- рифмически равномерного распределения; • random_strength — вещественное число, обычно из промежутка от 1е-9 до 10.0. задает уровень случайности при ветвлении; • bagging_temperature— вещественное число от 0.0 до 1.0, байесовский бутст- рэп; • border_count — целое число между 1 и 255, количество разбиений для число- вых признаков; • 12_leaf_reg — целое число от 2 до 30, параметр L2-регуляризации; • scale_pos_weight— вещественное число от 0.01 до 10.0, вес положительного класса. CatBoost имеет некоторые отличия от других алгоритмов градиентного бустинга (заметные и по набору параметров), которые могут оказаться полезными на сорев- нованиях (как при использовании в качестве единственной модели, так и в составе ансамбля). HistGradientBoosting Недавно в библиотеку Scikit-leam была добавлена новая версия градиентного бус- тинга, основанная на гистограммах LightGBM, о чем можно узнать из презентации Оливье Гризеля (Olivier Grisel) на EuroPython (https://www.youtube.com/watch?v= urVU!KbQfQ4). Она пригодна как для классификации (HistGradientBoostingClassifier). так и для регрессии (HistGradientBoostingRegressor), может использоваться в составе ансамблей и имеет небольшой набор самых важных гиперпараметров: • learning_rate— вещественное число от 0.01 до 1.0, обычно берется из лога- рифмически равномерного распределения; • max_iter — целое число от 10 до 10000; • max_leaf_nodes — целое число от 2 до 500. Рекомендуется выставлять только один из параметров max_leaf_nodes и max_depth и оставлять другой равным None;
L лава 8. Оптимизация гиперпараметров 233 • max_depth — целое число от 2 до 12; • min_samples_leaf — целое число от 2 до 300; • 12_regularization — вещественное число от 0.0 до 100.0; • max_bins — целое число от 32 до 512. Хотя отличия HistGradientBoosting от LightGBM или XGBoost не так уж велики, это еще одна модель градиентного бустинга, которую можно использовать на соревно- ваниях, в том числе в составе ансамблей. К концу этого раздела вы ближе познакомились с самыми распространенными ал- горитмами машинного обучения (кроме глубокого обучения) и их наиболее важ- ными гиперпараметрами, которые могут помочь при построении отличного кон- курсного решения. Однако это только начало, в следующем разделе мы подробно расскажем о настройке моделей с использованием байесовской оптимизации. Альберто Данезе https://www.kaggle.com/albedan Наше второе интервью в этой главе — с Альберто Данезе, главой отдела Data science в итальянской компании Nexi, которая занимается кредитными картами и цифровыми платежами. Пришедший на Kaggle в 2015г.— гроссмей- стер в категории Competitions, большую часть своих меда- лей выигравший в одиночку. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я всегда работал в финансовой индустрии и имел дело в основном со структури- рованными данными, поэтому предпочитаю их и на соревнованиях. Мне нравит- ся понимать практическое значение данных и придумывать преобразования при- знаков, чтобы извлечь из них как можно больше информации. Что касается технических деталей, мне нравится работать с классическими биб- лиотеками машинного обучения и особенно с градиентным бустингом на ре- шающих деревьях. В первую очередь я обращаюсь к таким популярным библио- текам, как XGBoost, LightGBM, CatBoost. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я всегда провожу много времени за изучением данных и пытаюсь понять, ка- кую реальную задачу спонсор хочет решить с помощью машинного обучения. Вопреки представлениям новичков о Kaggle, я не слишком много времени про- вожу за настройкой параметров конкретного алгоритма, и такой подход себя оправдывает.
234 Часть II. Оттачивание соревновательных навыков В моей обычной работе также критически важно понимать данные, но есть и не- которые дополнительные аспекты, полностью отсутствующие на конкурсах. Мне необходимо: • определить (совместно с коллегами из других отделов) бизнес-задачу, ко- торую нужно решить с помощью машинного обучения; • найти данные, иногда из внешних источников; • создав модель, понять, как ее внедрять и поддерживать. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Мне очень понравился конкурс TalkingData AdTracking Fraud Detection Challenge. после которого я стал гроссмейстером. Помимо очень интересной темы (борьбы с мошенничеством от ботоферм), этот конкурс отличался огромным объемом данных (более 100 млн строк), что заста- вило искать нестандартные преобразования признаков и думать, как сократить время вычислений. На этом конкурсе мне также пришлось понять, как использо- вать оконные функции, чтобы рассматривать задачу как анализ временного ряда. Помог ли тебе Kaggle в карьере? Если да, то как? Определенно! Объективные и проверяемые высокие результаты, конечно, позво- ляют вашему резюме выделиться из общей массы. Когда я устраивался на работу в компанию Cerved в 2016 г., нанимающий менеджер отлично понимал, что такое Kaggle, — а иметь возможность обсудить на интервью конкретные проекты все- гда полезно. Безусловно, Kaggle сыграл важную роль в моей карьере. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Все просто начинают писать код, возможно, копируя и слегка меняя одно из опубликованных решений. Это нормально для начинающего, но на самом деле необходимо уделить немало времени изучению данных и пониманию задачи. Какие ошибки ты допускал на соревнованиях? Не знаю, считается ли это ошибкой, но я часто предпочитал соревноваться в одиночку. С одной стороны, это заставляет тебя заниматься всеми аспектами за- дачи, а также позволяет распределять свое время по собственному желанию. Но на нескольких соревнованиях мне очень понравилось быть частью команды. На- верное, стоит чаще участвовать в конкурсах совместно с кем-то, поскольку при этом можно многому научиться. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Помимо стандартных инструментов, я очень люблю data.table (еще со времен версии для R) и считаю недооцененной эту прекрасную библиотеку, позволяю- щую локально работать с большими объемами данных. О чем важнее всего помнить, приступая к участию в соревновании? Не начинайте сразу писать код, сначала разберитесь в задаче и данных!
- лава 8. Оптимизация гиперпараметров 235 Байесовская оптимизация Поиск по сетке применим только при очень ограниченном наборе параметров. Эбычно на практике применяют случайный поиск или более сложный подход — байесовскую оптимизацию. ключевая идея байесовской оптимизации, сформулированная в статье Snoek J., La- rochelle Н., Adams R. P. ’’Practical Bayesian optimization of machine learning algo- rithms” (http://export.arxiv.org/pdf/1206.2944),— оптимизация некоторой проме- жуточной (суррогатной) функции вместо настоящей целевой функции (с которой работали поиск по сетке и случайный поиск). Мы делаем это в случаях, когда не- возможно вычислить градиент, когда вычисление целевой функции слишком слож- но или в случае шумного и сложного пространства поиска. Байесовский поиск ищет баланс между ’’разведыванием” новой области простран- гтва и использованием уже имеющейся информации (exploration и exploitation). Сначала происходит случайное ’’разведывание" и обучение суррогатной функции. На основе полученной информации берутся более полезные точки. Слово "байесов- ский" в названии подсказывает, что мы используем априорное знание, чтобы оце- нивать выбор новых точек. Таким образом мы быстрее приходим к оптимуму. Байесовская оптимизация использует функцию выбора (acquisition function), что- 5ы понять, насколько многообещающей будет следующая точка. Обычно она осно- вана на гауссовских процессах, которые лучше работают при "гладком" простран- стве поиска, с постепенным и предсказуемым изменением результатов. В более сложных ситуациях применяют парзеновские деревья (tree Parzen estimators, tree- structured Parzen estimators, ТРЕ). Вместо того чтобы напрямую строить модель, эценивающую (как оракул) успешность набора параметров, ТРЕ ищут параметры многомерного распределения, задающего наилучшие наборы параметров, на основе последовательных приближений. Таким образом, ТРЕ ищут наилучший набор па- раметров, семплируя их из распределения, а не напрямую с помощью модели ма- линного обучения, как гауссовские процессы. Мы обсудим оба подхода, сначала изучив подходы из Scikit-optimize и KerasTuner, хнованных на гауссовских процессах (Scikit-optimize может также использовать случайные леса, a KerasTuner — многоруких бандитов), а затем фреймворк Optuna, хнованный на ТРЕ (хотя предлагающий и другие стратегии: https:// •ptuna.readthedocs.io/en/stable/reference/samplers.html). Хотя байесовская оптимизация считается самым современным спосо- бом настройки гиперпараметров, помните, что для сложных про- странств параметров ее использование обычно не дает преимуществ в скорости перед случайным поиском. Так, в Google Cloud Machine Learn- ing Engine байесовская оптимизация используется лишь для задач не более чем с шестнадцатью параметрами.
236 Часть II. Оттачивание соревновательных навыке* Использование Scikiboptimize Библиотека Scikit-optimize (skopt) была разработана с применением того же APL что и Scikit-leam, а также активно использует функции из NumPy и SciPy. Ее созда- тели, в частности Жиль Лупп (Gilles Louppe), также были составителями Scikit- leam. Эта библиотека, основанная на гауссовских процессах, в целом хорошо поддержи- вается, хотя иногда и не успевает за обновлениями Scikit-leam, NumPy или SciPy Так, на момент написания книги, чтобы применять Scikit-optimize в блокнотах Kaggle, необходимо было использовать старые версии этих библиотек (см. обсуж- дение https://github.com/scikit-optimize/scikit-optimize/issues/981). Scikit-optimize имеет интуитивно понятный API, ее легко использовать в собствен- ных стратегиях оптимизации. Она также имеет полезные функции визуализации Так, с помощью функции plot_objective можно представить результаты оптимиза- ции графически и понять, как работает оптимизация и можно ли переопределил пространство поиска. В качестве примера обратимся к следующим блокнотам: • https://www.kaggle.com/lucamassaron/tutorial-bayesian-optimization-with- lightgbm; • https://www.kaggle.com/lucamassaron/scikit-optimize-for-lightgbm. Здесь мы хотим показать, как работать с задачами оптимизации для таких конкур- сов, как 30 Days of ML. например. Этот недавно прошедший популярный конкурс продолжался 30 дней и был нацелен на получение новых знаний и их применение г задаче. Целью было предсказание суммы страховой компенсации (т. е. решение задачи регрессии). Подробно прочитать о конкурсе и скачать данные можно иг https://www.kaggle.com/thirty-days-of-ml. Если доступа к данным нет, поскольку вы не принимали участия в конкурсе, можно найти датасет на https://www.kaggle.com lucamassaron/30-days-of-ml. В представленном нами коде будет показано, как загрузить данные и запустил процесс байесовской оптимизации для модели LightGBM. Начнем с загрузки биб- лиотек: # Базовые библиотеки import numpy as пр import pandas as pd from time import time import pprint import joblib from functools import partial
Глава 8. Оптимизация гиперпараметров 237 # Подавление предупреждений из-за избыточности skopt import warnings warnings.filterwarnings("ignore") # Классификаторы import lightgbm as Igb # Выбор модели from sklearn.model_selection import Kfold # Метрики from sklearn.metrics import mean_squared_error from sklearn.metrics import make_scorer # Функции Skopt from skopt import BayesSearchCV from skopt.callbacks import Deadlinestopper, DeltaYStopper from skopt.space import Real, Categorical, Integer Затем мы загружаем данные. Они почти не требуют предобработки, за исключени- ем преобразования категориальных признаков, для которых буквы алфавита обо- значают уровень, в порядковые: # Загрузка данных X = pd.read_csv("../input/30-days-of-ml/train.csv") X_test = pd.read_csv("../input/30-days-of-ml/test.csv") # Подготовка таблицы с данными у = X.target X = X.set_index(’id’).drop(’target’, axis=’columns’) X_test = X_test.set_index(’id’) # Работа с категориальными признаками categoricals = [item for item in X.columns if ’cat' in item] cat-Values = np.unique(X[categoricals].values) cat_dict = diet(zip(cat_values, range(len(cat_values)))) X[categoricals] = X[categoricals].replace(cat_dict).astype(’category’) X_test[categoricals] = X_test[categoricals].replace(cat_dict).astype(’category’)
238 Часть II. Оттачивание соревновательных навыков Теперь определим функцию, сообщающую нам о результатах оптимизации (и принимающую на вход данные и модель). Она может также работать с функция- ми обратного вызова (callback functions), сообщающими об ошибках, сохраняю- щими промежуточные состояния или осуществляющими досрочное прекращение обучения: # Создание отчетов для различных оптимизаторов def report_perf(optimizer, X, у, title="model", callbacks=None): IIIIII Оберка для измерения времени и производительности оптимизаторов optimizer - оптимизаторы sklearn или skopt X - тренировочный набор у - ваша цель title - строковая метка для эксперимента IIIIII start = time() if callbacks is not None: optimizer.fit(X, y, callback=callbacks) else: optimizer.fit(X, y) d=pd.DataFrame(optimizer.cv_results_) best_score = optimizer.best_score_ best_score_std = d.iloc[optimizer.best_index_].std_test_score best_params = optimizer.best_params_ print((title + " took %.2f seconds, candidates checked: %d, best CV score: %.3f" + u" \u00Bl"+" %.3f") % (time() - start, len(optimizer.cv_results_[’params']), best_score, best_score_std)) print('Best parameters:') pprint.pprint(best _params) print() return best_params Теперь мы должны определить функцию оценивания, стратегию валидации, модель и пространство поиска. В качестве функции оценивания мы берем RMSE. По тра- диции, в Scikit-leam мы всегда минимизируем функцию (а тем функциям, которые нужно максимизировать, меняем знак).
Глава 8. Оптимизация гиперпараметров 239 Мы делаем это с помощью обертки make_scorer: # Задаем функцию оценивания scoring = make_scorer(partial(mean_squared_error, squared=False), greater_is_better=False) # Задаем стратегию валидации kf = KFold(n_splits=5, shuffle=True, random_state=0) # Задаем базовый алгоритм регрессии reg = lgb.LGBMRegressor(boosting_type=’gbdt', metric='rmse’3 objective=’regression', n_jobs=l, verbose=-l, random_state=0) Задать пространство поиска можно с помощью таких функций из Scikit-optimize, как Real, Integer или Choice, каждая из которых использует данное ей в качестве па- раметра распределение (чаще всего равномерное, но если вас больше волнует по- рядок параметра, а не точное его значение, стоит использовать логарифмически равномерное): # Задаем пространство поиска search_spaces = { # Скорость обучения ’learning_rate’: Real(0.01, 1.0, ’log-uniform’), # Количество деревьев 'n_estimators’: Integer(30, 5000), # Максимальное число листьев 'num_leaves': Integer(2, 512), # Максимальная глубина дерева ’maX-depth’: Integer(-1, 256), # Минимальное число примеров в листе 'min_child_samples': Integer(1, 256),
240 Часть II. Оттачивание соревновательных навыков # Максимальное количество ’maX-bin': Integer(100, 1000), # Доля выборки ’subsample': Real(0.01, 1.0, ’uniform'), # Частота выбора 'subsample_freq': Integer(0, 10), # Доля столбцов 'colsample_bytree': Real(0.01, 1.0, 'uniform'), # Минимальная сумма весов 'min_child_weight': Real(0.01, 10.0, 'uniform'), # L2-регуляризация 'reg_lambda': Real(le-9J 100.0, 'log-uniform'), # LI-регуляризация 'reg_alpha': Real(le-9, 100.0, 'log-uniform'), } Итак, мы определили: • стратегию кросс-валидации; • метрику оценивания; • базовую модель; • пространство поиска. Теперь надо передать все это в функцию оптимизации, BayesSearchCV. Она будет ис- кать минимум заданной функции оценивания в пространстве поиска с помощью заданной схемы кросс-валидации. Можно также задать максимальное число итера- ций, тип суррогатной функции (в большинстве случаев хорошо работают гауссов- ские процессы) и начальное состояние случайного генератора для воспроизводимости: # Байесовский оптимизатор opt = BayesSearchCV(estimator=reg, search_spaces=search_spaces, scoring=scoring, cv=kfj n_iter=60, # максимальное количество итераций
. лава 8. Оптимизация гиперпараметров 241 n_jobs=-l, # распараллеливание iid=False, # оптимизация идет по результату кросс-валидации return_train_score=False, refit=False, # гауссовский процесс (GP) optimizer _kwargs={'base_esTimator’: ’GP’}, # начальное состояние генератора random_state=0) Теперь можно начинать поиск с помощью ранее определенной функции: # Запускаем оптимизацию overdone_control = DeltaYStopper(delta=0.0001) # Останавливаемсяj если прирост качества слишком мал time_limit_control = Deadlinestopper(total_time=60 * 60 * 6) # Ограничиваем время роботы (6 часов) best_params = report_perf(opt, X, у/LightGBM_regression', callbacks=[overdone_control, time_limit_control]) Мы ограничиваем максимально допустимое время поиска (6 часов), после которого происходит остановка и возвращается наилучший результат. Тем не менее лучшая из найденных комбинаций гиперпараметров может оказаться не лучшей из всех возможных (поскольку исследовались сначала наиболее многообещающие части пространства поиска, определенные на основе оценок суррогатной функции). Настройки байесовской оптимизации Функция BayesSearchCV из Scikit-optimize удобна тем, что объединяет в себе все ас- пекты поиска гиперпараметров, но у нее есть свои ограничения. Так, на соревнова- ниях вы можете хотеть: • иметь больше контроля над каждой из операций поиска, например чередовать случайный и байесовский поиск; • делать раннюю остановку алгоритма; • вносить изменения в стратегию валидации; • сразу прекращать эксперименты, дающие плохие результаты (например, по одному блоку кросс-валидации); • искать кластеры наборов гиперпараметров, ведущие себя сходным образом (например, для создания нескольких моделей с разными гиперпараметрами и последующего блендинга).
242 Часть IL Оттачивание соревновательных навыку Каждая из этих задач не слишком сложна при наличии доступа к внутренним про- цедурам BayesSearchCV, который, к счастью, предоставлен в Scikit-optimize. Внутр BayesSearchCV, как и внутри других классов-оберток этой библиотеки, используюта функции минимизации, которые вы можете использовать и как часть собственны! функций поиска: • gpjninimize — байесовская оптимизация с помощью гауссовских процессов; • forestjninimize — байесовская оптимизация с помощью случайных лесов иж экстремально рандомизированных деревьев; • gbrtjninimize — байесовская оптимизация с помощью градиентного бустинга: • dummyjninimize — случайный поиск. Наш новый пример будет модификацией предыдущего с нашей собственной функ- цией поиска, допускающей раннюю остановку и прекращающей эксперимент, еслк один из результатов на контрольном блоке был не слишком хорош. Он размещен на https://www.kaggle.com/lucamassaron/hacking-bayesian-optimization. Как и в предыдущем примере, мы начинаем с подключения библиотек: # Загружаем базовые библиотеки import numpy as пр import pandas as pd from time import time import pprint import joblib from functools import partial # Подавляем предупреждения из-за избыточности skopt import warnings warnings.filterwarnings("ignore") # Классификатор/регрессор from xgboost import XGBRegressor # Выбор модели from sklearn.model_selection import KFold, StratifiedKFold from sklearn.model-Selection import cross_val_score from sklearn.model_selection import train_test_split
. лава 8. Оптимизация гиперпараметров 243 # Метрики from sklearn.metrics import mean_squared_error from sklearn.metrics import make_scorer # Функции Skopt from skopt import BayesSearchCV from skopt.callbacks import Deadlinestopper, DeltaYStopper from skopt.space import Real, Categorical, Integer from skopt import gp_minimize, forestjninimize from skopt import gbrtjninimize, dummy -minimize # Декоратор для преобразования списка параметров в именованные аргументы from skopt.utils import use_named__args # Обработка данных from sklearn.preprocessing import OrdinalEncoder Л снова загружаем данные конкурса 30 Days of ML: # Загрузка данных X_train = pd.read_csv("../input/30-days-of-ml/train.csv") X_test = pd.read_csv("../input/30-days-of-ml/test.csv") # Подготовка донных в табличном виде y_train = X_train.target X_train = X_train.set_index(’id’).drop(‘target’, axis=’columns’) X_test = X_test.set_index(’id’) # Найдем категориальные признаки categoricals = [item for item in X_train.columns if ’cat’ in item] # Закодируем их с помощью OrdinaLEncoder ordinal_encoder = OrdinalEncoder() X_train[categoricals] = ordinal_encoder.fit_transform(X_train[categoricals]) X_test[categoricals] = ordinal-encoder.transform(X_test[categoricals]) Теперь мы имеем все необходимые элементы для поиска гиперпараметров: функ- зию оценивания, стратегию валидации, пространство поиска и модель машинного ?бучения. Функция оценивания и стратегия валидации затем станут главными оп-
244 Часть II. Оттачивание соревновательных навыко- ределяющими элементами для целевой функции, которую будет минимизировав байесовская оптимизация. # Настройка функции оценивания scoring = partial(mean_squared_error, squared=False) # Настройка стратегии валидации kf = KFold(n_splits=5, shuffle=True, random_state=0) # Настройка пространства поиска space = [Real(0.01, 1.0, 'uniform', name='learning_rate'), Integer(l, 8, name='max_depth'), Real(0.1, 1.0, 'uniform', name='subsample'), # Соотношение столбцов подвыборки no дереву Real(0.1, 1.0, 'uniform', name='colsample_bytree'), # L2-регуляризация Real(0, 100., 'uniform', name='regjambda'), # LI-регуляризация Real(0, 100., 'uniform', name='reg_alpha'), # minimum sum of instance weight (hessian) Real(l, 30, 'uniform', name='min_child_weight') ] model = XGBRegressor(n_estimators=10_000, booster='gbtree', random_state=0) Заметим, что на этот раз мы не задали количество деревьев (n_estimators) в про- странстве поиска, вместо этого мы задали его при создании модели, выбрав боль- шое значение, т. к. ожидаем раннюю остановку. Теперь мы должны определить целевую функцию. Она должна принимать оптими- зируемые параметры и возвращать некоторую оценку (score). Однако ей также нужны все те же элементы, что и поиску. Можно обращаться к ним из этой функ ции, но считается правильным сделать их внутренними неизменяемыми парамет- рами функции (что будет полезно, например, при распараллеливании). Этого мот? но добиться созданием функции make, принимающей перечисленные вышч элементы и возвращающей целевую функцию. После этого данные и модель буду содержаться ’’внутри” целевой функции, и передавать ей нужно будет только тес- тируемые параметры. Начнем писать нашу функцию (порой прерываясь на пояснения): # Целевая функция} которая должна быть сведена к минимуму def make_objective(model, X, у, space, cv, scoring, validation=0.2): # Этот декоратор конвертирует вашу целевую функцию # с именованными аргументами в ту, что принимает список в качестве аргумента, # при автоматическом выполнении преобразования.
Гшва 8. Оптимизация гиперпараметров 245 @use_named_args(space) def objective(**params): model.set_params(**params) print("\nTesting: ", params) validation_scores = list() for k, (train_index, test_index) in enumerate(kf.split(X, y)): val_index = list() train_examples = int(train_examples * (1 - validation)) train-index, val_index = (train_index[:train_examples], train_index[train_examples:]) start_time = time() model.fit(X.iloc[train_index,:], y[train_index], early_stopping_rounds=50, eval_set=[(X.iloc[val_index,:], y[val_index])], verbose=0) end-time = time() rounds = model.best-iteration test_preds = model.predict(X.iloc[test_index,:]) test-score = scoring(y[test_index], test_preds) print(f"CV Fold {k+1} rmse:{test_score:0.5f}-{rounds} rounds - it took {end_time-start-time:0.0f} secs") validation_scores.append(test_score) Сначала мы создаем целевую функцию, выполняем кросс-валидацию и проводим обучение с ранней остановкой. Мы использовали для экономии времени очень аг- рессивную стратегию ранней остановки, но вы можете увеличить число итераций ожидания. Заметим, что контрольные примеры берутся последовательно из обу- чающих блоков (обратите внимание на определение train-index и val_index), остав- ляя отложенные примеры (test_index) для итоговой валидации — это важно, если вы хотите избежать переобучения на данных, на которых проверяется условие ран- ней остановки. Далее, прежде чем переходить к следующим контрольным блокам, мы проверяем результат на отложенных данных: if len(history[k]) >= 10: threshold = пр.percentile(history[k], q=25) if test-score > threshold:
246 Часть II. Оттачивание соревновательных навыков print(f"Early stopping for under-performing fold: threshold is {threshold:0.5f}") return np.mean(validation_scores) history[k].append(test_score) return np.mean (validations cores) return objective Заметим, что мы определили глобальный словарь history с результатами на каждом блоке. Мы можем сравнить результаты разных экспериментов и кросс-валидаций, при заданных начальных состояниях случайного генератора результаты воспроиз- водимы и сравнимы. Если результаты на текущем блоке сильно уступают (в каче- стве отсечки можно взять первый квартиль) результатам на других итерациях, име- ет смысл остановиться и вернуть среднее по уже проверенным блокам. Обоснование заключается в том, что если один из блоков дает плохой результат, кросс-валидация в целом также будет давать плохой результат. Поэтому можно просто перейти к более многообещающему набору параметров, совершив своего рода раннюю остановку на кросс-валидации, ускоряющую поиск параметров. Теперь мы упаковываем все элементы (модель, данные, пространство поиска, стра- тегию валидации, функцию оценивания) в целевую функцию с помощью make_objective. В результате мы получили функцию, принимающую набор гиперпа- раметров и возвращающую оценку, на основе которой алгоритм оптимизации будет выбирать дальнейшие действия: objective = make__objective (model, X_train, y_train, space=space, cv=kf, scoring=scoring) Так как мы хотим контролировать каждый шаг оптимизации для дальнейшего ис- пользования, мы также заведем функцию, записывающую результаты всех прове- денных экспериментов. На основе этой информации можно в любой момент оста- новить, а затем снова возобновить алгоритм оптимизации: def onstep(res): global counter x0 = res.x_iters # Список входных точек y0 = res.func_vals # Оценка входных точек print(’Last eval: х0[-1], ' - Score у0[-1])
Глава 8. Оптимизация гиперпараметров 247 print('Current iter: ', counter, ' - Best Score res.fun, ' - Best Args: ', res.x) # Сохранение контрольной точки на диск joblib.dump((x0, у0), 'checkpoint.pkl') counter += 1 Теперь мы готовы запускать байесовскую оптимизацию. В качестве начальных то- чек мы берем несколько наборов гиперпараметров, взятых с помощью случайного поиска (функция dummyjninimize), и сохраняем их результаты: counter = 0 history = {i:list() for i in range(5)} used_time = 0 gp_round = dummy_minimize(func=objective, dimensions=space, n_calls=30, callback=[onstep], random_state=0) Затем мы можем извлечь сохраненные результаты экспериментов и вывести про- тестированные наборы гиперпараметров вместе с их результатами. Наборы гипер- параметров и результаты хранятся в списках х0 и у0: х0, у0 = joblib.load('checkpoint.pkl') print(1еп(х0)) Теперь мы можем даже возобновлять работу оптимизации, меняя пространство по- иска, функцию выбора, количество вызовов или callbacks: х0, у0 = joblib.load('checkpoint.pkl') gp_round = gp_minimize(func=objective, x0=x0, # уже рассмотренные значения для х у0=у0, # наблюдаемые значения для х0 dimensions=space, acq_func='gp_hedge', n_calls=30, n_initial_points=0, callback=[onstep], random_state=0)
248 Часть II. Оттачивание соревновательных навыке* Когда результат нас устраивает и мы завершаем оптимизацию, мы можем вывеете как наилучший результат, так и набор гиперпараметров: х0, у0 = joblib.load('checkpoint.pkl') print(f"Best score: {gp_round.fun:0.5f}") print("Best hyperparameters:") for sp, x in zip(gp_round.space, gp_round.x): print(f"{sp.name:25} : {x}") Зная их, мы можем заново обучить модель для использования на соревновании. Имея наборы параметров и соответствующих результатов (списки х0 и у0), мы мо- жем кластеризовать наборы параметров со схожими результатами. Это позволяет обучить несколько моделей с разными параметрами, но близким качеством. Этс идеальная ситуация для блендинга, т. е. усреднения нескольких моделей, чтобы уменьшить разброс оценок. Более подробно о блендинге рассказано в главе 9. Обобщение байесовской оптимизации на параметры нейронных сетей Перейдя в область глубокого обучения, мы обнаруживаем, что у нейронных сетей также довольно много гиперпараметров: • размер пакета (batch); • скорость обучения; • тип алгоритма оптимизации и его параметры. Все они влияют на обучение, и порой небольшое различие в размере пакета иле скорости обучения оказывается критичным в вопросе, сможет ли сеть уменьшите свою ошибку до нужного уровня. Тем не менее это не все параметры глубоких нейронных сетей, которые вы можете оптимизировать. Еще большее значение имеет архитектура нейросети. По сути, архитектура задает выразительную способность сети, в зависимости от нее сеть либо будет способна извлечь нужную информацию из данных, либо нет. Прь работе с другими алгоритмами машинного обучения выбор параметров велик, нс ограничен, с глубокими нейронными сетями он кажется бесконечным, вы ограни- чены только собственными знаниями и опытом.
лава 8. Оптимизация гиперпараметров 249 fro стоит делать для создания отлично работающих нейронных сетей? • Использовать предобученные модели (для чего необходимо знать об имею- щихся решениях, например, с GitHub или Hugging Face (https://huggingface.co models). • Читать новые статьи. • Копировать лучшие блокноты с текущего или предыдущих конкурсов Kaggle. • Использовать метод проб и ошибок. Изобретательность и удача также не помешают! Профессор Джеффри Хинтон (Geoffrey Hinton) в своей знаменитой лекции говорит, иго таких же, если не лучших, результатов можно добиться автоматическими мето- нами, подобными байесовской оптимизации. Байесовская оптимизация предотвра- тит ситуацию, в которой вы не можете найти лучшие комбинации гиперпараметров среди огромного числа возможностей. Запись лекции можно найти на https://www.youtube.com/watch7vM0cKa0di_lo, а слайды — на https://www.cs.toronto.edu/~hinton/coursera/lecturel6/lecl6.pdf. Как мы уже упоминали, даже в самых продвинутых системах автоматического ма- линного обучения при слишком большом числе гиперпараметров случайный поиск тает такие же или лучшие результаты за данное время по сравнению с байесовской оптимизацией. Однако при этом приходится бороться с тем, что пространство по- иска изобилует крутыми склонами и ямами. Более того, в оптимизации нейронных гетей многие параметры будут не вещественными, а булевыми, и их варьирование может радикально изменить качество результатов — к лучшему или к худшему. По нашему опыту, на соревнованиях случайный поиск гиперпараметров себя не оправдывает из-за ограниченности времени и ресурсов. Нужно использовать пре- ныдущие результаты оптимизации в дальнейшем поиске. Для этого идеальна байе- говская оптимизация: ее можно проводить поэтапно, постепенно улучшая резуль- тат, и учитывать наличие времени и вычислительных ресурсов. Кроме того, поскольку нейронные сети обычно работают на GPU, вы вряд ли сможете восполь- зоваться распараллеливанием. Байесовская оптимизация рассчитана на использова- ние одного компьютера. Наконец, хотя поиск оптимальных параметров и является непростой задачей, использование информации от предыдущих этапов позволяет избежать совсем плохих комбинаций гиперпараметров. При случайном же поиске, если не изменять на ходу само пространство поиска, может попасться любая из юмбинаций. Тем не менее у байесовской оптимизации есть и недостатки. Она использует сурро- гатную функцию, построенную на основе предшествующей информации, не всегда
250 Часть II. Оттачивание соревновательных навыков свободной от ошибок. Есть некоторая вероятность, что процесс оптимизации будет исследовать только один из участков пространства поиска, игнорируя остальные (в том числе, возможно, содержащие искомый минимум). Решением может быть про- ведение большого числа попыток или чередование байесовской оптимизации и случайного поиска (когда байесовской модели в некоторый момент дается случай- ная комбинация гиперпараметров). Для того чтобы привести пример, мы опять будем использовать данные для задачи регрессии с конкурса 30 Days of ML. Пример использует TensorFlow, но при не- больших изменениях может работать и с другими фреймворками для глубокого обучения, например PyTorch и MXNet. Вы можете найти код на Kaggle: https://www.kaggle.com/lucamassaron/ hacking-bayesian-optimization-for-dnns. Начнем: import tensorflow as tf Загрузив библиотеку TensorFlow, мы используем ее класс Dataset, чтобы передавать нейросети порции (пакеты, batches) данных: def df_to_dataset(dataframe, shuffle=True, batch_size=32): dataframe = dataframe.copy() labels = dataframe.pop('target') ds = tf.data.Dataset.from_tensor_slices((diet(dataframe), labels)) if shuffle: ds = ds.shuffle(buffer_size=len(dataframe)) ds = ds.batch(batch_size) return ds tf.keras.utils.get_custom_objects().update({'leaky-relu': tf.keras.layers. Activation(tf.keras.layers.LeakyReLU(alpha=0.2))}) В качестве функции активации мы будем использовать протекающую (leaky) ReLU. Напишем функцию, создающую нейросеть по набору гиперпараметров: def create_model(cat0_dim, catl_dim, cat2_dim, cat3_dim, cat4_dim, cat5_dim, cat6_dim, cat7_dim, cat8_dim, cat9_dim,
лава 8. Оптимизация гиперпараметров 251 layers, 1ауег_1, 1ауег_2, 1ауег_3, 1ауег_4, 1ауег__5, activation, dropout, batch_normalization, learning__rate, **others): dims = {’cat0': cat0_dim, ’catl’: catl_dim, ’cat2’: cat2_dim, ’cat3’: cat3_dim, ’cat4': cat4_dim, ’cat5': cat5_dim, ’cat6’: cat6_dim, ’cat7’: cat7_dim, ’cat8’: cat8_dim, ’cat9’: cat9_dim} vocab = {h:X_train[’cat4’].unique().astype(int) for h in [’cat0’, ’catl’, ’cat2’, ’cat3’, ’cat4’, ’cat5’, ’cat6’, ’cat7’, ’cat8’, ’cat9’]} layers = [layer_l, layer_2, layer_3, layer_4, layer_5][:layers] feature_columns = list() for header in [’contl’, ’cont2', ’cont3’, ’cont4’, ’cont5’, ’cont6’,’cont7’, ’cont8’, ’cont9’, ’contl0’, ’contll’, ’contl2’, ’contl3’]: feature_columns.append(tf.feature_column.numeric_column(header)) for header in [’cat0’, ’catl’, ’cat2’, ’cat3’, ’cat4’, ’cats’, ’cat6’, ’cat7’, ’cat8’, ’cat9’]: feature_columns.append( tf.feature_column.embedding_column( tf.feature_column.categorical_column_with_vocabulary_list( header, vocabulary_list=vocab[header]), dimension=dims[header])) feature_layer = tf.keras.layers.DenseFeatures(feature_columns) network_struct = [feature_layer] for nodes in layers: network_struct.append( tf.keras.layers.Dense(nodes, activation=activation))
252 Часть II. Оттачивание соревновательных навыков if batch_normalization is True: network_struct.append( tf.keras.layers.BatchNormalization()) if dropout > 0: network_struct.append(tf.keras.layers.Dropout(dropout)) model = tf.keras.Sequential(network_struct + [tf.keras.layers.Dense(1)]) model.compile(optimizer=tf.keras.optimizers.Adam( learning_rate=learning_rate)} loss= tf.keras.losses.MeanSquaredError()} metrics=['mean_squared_error’]) return model Код внутри функции createjnodel задает архитектуру нейронной сети на основе пе- реданных функции аргументов. Так, вы можете задать размерность встраивания для каждой категориальной переменной или структуру и количество полносвязных слоев. Все эти параметры относятся к пространству, которое мы хотим исследовать с помощью байесовской оптимизации, поэтому каждый входной параметр функ- ции, строящей модель, должен быть связан с семплирующей функцией в простран- стве поиска. Для этого достаточно передать список семплирующих функций в по- рядке, ожидаемом функцией createjnodel: # Настройка пространства поиска space = [Integer(l, 2, name=’cat0_dim1)} Integer(1, 2, name=’catl_dim’ Integer(l, 2, name=’cat2_dim’)3 Integer(1, 3, name=’cat3_dim’), Integer(l, 3, name=’cat4_dim’)} Integer(l, 3, name=,cat5_dim’), Integer(1, 4, name=,cat6_dim’), Integer(1, 4, name=1cat7_dim’), Integer(1, 6, name=,cat8_dim’), Integer(1, 8, name=’cat9_dim’ Integer(1, 5, name=’layers’)> Integer(2, 256, name=’layer_l’) Integer(2, 256, name=’layer_2 ’) Integer(2, 256, name=’layer_3 ’)
Глава 8. Оптимизация гиперпараметров 253 Integer(2, 256, name= ’ layer_4 ’), Integer(2, 256, name=’layer_5’), Categorical([’relu’, ’leaky-relu’], name=’activation’), Real(0.0, 0.5, ’uniform’, name=’dropout’), Categorical([True, False], name=’batch_normalization’), Categorical([0.01, 0.005, 0.002, 0.001], name='learning_rate’), Integer(256, 1024, name=’batch_size’) ] Как мы уже показывали, теперь на основе всех необходимых элементов (таких как данные и стратегия кросс-валидации) создается целевая функция: def make_objective(model_fn, X, space, cv, scoring, validation=0.2): # Этот декоратор конвертирует вашу целевую функцию # с именованными аргументами в ту, что принимает список в качестве аргумента, # при автоматическом выполнении преобразования. @use_named_args(space) def objective(**params): print(’’\nTesting: ’’, params) validation_scores = list() for k, (train_index, test_index) in enumerate(kf.split(X)): val_index = list() train_examples = len(train_index) train_examples = int(train_examples * (1 - validation)) train_index, val_index = (train_index[:train_examples], train_index[train_examples:]) start_time = time() model = model_fn(**params) measure_to_monitor = ’val_mean_squared_error’ modality=’min’ early_stopping = tf.keras.callbacks.EarlyStopping( monitor=measure_to_monitor mode=modality, patience=5, verbose=0)
254 Часть II. Оттачивание соревновательных навыке* model_checkpoint = tf.keras.callbacks.Modelcheckpoint( ’best.model’, monitor=measure_to_monitor, mode=modality, save_best_only=T rue, verbose=0) run = model.fit(df_to_dataset( X_train.iloc[train_index, :], batch_size=params[’batch_size’ ]), validation_data=df_to_dataset( X_train.iloc[val_index, :], batch_size=1024), epochs=l_000, callbacks=[model_checkpoint, early_stopping], verbose=0) end_time = time() rounds = np.argmin(run.history['val_mean_squared_error’]) + 1 model = tf.keras.models.load_model(’best.model’) shutil.rmtree(’best.model’) test_preds = model.predict(df_to_dataset( X.iloc[test-index, :], shuffle=False, batch_size=1024)).flatten() test-score = scoring( X.iloc[test_index, :][’target’], test_preds) print(f’’CV Fold {k+1} rmse:{test_score:0.5f} - {rounds} rounds - it took {end_time-start-time:0.0f} secs’’) validation_scores.append(test_score) if len(history[k]) >= 10: threshold = np.percentile(history[k], q=25) if test_score > threshold:
лава 8. Оптимизация гиперпараметров 255 print(f"Early stopping for under-performing fold: threshold is {threshold:0.5f}") return np.mean(validation_scores) history[k].append(test_score) return np.mean(validation_scores) return objective Следующим шагом будет запуск случайного поиска несколько раз подряд. Резуль- таты станут отправной точкой для дальнейших действий, мы передадим их байе- совской оптимизации и продолжим с использованием forest_minimize в качестве суррогатной функции: counter = 0 history = {i:list() for i in range(5)} used_time = 0 gp_round = dummy_minimize(func=objective, dimensions=space, n_calls=10, callback=[onstep], random_state=0) gc.collect() x0, y0 = joblib.load(’checkpoint.pkl’) gp_round = gp_minimize(func=objective, x0=x0, # уже рассмотренные значения для х у0=у0, # наблюдаемые значения для хв dimensions=space, n_calls=30, n_initial_points=0, callback=[onstep], random_state=0) gc.collect() После десяти итераций случайного поиска мы продолжили поиск, взяв в роли сур- рогатной функции алгоритм случайного леса. Он даст более быстрый и точный ре- зультат, чем гауссовский процесс.
256 Часть II. Оттачивание соревновательных навыке* Как и раньше, мы стремимся сделать оптимизацию возможной с имеющимися вре- менем и ресурсами (например, выставив небольшое значение n_calls). Таким обра- зом, мы можем проводить несколько итераций поиска, сохранять состояние, прове- рять полученные результаты и затем решать, продолжать ли процесс оптимизации или завершить его. Создание моделей с KerasTuner Если предыдущий раздел показался вам слишком сложным, провести оптимизацик без лишней головной боли поможет KerasTuner. По умолчанию эта библиотека ис- пользует байесовскую оптимизацию и гауссовские процессы, но по-настоящем? новая идея в ней — hyperband-оптимизация. Она использует для поиска наилуч- ших параметров метод "бандитов" (см. http://web.eecs.umich.edu/-mosharaf Readings/HyperBand.pdf), достаточно хорошо работающий с нейросетями (копи пространство поиска сложное и не всегда непрерывное, и потому часто неподхо- дящее для гауссовских процессов). Мы не можем избежать создания функции, строящей модель по задан- ным гиперпараметрам, но KerasTuner делает эту задачу гораздо легче. Начнем с истоков. Библиотека KerasTuner (https://keras.io/keras_tuner/) бьги анонсирована создателем Keras Франсуа Шолле как инструмент для гибкой и эф- фективной настройки гиперпараметров моделей. Простая инструкция от Франсуа Шолле по использованию KerasTuner (считаем что у нас уже есть модель Keras): 1. Напишите для модели функцию-обертку с первым параметром hp. 2. Определите список гиперпараметров. 3. Замените статические значения в нейросети на гиперпараметры. 4. Напишите код, строящий нейронную сеть по заданным гиперпараметрам. 5. При необходимости дополняйте список гиперпараметров. Теперь мы покажем на примере, как пройти эти шаги на конкурсе Kaggle. На даь ный момент KerasTuner поддерживается в среде Kaggle Notebooks, так что ее б-. надо устанавливать дополнительно. Также предустановлены и дополнения хи TensorFlow. Если вы хотите поработать с KerasTuner не из Kaggle Notebooks, мо> но установить то и другое с помощью команд: •pip install -U keras-tuner •pip install -U tensorflow-addons
Глава 8. Оптимизация гиперпараметров 257 Наш пример можно найти по адресу https://www.kaggle.comnucamassaron/kerastuner-for-imdb/. Первым шагом мы подключаем нужные библиотеки и загружаем данные: import numpy as np import pandas as pd import tensorflow as tf from tensorflow import keras import tensorflow_addons as tfa from sklearn.model_selection import train_test_split from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LeakyReLU from tensorflow.keras.layers import Activation from tensorflow.keras.optimizers import SGD, Adam from tensorflow.keras.wrappers.scikit_learn import KerasClassifier from tensorflow.keras.callbacks import EarlyStopping, Modelcheckpoint pad_sequences = keras.preprocessing.sequence.pad_sequences imdb = keras.datasets.imdb(train_data, train-labels), (test_data, test_labels) = imdb.load_data(num_words=10000) train_data, val_data, train_labels, val_labels = train_test_split(train_data, train_labels, test_size=0.30, shuffle=True, random_state=0) Мы используем датасет IMDb, доступный через Keras (https://keras.io/api/datasets/ imdb/) и обладающий следующими свойствами: • датасет содержит 25 тыс. отзывов на фильмы; • каждый отзыв помечен как положительный или отрицательный; • каждый отзыв закодирован как список (целочисленных) индексов слов; • для удобства индексы слов отсортированы по их частоте. Этот датасет использовался на популярном конкурсе по вложениям слов https://www.kaggle.eom/c/word2vec-nlp-tutorial/overview). Наш пример относится к задачам обработки естественного языка, которые часто решают с помощью рекуррентных нейронных сетей (recurrent neural networks,
258 Часть II. Оттачивание соревновательных навыкое RNN) с LSTM- или GRU-слоями. Модели, основанные на трансформерах (BERT. RoBERTa и др.), часто показывают лучшие результаты (поскольку они предобуче- ны на больших корпусах текстов). Тем не менее RNN могут оказаться хорошей от- правной точкой или внести важный вклад в ансамбль нейросетей. В нашем примере слова проиндексированы числами. Мы добавим к существующим индексам коды, обозначающие "дополнительный элемент" (так что мы можем до- биться того, чтобы все фразы имели одинаковую длину), начало предложения, не- известное слово или неиспользованное слово: # Словарь} сопоставляющий словам числовые индексы word_index = imdb.get_word_index() # Первые индексы зарезервированы word_index = {k:(v+3) for k,v in word_index.items()} word-index[,,<PAD>”] = 0 word-indext’^START^’] = 1 word_index["<UNK>"] =2 # unknown - неизвестное слово word_index [,,<UNUSED>”] = 3 reverse_word_index = dict([(value, key) for (key, value) in word_index.items()]) def decode_review(text): return ’ ’.join([reverse_word_index.get(i, '?’) for i in text]) На следующем шаге создается слой с механизмом внимания (который является од- ной из самых прорывных идей в обработке естественного языка и основой транс- формерных моделей). Обо всех деталях работы таких слоев можно узнать в основополагаю- щей статье Vaswani A. et al. "Attention is all you need. Advances in neural information processing systems" (2017) (https://proceedings.neurips.cc/ paper/2017/ffle/3f5ee243547dee91fbd053clc4a845aa-Paper.pdf). Основную идею механизма внимания сформулировать несложно. Не все элементы из выхода LSTM- и GRU-слоев обязательно полезны для предсказаний. Вместо ус- реднения этих элементов с помощью pool-слоя можно взять взвешенное среднее с весами, определенными на этапе обучения. Этот процесс (attention— внимание значительно улучшает передаваемый далее результат. Можно добавить и несколькс слоев с attention, но для нашего примера хватит и одного. Мы увидим, что исполь- зование механизма внимания эффективнее для нашей задачи, чем просто усредне- ние или объединение всех результатов:
. лава 8. Оптимизация гиперпараметров 259 from tensorflow.keras.layers import Dense, Dropout from tensorflow.keras.layers import Flatten, RepeatVector, dot, multiply, Permute, Lambda К = keras.backend def attention(layer): # — Внимание! Это все> что вам нужно — # units = layer.shape.as_list() attention = Dense(l, activation=’tanh’)(layer) attention = Flatten()(attention) attention = Activation(’softmax’)(attention) attention = RepeatVector(units)(attention) attention = Permute([2, 1])(attention) representation = multiply([layer, attention]) representation = Lambda(lambda x: K.sum(x, axis=-2), output_shape=(units,))(representation) #-----------------------------------# return representation 3 порядке еще одного эксперимента с архитектурой нейросетей для этой задачи проверим эффективность различных алгоритмов оптимизации, например Rectified Adam (адаптивная версия алгоритма Adam, о которой можно больше узнать из поста https://lessw.medium.com/new-state-of-the-art-ai-optimizer-rectified-adam-radam- 5d854730807b) или Stochastic Weighted Averaging (SWA). SWA усредняет веса, пройденные при оптимизации с расписанием скорости обучения, если модель гклонна к переобучению. SWA помогает приблизиться к оптимальному решению. Особенно хорошо этот метод работает в обработке естественного языка. def get_optimizer(option=0, learning_rate=0.001): if option==0: return tf.keras.optimizers.Adam(learning_rate) elif option==l: return tf.keras.optimizers.SGD(learning_rate, momentum=0.9, nesterov=True) elif option==2: return tfa.optimizers.RectifiedAdam(learning_rate) elif option==3: return tfa.optimizers.Lookahead( tf.optimizers.Adam(learning_rate), sync_period=3) elif option==4: return tfa.optimizers.SWA(tf.optimizers.Adam(learning_rate))
260 Часть IL Оттачивание соревновательных навыков elif option==5: return tfа.optimizers.SWA(tf.keras.optimizers.SGD(learning_rate. momentum=0.9, nesterov=True)) else: return tf.keras.optimizers.Adam(learning_rate) Написав код двух ключевых функций, мы переходим к самой важной, строящей архитектуру нейросети по заданным параметрам. Мы не перечисляем все возмож- ные параметры для всех архитектур, вместо этого мы задаем все нужные нам как один параметр hp. Кроме того, мы фиксируем размер словаря и длину фразы (более длинные фразы мы обрезаем, более короткие — дополняем специальными "пусты- ми" (dummy) значениями: layers = keras.layers models = keras.models def create_tunable_model(hp, vocab_size=10000, pad_length=256): # Задаем параметры модели embedding_size = hp.Int('embedding_size', min_value=8, max_value=512, step=8) spatial_dropout = hp.Float(’spatial-dropout', min_value=0, max_value=0.5, step=0.05) conv_layers = hp.Int(’conv_layers’, min_value=l, max_value=5, step=l) rnn_layers = hp.Int(’rnn_layers’, min_value=l, max_value=5, step=l) dense_layers = hp.Int(’dense_layers’, min_value=l, max_value=3, step=l) conv_filters = hp.Int(’conv_filters’, min_value=32, max_value=512, step=32) conv_kernel = hp.Int(’conv_kernel’, min_value=l, max_value=8, step=l) concat_dropout = hp.Float(’concat_dropout’} min_value=0, max_value=0.5, step=0.05) dense_dropout = hp.Float(’dense_dropout’, min_value=0, max_value=0.5, step=0.05) В первой части функции мы просто выделяем все элементы из параметра hp и явнс задаем пространство поиска для каждого из них. В отличие от предыдущих реше- ний эта работа производится внутри строящей модель функции. Далее с помощью выделенных параметров задаются слои сети. В некоторых случа- ях параметр ответственен за включение или отключение участка сети, отвечающей: за определенный этап обработки данных. Так, в нашем коде имеется ветвь графе (conv_filters и conv_kernel), обрабатывающая цепочки слов с помощью сверточных слоев; в своей одномерной форме они могут быть полезны для задач NLP, поскольку могут улавливать локальные значения слов и словосочетаний, сложные для LSTM.
Глава 8. Оптимизация гиперпараметров 261 Теперь мы можем задать собственно модель: inputs = layers. Input (name=' inputs' ,shape=[pad_length]) layer = layers.Embedding(vocab_size, embedding_size, input_length=pad_length)(inputs) layer = layers.SpatialDropoutlD(spatial_dropout)(layer) for 1 in range(conv_layers): if 1==0: conv = layers.ConvlD(filters=conv_fliters, kernel_size=conv_kernel, padding='valid', kernel_initializer='he_uniform')(layer) else: conv = layers.ConvlD(filters=conv_fliters, kernel_size=conv_kernel, padding='valid', kernel_initializer='he_uniform')(conv) avg pool conv = layers.GlobalAveragePoolinglD()(conv) max_pool_conv = layers.GlobalMaxPoolinglD()(conv) representations = list() for 1 in range(rnn_layers): use_bidirectional = hp.Choice(f'use_bidirectional_{l}', values=[0, 1]) use_lstm = hp.Choice(f'use-lstm-fl}', values=[0, 1]) units = hp.Int(f'units_{l}', min_value=8, max_value=512, step=8) if use_lstm == 1: rnl = layers.LSTM else: rnl = layers.GRU if use_bidirectional==l: layer = layers.Bidirectional(rnl(units, return_sequences=T rue))(layer) else: layer = rnl(units, return_sequences=True)(layer) representations.append(attention(layer)) layer = layers.concatenate(representations + [avg pool conv, max_pool_conv]) layer = layers.Dropout(concat_dropout)(layer)
262 Часть II. Оттачивание соревновательных навыков for 1 in range(dense_layers): dense_units = hp.Int(f'dense_units_{l}'3 min_value=8, max_value=512, step=8) layer = layers.Dense(dense_units)(layer) layer = layers.LeakyReLU()(layer) layer = layers.Dropout(dense_dropout)(layer) layer = layers.Dense(l, name='out_layer')(layer) outputs = layers.Activation('sigmoid')(layer) model = models.Model(inputs=inputs, outputs=outputs) Мы задаем входной слой, преобразуем его с помощью уровня встраивания и пода- ем на вход полносвязному слою. При этом мы применяем регуляризацию методом отсева (dropout) с помощью функции SpatialDropoutlD, которая случайным образом удаляет целые столбцы выходной матрицы (в то время как стандартный dropout — только отдельные значения). После этого мы разделяем нейросеть на два потока один из которых основан на сверточных слоях (conviD), а другой — на рекуррент- ных (GRU или LSTM). После рекуррентных слоев мы вводим слой с вниманием. Б конце выходы двух потоков объединяются и, пройдя еще через несколько полно- связных слоев, мы приходим к итоговому узлу нейросети (где применяем сигмоид- ную функцию, поскольку результатом должна быть вероятность, а она лежит в ин- тервале от 0 до 1). Определив модель, мы выставляем параметры обучения и компилируем ее, прежде чем вернуть: hp_learning_rate = hр.Choice('learning_rate', values=[0.002, 0.001, 0.0005]) optimizer_type = hp.Choice('optimizer', values=list(range(6))) optimizer = get_optimizer(option=optimizer_type, learningu_rate=hp_learningu_rate) model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['acc']) return model Заметим, что мы построили модель, используя функциональный API Keras, а не модель Sequential. Последнюю мы бы рекомендовали не использовать — она про- ста в работе, но существенно ограничивает выбор архитектур. Мы почти у цели. Мы сами попробовали различные алгоритмы оптимизации с KerasTuner и предлагаем построить непараметрическую модель с использование*
. лава 8. Оптимизация гиперпараметров 263 зсех архитектурных деталей, которые хотим протестировать. Имея порождающую функцию и работающую модель, мы можем, например, представить ее в виде графа а обучить на примерах. После этого начнем добавлять значения параметров в архи- тектуру и определять параметр hp. По нашему опыту, начинать сразу с параметрической функции — это лишняя трата времени и сил на поиск ошибок. Идея, лежащая в основе KerasTuner, — представить нейросеть как набор модулей и оптимизи- ровать то, как данные проходят через них. Подключаем KerasTuner, задаем алгоритм для поиска гиперпараметров и начина- ем его: import keras_tuner as kt tuner = kt.BayesianOptimization(hypermodel=create_tunable_modelJ objective='val_acc', max_trials=100, num_initial_points=3J directory='storage', project_name=' imdb' , seed=42) tuner.search(train_data, train_labels, epochs=30, batch_size=64, validation_data=(val_data, val_labels), shuffle=True, verbose=2, callbacks = [EarlyStopping('val_acc', patience=3, restore_best_weights=True)] ) В качестве алгоритма мы выбрали байесовскую оптимизацию, но вы можете по- пробовать Hyperband (https://keras.io/api/keras__tuner/tuners/hyperband/) и срав- нить их качество для вашей задачи. Мы передаем функцию, строящую модель, как параметр hypermodel, задаем целевую функцию (как функцию или как строку), коли- чество попыток (KerasTuner остановится раньше, если делать больше нечего) и ко- личество итераций случайного поиска в начале для получения информации (чем больше, тем лучше). Ранняя остановка— стандартная и хорошо зарекомендовав-
264 Часть II. Оттачивание соревновательных навыков шая себя практика в современном глубоком обучении, так что ее тоже не стоит иг- норировать. Наконец, мы задаем, где сохранять результаты поиска и каково на- чальное состояние случайного генератора. Поиск происходит так же, как обычное обучение модели Keras, и, что важно, до- пускает вспомогательные функции обратного вызова (callbacks). Таким образом, вы можете легко добавить раннюю остановку. Вы можете также оптимизировать раз- мер пакета (чего мы не делали в нашем примере). Это потребует дополнительных действий, о чем можно прочитать здесь: https://github.com/keras-team/keras-tuner/ issues/122. Завершив оптимизацию, вы можете узнать лучшие параметры и сохранить лучшую модель без повторного обучения: best_hps = tuner.get_best_hyperpanameters()[0] model = tuner.hypermodel.build(best_hps) print(best_hps.values) model.summary() model.save("best_model.h5") В нашем примере KerasTuner находит решение, использующее: • больший (по сравнению с предыдущим решением) слой встраивания; • обычные GRU- и LSTM-слои; • множество идущих подряд одномерных сверточных слоев (convlD); • больше, чем в предыдущем решении, полносвязных слоев. Интересно, что новое решение не только эффективнее, но и легче и быстрее преды- дущих моделей, строившихся на основе опыта и интуиции. Сам Шолле предлагает использовать KerasTuner не только для повышения качества нейронных сетей, но и для их уменьшения до более приемлемых размеров (что мо- жет быть важным в соревнованиях категории Code). Это позволяет объединить больше моделей и уложиться в лимит времени. Для тех, кто хочет увидеть больше примеров использования KerasTuner, Франсуа Шолле создал серию блокнотов, показывающих функционал оптимизатора: для данных с конкурса Digit Recognizer (https://www.kaggle.com/fchollet/keras-kerastuner-best-practices); для датасета Titanic (https://www.kaggle.com/fchollet/titanic- keras-kerastuner-best-practices); для конкурса Mechanisms of Action (МоА) Prediction (https://www.kaggle.com/fchollet/moa-keras-kerastuner-best- practices).
Diaea 8. Оптимизация гиперпараметров 265 Подход ТРЕ и Optuna Наш обзор байесовской оптимизации мы завершим рассказом о еще одном инте- ресном инструменте. Как мы говорили, библиотека Scikit-optimize использует гаус- совские процессы и решающие деревья и напрямую строит суррогатную функцию и функцию выбора. Напомним, что суррогатная функция помогает процессу оптимизации оценить потенциальное качество результата при данном наборе гипер- параметров. Она строится на основании предыдущих экспериментов и предсказывает качество заданного алгоритма обучения на заданной за- даче. На вход она принимает гиперпараметры, на выходе выдает ожи- даемое качество. Функция выбора показывает, какой набор гиперпараметров необхо- димо протестировать, чтобы улучшить способность суррогатной функ- ции к предсказанию качества. Она полезна также для проверки, сможем ли мы достичь наилучшего результата на основании предсказаний сур- рогатной функции. Эти две ее цели соответствуют "разведке" и ис- пользованию информации" ъ байесовской оптимизации. Алгоритмы оптимизации, основанные на ТРЕ, подходят к задаче, оценивая прав- доподобие успеха для значений параметров. Иначе говоря, они последовательными приближениями строят распределение успеха параметров, присваивая большую вероятность более успешным комбинациям значений. При этом подходе множество гиперпараметров делится на хорошие и плохие в со- ответствии с этими распределениями, роль которых аналогична суррогатной функ- ции и функции выбора при байесовской оптимизации, — они подсказывают, где семплировать для лучшего качества или для исследования новых значений. Для того чтобы разобраться в технических деталях ТРЕ, советуем обра- титься к статье Bergstra J. et al. Algorithms for hyper-parameter optimiza- tion I I Advances in neural information processing systems. — 2011. — № 24 (https://proceedmgs.neurips.cc/paper/2011/file/86e8f7ab32cfdl2577bc26 19bc635690-Paper.pdf). Таким образом, ТРЕ могут моделировать пространство поиска и предлагать комби- нации гиперпараметров для проверки, семплируя их в соответствии с уточненным распределением. Долгое время те, кто выбирал ТРЕ вместо байесовской оптимизации, основанной на гауссовских процессах, пользовались библиотекой Hyperopt. В октябре 2015 г.
266 Часть II. Оттачивание соревновательных навыков появилась библиотека Optuna с открытым исходным кодом, и кэгглеры в основном стали выбирать ее из-за ее универсальности (работы "из коробки" также с нейрон- ными сетями и ансамблями), скорости и эффективности в поиске наилучшего ре- шёция. В этом разделе мы покажем, насколько легко провести поиск (study — "изучение”, в терминологии Optuna). Достаточно написать целевую функцию, принимающую параметры для проверки и возвращающую их оценку. Валидация и прочие алго- ритмические аспекты могут быть размещены внутри целевой функции, но обра- щаться к внешним (глобальным или локальным) переменным. Optuna позволяет также производить отсечение (pruning) — сообщение, что данный эксперимент неудачен и его можно завершить и не учитывать. Для этого Optuna предоставляет несколько функций (см. https://optuna.readthedocs.io/en/stable reference/integration.html). Использование отсечения существенно сокращает вре- мя оптимизации. Все это будет показано в нашем новом примере. Данные снова взяты с конкурса 30 Days of ML. Теперь мы хотим выяснить, какие параметры оптимальны для алго- ритма XGBoost. Блокнот с кодом можно найти на https://www.kaggle.com/lucamassaron/optuna-bayesian-optimization. Сначала, как и ранее, мы подключаем библиотеки и загружаем данные: import pandas as pd import numpy as np from sklearn import preprocessing from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split from sklearn.preprocessing import OrdinalEncoder from xgboost import XGBRegressor import optuna from optuna.integration import XGBoostPruningCallback # Загрузка данных X_train = pd.read_csv("../input/30-days-of-ml/train.csv").iloc[:100_000, :] X_test = pd.read_csv("../input/30-days-of-ml/test.csv") # Подготовка данных в табличном виде y_train = X_train.target
- лава 8. Оптимизация гиперпараметров 267 X_train = X_train.set_index('id').drop('target', axis='columns') X_test = X_test.set_index('id') # Находим категориальные признаки categoricals = [item for item in X_train.columns if 'cat' in item] # Кодируем категориальные признаки с помощью OrdinaLEncoder ordinal_encoder = OrdinalEncoderQ X-train[categoricals] = ordinal_encoder.fit-transform(X_train[categoricals]) X-test[categoricals] = ordinal_encoder.transform(X_test[categoricals]) При использовании Optuna достаточно определить целевую функцию, содержащую модель, логику кросс-валидации, способ оценки качества и пространство поиска. Конечно, вы можете обращаться к данным вне самой функции, делая ее проще. Как а в KerasTuner, вам понадобится специальный входной параметр на основе класса из Optuna: def objective(trial): params = { 'learning_rate': trial.suggest_float("learning-rate", 0.01, 1.0, log=True), 'regJLambda': trial.suggest_loguniform("reg_lambda", le-9, 100.0), 'reg_alpha': trial.suggest_loguniform("reg_alpha", le-9, 100.0), 'subsample': trial.suggest_float("subsample", 0.1, 1.0), 'colsample-bytree': trial.suggest-float( "colsample_bytree", 0.1, 1.0), 'max-depth': trial.suggest_int("max_depth", 1, 7), 'min-Child_weight': trial.suggest_int("min_child_weight", 1, 7), 'gamma': trial.suggest_float("gamma", 0.1, 1.0, step=0.1) } model = XGBRegressor(random_state=0, tree_method="gpu_hist", predictor="gpu_predictor", n_estimators=10_000, **params) model.fit(x, y, early_stoppingL_rounds=300, eval-Set=[(x_val, y_val)], verbose=1000, callbacks=[XGBoostPruningCallback(trial, 'validation_0-rmse')])
268 Часть II. Оттачивание соревновательных навыков preds = model.predict(x_test) rmse = mean_squared_error(y_testj preds, squared=False) return rmse В этом примере для скорости работы мы не используем кросс-валидацию, а фикси- руем обучающее, контрольное (с ранней остановкой) и тестовое подмножества данных. Мы также используем GPU, чтобы провести 60 итераций за разумное время. Если вы не хотите использовать GPU, достаточно удалить параметры tree_method и predictor при создании экземпляра XGBRegressor. Заметим, что в методе fit мы пользуемся функцией обратного вызова, чтобы давать обратную связь о качестве модели, а также о том, что неудачный эксперимент может быть остановлен раньше времени. И х, x_val, у, y_val = train_test_split(X_train, y_train, random_state=0, I test_size=0.2) I x, x_test, y, y_test = train_test_split(x, y, random_state=0, test_size=0.25) I study = optuna. create__study(direction="minimize") study.optimize(objective, n_trials=100) Заметим, что в зависимости от задачи мы можем проводить как минимизацию, так и максимизацию (Scikit-optimize работает только с задачами минимизации). print(study.best_value) print(study.best_params) В завершение осталось только вывести на экран либо сохранить наилучшее значе- ние качества и наилучшие значения параметров. Ручи Бхатия https ://www.kaggle.com/ruchi798 В качестве завершения этой насыщенной главы приведем еще одно интервью. На этот раз мы говорим с Ручи Бхатия, гроссмейстером в категориях Datasets и Notebooks. Ручи сейчас учится в аспирантуре университета Карнеги — Меллона, работает исследователем данных в компании OpenMined и является глобальным послом HP в области науки о данных (HP Data Science Global Ambassador). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Мои любимые виды соревнований — соревнования по аналитике и по обработке естественного языка. Я сама многоязычна, и это сыграло роль в моем интересе к обработке естественного языка. Что касается аналитики, я люблю находить
Глава 8. Оптимизация гиперпараметров 269 смысл в данных и отвечать на вопросы, опираясь на данные. Каждый конкурс на Kaggle приносит что-то новое и требует своих методов. При выборе алгоритма я опираюсь на данные, здесь у меня нет заранее определенных предпочтений. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Когда анонсируется новый конкурс, я в первую очередь стараюсь глубоко понять задачу. Иногда постановка задачи может быть непривычной для нас, принадле- жать к неизвестной области, поэтому критически важно понять ее до перехода к разведочному анализу данных. При проведении EDA моя цель — понять распре- деление данных и ознакомиться с ними, увидев своими глазами. При этом мы, скорее всего, заметим закономерности. Мы должны понять их и сформулировать гипотезы для выбросов и исключений. После этого я разбираюсь в метриках, используемых на конкурсе. Следующий шаг — создание стратегии кросс-валидации, свободной от утечек. Затем я выби- раю базовую модель и отправляю первое решение. Если меня не устраивает кор- реляция между локальными результатами валидации и результатами в таблице, я повторяю свои действия до тех пор, пока не найду причины расхождений и не смогу их учесть. Затем я стараюсь улучшить результаты своих моделей. Изменение параметров и проведение экспериментов позволяют понять, какие подходы лучше всего рабо- тают на имеющихся данных (при этом необходимо избегать переобучения). На- конец, в последние недели конкурса я строю ансамбли и проверяю устойчивость своего решения. В проектах, не относящихся к Kaggle, напротив, большую часть времени зани- мают сбор и очистка данных. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle невероятно помог мне продвинуться в карьере. Он позволил мне увлечься наукой о данных, мотивировал меня эффективно и последовательно работать. Это идеальное место для того, чтобы попробовать свои силы в работе с различ- ными типами данных и показать результат всему миру. Я использовала большую часть сделанного на Kaggle в своем портфолио, чтобы показать разнообразие решенных мною задач. Конкурсы Kaggle ставят новые за- дачи, основанные на реальных проблемах, и работодатели ищут кандидатов, спо- собных решать такие задачи. Так как я много работала с датасетами, это помогло мне показать свои навыки обращения с сырыми данными. В итоге я имела мно- жество предложений о работе. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотела бы знать, когда начинала участвовать в соревнованиях? По своему опыту я заметила, что многие кэгглеры падают духом, заняв место ниже ожидаемого. После недель и месяцев труда я понимаю, почему они сдают- ся, но выиграть конкурс Kaggle всегда нелегко. Важно иметь смелость пробовать. В конкурсах участвуют люди с разным опытом и образованием, поэтому стоит следить за своим личным прогрессом и смотреть, какой путь прошел именно ты.
270 Часть II. Оттачивание соревновательных навыкос Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Заметить закономерности и понять контекст нам помогают подробный разведочный анализ данных и подходящая визуализация. Я очень верю в силу визуализации, по- этому мои любимые библиотеки — это Seaborn (для этапа EDA) и TensorBoard (по- лезная уже при построении и обучении моделей). Иногда я также использую Tableau. О чем важнее всего помнить, приступая к участию в соревновании? Приступая к участию, на мой взгляд, нужно быть готовым к глубокому погруже- нию в задачу. Конкурсы Kaggle сложны и часто основаны на реальных задачах. Нужно верить в себя и не сдаваться, соревнования дают идеальную возможность учиться и прогрессировать! Резюме В этой главе мы подробно обсудили оптимизацию гиперпараметров как способ улучшить качество модели и занять более высокое место. Сначала мы рассказали о функционале библиотеки Scikit-leam — поиске по сетке, случайном поиске и алго- ритме сокращения вдвое. Затем мы перешли к байесовской оптимизации, изучили возможности библиотек Scikit-optimize, KerasTuner и Optuna. Мы много обсуждали прямое построение сур- рогатной функции с помощью гауссовских процессов, поскольку оно более интуи- тивно. На данный момент большинство кэгглеров использует Optuna как для таб- личных конкурсов, так и для глубокого обучения благодаря способности найти оптимальные параметры за ограниченное время работы блокнота. Однако если вы хотите обойти конкурентов, стоит протестировать и другие алгоритмы. В следующей главе мы обсудим еще один способ улучшить результаты: объединение моделей в ансамбли. Мы покажем, как с помощью усреднения, блендинга и стекинга добиться результатов, которых не достичь одной настройкой гиперпараметров. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
9 Ансамбли: блендинг и стекинг Начав участвовать в соревнованиях на Kaggle, вы вскоре обнаруживаете, что не- возможно победить с одной сколь угодно хорошей моделью, необходимо объеди- нять разные (составлять ансамбль). Затем вы задумываетесь, как это делать. Суще- ствует несколько руководств, но многие нюансы не записаны в статьях, а передаются от одного кэгглера другим. Дело в том, что если на соревнованиях ансамбли — ключ к победе, то в реальном мире они ассоциируются с избыточной сложностью, плохой поддерживаемостью и воспроизводимостью, скрытыми техническими издержками при совсем незначи- тельном приросте качества. Такой прирост может вывести вас из низов таблицы в топ, но несущественен в реальном мире — минусы перевесят плюсы. Тем не менее это не означает, что ансамбли в реальном мире бесполезны во всех случаях. При небольшом числе моделей, например, усреднение их результатов может решить многие задачи быстрее и качественнее. На Kaggle использование ансамблей — это не только способ повысить качество предсказаний, но и командная стратегия. Объединение усилий всех участников ко- манды приносит лучший результат, чем работа в одиночку. Важно, однако, органи- зовать работу команды для достижения общей ясной цели. Когда участники рабо- тают в различных часовых поясах и каждый имеет свои ограничения (часы работы, учебы, экзамены и т. д.), методы вроде парного программирования не годятся. На- выки членов команды также могут различаться. Обычно нет возможности добиться того, чтобы все участники работали над одним заданием, но обычно это и не нуж- но. Хорошая ансамблевая стратегия позволит каждому работать над задачей в сво- ем темпе и стиле, но при этом быть полезным команде. Разный набор навыков здесь может стать преимуществом, поскольку даст разнообразие предсказаний мо- делей. В этой главе мы начнем с ансамблевых методов, с которыми вы уже знакомы, по- скольку они зашиты в такие алгоритмы, как случайные леса и градиентный бус- тинг. Затем мы перейдем к таким методам, как усреднение, блендинг и стекинг. Мы
272 Часть II Оттачивание соревновательных навыке* познакомим вас с теорией, практикой и примерами кода, которые вы сможете ис- пользовать как образцы для собственных решений. Мы затронем следующие темы: • краткое введение в ансамблевые алгоритмы; • усреднение; • блендинг и метамодели; • стекинг; • сложные решения с блендингом и стекингом. Перед началом обсуждения сошлемся на пост 2015 г., который может служить отличным справочным материалом для участников соревнова- ний на Kaggle. The Kaggle Ensembling Guide был написан кэгглером Triskelion (Хенрик Якоб ван Вин, Hendrik Jacob van Veen) с нескольки- ми соавторами (Le Nguyen The Dat, Armando Segnini) и исходно выло- жен в ныне несуществующем блоге mlwave (https://mlwave.com/kaggle- ensembling-guide), но вы можете увидеть сохраненную версию на https://usermanual.wiki/Document/Kaggle20ensembling20guide.685545 114.pdf. В посте были собраны почти все знания об ансамблях, явно и неявно присутствующие на форумах Kaggle на тот момент. Краткое введение в ансамблевые алгоритмы Идея, что ансамбли моделей могут превосходить отдельные модели, уже не нова, ее истоки можно проследить в викторианской Англии у сэра Фрэнсиса Гальтона. О выяснил, что при угадывании веса быка на деревенской ярмарке лучше взять сред- нее многих оценок, чем одну тщательно обдуманную оценку от эксперта. В 1996 г. Лео Брейман формализовал идею объединения множества моделей в оде;* с лучшей предсказательной способностью, продемонстрировав метод бэггинп (bagging— ’’bootstrap aggregating”), позднее приведший к созданию более эффек- тивных случайных лесов. После этого появились и другие ансамблевые методы которые мы сейчас используем, например, градиентный бустинг и стекинг. Для того чтобы понять, как они создавались, можно обратиться к статьям: • случайные леса: Breiman L. Bagging predictors И Machine learn- ing. — 1996. — № 24.2. — P. 123-140;
:ва 9. Ансамбли, блендинг и стекинг 273 • исходный вариант бустинга: Freund Y., Schapire R. E. Experiments with a new boosting algorithm // IcmL — 1996. — Vol. 96; Friedman J. H. Greedy function approximation: a gradient boosting machine // Annals of Statistics. — 2001. — P. 1189-1232; • первое описание стекинга: Ting К. M., Witten 1. Н. Stacking bagged and dagged models. — 1997. Первые базовые ансамблевые стратегии на конкурсах Kaggle представляли собой обычные бэггинг и случайные леса для классификации и регрессии. Они стали из- вестны как методы усреднения, поскольку основаны на нахождении среднего раз- ных предсказаний. Они стали распространенными с самых первых соревнований на Kaggle отчасти и из-за конкурса Netflix, еще на нем доминировали стратегии, осно- ванные на усреднении результатов разных моделей. Благодаря своим успехам базо- вые ансамблевые модели надолго стали стандартом на конкурсах и до сих пор по- могают занять более высокое место. Более сложный и требующий больше вычислительных ресурсов метод стекинга появился позже, из-за усложнения конкурсных задач и усиления конкуренции. По- добно тому как алгоритм случайного леса дал идею усреднения различных пред- сказаний, общая идея стекинга была вдохновлена бустингом. При бустинге благо- даря последовательным преобразованиям информации алгоритм обучения может лучше и полнее моделировать задачи. При градиентном бустинге последовательно строятся деревья, извлекающие из данных ту часть информации, которую не учли предыдущие деревья. Эта идея обобщается при стекинге: результаты предшест- вующих моделей обрабатываются с целью обеспечить улучшение качества. Роб Мулла https://www.kaggle.com/robikscube Роб поговорил с нами о своей точке зрения на ансамбли и о том, чему он научился на Kaggle. Мы многому можем нау- читься у Роба, ведь он гроссмейстер в категориях Competi- tions, Notebooks и Discussions, а также старший исследова- тель данных в компании Biocore LLC. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я люблю соревнования с уникальными датасетами, требующие новых решений, включающих в себя разные типы моделей. Мне нравится, когда конкурс не сво- дится просто к обучению очень большой модели, но действительно требует по- нимания данных и использования методов, специально подобранных для этой задачи. Я не стремлюсь специализироваться на конкретном подходе. Когда я на-
274 Часть II. Оттачивание соревновательных навыков чал соревноваться на Kaggle, я в основном использовал градиентный бустинг, но в последние годы, чтобы оставаться конкурентоспособным, продвинулся в изу- чении глубокого обучения, компьютерного зрения, обработки естественного языка и оптимизации. Лучшие, на мой взгляд, соревнования требуют использо- вания более чем одного метода. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я во многом подхожу к конкурсам на Kaggle так же, как к рабочим проектам. В первую очередь надо понять данные. В реальных проектах, возможно, понадо- бится сформулировать задачу и разработать хорошую метрику. На Kaggle это уже сделано за вас. Затем идет этап понимания, как соотносятся данные и метри- ка, разработки и тестирования моделей, которые, на ваш взгляд, лучше всего по- дойдут для задачи. Самое большое различие между Kaggle и реальной наукой о данных — на последнем этапе создания и настройки ансамблей, чтобы хоть не- много вырваться вперед. В настоящих приложениях большие ансамбли обычно не используют — выигрыш в качестве не окупает расход вычислительных ресурсов. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Очень непростым был конкурс NFL Helmet Impact Detection, посвященный аме- риканскому футболу. На нем требовалось работать с видеоданными (опыта об- ращения с которыми у меня не было), изучать актуальные методы и читать ста- тьи по теме. Мне пришлось применять двухстадийный подход, что добавило сложности решению. Другой сложный конкурс — Indoor Location Navigation, требовавший отличного понимания данных, моделирования и оптимизации. Я не достиг на нем заметных результатов, но очень многому научился. Помог ли тебе Kaggle в карьере? Если да, то как? Да, Kaggle очень помог мне приобрести известность в области науки о данных. Я научился многим методам, встретился и поработал с замечательными людьми, которые помогли мне приобрести новые навыки и лучше понимать машинное обучение. На конкурсе NFL Helmet Impact Detection наша команда заняла второе место. До этого я уже участвовал в некоторых конкурсах, посвященных NFL. Организато- ры конкурса связались со мной, и в итоге я получил свою нынешнюю работу. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? На мой взгляд, новички слишком озабочены подбором гиперпараметров и по- строением ансамблей. Это важные моменты в конце соревнования, но от них не будет толку, если у вас нет хорошей базовой модели. Я также считаю, что крити- чески важно понимать используемую на конкурсе метрику. Многие кэгглеры упускают из виду то, как важно оптимизировать свое решение в соответствии с заданной метрикой.
Глава 9. Ансамбли: блендинг и стекинг 275 Какие ошибки ты допускал на соревнованиях? Я допускал множество ошибок. Я переобучал модели, я терял время на бесполез- ные вещи. Однако, на мой взгляд, это было необходимо для обучения. Ошибки могли испортить мне результат конкретного конкурса, но они помогали мне быть лучше на следующем соревновании. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Для разведочного EDA нужно уметь использовать NumPy, pandas и Matplotlib либо другую библиотеку для построения графиков. Для моделирования необходимо понимать, как правильно провести кросс- валидацию с помощью Scikit-leam. Полезно знать стандартные базовые модели, такие как XGBoost/LightGBM. Глубокое обучение — это в основном TensorFlow/ Keras либо PyTorch, и знакомство с одной из этих двух библиотек очень важно. Усреднение Перед тем как мы подробно расскажем об усреднении, вкратце опишем все страте- гии построения ансамблей, разработанные Лео Брейманом. Его работы — осново- полагающие в этой области, и даже сейчас описанные им методы неплохо работают на большом спектре задач. Брейман рассматривал все эти методы, чтобы найти способ уменьшить разброс ошибок у мощных и склонных к переобучению моде- лей, таких как решающие деревья. Главная его идея в том, что качество работы ансамбля зависит от трех компонен- тов: семплирования обучающих примеров, построения моделей и того, как мы со- единяем эти модели вместе. Что касается семплирования, были обнаружены и протестированы следующие ме- тоды: • "метод вставки" (pasting), при котором модели строятся по подвыборкам (без возвращений) примеров (строк в табличных данных); • бэггинг, при котором модели строятся по подвыборкам примеров с возвра- щением; • случайные подпространства (random subspaces) — модели строятся по под- выборкам (без возвращений) признаков (столбцов в таблице); • случайные патчи (random patches) — модели строятся по подвыборкам (с . возвращением) признаков. Мы используем не все данные для каждой модели, чтобы получить набор моделей, относящихся к одной задаче, но отличающихся друг от друга. Они отличаются в том числе по тому, как будут переобучаться, — мы ожидаем, что они одинаково выделят из данных полезную информацию и по-разному будут реагировать на шум.
276 Часть II. Оттачивание соревновательных навыков Разнообразие моделей, таким образом, уменьшит разброс предсказаний — ошибки будут взаимно компенсировать друг друга. Если мы знаем, что разнообразие полезно, следующим шагом должно быть измене- ние не только данных, но и моделей. Ансамбли могут состоять: • из моделей одного типа; • из моделей разных типов. Интересно, что создание ансамблей мало помогает в ситуации, когда модели слиш- ком сильно различаются по предсказательной способности. Преимущество прояв- ляется, если объединять модели, качество которых близко, поэтому они могут ком- пенсировать ошибки друг друга. При объединении же моделей с сильно разным качеством предсказаний вы не столько исправляете неверные предсказания, сколь- ко портите верные, и совокупный эффект оказывается отрицательным. Мы сформулировали важное ограничение на методы усреднения: они могут ис- пользовать набор различных моделей (например, обученных на разных примерах и разных наборах признаков) только в том случае, если модели близки по предсказа- тельной способности. Так, линейная регрессия и метод ближайших соседей разли- чаются по способу выделять сигнал из данных, они могут улавливать разные зако- номерности и лучше работать на каких-то частях данных, но их усреднение не даст вам преимущества. С другой стороны, стекинг может использовать алгоритмы с кардинально различающимися подходами и брать лучшее от каждого из них. Мы можем резюмировать, что для эффективности использования ансамблей, осно- ванных на усреднении, они должны: • состоять из моделей, обученных на разных примерах; • состоять из моделей, обученных на разных подмножествах признаков; • состоять из моделей, близких по предсказательной способности. Формально это означает, что предсказания моделей должны иметь как можно меньшую корреляцию между собой, но при этом одинаковый уровень качества предсказаний. Теперь, обсудив возможности и ограничения усреднения, перейдем к техническим деталям. Существует три способа усреднить результаты множества моделей клас- сификации или регрессии: • голосование (для моделей классификации): в качестве итогового берется класс, за который проголосовало большинство моделей; • усреднение значений или вероятностей; • усреднение значений или вероятностей с весами. В нескольких ближайших разделах мы подробно обсудим каждый из этих способов для конкурсов Kaggle.
Глава 9. Ансамбли: блендинг и стекинг 277 Голосование Построение различных моделей (разного типа, построенных по разным примерам и признакам), сравнимых по предсказательной способности, требует определенных вычислительных ресурсов, но не обязывает строить схему обработки данных, ради- кально отличающуюся от ситуации одной модели. Вам достаточно собрать пред- сказания на тестовых данных, отслеживая примененные модели, их гиперпараметры, использованные выборки объектов и признаков и качество при кросс-валидации. Если на конкурсе требуется предсказать класс тестового примера, можно восполь- зоваться голосованием и предсказывать тот класс, за который проголосовало большинство моделей. Такой подход основан на том, что иногда модели могут ошибаться, но в большинстве случаев их предсказания верны. Он годится как для бинарной, так и для многоклассовой классификации. Голосование можно рассмат- ривать как процедуру ’’исправления ошибок”, отбрасывающую шум и сохраняю- щую значимый сигнал. В нашем первом простом примере мы покажем, как работает голосование. Сначала мы создадим датасет с помощью функции make_classification из библиотеки Scikit- leam. Он будет похож на известный искусственный датасет Madelon, в кото- ром точки данных были сгруппированы в кластеры, размещенные в вершинах гиперкуба и случайным образом помеченные. Помимо не- скольких информативных признаков, он содержал нерелевантные и по- _вторяющиеся (чем создавалась мультиколлинеарность), а также добав- ленный случайный шум. Madelon, созданный Изабель Гийон (Isabelle Guyon), одной из создателей метода опорных векторов, для конкурса NIPS 2003 Feature Selection Challenge, — классический пример сложно- го синтезированного конкурсного датасета, вдохновившего организато- ров нескольких конкурсов Kaggle (https://www.kaggle.eom/c/overfitting и https://www.kaggle.eom/c/dont-overfit-ii). Далее в этой главе мы будем использовать наш ’’воссозданный" Madelon для тести- рования ансамблевых методов: from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, у = make_classification(n_samples=5000J n_features=50J n_informative=10, n_redundant=25, n_repeated=15, n_clustersj3er_class=5J
278 Часть II. Оттачивание соревновательных навыке* flip_y=0.05, class_sep=0.5, random_state=0) X-train, X-test, yjtrain, y_test = train_test_split(X, y, test_size=0.33, random_state=0) Разбив данные на обучающие и тестовые, мы задаем алгоритмы обучения. Мы бу- дем использовать три базовых алгоритма: SVM, случайный лес и метод ближайших соседей (с гиперпараметрами по умолчанию). Вы можете провести свой экспери- мент, изменив количество моделей, их тип или гиперпараметры: from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import log_loss, roc_auc_score, accuracy_score model_l = SVCCprobability^True, random_state=0) model_2 = RandomForestClassifier(random_state=0) model_3 = KNeighborsClassifier() Далее мы обучаем каждую модель: model-l.fitCXjtrain, y_train) model_2.fit(X_trainJ y_train) model_3.fit(X_train, y_train) Теперь нам нужно получить предсказания каждой модели на тестовом множестве и провести голосование, для чего мы пользуемся функцией mode из SciPy: import numpy as пр from scipy.stats import mode preds = np.stack([model_l.predict(X_test), model-2.predict(X_test), model_3.predict(X_test)]).T max_voting = np.apply-along-axisCmode, 1, preds)[:,0] Сначала мы найдем долю правильных ответов для каждой модели: for i, model in enumerate^'SVC, 'RF ', 'KNN']): acc = accuracy_score(y_true=y_test, y_pred=preds[:, i]) print(f'Accuracy for model {model} is: {acc:0.3f}")
Глава 9. Ансамбли: блендинг и стекинг 279 Как мы видим, качество всех трех моделей примерно одинаково, около 0,8. Прове- рим качество ансамбля: max_voting_accuray = accuracy_score(y_true=y_test, y__pred=max_voting) print(f"Accuracy for majority voting is: {max_voting_accuray:0.3f}") Доля правильных ответов у ансамбля выше: 0,817, поскольку удалось объединить правильные ответы от большинства моделей. Для задач с множественными метками (multilabel problems), в которых один объект может относиться к нескольким классам, можно брать в качестве предсказания те классы, за которые проголосовало больше определенного числа моделей (этот по- рог должен быть выбран так, чтобы удавалось ловить сигнал, а не шум). Так, если у вас имеется пять моделей, можно взять порог, равный трем: если класс предсказан более чем тремя моделями, предсказание считается правильным. В задачах регрессии, как и при предсказании вероятностей, голосование неприме- нимо, оно работает только для принадлежности объектов классам. Вместо этого при предсказании числовых значений используют обычные или взвешенные средние. Усреднение предсказаний При усреднении предсказаний различных моделей вы можете рассматривать их как равноправные и использовать среднее арифметическое. Мы обнаружили, что довольно эффективны также: • среднее геометрическое — перемножив п предсказаний от разных моделей, вы затем извлекаете из результата корень степени и; • среднее логарифмическое — вы ищете среднее от логарифмов предсказаний и берете от него экспоненту; • среднее гармоническое — вы берете среднее от обратных к предсказаниям чисел, а затем берете обратное к этому среднему; • среднее степенное — вы берете среднее от и-х степеней предсказаний и из- влекаете из результата корень степени п. Иногда эти варианты оказываются эффективнее обычного среднего арифметиче- ского, но в большинстве случаев и этот простейший вариант работает очень хорошо. Продолжая наш предыдущий пример, выясним, какое из средних даст лучший ре- зультат при переключении на метрику ROC-AUC. Сначала вычислим метрику для каждой отдельной модели: proba = np.stack([model_l.predict_proba(X_test)[:, 1], model_2.predict_jDroba(X_test)[:> 1], model_3.predict_proba(X_test)[:, 1]]).T
280 Часть II. Оттачивание соревновательных навыке* for i, model in enumerate^'SVC, 'RF ', 'KNN']): ras = roc_auc_score(y_true=y_test, y_score=proba[:, i]) print(f"ROC-AUC for model {model} is: {ras:0.5f}") Результаты лежат в промежутке от 0,875 до 0,881. Начнем со среднего арифметического: arithmetic = proba.mean(axis=l) ras = roc_auc_score(y_true=y_testj y_score=arithmetic) print(f'Mean averaging ROC-AUC is: {ras:0.5f}") ROC-AUC для ансамбля гораздо лучше, чем для отдельных моделей: 0,90192. Про- верим, улучшится ли результат от использования среднего геометрического, сред- него гармонического, среднего логарифмического или среднего степенного: geometric = proba.prod(axis=l)**(1/3) ras = roc_auc_score(y_true=y_test, y_score=geometric) print(f"Geometric averaging ROC-AUC is: {ras:0.5f}") harmonic = 1 / np.mean(l. I (proba + 0.00001), axis=l) ras = roc_auc_score(y_true=y_test, y_score=harmonic) print(f"Geometric averaging ROC-AUC is: {ras:0.5f}") n = 3 mean_ofjDowers = np.mean(proba**n, axis=l)**(l/n) ras = roc_auc_score(y_true=y_test, y_score=mean_of -powers) print(f"Mean of powers averaging ROC-AUC is: {ras:0.5f}") logarithmic = np.expml(np.mean(np.loglp(proba), axis=l)) ras = roc_auc_score(y_true=y_test, y_score=logarithmic) print(f"Logarithmic averaging ROC-AUC is: {ras:0.5f}") Запустив код, мы понимаем, что в этом случае среднее арифметическое было наи- лучшим выбором. На самом деле, однако, почти всегда улучшает результат уче” некоторых априорных знаний при комбинировании предсказаний моделей. Это де- лается с помощью введения весов. Взвешенные средние Вводя веса моделей, вы должны подобрать их правильно. Часто используемый, хо- тя и очень склонный к переобучению, метод — проверить различные комбинации весов на публичных тестовых данных и выбрать вариант с лучшим местом в табли-
Глава 9. Ансамбли: блендинг и стекинг 281 те. Разумеется, это не гарантирует столь же высокого места в итоговой таблице ре- зультатов. Как мы уже говорили, часто из-за различий между публичными и при- ватными тестовыми данными результатам в публичной таблице нельзя полностью доверять. Можно, однако, использовать оценку качества при кросс-валидации или за отложенных данных (о чем мы поговорим позже при обсуждении стекинга). Другая возможная стратегия — брать веса, пропорциональные качеству моделей ри кросс-валидации. Также хорошо работающий, хотя и контринтуитивный способ— выбирать веса обратно пропорционально ковариациям решений. Так как мы стремимся взаимно компенсировать ошибки, такое усреднение позволяет присвоить большие веса сильнее отличающимся друг от друга предсказаниям и тем уменьшить разброс в итоговых результатах. 3 нашем следующем примере мы построим матрицу корреляций для предсказан^- зых вероятностей, а затем проделаем следующее: 1. Заменим единицы на диагонали нулями. 2. Создадим вектор из средних значений в каждой строке. 3. Возьмем обратные к средним значениям из пункта 2. 4. Нормализуем вектор так, чтобы сумма значений в нем была равна 1,0. 5. Умножим матрицу вероятностей на полученный вектор. Код выглядит так: cormat = np.corrcoef(proba.T) np.fill_diagonal(cormatj 0.0) W = 1 / np.mean(cormatj axis=l) W = W / sum(W) # нормализуем do sum==1.0 weighted = proba.dot(W) ras = roc__auc__score(y_true=y__testj y_score=weighted) print(f"Weighted averaging ROC-AUC is: {ras:0.5f}") Итоговое значение ROC-AUC равно 0,90206, что несколько лучше, чем при про- лом усреднении. Придание больших весов менее скоррелированным предсказани- ем — стратегия, которая часто приносит плоды. Даже если выигрыш в качестве не- эелик, на соревнованиях он может оказаться очень важным. Усреднение и кросс-валидация Как мы уже писали, усреднение не требует от вас построения сложных процессов обработки данных, вы стандартным образом создаете модели для усреднения и бе- рете сумму результатов с одинаковыми или различными коэффициентами. Протес- тировать полученный ансамбль можно, отправив результаты на проверку, но при утом возникает риск переобучения.
282 Часть II. Оттачивание соревновательных навыке* Можно, однако, провести кросс-валидацию, усреднив результаты моделей на каж- дом блоке (когда он не задействован при обучении модели). Полученная оценка качества надежнее, чем результат на публичных тестовых данных. Ниже вы найде- те код кросс-валидации: from sklearn.model_selection import KFold kf = KFold(n_splits=5j shuffle^rue, random_state=0) scores = list() for k, (train_indexj test_index) in enumerate(kf.split(X_train)): model_l.fit(X_train[train_indeXj :]3 y_train[train_index]) model_2.fit(X_train[train_indeXj :], y_train[train_index]) model_3.fit(X_train[train_indeXj :], y_train[train_index]) proba = np.stack( [model_l.predict_proba(X_train[test_index> :])[:, 1]> model_2.predict_proba(X_train[test_index3 :])[:, 1], model_3.predict_proba(X_train[test_index, :])[:, 1]]).T arithmetic = proba.mean(axis=l) ras = roc_auc_score(y_true=y_train[test_index]j y_score=arithmetic) scores.append(ras) print(f"FOLD {k} Mean averaging ROC-AUC is: {ras:0.5f}") print(f"CV Mean averaging ROC-AUC is: {np.mean(scores):0.5f}") Результаты такой кросс-валидации помогут понять, какая стратегия усреднение более перспективна, без привлечения публичных тестовых данных. Корректируем усреднение для оценок ROC-AUC Если метрикой для задачи будет ROC-AUC, простое усреднение результатов моде- лей может оказаться недостаточным. Дело в том, что модели могут задействовать разные стратегии оптимизации и давать очень разные ответы на выходе. Решением может быть калибровка моделей (способ постобработки, который мы обсуждали i главе 5), но она требует дополнительного времени и вычислительных ресурсов. Самым очевидным решением в таких случаях будет преобразование вероятностей i ранги и усреднение этих рангов (возможно, с весами). С помощью стандартизации
Глава 9. Ансамбли: блендинг и стекинг 283 min-max scaler) мы переводим оценки каждой из моделей в интервал от 0 до 1 и затем усредняем их. Таким образом вероятностные предсказания модели можно превратить в сравнимые друг с другом ранги: from sklearn.preprocessing import MinMaxScaler proba = np.stack( [model_l.predict_proba(X_train)[:, 1]3 model_2.predict_proba(X_train)[:3 1], model_3.predict_proba(X_train)[:3 1]]).T arithmetic = MinMaxScaler().fit_transform(proba).mean(axis=l) ras = roc_auc_score(y_true=y_testj y_score=arithmetic) print(f"Mean averaging ROC-AUC is: {ras:0.5f}") Такой подход отлично работает в применении к предсказаниям на тестовом множе- стве. Если, однако, вы пытаетесь усреднять результаты во время кросс-валидации, зы можете столкнуться с проблемами, т. к. интервалы, в которых лежат предсказа- ния для обучающих и тестовых данных, могут различаться. Можно решить эту проблему обучением модели калибровки (о калибровке вероятностей в Scikit- leam можно прочитать на https://scikit-learn.org/stable/modules/calibration.html и з главе 5), преобразуя предсказания в настоящие вероятности. Блендинг и метамодели Конкурс Netflix (который мы подробно обсуждали в главе 1) не только показал, что усреднение может давать преимущество для различных конкурсных задач, но и привел к появлению идеи специальной модели для более эффективного усреднения. Команда-победитель, BigChaos, опубликовала статью (Toscher A., Jahrer М., Bell R. М. The BigChaos Solution to the Netflix Grand Prize // Netflix prize documentation.— 2009), в которой многократно упоминала блендинг и привела много полезных деталей касательно его эффективности и того, как он работает. Вкратце, блендинг — это процедура усреднения с весами, при которой веса подби- раются метамоделью, обученной на отложенных данных. Метамоделью мы назы- ваем алгоритм машинного обучения, обучающийся на выходных данных других моделей. Обычно (хотя не всегда, о чем мы поговорим в следующем разделе) это линейная модель, но можно использовать и другие (связанные с этим риски мы также обсудим). Процедуру блендинга описать несложно: 1. Перед построением всех моделей вы случайным образом выбираете отложен- ные данные (при командной работе они должны быть одинаковы для всех уча- стников)— обычно около 10% от всех данных, однако в зависимости от об-
284 Часть II. Оттачивание соревновательных навыков стоятельств (количество данных, их деление на группы) эта доля может менять- ся. Как и всегда при семплировании, вы можете сделать выборку стратифици- рованной, а также проверить совпадение распределений в ней и во всех данных с помощью adversarial validation. 2. Обучите все ваши модели на оставшихся данных. 3. Сделайте предсказания на отложенных и тестовых данных. 4. Используйте предсказания на отложенных данных как обучающие данные для метамодели. Дав на вход этой метамодели предсказания отдельных моделей на тестовых данных, получите итоговые предсказания на тестовых данных. Аль- тернативная стратегия — применить метамодель для отбора используемых мо- делей и подбора их весов. У такой процедуры имеются и достоинства, и недостатки. Начнем с достоинств. Во-первых, она проста в реализации, достаточно уметь семплировать отложенные данные. Во-вторых, метамодель позволяет найти оптимальные веса без привлече- ния публичной таблицы. Что касается недостатков, иногда (в зависимости от количества данных и типов мо- делей) уменьшение обучающего множества увеличивает разброс в предсказаниях моделей. Кроме того, даже при корректном семплировании есть риск переобуче- ния— нахождения весов, дающих высокое качество на отложенных данных, нс плохо обобщаемых (в особенности это относится к сложным метамоделям). Нако- нец, такое применение отложенных данных имеет те же ограничения, что и при ва- лидации: если их слишком мало или они нерепрезентативны, вы не получите на- дежных результатов. Блендинг: лучшие практики Тип метамодели, используемой при блендинге, очень важен. Чаще всего приходит» ся делать выбор между линейными и нелинейными моделями. Среди линейных мо- делей самые популярные — линейная и логистическая регрессия. Применение ре- гуляризации позволяет уменьшить влияние менее полезных моделей (L2- регуляризация) или отбросить вовсе бесполезные (L1-регуляризация). Одна из про- блем при использовании таких метамоделей заключается в том, что они могут при- сваивать некоторым моделям отрицательные веса. Обычно речь идет о переобуче- нии: все модели должны вносить положительный вклад в результаты ансамблх (либо не вносить никакого). Последние версии Scikit-leam позволяют подбирать только положительные веса и не использовать свободный член. Такие ограничени! действуют как регуляризация и предотвращают переобучение. Нелинейные метамодели встречаются реже, поскольку склонны к переобучению на задачах регрессии и бинарной классификации. Они, однако, могут уловить слож- ные взаимодействия между классами, поэтому часто хорошо работают в задачах многоклассовой классификации и задачах со множественными метками классов Они также лучше работают, если дать им, помимо предсказаний моделей, исходные
Глава 9. Ансамбли: блендинг и стекинг 285 признаки — они способны выявить полезные закономерности и понять, каким мо- делям стоит доверять больше. В нашем следующем примере мы сначала проведем блендинг с линейной метамо- делью (логистическая регрессия), затем с нелинейной (случайный лес). Сначала мы разобьем обучающее множество на две части: на одной будут обучаться исходные модели, другая будет отложена для метамодели. Обучив исходные модели, мы сде- лаем предсказания на отложенных данных. from sklearn.preprocessing import StandardScaler X-blend, X_holdoutj y_blendj y_holdout = train_test_split(X_trainj y_train, test_size=0.25j random_state=0) model_l.fit(X_blendj y_blend) model_2.fit(X_blendj y_blend) model_3.fit(X_blendj y_blend) proba = np.stack([model__l.predict_proba(X_holdout)[:3 1], model_2.predict_proba(X_holdout)[:, 1]3 model_3.predict_proba(X_holdout)[:3 1]]).T scaler = StandardScalerQ proba = scaler.fit_transform(proba) Теперь по этим предсказаниям обучим метамодель: from sklearn.linearjnodel import LogisticRegression blender = LogisticRegression(solver='liblinear') blender.fit(proba3 y_holdout) print(blender.coef_) Ее коэффициентами будут: [[0.78911314 0.47202077 0.75115854]] По этим коэффициентам мы можем понять, какие модели вносят наибольший вклад в ансамбль. Заметим, однако, что коэффициенты масштабируют вероятности, по- этому больший коэффициент модели не всегда означает, что эта модель самая важ- ная. Для того чтобы понять истинную роль каждой модели, необходимо провести стандартизацию коэффициентов (в нашем коде это сделано с помощью StandardScaler).
286 Часть II. Оттачивание соревновательных навыков В итоге мы видим, что методы опорных векторов и ближайших соседей весят при- мерно одинаково и больше, чем случайный лес. Обучив метамодель, мы делаем предсказания на отложенных данных и вычисляем качество: test_proba = np.stack([model_l.predict_proba(X_test)[1], model_2.predict_proba(X_test)[:3 1]} model_3.predict_proba(X_test)[:} 1]]).T blending = blender.predict_proba(test_proba)[:, 1] ras = roc_auc_score(y_true=y_test, y_score=blending) print(f"ROC-AUC for linear blending {model} is: {ras:0.5f}") To же самое мы можем повторить и с нелинейной моделью, например, случайным лесом: blender = RandomForestClassifier() blender.fit(probaj yjwldout) test_proba = np.stack([model_l.predict_proba(X_test)[:3 1], model_2.predict_proba(X_test)[:3 1]3 model_3.predict_proba(X_test)[:} 1]]).T blending = blender.predict_proba(test_proba)[:, 1] ras = roc_auc_score(y_true=y_testj y_score=blending) print(f"ROC-AUC for non-linear blending {model} is: {ras:0.5f}") Альтернативой использованию линейной или нелинейной метамодели может слу- жить метод выбора ансамбля, формализованный в знаменитой статье Р. Каруаны. А. Никулеску-Мизила, Д. Крю, А. Ксикеса. Если вам интересны детали, прочитайте эту статью: Caruana R., Ni- culescu-Mizil A., Crew G., Ksikes A. Ensemble selection from libraries of models // Proceedings of the Twenty-First International Conference on Ma- chine Learning. — 2004. Выбор ансамбля, по сути, осуществляется с помощью линейной комбинации моде- лей, однако, имеющей некоторые ограничения, помогающие делать отбор моделей и обеспечивающие положительность коэффициентов (в основе метода лежит опти- мизация восхождением к вершине). Благодаря этому уменьшается риск переобуче-
. лава 9. Ансамбли: блендинг и стекинг 287 зия и, поскольку происходит отбор моделей, решение становится более компакт- ным. С учетом этого метод выбора ансамбля рекомендуется применять во всех си- туациях, когда высок риск переобучения (например, из-за нехватки данных или сложности модели). Из-за его простоты и при этом эффективности данный метод рекомендуется и для реальных приложений. При использовании метамодели результат зависит от ее функции стоимости, кото- рая может отличаться от используемой на конкурсе метрики. Преимуществом вы- бора ансамбля является возможность оптимизации с произвольной функцией стои- мости, поэтому данный метод рекомендуется использовать, когда конкурсная метрика отличается от канонической для выбранного типа модели. Этапы выбора ансамбля, согласно упомянутой выше статье: I. Пусть у вас имеется набор обученных моделей и отложенные данные 2. Протестируйте все модели на отложенных данных и оставьте самую эффективную. 3. Продолжайте тестирование, добавляя к уже выбранным оставшиеся модели. Если новый усредненный результат превосходит текущий, оставляем эту мо- дель. Эту процедуру можно проводить как с повторами (когда одну и ту же мо- дель можно добавить в ансамбль много раз), так и без них. Во втором случае результат аналогичен получаемому при таком способе действий: каждый раз добавляем ту модель, которая сильнее всего улучшает результат, до тех пор, пока улучшения не прекращаются (forward selection). Первый способ аналоги- чен взвешенному среднему. 4. Остановитесь, когда качество перестанет улучшаться. Ниже приведен пример кода для выбора ансамбля. Сначала мы делим данные на эбучающие и отложенные. Затем мы обучаем модели и делаем предсказания на от- ложенных данных (как и в случае с метамоделью): X_blendj XJioldout, y_blend, y_holdout = train_test_split (X-train, yjtrain, test_size=0.5, random_state=0) model_l.fit(X_blendj y_blend) model_2.fit(X_blendj y_blend) model_3.fit(X_blend, y_blend) proba = np. stack ([ model__l. predict_proba (X_holdout) [:, 1], model_2.predictj3roba(X_holdout)[:> 1]> model_3.predict_proba(X_holdout)[:3 1]]).T Затем итеративно создается ансамбль. На каждой итерации мы пробуем добавлять к имеющемуся ансамблю каждую из моделей и проверять, улучшается ли качество. Если новый ансамбль работает на отложенных данных лучше предыдущего, ан-
288 Часть II. Оттачивание соревновательных навыков самбль обновляется, планка качества повышается. Если ни одна из моделей не спо- собна улучшить качество, построение ансамбля завершается. iterations = 100 proba = пр•stack([model_l.predict_proba(X_holdout)[:j 1], model_2.predict j3roba(X_holdout)[:, 1]3 model_3.predict_proba(X_holdout)[:3 1]]).T baseline =0.5 print(f"starting baseline is {baseline:©.5f}") models = [] for i in range(iterations): challengers = list() for j in range(proba.shape[1]): new_proba = np.stack(proba[:3 models + [j]]) score = roc_auc_score(y_true=y_holdoutj y_score=np.mean(new_proba, axis=l)) challengers.append([scorej j]) challengers = sorted(challengers3 key=lambda x: x[0], reverse=True) best_scorej bestjnodel = challengers[0] if best_score > baseline: print(f"Adding model_{best_model+l} to the ensemble"3 end=': ') print(f"ROC-AUC increases score to {best_score:0.5f}") models.append(bestjnodel) baseline = best_score else: print("Cannot improve further - Stopping") Наконец, мы можем посчитать количество добавлений каждой модели и соответст- вующие веса: from collections import Counter freqs = Counter(models) weights = {key: freq/len(models) for key, freq in freqs.items()} print(weights)
Глава 9. Ансамбли: блендинг и стекинг 289 Эту процедуру можно изменять и дополнять. Так, исходный вариант склонен к пе- реобучению, особенно на начальных этапах, поэтому можно начинать с нескольких случайно выбранных или (как предлагают авторы метода) нескольких лучших мо- делей (их число п будет гиперпараметром). Также можно на каждом шаге выбирать случайное подмножество проверяемых моделей (т. е. некоторые модели невозмож- но будет выбрать на этом шаге). Это не только добавит в процесс случайность, но и предотвратит ситуацию, когда в ансамбле доминируют одна-две модели. Стекинг Метод стекинга был впервые описан в статье Дэвида Вольперта (Wolpert D. Н. Stacked generalization // Neural networks. — 1992. — Vol. 5, № 2. — P. 241-259). Од- нако лишь спустя годы он стал широко известен и распространен (так, в библиоте- ке Scikit-leam он появился лишь в версии 0.22 в декабре 2019 г.) благодаря конкур- су от Netflix и последующим соревнованиям на Kaggle. При стекинге всегда создается метамодель. Обучается она, однако, не на отложен- ных данных, а на всем обучающем множестве, благодаря стратегии OOF- предсказаний, которую мы обсуждали в главе 6. Мы осуществляем воспроизводи- мое (благодаря записи или заданию начального состояния генератора) разбиение данных на к блоков, которое используется для всех моделей. На конкурсе Netflix стекинг и блендинг часто использовались одинако- вым образом, хотя исходно метод Вольперта применялся в схеме кон- г—ТР0™ по блокам, а не по отложенным данным. Основная идея стекин- га, в отличие от методов усреднения, не в уменьшении разброса, а в уменьшении смещения (т. к. предполагается, что каждая из моделей выявит часть присутствующей в данных информации, а метамодель объединит эти части). Вспомним, как работают OOF-предсказания на обучающих данных. При валидации вы на каждой итерации обучаете модель на части данных и используете для кон- троля оставшуюся часть. Записав предсказания на этих оставшихся примерах, а затем расположив их в том же порядке, в котором они шли в исходных данных, вы получите предсказания на всем обучающем множестве. Так как при этом вы использовали разные модели и каждая делала предсказания не на тех данных, на которых обучалась, переобучения не происходит. Получив OOF-предсказания от каждой модели (предсказания первого уровня), вы можете построить метамодель, делающую итоговые предсказания на их основе ли- бо выдающую новые OOF-предсказания на основе предыдущих (предсказания вто- рого и последующих уровней), создавая несколько уровней стекинга. Такая схема
290 Часть II. Оттачивание соревновательных навыков согласуется с предложенной самим Вольпертом идеей о том, что многочисленные метамодели имитируют полносвязную нейронную сеть прямого распространения, в которой веса подобраны так, чтобы максимизировать предсказательную способ- ность отдельно на каждом уровне. На практике многоуровневый стекинг весьма эффективен, особенно для сложных задач, с которыми не справляются отдельные модели. Интересно, что стекинг, в отличие от усреднения и во многих случаях от блендин- га, не требует от моделей близкой предсказательной способности. Даже относи- тельно плохо работающие модели могут быть полезны в составе стекинга. Так, ме- тод ближайших соседей может сильно уступать градиентному бустингу, но его OOF-предсказания все равно улучшат общий результат при стекинге. Обучив все уровни стекинга, надо получить предсказания. Заметим, что это (на ка- ждом из уровней) можно делать двумя способами. Исходная статья Вольперта предлагает повторно обучить модели на всем обучаю- щем множестве, а затем использовать их для предсказаний на тестовом множестве. На практике многие кэгглеры вместо повторного обучения используют модели, со- ответствующие каждому контрольному блоку, и усредняют их предсказания на тес- товых данных. Рис. 9.1. Диаграмма двухуровневого стекинга с усреднением итоговых предсказаний По нашему опыту повторное обучение на всех доступных данных действительно более эффективно при небольшом количестве блоков валидации. В этих случаях обучение на меньшем количестве данных заметно увеличивает разброс в результа- тах. Как мы говорили в главе 6, для OOF-предсказаний всегда предпочтительнее большое число блоков, от 10 до 20. Такое условие ограничивает количество неза- действованных в обучении примеров, так что можно обойтись без переобучения на
Глава 9. Ансамбли: блендинг и стекинг 291 всех данных, взять модели, обученные на всех блоках, кроме одного, и просто ус- реднить полученные от них предсказания на тестовом множестве. В нашем следующем примере для наглядности будет использоваться пять блоков и два уровня стекинга. На рис. 9.1 показаны модели и движение данных между раз- ными этапами стекинга. Заметим, что: • обучающие данные передаются обоим уровням стекинга (OOF-предсказания на втором уровне стекинга объединяются с ними); • получив OOF-предсказания от кросс-валидации, модели повторно обучаются на всех обучающих данных; • итоговые предсказания являются средним от предсказаний всех моделей. Давайте теперь посмотрим, как стратегия с диаграммы реализуется в коде. Начнем с первого уровня: from sklearn.model_selection import KFold kf = KFold(n_splits=5, shuffle=True, random_state=0) scores = list() first__lvl_oof = np.zeros((len(X_train), 3)) fist_lvl_preds = np.zeros((len(X_test), 3)) for k, (train_index, val_index) in enumerate(kf.split(X_train)): model-1.fit(X_train[train_index, :], y_train[train_index]) first-lvl_oof[val_index, 0] = model_l.predict_proba( X_train[val_index, :])[:, 1] model_2.fit(X_train[train_index, : ], y_train[train_index]) first-lvl_oof[val_index, 1] = model_2.predict_proba( X_train[val_index, :])[:, 1] model_3.fit(X_train[train_index, : ], y_train[train_index]) first_lvl_oof[val_index, 2] = model_3.predict_proba( X_train[val_index, :])[:, 1] Проведем повторное обучение на всех данных: model_l.fit(X_train, y_train) fist_lvl_preds[:, 0] = model_l.predict_proba(X_test)[:, 1]
292 Часть II Оттачивание соревновательных навыков model_2.fit(X_train, yjtrain) fist_lvl_preds[:, 1] = model_2.predict_proba(X_test)[1] model_3.fit(X_train, y_train) fist_lvl_preds[:, 2] = model_3.predict_proba(X_test)[1] На втором уровне мы используем те же модели, что и на первом, добавив получен- ные OOF-предсказания к исходным данным: second_lvl_oof = np.zeros((len(X_train), 3)) second_lvl_preds = пр.zeros((len(X_test), 3)) for k, (train_index, val_index) in enumerate(kf.split(X_train)): skip_X_train = np.hstack([X_train, first_lvl_oof]) model_l.fit(skip_X__train[train_index, : ], y__train[train_index]) second_lvl_oof[val_index, 0] = model_l.predict_proba( skip_X_train[val_index, :])[:, 1] model_2.fit(skip_X_train[train_index, :], y_train[train_index]) second_lvl_oof[val_index, 1] = model_2.predict_proba( skip_X_train[val_index, :])[:, 1] model_3.fit(skip_X_train[train_index, :], y_train[train_index]) second_lvl_oof[val_index, 2] = model_3.predict_proba( skip_X_train[val_index, :])[:, 1] Теперь мы снова проводим обучение на всех данных для второго уровня: skip_X_test = np.hstack([X_test, fist_lvl_preds]) model_l.fit(skip_X_train, y_train) second_lvl_preds[:> 0] = model_l.predict_proba(skip_X_test)[1] model_2.fit(skip_X_train, y__train) second_lvl_preds[:, 1] = model_2.predict_proba(skip_X_test)[1] model_3.fit(skip_X_train, y_train) second_lvl_preds[:, 2] = model_3.predictjjroba(skip_X_test)[:, 1]
Глава 9. Ансамбли: блендинг и стекинг 293 Завершаем усреднением всех OOF-предсказаний второго уровня: arithmetic = second JLvl_preds.mean(axis=l) ras = roc_auc_score(y_true=y_test, y_score=arithmetic) scores.append(ras) print(f'Stacking ROC-AUC is: {ras:0.5f}") В итоге значение метрики ROC-AUC составляет примерно 0,90424, что лучше, чем в наших примерах блендинга и стекинга на тех же данных и моделях. Варианты стекинга Яри применении стекинга приходится выбирать, как обрабатываются тестовые данные на каждом уровне, используются ли на каждом уровне только OOF- предсказания или также и исходные признаки, какую модель взять в качестве по- следней. Также существует немало приемов, позволяющих избежать переобучения. Перечислим некоторые наиболее эффективные варианты, которые мы использова- ли сами. • Не всегда обязательно применять оптимизацию. Некоторые решения не слишком заботятся об оптимизации отдельных моделей, кое-какие оптимизи- руют только первые или последние уровни. По нашему опыту, однако, опти- мизация отдельных моделей важна, и мы предпочитаем делать ее как можно раньше. • Модели на разных уровнях могут различаться либо повторяться. Общего правила здесь нет, все зависит от задачи. Наиболее эффективные типы моде- лей будут разными для различных задач. Тем не менее соединение моделей градиентного бустинга и нейросетей нас никогда не разочаровывало. • На первом уровне стекинга стоит создавать как можно больше моделей. Можно использовать регрессионную модель в задаче классификации, и на- оборот. Можно брать различные комбинации гиперпараметров, тем самым избегая затрат ресурсов на оптимизацию,— стекинг сделает выбор за вас. При применении нейросетей достаточно поменять начальное состояние слу- чайного генератора, чтобы получить большое разнообразие моделей. Можно использовать различные преобразования признаков и даже обучение без учителя (так, Майк Ким (Mike Kim) воспользовался t-SNE: https://www.kaggle.com/ c/otto-group-product-classification-challenge/discussion/14295). Идея состоит в том, что отбор происходит на втором уровне стекинга. На нем, таким обра- зом, вам не нужно экспериментировать, а достаточно сосредоточиться на не- большом подмножестве лучших моделей. Стекинг позволяет повторно ис- пользовать все ваши эксперименты и автоматически отбирать полезные. • Некоторые из реализаций стекинга используют исходные признаки (все или часть из них) и на следующих уровнях (что аналогично skip-слоям в нейрон- ных сетях). Это может улучшить результаты, но увеличивает шум и риск пе- реобучения.
294 Часть II. Оттачивание соревновательных навыков • В идеале OOF-предсказания должны делаться кросс-валидацией с большим количеством блоков, от 10 до 20, но мы видели рабочие решения и с 5 блоками. • Для каждого блока многократный семплинг данных с повторением и усред- нение всех предсказаний модели (контрольных и OOF) позволяет избежать переобучения и тем самым повысить итоговое качество. • Остерегайтесь ранней остановки. Ее использование на контрольном блоке может привести к переобучению, которое иногда, но не обязательно, компен- сируется при стекинге. Мы советуем перестраховаться и осуществлять ран- нюю остановку на основе семпла из обучающих, а не контрольных блоков. Вариантов стекинга бесконечно много. Вообще, поняв общую идею ансамблевого метода, нужно творчески подходить к имеющейся задаче. В последнем разделе этой главы мы приведем пример конкурсного решения с помощью стекинга. Сложные решения с блендингом и стекингом К этому моменту вы наверняка задались вопросом, когда стоит применять описан- ные в этой главе методы. Теоретически все их можно использовать на любом со- ревновании, на практике возникают некоторые ограничения. • Иногда данных слишком много, и обучение каждой модели занимает очень много времени. • На соревнованиях по распознаванию изображений вы вынуждены использо- вать глубокое обучение. • Даже если вы можете позволить себе применить стекинг с моделями глубо- кого обучения, выбор этих моделей будет довольно ограниченным. Вы смо- жете менять очень немногое в архитектуре и гиперпараметрах сети, не ухуд- шая ее качество (порой допустимо менять только начальное состояние случайного генератора). В итоге при одинаковом типе моделей и близкой ар- хитектуре решения оказываются коррелирующими сильнее, чем нужно, чтс ограничивает эффективность ансамбля. При этих условиях сложные стекин- говые решения обычно неприменимы, однако усреднение и блендинг чаше всего годятся для больших данных. На первых конкурсах, как и на современных табличных, стекинг и блендинг 6ыле лидирующими методами. Для того чтобы дать вам представления об изобретатель- ности, применявшейся при использовании стекинга, в этом последнем разделе мы обсудим решение Жилберту Титерича (Gilberto Titericz, https://www.kaggle.com titericz) и Станислава Семенова (https://www.kaggle.com/stasg7) для конкурса Otte Group Product Classification Challenge (https://www.kaggle.com/c/otto-group-product- classification-challenge). На этом соревновании, проходившем в 2015 г., требовалось распределить более 200 тыс. продуктов по 9 классам на основании 93 признаков. Решение Гильберто и Станислава имело три уровня. 1. Первый уровень содержал 33 модели. Все они использовали разные алгоритмы. кроме нескольких основанных на методе к ближайших соседей (для различных h
Глава 9. Ансамбли: блендинг и стекинг 295 Также авторы применяли t-SNE (метод обучения без учителя). Кроме того, они создали восемь новых признаков на основе действий с размерностью простран- ства, подсчета расстояний до ближайших соседей и кластеров и количества не- нулевых элементов строк. Все OOF-предсказания и признаки передавались на следующий уровень. 2. На втором уровне начинались оптимизация гиперпараметров, отбор моделей и бэггинг. Создавалось множество вариантов каждой модели, их результаты ус- реднялись. В итоге были получены три модели, которые повторно обучили на всех имеющихся данных: XGBoost, AdaBoost и нейронная сеть. 3. На третьем уровне авторы взяли среднее геометрическое результатов XGBoost и нейронной сети, а затем усреднили его с результатами AdaBoost. Это решение может многому нас научить, и эти уроки относятся не только к кон- кретному соревнованию. Кроме его сложности (на втором уровне для каждой мо- дели брались сотни семплов), примечательны многочисленные отступления от схем, обсуждавшихся ранее. К решению вели творческий подход и многочислен- ные пробы и ошибки, что типично для конкурсов Kaggle, поскольку задачи редко повторяются и каждое решение уникально. Многие средства автоматического машинного обучения, такие как AutoGluon, бо- лее или менее явно пытаются воспроизвести ’’человеческий” подход к построению ансамблей с помощью стекинга и блендинга, при этом переведя его в последова- тельность заранее определенных шагов. Довольно длинный список алгоритмов, используемых в AutoGluon, можно обнаружить в статье https://arxiv.org/abs/2003.06505. Вы може- те найти в нем и идеи для собственных решений. Тем не менее результаты AutoGluon уступают результатам хорошей команды кэгг- леров — изобретательность при экспериментировании и построении ансамбля яв- ляется ключом к успеху. Поэтому данную главу также стоит рассматривать как от- правную точку. Мы показали вам лучшие методы построения ансамблей, идите дальше, меняйте и развивайте их в соответствии со стоящей пред вами конкурсной или реальной задачей. Ксавье Конорт https://www.kaggle.com/xavierconort В завершение этой главы поговорим с Ксавье Конортом, гроссмейстером в категории Competitions, лидером рейтинга в 2012—2013 гг., на заре истории Kaggle бывшим примером для подражания многих участников. Ныне он — СЕО собст- венной компании, Data Mapping and Engineering. Мы обсу- дили с Ксавье его опыт на Kaggle, карьеру и многое другое.
296 Часть IL Оттачивание соревновательных навыков Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я очень люблю соревнования, где необходимо преобразовывать признаки из не- скольких таблиц, искать удачные признаки, особенно в новых для меня областях. Участие в конкурсах дало мне уверенность при столкновении с новыми задача- ми. Кроме умения преобразовывать признаки, мне очень помогает метод стекин- га, позволяющий объединять модели, преобразовывать тексты и категориальные признаки в числовые. Больше всего я люблю алгоритмы градиентного бустинга, но в ансамблях стремлюсь к разнообразию моделей. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я исходно ставил перед собой цель научиться как можно большему на каждом конкурсе. Перед началом участия я всегда думал, какие навыки могу развить. Я не боялся выходить из зоны комфорта и знал, что могу быстро учиться на ошиб- ках (благодаря тому, что видел результат в таблице). Обычная работа редко дает такие возможности, поскольку в ней сложно оценить качество решения, и мы часто перестраховываемся и идем по старым схемам. Не думаю, что без Kaggle я смог бы так многому научиться. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Мой любимый конкурс — GE Flight Quest, на котором требовалось предсказать время прибытия внутренних авиарейсов в США. Особенно мне понравилось, что итоговое оценивание проводилось по данным полетов, произошедших после окончания конкурса. Так как мы имели данные всего за несколько месяцев (если не ошибаюсь, три или четыре), я понимал, что велик риск переобучения. Для того чтобы умень- шить его, я решил строить только признаки, имеющие очевидную причинно- следственную связь с задержками рейсов (касающиеся, например, погодных ус- ловий и интенсивности полетов). Также я удалил из списка признаков, исполь- зуемых на первом этапе, название аэропорта, поскольку в некоторых аэропортах за эти несколько месяцев не было плохих погодных условий. Я боялся, что мой любимый алгоритм градиентного бустинга будет делать предсказания так, как будто в них всегда хорошая погода, и покажет плохие результаты на новых дан- ных. В итоге я все же использовал данные о названии аэропорта, чтобы улучшить результат (поскольку в некоторых из них лучше организация работы), но только на втором этапе, дополняющем результаты первого. Такой подход напоминает двухступенчатый бустинг, у которого на первом этапе не учитывается часть ин- формации. Такой подход я позаимствовал у тех, кто занимается страхованием. Помог ли тебе Kaggle в карьере? Если да, то как? Да, он определенно помог мне в карьере исследователя данных. До перехода в эту область я работал в страховой компании актуарием (специалистом по страхо- вой математике), не имел понятия о машинном обучении и не знал ни одного ис-
Глава 9. Ансамбли: блендинг и стекинг 297 следователя данных. Благодаря разнообразию конкурсов на Kaggle я смог быстро учиться. Теперь я мог показывать свои результаты соревнований, чтобы убедить работодателей, что 39-летний актуарий может самостоятельно освоить новую профессию. Также благодаря Kaggle я смог общаться с множеством увлеченных своим делом исследователей данных со всего мира. Сначала они были моими со- перниками или сокомандниками, потом с некоторыми из них мы стали коллега- ми. С основателями DataRobot Джереми Ачином и Томом де Годоем мы сорев- новались в одной команде, а потом они позвали меня в DataRobot. Думаю, что без Kaggle я так и работал бы актуарием. Использовал ли ты свои результаты на Kaggle в портфолио для потенциальных работодателей? Должен признаться, что я участвовал в нескольких соревнованиях с целью впе- чатлить работодателя или потенциального клиента. Это удавалось, но приносило меньше удовольствия и больше стресса. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Я бы посоветовал начинающим не смотреть на решения, которые выкладываются во время конкурса, а стремиться найти собственное. Я очень рад, что на заре ис- тории Kaggle участники не выкладывали свои решения— это заставило меня учиться самостоятельно. Какие ошибки ты допускал на соревнованиях? Одна из ошибок — продолжать участвовать в соревнованиях с утечками в дан- ных. Это трата времени, вы ничему там не научитесь. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Больше всего я люблю метод градиентного бустинга. Я использовал поначалу библиотеку gbm для языка R, затем GBM из Scikit-leam, затем XGBoost и, нако- нец, LightGBM. Чаще всего именно градиентный бустинг был ключевой частью выигрышного решения. Для того чтобы разобраться в работе GBM, я рекомен- дую познакомиться с библиотекой SHAP. О чем важнее всего помнить, приступая к участию в соревновании? Соревнуйтесь не только с целью победить, но и с целью учиться и общаться с другими исследователями даннх. Резюме В данной главе мы поговорили о том, как работают ансамблевые методы, и приве- ли примеры кода, которые вы можете использовать как отправную точку для соб- ственных решений. Мы начали с идей, стоящих за такими моделями, как случайные леса и градиентный бустинг. Затем мы перешли к обсуждению разновидностей ан- самблевых методов, от простого усреднения до многоуровневого стекинга.
298 Часть II. Оттачивание соревновательных навыков Как мы заметили в конце, построение ансамблей— скорее искусство, котором} учатся на своем и чужом опыте. Мы увидели решение победителей, использующее стекинг, и могли восхититься тем, как вся схема была подобрана под задачу и данные. Вы не можете просто воспроизвести ее для другой задачи и надеяться на высокий результат. Можно только следовать общим принципам и искать лучшее ансамбле- вое решение самостоятельно, своими усилиями (заметим, что многочисленные экс- перименты потребуют и немалых вычислительных ресурсов). В следующей главе мы перейдем к конкурсам по глубокому обучению и начнем с задач классификации и сегментации в компьютерном зрении. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
10 Моделирование в компьютерном зрении Задачи компьютерного зрения — одни из самых популярных в практических при- ложениях машинного обучения; они стали возможностью входа в мир глубокого обучения для многих кэгглеров, включая Конрада. За последние несколько лет в этой области произошел огромный прогресс, и новые библиотеки SOTA продол- жают выпускаться. В этой главе мы дадим вам обзор наиболее популярных видов соревнований в компьютерном зрении: • классификация изображений; • распознавание объектов; • сегментация изображений. Мы начнем с краткого раздела об аугментации изображений — группе методов, не зависящих от задачи, которые можно применить в решении различных проблем для повышения обобщающей способности наших моделей. Стратегии аугментации Хотя методы глубокого обучения оказались чрезвычайно успешными в задачах компьютерного зрения, таких как распознавание изображений, сегментация или обнаружение объектов, лежащие в их основе алгоритмы, как правило, чрезвычайно требовательны к данным: им необходимы большие объемы данных, чтобы можно было избежать чрезмерной подгонки. Однако не все области, представляющие ин- терес, удовлетворяют этому требованию, поэтому на помощь приходит аугмента- ция данных. Это название для группы методов обработки изображений, которые создают модифицированные версии изображений, увеличивая размер и качество обучающих датасетов, что приводит к улучшению производительности моделей глубокого обучения. Данные после аугментации, как правило, представляют собой
300 Часть II. Оттачивание соревновательных навыков более полный набор возможных точек данных, что позволяет минимизировать дис- танцию между обучающим и валидационным наборами, а также любыми будущи- ми тестовыми наборами. В этом разделе мы рассмотрим некоторые из наиболее распространенных методов аугментации, а также варианты их программных реализаций. Вот наиболее часто используемые преобразования: • переворот— переворачивание изображения (по горизонтальной или верти- кальной оси); • поворот — поворот изображения на заданный угол (против часовой стрелки или по ней); • обрезка (кадрирование) — выбор случайного фрагмента изображения; • яркость — изменение яркости изображения; • масштабирование— изменение изображения до большего (наружу) или меньшего (внутрь) размера. Ниже мы продемонстрируем, как эти трансформации работают на практике, ис- пользуя изображение легенды американского актерского искусства и комедийной актрисы Бетти Уайт (Betty White), рис. 10.1. Рис. 10.1. Изображение Бетти Уайт Мы можем перевернуть изображение по вертикальной или горизонтальной оси (рис. 10.2). Поворот не требует пояснений; обратите внимание на автоматическое дополнение изображения на заднем плане (рис. 10.3). Мы также можем обрезать изображение до границ интересующей нас области (рис. 10.4).
Глава 10. Моделирование в компьютерном зрении 301 Рис. 10.2. Изображение Бетти Уайт, перевернутое по вертикали (слева) и по горизонтали (справа) Рис. 10.3. Изображение Бетти Уайт повернуто по часовой стрелке Рис. 10.4. Изображение Бетти Уайт, обрезанное
302 Часть II. Оттачивание соревновательных навыков Обобщая, можно сказать, что аугментации можно применять одним из двух способов. • Офлайн. Обычно они применяются для небольших датасетов (меньшее ко- личество изображений или меньший размер, хотя смысл слова ’’небольшой” зависит от имеющегося оборудования). Идея заключается в том, чтобы соз- дать модифицированные версии оригинальных изображений в качестве этапа предварительной обработки вашего датасета, а затем использовать их наряд} с исходниками. • Онлайн. Используются для больших датасетов. Аугментированные изобра- жения не сохраняются на диске; аугментации применяются в мини-пакетах и подаются в модель. В нескольких следующих разделах мы дадим обзор двух наиболее распространен- ных методов аугментации датасета изображений: встроенной функциональности Keras и пакета albumentations. Существует еще несколько вариантов (skimage. OpenCV, imgaug, Augmentor, SOLT), но мы остановимся на самых популярных. Методы, обсуждаемые в этой главе, базируются на анализе изображе- ний с помощью GPU. Использование в обработке тензорных процес- соров (tensor processing units, TPU) является развивающейся, но все еще несколько нишевой областью применения. Читателям, интересующим- ся увеличением изображений в сочетании с анализом на основе TPU, рекомендуем ознакомиться с прекрасной работой Криса Деотте (@cdeotte): https://www.kaggle.com/cdeotte/triple-stratified-kfold-with-tfrecords Крис является четырехкратным гроссмейстером Kaggle и фантастиче- ским преподавателем через создаваемые им блокноты и обсуждения, в которых он участвует. В целом это человек, за которым определенно стоит следить любому кэгглеру независимо от уровня своего опыта. Мы будем использовать данные конкурса Cassava Leaf Disease Classification (https://www.kaggle.eom/c/cassava-leaf-disease-classification). Как обычно, начина- ем с подготовительной работы — сначала загружаем необходимые пакеты: import os import glob import numpy as np import scipy as sp import pandas as pd import cv2 from skimage.io import imshow, imread, imsave
Глава 10. Моделирование в компьютерном зрении 303 # imgaug import imageio import imgaug as ia import imgaug.augmenters as iaa # ALbumentations import albumentations as A # Keras # из keras.preprocessing.image импортируйте ImageDatoGeneratorj array_to_imgj # img_to_orroyj Lood_img # Визуализация import matplotlib.pyplot as pit import matplotlib.image as mpimg %matplotlib inline import seaborn as sns from IPython.display import HTML, Image # Предупреждения import warnings warnings.filterwarnings("ignore") Затем определяем некоторые вспомогательные функции, которые в дальнейшем упростят представление. Нам нужен способ загрузки изображений в массивы: def load_image(image_id): file_path = image_id image = imread(Image_Data_Path + file_path) return image Требуется отобразить несколько изображений в стиле галереи, поэтому мы создаем функцию, которая принимает на вход массив, содержащий изображения вместе с желаемым количеством столбцов, и выводит массив, преобразованный в сетку с заданным количеством столбцов: def gallery(array, ncols=3): nindex, height, width, intensity = array.shape nrows = nindex//ncols assert nindex == nrows*ncols
304 Часть II. Оттачивание соревновательных навыков result = (array.reshape(nrows, ncols, height, width, intensity) .swapaxes(1,2) .reshape(height*nrows, width*ncols, intensity)) return result Позаботившись о шаблоне, мы можем загрузить изображения для аугментации: data_dir = ’../input/cassava-leaf-disease-classification/' Image_Data_Path = data__dir + '/train-images/' train_data = pd.read_csv(data_dir + ’/train.csv’) # Загружаем и храним первые 10 изображений в памяти # для более быстрого доступа к ним train_images = train__data[”image_id,,][:10].apply(load_image) Давайте загрузим одно изображение, чтобы знать, на что мы ссылаемся: I curr_img = train_images[7] I plt.figure(figsize = (15,15)) pit.imshow(curr_img) pit.axis(’off1) Вот оно (рис. 10.5). Puc. 10.5. Контрольное изображение В следующих разделах мы покажем, как генерировать аугментированные изобра- жения из этого эталонного изображения, используя как встроенные функции Keras, так и библиотеку albumentations.
Глава 10. Моделирование в компьютерном зрении 305 Встроенные аугментации Keras В библиотеке Keras есть встроенная функциональность для аугментации. Хотя она не так обширна, как специализированные пакеты, ее преимущество заключается в лег- кой интеграции в ваш код. Нет необходимости в отдельном блоке кода для определе- ния преобразований аугментации, но мы можем включить их в imageDataGenerator — функциональность, которую мы, скорее всего, будем использовать. Первый рассматриваемый нами подход Keras основан на классе ImageDataGenerator. Как следует из названия, он может использоваться для создания пакетов данных изображений с аугментацией данных в режиме реального времени. Подход на основе ImageDataGenerator Начнем с создания объекта класса ImageDataGenerator следующим образом: import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img datagen = ImageDataGenerator( rotation_range = 40, shear_range = 0.2, zoom_range =0.2, horizontal-flip = True, brightness_range = (0.5, 1.5)) curr_img_array = img_to_array(curr_img) curr_img_array = curr_img_array.reshape((1,) + curr_img_array.shape) Мы определяем желаемые аугментации как аргументы для ImageDataGenerator. В официальной документации этот вопрос не рассматривается, но практические ре- зультаты показывают, что аугментации применяются в том порядке, в котором они определены в качестве аргументов. В приведенном выше примере мы используем лишь ограниченный на- бор возможных вариантов; полный список доступен в официальной до- кументации : https ://keras.io/api/preprocessing/image/. Далее мы перебираем изображения с помощью метода .flow объекта ImageDataGenerator. Класс предоставляет три различные функции для загрузки дата- сета изображений в память и генерации пакетов аугментированных данных: • flow; • flow_from_directory; • flow_from_dataframe.
306 Часть II. Оттачивание соревновательных навыков Все они достигают одной и той же цели, но различаются способом указания место- положения файлов. В нашем примере изображения уже находятся в памяти, поэтому мы можем выпол- нять итерации, используя самый простой метод: i = e for batch in datagen.flow( curr_img__array, batch_size=l, save_to_dir=’.’3 save_prefix=’Augmented_image’, save_format=’jpeg’): i += 1 # Жестко закодированная остановка> без нее генератор входит в бесконечный цикл if i > 9: break Можно изучить дополненные изображения с помощью вспомогательных функций, которые мы определили ранее: aug_images = [] for img path in glob.glob("*.jpeg”): aug__images. append (mpimg. imread (img path)) pit.figure(figsize=(20,20)) pit.axis(’off’) plt.imshow(gallery(np.array(augL_images[0:9])J ncols = 3)) pit.title(’Augmentation examples’) Результат будет таким, как на рис. 10.6. Аугментации— очень полезный инструмент, но его эффективное использование требует рассудительности. Во-первых, очевидно, что неплохо было бы визуализиро- вать его работу, чтобы оценить влияние на данные. С одной стороны, мы хотим вне- сти некоторую вариативность в данные, чтобы повысить обобщенность нашей моде- ли; с другой стороны, если мы изменим изображения слишком радикально, входные данные будут менее информативными, и производительность модели, скорее всего, снизится. Кроме того, выбор того, какие именно аугментации использовать, также может зависеть от конкретной задачи, и это мы видим, сравнивая различные конкурсы. Если вы посмотрите на рис. 10.6 (эталонное изображение с конкурса Cassava Leaf Disease Classification), листья, по которым мы должны определить болезнь, могут быть разных размеров, направлены под разными углами и т. д., что обусловлено формой растений и различиями в способах получения изображений. Это означает, что такие преобразования, как вертикальное или горизонтальное переворачивание, кадрирование и поворот, имеют смысл в данном контексте.
Глава 10. Моделирование в компьютерном зрении 307 Augmentation examples Рис. 10.6. Коллекция оугментировонных изображений 5a8203514.jpg has defect 3 8e7bace88.jpg has defect з Рис. 10.7. Образцы изображений с соревнования Severstal
308 Часть II. Оттачивание соревновательных навыков Для сравнения мы можем посмотреть на пример изображения из конкурса Severstal: Steel Defect Detection (https://www.kaggle.eom/c/severstal-steel-defect-detection). В нем участники должны были локализовать и классифицировать дефекты на стальном листе (рис. 10.7). Все изображения имели одинаковый размер и ориента- цию, а значит, поворот или обрезка дали бы нереалистичные изображения, увели- чивая шум и негативно влияя на обобщающие способности алгоритма. Слои предварительной обработки Альтернативный подход к аугментации данных в качестве этапа предварительной обработки в нативном Keras заключается в использовании API слоев preprocessing. Функциональность удивительно гибкая: эти конвейеры можно применять как в со- четании с моделями Keras, так и самостоятельно, подобно ImageDataGenerator. Ниже мы кратко покажем, как можно настроить слой предварительной обработки. Сначала импорт: from tensorflow.keras.layers.experimental import preprocessing from tensorflow.keras import layers Загружаем предварительно обученную модель стандартным для Keras способом: pretrained_base = tf. keras. models. load__model( '../input/cv-course-models/cv-course-models/vggl6-pretrained-base', ) pretrained_base.trainable = False Слои предварительной обработки могут использоваться так же, как и другие слои в конструкторе Sequential. Единственное требование— они должны быть указаны раньше других, в начале определения нашей модели: model = tf.keras.Sequential([ # Слои предварительной обработки preprocessing.RandomFlip('horizontal'), # переворот слева направо preprocessing.Randomcontrast(0.5), # изменение контрастности на 50% # Базовая модель pretrained_base, # Определение заголовка модели layers.Flatten(), layers.Dense(6, activation='relu'), layers.Dense(l, activation='sigmoid'), ])
Глава 10. Моделирование в компьютерном зрении 309 Пакет albumentations Пакет albumentations — это библиотека быстрой аугментации изображений, создан- ная как своеобразная обертка для других библиотек. Пакет стал результатом интенсивного программирования в рамках не- скольких конкурсов Kaggle (см. https://medium.com/@iglovikov/the- birth-of-albumentationsfe38cl411cb3), и утверждается, что среди его основных разработчиков и участников есть несколько известных кэгг- леров, включая Евгения Хведченя (https://www.kaggle.com/bloodaxe), Владимира Игловикова (https://www.kaggle.com/iglovikov), Алексея Паринова (https://www.kaggle.com/creafz) и кэгглера с ником ZFTurbo (https://www.kaggle.com/zfturbo). Полную документацию можно найти на сайте https://albumentations. readthedocs.io/en/latest/. Перечислим важные характеристики: • унифицированный API для различных типов данных; • поддержка всех распространенных задач компьютерного зрения; • интеграция как с TensorFlow, так и с PyTorch. Использование функциональности albumentations для преобразования изображения очень простое. Мы начинаем с инициализации необходимых преобразований: import albumentations as А horizontal-flip = A.HorizontalFlip(p=l) rotate = A.ShiftScaleRotate(p=l) gaus_noise = A.GaussNoise() bright_contrast = A.RandomBrightnessContrast(p=l) gamma = A.RandomGamma(p=l) blur = A.Blur() Затем применяем преобразования к нашему эталонному изображению: img_flip = horizontal_flip(image = curr_img) imggaus = gaus_noise(image = curr_img) img_rotate = rotate(image = curr_img) img_bc = bright_contrast(image = curr_img) img-gamma = gamma(image = curr_img) imgjolur = blur(image = curr_img)
310 Часть II. Оттачивание соревновательных навыке* Можно получить доступ к аугментированным изображениям с помощью ключа ’image’ и визуализировать результаты: img_list = [img flip['image'],img gaus['image'], img_rotate['image'], imgjDC['image'], img_gamma['image'], irngjolur ['image']] pit.figure(figsize=(20}20)) pit.axis('off') pit.imshow(gallery(np.array(img_list)3 ncols = 3)) pit.title('Augmentation examples') Вот результаты (рис. 10.8). Augmentation examples Puc. 10.8. Изображение, аугмент ирован ное с помощью библиотеки aLbumentations Обсудив аугментацию как важнейший этап предварительной обработки при реше- нии задач компьютерного зрения, мы теперь можем применить эти знания в сле- дующих разделах, начиная с очень распространенной задачи— классификации изображений. Крис Деотт https ://www.kaggle.com/cdeotte Прежде чем мы продолжим, давайте вспомним короткий разговор с Крисом. Его уже неоднократно упоминали в этой книге (в том числе в начале этой главы), и не без ос- нований. Он четырехкратный гроссмейстер Kaggle и стар- ший специалист по данным и исследователь в NVIDIA, присоединившийся к Kaggle в 2019 г.
Глава 10. Моделирование в компьютерном зрении 311 Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я люблю соревнования с интересными данными и конкурсы, требующие по- строения новых креативных моделей. Моя специализация — анализ обученных моделей для определения их сильных и слабых сторон. Мне также нравится улучшать модели и (или) разрабатывать постобработку с целью повышения уровня кросс-валидации и положения в таблице лидеров. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Каждое соревнование я начинаю с проведения EDA (разведочного анализа дан- ных), создания локальной валидации, построения нескольких простых моделей и отправки на Kaggle для получения баллов в таблице результатов. Это способст- вует развитию интуиции в отношении того, что необходимо сделать для по- строения точной и конкурентоспособной модели. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Конкурс Shopee — Price Match Guarantee на Kaggle был сложным. В нем требо- вались как модели изображений, так и модели обработки естественного языка. Ключевым моментом было извлечение встраиваний из двух типов моделей, а за- тем определение того, как использовать информацию об изображении и языке для поиска совпадений товаров. Помог ли тебе Kaggle в карьере? Если да, то как? Да. Kaggle помог мне стать старшим специалистом по данным в NVIDIA, улуч- шив мои навыки и повысив конкурентоспособность моего резюме. Многие работодатели просматривают работы на Kaggle, чтобы найти сотрудни- ков с определенными навыками, способных решить их конкретные задачи. Таким образом, я получил множество предложений о работе. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? На мой взгляд,' начинающие кэгглеры часто упускают из виду важность локаль- ной валидации. Видеть свое имя в таблице лидеров весьма приятно. И очень лег- ко сосредоточиться на улучшении результатов в таблице лидеров, а не на резуль- татах кросс-валидации. Какие ошибки ты допускал на соревнованиях? Много раз я совершал ошибку, доверяя своему результату в таблице лидеров, а не результату кросс-валидации, и выбирал неправильный вариант для отправки решения. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Безусловно. При оптимизации табличных моделей данных важными являются построение признаков и быстрое экспериментирование. Для ускорения цикла
312 Часть II. Оттачивание соревновательных навыке экспериментов и проверки рекомендую использовать NVIDIA RAPIDS cuDF и cuML на GPU. О чем важнее всего помнить, приступая к участию в соревновании? Самое главное— получать удовольствие и учиться. Не беспокойтесь о своем окончательном положении в таблице результатов. Если вы сосредоточитесь на обучении и развлечении, то со временем ваши итоговые результаты будут улуч- шаться. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Да, я участвовал и в других соревнованиях, кроме Kaggle. Некоторые компании, например Booking.com или Twitter.com, иногда проводят конкурсы. Такие меро- приятия проходят увлекательно и с использованием высококачественных, реаль- ных данных. Классификация В этом разделе мы продемонстрируем сквозной конвейер, который можно исполь- зовать в качестве шаблона для решения задач классификации изображений. Мы пройдем через все необходимые этапы, начиная с подготовки данных, настройки е оценки модели и заканчивая визуализацией результатов. Помимо информативности (и крутизны), этот последний шаг может быть очень полезен, если вам необходимс глубоко изучить свой код, чтобы лучше понять его производительность. Мы продолжим использовать данные конкурса Cassava Leaf Disease Classificatior (https://www.kaggle.eom/c/cassava-leaf-disease-classification). Как обычно, начинаем с загрузки необходимых библиотек: import numpy as пр import pandas as pd import matplotlib.pyplot as pit import datetime from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import tensorflow as tf from tensorflow.keras import models, layers from tensorflow.keras.preprocessing import image from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.callbacks import Modelcheckpoint, EarlyStopping, ReduceLROnPlateau
Глава 10. Моделирование в компьютерном зрении 313 from tensorflow.keras.applications import EffieientNetBO from tensorflow.keras.optimizers import Adam import os, cv2, json from PIL import Image Обычно полезно определить несколько вспомогательных функций— это делает код более легким как для чтения, так и для отладки. Если вы решаете общую задачу классификации изображений, удачной отправной точкой может послужить модель из семейства EfficientNet, представленная в 2019 г. в статье команды Google Research Brain Team (https://arxiv.org/abs/1905.11946). Основная идея — сбаланси- ровать глубину, ширину и разрешение сети, чтобы обеспечить более эффективное масштабирование по всем измерениям и, соответственно, более высокую произво- дительность. Для нашего решения мы будем использовать самого простого члена семейства— модель EfficientNet ВО. Она представляет собой мобильную сеть с 11 млн обучаемых параметров. ч । z Более подробные объяснения сетей EfficientNet можно найти здесь: https://ai.googleblog.com/2019/05/efficientnet-improving-accuracy- and.html. Мы строим нашу модель с ВО в качестве основы, за которой следует слой объеди- нения для улучшения инвариантности перевода и полносвязный слой с функцией активации, подходящей для нашей задачи многоклассовой классификации: class CFG: # конфигурация WORK_DIR = '.,/input/cassava-leaf-disease-classification' BATCH_SIZE = 8 EPOCHS = 5 TARGET-SIZE = 512 def create_model(): conv-base = EfficientNetB0(include_top = False, weights = None, input-shape = (CFG.TARGET-SIZE, CFG.TARGET_SIZE, 3)) model = conv-base.output model = layers.GlobalAveragePooling2D()(model)
314 Часть II. Оттачивание соревновательных навыков model = layers.Dense(5, activation = "softmax")(model) model = models.Model(conv_base.input, model) model.compile(optimizer = Adam(lr = 0.001), loss = "sparse_categorical_crossentropy", metrics = ["acc"]) return model Несколько кратких замечаний о параметрах, которые мы передаем в функцию EfficientNetB0: • параметр includejtop позволяет вам решить, включать ли последние полно- связные слои. Поскольку мы хотим использовать предварительно обучен- ную модель в качестве извлекателя признаков, стратегия по умолчанию за- ключается в том, чтобы пропустить их, а затем определить заголовок само- стоятельно; • параметр weights можно установить в значение None, если мы хотим обучить модель с нуля, либо в значения 'imagenet' или 'noisy-student', если предпочи- таем использовать веса, предварительно обученные на больших коллекциях изображений. Приведенная ниже вспомогательная функция позволяет нам визуализировать слои активации, чтобы мы могли изучить работу сети визуально. Это часто помогает развить интуицию в области, известной своей непрозрачностью: def activation_layer_vis(img, activation_layer = 0, layers = 10): layer_outputs = [layer.output for layer in model.layers[:layers]] activation_model = models.Model(inputs = model.input, outputs = layer_outputs) activations = activation_model.predict(img) rows = int(activations[activation_layer].shape[3] / 3) cols = int(activations[activation_layer].shape[3] / rows) fig, axes = pit.subplots(rows, cols, figsize = (15, 15 * cols)) axes = axes.flatten() for i, ax in zip(range(activations[activation_layer].shape[3]), axes): ax.matshow(activations[activation_layer][0, :, :, i], стар = 'viridis') ax.axis('off') pit.tight_layout() plt.show()
Глава 10. Моделирование в компьютерном зрении 315 Мы генерируем активации путем создания предсказаний для данной модели на ос- нове "ограниченной" модели, другими словами, используя всю архитектуру до предпоследнего слоя; это код до переменной activations. Остальная часть функции гарантирует, что мы показываем правильное расположение активаций, соответст- вующее форме фильтра в подходящем слое свертки. Далее мы обрабатываем метки и устанавливаем схему проверки; в данных нет осо- бой структуры (например, временного измерения или перекрытия между классами), поэтому мы можем использовать простое случайное разбиение: train_labels = pd.read_csv(os.path.join(CFG.WORK_DIR, "train.csv")) STEPS_PER_EPOCH = len(train_labels)*0.8 / CFG.BATCH_SIZE VALIDATION_STEPS = len(train_labels)*0.2 / CFG.BATCH_SIZE Для ознакомления с более сложными схемами валидации обратитесь к главе 6. Теперь мы можем настроить генераторы данных, которые необходимы для того, чтобы наш TF-алгоритм мог просмотреть данные изображения. Сначала мы создаем два объекта imageDataGenerator; именно тогда мы включаем аугментации изображения. В нашем примере мы будем использовать встроенные в Keras функции. После этого создаем генератор с помощью метода flow_from_dataframe(), который используется для генерации пакетов данных тензор- ного изображения с аугментацией данных в режиме реального времени: train_labels.label = train_labels.label.astype('str') train_datagen = ImageDataGenerator( validation_split=0.2, preprocessing_function=None, rotation_range=45, zoom_range=0.2, horizontal_flip=True, vertical_flip=True, fill_mode='nearest', shear_range=0.1, height_shift_range=0.1, width_shift_range=0.1) train_generator = train_datagen.flow_from_dataframe( train_labels, directory=os.path.join(CFG.WORK_DIR, "train_images"), subset=,,training",
316 Часть II. Оттачивание соревновательных навыков x_col="image_id", y_col="label", target_size=(CFG.TARGET_SIZE, CFG.TARGET_SIZE), batch_size=CFG.BATCH_SIZE, class_mode="sparse") validation_datagen = ImageDataGenerator(validation_split=0.2) validatiori-^generator = validation_datagen.flow_from_dataframe( train_labels, directory=os.path. join(CFG.WORK_DIR, "train-images"), subset="validation", x_col="image_id", y_col="label", target_size=(CFG.TARGET_SIZE, CFG.TARGET_SIZE)} batch_size=CFG.BATCH-SIZE, class_mode="sparse") Когда структуры данных определены, мы можем создать модель: model = create_model() model.summary() После того как модель создана, можно быстро изучить сводку. Это полезно в ос- новном для санитарного теста (sanity checks), потому что если у вас не фотографи- ческая память, имеется шанс, что вы не запомните пакеты состава слоев такой сложной модели, как EffNetBO. На практике можно использовать сводку для про- верки правильности размеров выходных фильтров или соответствия количества параметров (обучаемых и необучаемых) ожиданиям. Для компактности приведем только первые несколько строк вывода; просмотрев диаграмму архитектуры для ВО, вы получите представление о том, насколько длинным будет полный вывод. Model: "functional-1" Layer (type) Output Shape Param # Connected to input_l (InputLayer) [(None, 512, 512, 3) 0 rescaling (Rescaling) (None, 512, 512, 3) 0 input-1[0][0] normalization (Normalization) (None, 512, 512, 3) 7 rescaling[0][0] stem_conv_pad (ZeroPadding2D) (None, 513, 513, 3) 0 normalization[0][0]
Гпава 10. Моделирование в компьютерном зрении 317 stem_conv (Conv2D) (None, 256, 256, 32) 864 stem_conv_pad[0] [0] stem_bn (BatchNormalization) (None, 256, 256, 32) 128 stem_conv[0][0] stem_activation (Activation) (None, 256, 256, 32) 0 stem_bn[0][0] blockla_dwconv (DepthwiseConv2D (None, 256, 256, 32) 288 stem_activation[0][0] blockla_bn (BatchNormalization) (None, 256, 256, 32) 128 blockla_dwconv[0][0] Выполнив все вышеперечисленные действия, можем приступать к подгонке мо- дели. На этом же шаге мы можем определить обратные вызовы. Первым будет Modelcheckpoint: model_save = Modelcheckpoint('./EffNetB0_512_8_best_weights.h5'Л save_best_only=T rue, save_weights_only=T rue, monitor= val-loss', mode=,min', verbose=l) Контрольная точка использует несколько параметров, на которых имеет смысл ос- тановиться подробнее: • можно сохранить наилучший набор весов модели, установив параметр save__best_only=T rue; • мы уменьшаем размер модели, сохраняя только веса, вместо полного набора состояний оптимизатора; • принимаем решение о том, какая модель является оптимальной, путем нахо- ждения минимумального значения для потерь при валидации. А теперь воспользуемся одним из популярных методов предотвращения переобу- чения — ранней остановкой. Отследим производительность модели на отложен- ном датасете и остановим алгоритм, если метрика перестает улучшаться за задан- ное количество эпох, в данном случае 5: early_stop = EarlyStopping(monitor='val_loss', min_delta=0.001, patience=5, mode=,min', verbose=l, restore_best_weights=True) Функция обратного вызова ReduceLROnPlateau отслеживает потери на отложенном датасете, и если в течение количества эпох, указанных в параметре patience, не на-
318 Часть II. Оттачивание соревновательных навыков блюдается улучшение, скорость обучения снижается, в данном случае в 0,3 раза. Хотя это не универсальное решение, оно часто способно помочь в сходимости: reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.3, patience=2, min_delta=0.001, mode=,min', verbose=l) Теперь мы готовы к подгонке модели: History = model.fit( train_generator, steps_per_epoch=STEPS_PER_EPOCH, epochs=CFG.EPOCHS, validation_data=validation_generator, validation_steps=VALIDATION_STEPS, callbacks=[model_save, early_stop, reduce_lr] ) Кратко объясним два параметра, с которыми мы раньше не сталкивались: • обучающий генератор дает указанное в параметре steps_per_epoch количество пакетов за эпоху обучения; • когда эпоха завершается, генератор валидации производит пакеты согласно параметру validation_steps. Пример вывода после вызова метода model.fit() приведен ниже: Epoch 00001: val_loss improved from inf to 0.57514, saving model to ./ EffNetB0_512_8_bestjweights.h5 После подгонки модели мы можем изучить активации на образце изображения с применением вспомогательной функции, которую написали в самом начале. Хотя эта процедура не является необходимой для успешного выполнения модели, она может оказать помощь в выяснении того, какого рода признаки извлекает наша мо- дель перед применением верхнего слоя классификации: activation_layer_vis(img_tensor, 0) Результат, который мы могли бы увидеть, приведен на рис. 10.9. Прогнозы можно генерировать с помощью метода model.predict(): ss = pd.read_csv(os.path.join(CFG.WORK_DIR, "sample_submission.csv")) preds = []
Глава 10. Моделирование в компьютерном зрении 319 " for image_id in ss.image_id: image = Image.open(os.path.join(CFG.WORK_DIR, "test-images", image-id)) image = image.resize((CFG.TARGETSIZE, CFG.TARGET-SIZE)) image = np.expand_dims(image, axis=0) preds.append(np.argmax(model.predict(image))) ss['label'] = preds Puc. 10.9. Выборочные активации из подогнанной модели Мы строим прогнозы перебором по списку изображений. Для каждого из них мы изменяем форму изображения до необходимых размеров и выбираем канал с самым сильным сигналом (модель предсказывает вероятности классов, из которых мы вы- бираем самый большой при помощи функции argmax). Окончательные прогнозы — это номера классов в соответствии с метрикой, используемой в соревновании. Мы только что продемонстрировали минимальный сквозной конвейер для класси- фикации изображений. Конечно, возможны дополнительные улучшения, например, больше аугментаций, более крупная архитектура, настройка обратных вызовов — но базовый шаблон должен обеспечить вам хорошую отправную точку в будущем. Теперь мы переходим ко второй популярной проблеме компьютерного зрения: об- наружению объектов. Обнаружение объектов Обнаружение объектов — это задача компьютерного зрения/обработки изображе- ний, в которой нам необходимо идентифицировать экземпляры семантических объ- ектов определенного класса на изображении или видео. В задачах классификации, подобных рассмотренным в предыдущем разделе, нам просто нужно присвоить класс каждому изображению, в то время как в задачах обнаружения объектов тре- буется нарисовать ограничивающую рамку вокруг интересующего нас объекта, чтобы определить его местоположение на изображении.
320 Часть II. Оттачивание соревновательных навыков В этом разделе мы будем использовать данные конкурса Global Wheat Detection (https://www.kaggle.eom/c/global-wheat-detection). В нем участники должны быта обнаружить колосья пшеницы — верхушки растений, содержащие зёрна (рис. 10.10). Обнаружение их на изображениях растений используется для оценки размера в плотности колосьев пшеницы разных сортов. Мы продемонстрируем процесс обу- чения модели для решения этой задачи на примере Yolov5. Это хорошо зарекомен- довавшая себя модель в обнаружении объектов, и до конца 2021 г. она занимай лидирующее положение, пока ее (по предварительным результатам) не превзошла архитектура YoloX. Yolov5 показала очень высокие результаты на соревнованиях, и хотя в итоге эта модель была запрещена организаторами из-за проблем с лицензи- рованием, она очень хорошо подходит для целей данной демонстрации. Рис. 10.10. Образцы визуализации изображений обнаруженных головок пшеницы Прежде чем приступить к работе, стоит упомянуть о различных форматах аннота- ций ограничивающих рамок; существуют различные (но математически эквива- лентные) способы описания координат прямоугольника. Наиболее распространенными типами считаются coco, voc-pascal и yolo. Различия между ними ясны из приведенного рис. 10.11. voc-pascal [х1,у1, х2,у2| СОСО lx, yf w, h) высота (h) yolo [х, у, w, h] ширина (w) х2,у2 Рис. 10.11. Форматы аннотаций для ограничивающих рамок
Diaea 10. Моделирование в компьютерном зрении 321 Еще один аспект, требующий определения, — это структура сетки: Yolo обнаружи- вает объекты, размещая сетку поверх изображения и проверяя наличие интересую- щего объекта (в нашем случае — пшеничного колоса) в любой из ячеек. Ограничи- вающие рамки изменяют форму для смещения в соответствующие ячейки Начнем с загрузки аннотаций для наших обучающих данных: df = pd.read_csv(’../input/global-wheat-detection/train.csv') df.head(3) Рассмотрим некоторые из них (рис. 10.13) imagejd width height bbox source 0 b6ab77fd7 1024 1024 [834.0, 222.0, 56.0, 36.0] usask__1 1 b6ab77fd7 1024 1024 [226.0, 548.0, 130.0, 58.0] usask_1 2 b6ab77fd7 1024 1024 [377.0, 504.0, 74.0, 160.0] usask_1 Рис. 10.13. Обучающие данные с аннотациями Из столбца bbox извлекаем фактические координаты ограничивающих рамок: bboxs = np.stack(df['bbox'].apply(lambda х: np.fromstring(x[l:-l], sep=',’))) bboxs Взгляните на массив результатов: аггау([[834., 222., 56., 36.], [226., 548., 130., 58.],
322 Часть II. Оттачивание соревновательных навыков [377., 504., 74., 160.], • • • J [134., 228., 141., 71.], [430., 13., 184., 79.], [875., 740., 94., 61.]]) Следующий шаг — извлечение координат в формате Yolo в отдельные столбцы: for i, column in enumerated'x', 'y', 'w', 'h']): df[column] = bboxs[:,i] df,drop(columns=['bbox'], inplace=True) df['x_center'] = df['x'] + df['w']/2 df['y_center'] = df['y'] + df['h']/2 df['classes'] = 0 df = df[['image_id', 'x', 'y', 'w', 'h'/x_center'/y_center'/classes']] df.head(3) У реализации от Ultralytics есть определенные требования к структуре датасета, в частности, к месту хранения аннотаций и папкам для данных обучения/валидации. Процесс создания папок в приведенном ниже коде достаточно простой, но более любознательному читателю рекомендуется обратиться к официальной документа- ции (https://github.com/ultralytics/yolov5/wiki/Train-Custom-Data): # стратификация по источнику source = 'train' # Выбор одной папки для демонстрации fold = 0 val__index = set (df[df['fold'] == fold]['image_id']) # Перебор ограничивающих рамок для каждого изображения for name,mini in tqdm(df.groupby('image_id')): # Где сохранить файлы if name in val_index: path2save = 'valid/' else: path2save = 'train/'
Глава 10. Моделирование в компьютерном зрении 323 # Путь для хранения меток if not os.path.exists('convertor/fold{}/labels/'. format(fold)+path2save): os.makedirs('convertor/fold{}/labels/'.format(fold)+path2save) with open('convertor/fold{}/labels/'.format(fold)+path2save+name+". txt", 'w+') as f: # Нормализация координат в соответствии с требованиями формата YoLo row = mini [ ['classes' ,'x_center','y_center','w','h']]. astype(float).values row = row/1024 row = row.astype(str) for j in range(len(row)): text = ' '.join(row[j]) f.write(text) f.write("\n") if not os.path.exists('convertor/fold{}/images/{}'. format(fold,path2save)): os.makedirs('convertor/fold{}/images/{}'.format(fold,path2save)) # Для изображений не требуется предварительная обработка => # копируйте их как пакет sh.сору("../input/global-wheat-detection/{}/{}.jpg". format(sou rce,name), 'convertor/fold{}/images/{}/{}.jpg'. format(fold,path2save,name)) Следующим шагом мы установим сам пакет Yolo. Если вы запускаете эту програм- му в Kaggle Notebook или Colab, то убедитесь, что графический процессор вклю- чен. Установленная версия Yolo будет работать и без него, но вы, скорее всего, столкнетесь со всевозможными таймаутами и проблемами с памятью из-за разницы в производительности CPU и GPU. Igit clone https://github.com/ultralytics/yolov5 && cd yolovS && pip install -r requirements.txt Мы опускаем выходные данные, поскольку они достаточно объемны. Последним необходимым элементом подготовки станет создание конфигурационного файла YAML, в котором мы указываем расположение данных для обучения и валидации, а также количество классов. Мы заинтересованы только в обнаружении колосьев
324 Часть IL Оттачивание соревновательных навыков пшеницы и не различаем отдельные типы, поэтому у нас есть один класс (его имя дано лишь для удобства и в данном случае может быть произвольной строкой): yaml_text = ..train: /kaggle/working/convertor/foldO/images/train/ val: /kaggle/working/convertor/foldO/images/valid/ nc: 1 names: ['wheat'].. with open("wheat.yaml", 'w') as f: f.write(yaml_text) %cat wheat.yaml После этого мы можем приступить к обучению нашей модели: Ipython ./yolovS/train.py --img 512 --batch 2 --epochs 3 --workers 2 - -data wheat.yaml --cfg "./yolov5/models/yolov5s.yaml" --name yolov5x_ fold© --cache Если вы не привыкли запускать код из командной строки, приведенное выше "за- клинание” выглядит довольно загадочно, поэтому давайте обсудим его состав более подробно. • train.ру — это рабочий скрипт для обучения модели YoloV5, начиная с пред- варительно обученных весов. • --img 512 означает, что мы хотим, чтобы исходные изображения (которые, как вы видите, мы никак не обрабатывали) были уменьшены до размера 512 х 512 пикселов. Для получения конкурентоспособного результата следует исполь- зовать более высокое разрешение, но этот код был выполнен в среде Kaggle Notebook, которая имеет определенные ограничения доступных ресурсов. • --batch означает размер пакета в процессе обучения. • --epochs 3 означает, что мы хотим обучить модель в течение трех эпох. • --workers 2 указывает количество исполнителей в загрузчике данных. Увели- чение этого числа может повысить производительность, но в версии 6.0 (са- мой последней из доступных в образе Kaggle Docker на момент написания этой книги) есть ошибка, указывающая на то, что число исполнителей слиш- ком велико, даже на машине, где их может быть больше. • --data wheat.yaml— это файл, указывающий на наш YAML-файл специфика- ции данных, определенный выше. • --cfg "./yolov5/models/yolov5s.yaml" задает архитектуру модели и соответст- вующий набор весов, которые будут применяться для инициализации. Можно использовать поставляемые вместе с установленной моделью (подробности
Глава 10. Моделирование в компьютерном зрении 325 см. в официальной документации) или создать собственные веса и хранить их в том же самом формате .yaml. • --name задает место хранения результирующей модели. Ниже приведены результаты команды обучения. Сначала основание: Downloading the pretrained weights, setting up Weights&Biases https:// wandb.ai/site integration, GitHub sanity check. Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/ Ultralytics/Arial.ttf... wandb: (1) Create a W&B account wandb: (2) Use an existing W&B account wandb: (3) Don't visualize my results wandb: Enter your choice: (30 second timeout) wandb: W&B disabled due to login timeout. train: weights=yolov5/yolov5s.pt, cfg=./yolov5/models/yolov5s.yaml, data=wheat.yaml, hyp=yolov5/data/hyps/hyp.scratch-low.yaml, epochs=3, batch_size=2, imgsz=512, rect=False, resume=False, nosave=False, noval=False, noautoanchor=False, evolve=None, bucket=, cache=ram, image_weights=False, device=, multi_scale=False, single_cls=False, optimizer=SGD, sync_bn=False, workers=2, project=yolov5/runs/train, name=yolov5x_fold0, exist_ok=False, quad=False, cos_lr=False, label_ smoothing=0.0, patience=100, freeze=[0], save_period=-l, local_rank=-l, entity=None, upload_dataset=False, bbox_interval=-l, artifact_alias=latest github: up to date with https://github.com/ultralytics/yolov5 Q YOLOvS v6.1-76-gc94736a torch 1.9.1 CUDA:0 (Tesla P100-PCIE-16GB, 16281MiB) hyperparameters: lr0=0.01, lrf=0.01, momentum=0.937, weight_decay=0.0005, warmup_epochs=3.0, warmup_momentum=0.8, warmup_bias_lr=0.1, box=0.05, cls=0.5, cls_pw=1.0, obj=1.0, obj_pw=1.0, iou_t=0.2, anchor_t=4.0, fl_ gamma=0.0, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, degrees=0.0, translate=0.1, scale=0.5, shear=0.0, perspective=0.0, flipud=0.0, fliplr=0.5, mosaic=1.0, mixup=0.0, copy_paste=0.0 Weights & Biases: run 'pip install wandb' to automatically track and visualize YOLOvS £ runs (RECOMMENDED) TensorBoard: Start with 'tensorboard --logdir yolovS/runs/train', view at http://localhost:6006/
326 Часть II. Оттачивание соревновательных навыков Downloading https://github.com/ultralytics/yolov5/releases/download/v6.1/yolov5s.pt to yolov5/yolov5s.pt... 100% 14.IM/14.IM [00:00<00:00? 40.7MB/S] Затем идет модель. Мы видим краткое описание архитектуры, настройки оптимиза- тора и используемых аугментаций: Overriding model.yaml nc=80 with nc=l from n params module arguments 0 -11 [3, 32, 6, 2, 2] 3520 models.common.Conv 1 -11 [32, 64, 3, 2] 18560 models.common.Conv 2 -11 [64, 64, 1] 18816. models. common. C3 3 -11 [64, 128, 3, 2] 73984 models.common.Conv 4 -12 [128, 128, 2] 115712 models.common.C3 5 -11 [128, 256, 3, 2] 295424 models.common.Conv 6 -13 [256, 256, 3] 625152 models.common.C3 7 -11 [256, 512, 3, 2] 1180672 models.common.Conv 8 -11 [512, 512, 1] 1182720 models.common.C3 9 -11 [512, 512, 5] 656896 models.common.SPPF 10 -1 1 [512, 256, 1, 1] 131584 models.common.Conv 11 -1 1 [None, 2, ’nearest’] 0 torch.nn.modules.upsampling.Upsample 12 [-1, 6] 1 0 models.common.Concat [1] 13 -1 1 [512, 256, 1, False] 361984 models.common.C3
Глава 10. Моделирование в компьютерном зрении 327 14 -1 1 33024 models.common.Conv [256, 128, 1, 1] 15 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, ’nearest'] 16 [-1, 4] 1 0 models.common.Concat [1] 17 -1 1 90880 models.common.C3 [256, 128, 1, False] 18 -1 1 147712 models.common.Conv [128, 128, 3, 2] 19 [-1, 14] 1 0 models.common.Concat [1] 20 -1 1 296448 models.common.C3 [256, 256, 1, False] 21 -1 1 590336 models.common.Conv [256, 256, 3, 2] 22 [-1, 10] 1 0 models.common.Concat [1] 23 -1 1 1182720 models.common.C3 [512, 512, 1, False] 24 [17, 20, 23] 1 16182 models.yolo.Detect [1, [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]], [128, 256, 512]] YOLOv5s summary: 270 layers, 7022326 parameters, 7022326 gradients, 15.8 GFLOPs Transferred 342/349 items from yolov5/yolov5s.pt Scaled weight_decay = 0.0005 optimizer: SGD with parameter groups 57 weight (no decay), 60 weight, 60 bias albumentations: Blur(always_apply=False, p=0.01, blur_limit=(3, 7)), MedianBlur(always_apply=False, p=0.01, blur_limit=(3, 7)), ToGray(always_ apply=False, p=0.01), CLAHE(always_apply=False, p=0.01, clip_limit=?(l, 4.0), tile_grid_size=(8, 8)) train: Scanning '/kaggle/working/convertor/fold0/labels/train’ images and labels train: New cache created: /kaggle/working/convertor/fold0/labels/train. cache
328 Часть II. Оттачивание соревновательных навыков train: Caching images (0.0GB ram): 100^IHMHBI 51/51 [00:00<00:00, 76.00it/ val: Scanning 7kaggle/working/convertor/fold0/labels/valid' images and labels.. val: New cache created: /kaggle/working/convertor/fold0/labels/valid.cache val: Caching images (2.6GB ram): 100%|НЦН|| 3322/3322 [00:47<00:00, 70.51i Plotting labels to yolov5/runs/train/yolov5x_fold0/labels.jpg... AutoAnthor: 6.00 anchors/target, 0.997 Best Possible Recall (BPR). Current anchors are a good fit to dataset Q Image sizes 512 train, 512 val Using 2 dataloader workers Затем следует собственно лог обучения: Starting training for 3 epochs... Epoch 0/2 gpujnem 0.371G box 0.1196 obj 0.05478 cis 0 labels 14 img_size 512 100%|И Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s i exceeded Class Images Labels P R mAP@.5 mAP@ all 3322 147409 0.00774 0.0523 0.00437 0.000952 Epoch gpujnem box obj cis labels img_size 1/2 0.474G 0.1176 0.05625 0 5 512 100% | Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded mAP@.5 Class mAP@WARNING: NMS Images time limit Labels 0.120s exceeded P R mAP@.5 Class mAP@ Images Labels P R all 3322 147409 0.00914 0.0618 0.00493 0.00108
Глава 10. Моделирование в компьютерном зрении 329 Epoch gpujnem 2/2 0.474G box 0.1146 0, obj cis .06308 0 labels 12 img_size 512: 100% Class Images Labels P R mAP@.5 mAP@ all 3322 147409 0.00997 0.0674 0.00558 0.00123 3 epochs completed in 0, .073 hours. Optimizer stripped from yolov5/runs/train/yolov5x_fold0/weights/last.pt, 14.4MB Optimizer stripped from yolov5/runs/train/yolov5x_fold0/weights/best.pt, 14.4MB Validating yolov5/runs/train/yolov5x_fold0/weights/best.pt... Fusing layers... YOLOvSs summary: 213 layers, 7012822 parameters, 0 gradients, 15.8 GFLOPs Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING; NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@WARNING: NMS time limit 0.120s exceeded Class Images Labels P R mAP@.5 mAP@ all 3322 147409 0.00997 0.0673 0.00556 0.00122 Results saved to yolov5/runs/train/yolov5x_fold0
330 Часть II. Оттачивание соревновательных навыков 'Результаты, полученные на этапах обучения и валидации, можно изучить — они хранятся в папке yolov5 по пути ./yolov5/runs/train/yolov5x_fold0 (рис. 10.14). Рис, 10.14. Валидоционные данные с аннотациями После обучения модели можно использовать веса модели, показавшей наилучшие результаты (в YoloV5 есть отличная функция автоматического сохранения лучшей и последней эпохальной модели; они сохраняются под названиями best.pt и last.pt), для создания прогнозов на тестовых данных: •python ./yolovS/detect.py --weights ./yolov5/runs/train/yolov5x_fold0/ weights/best.pt --img 512 --conf 0.1 --source /kaggle/input/global-wheatdetection/ test --save-txt --save-conf --exist-ok
Глава 10. Моделирование в компьютерном зрении 331 Обсудим параметры, характерные для этапа вывода: • --weights — указывает на расположение лучших весов из нашей модели, обу- ченной выше; • --conf 0.1 — указывает, какие из созданных моделью ограничивающих рамок необходимо сохраненить. Как обычно, это компромисс между точностью и полнотой (слишком низкий порог дает большое количество ложноположи- тельных срабатываний, а слишком высокий порог означает, что мы можем вообще не найти ни одного пшеничного колоса); • - - source — местоположение тестовых данных. Метки, созданные для наших тестовых изображений, можно проверить локально: ’Is ./yolov5/runs/detect/exp/labels/ Вот что мы можем увидеть: 2fd875eaa.txt 53f253011.txt aac893a91.txt f5alf0358.txt 348a992bb.txt 796707dd7.txt CC3532ff6.txt Давайте рассмотрим отдельный прогноз: ’cat 2fd875eaa.txt Он имеет следующий формат: 0 0.527832 0.580566 0.202148 0.838867 0.101574 0 0.894531 0.587891 0.210938 0.316406 0.113519 Это означает, что на изображении 2fd875eaa наша обученная модель обнаружила две ограничивающие рамки (их координаты — записи 2-5 в строке) с оценками досто- верности выше 0,1, указанными в конце строки. Как нам объединить прогнозы и представить их в требуемом формате? Начнем с определения вспомогательной функции, которая поможет преобразовать координа- ты из формата yolo в формат coco (как требуется в этом соревновании): это вопрос простой перестановки порядка и нормализации к исходному диапазону значений путем умножения дробей на размер изображения: def convert(s): х = int(1024 * (s[l] - s[3]/2)) у = int(1024 * (s[2] - s[4]/2)) w = int(1024 * s[3]) h = int(1024 * s[4]) return(str(s[5]) + ' ’ + str(x) + ’ ' + str(y) + ' ' + str(w) + ' ' + str(h))
332 Часть II. Оттачивание соревновательных навыков Затем приступаем к созданию файла представления: 1. Перебираем перечисленные выше файлы. 2. Все строки каждого файла приводим к требуемому формату (одна строка пред- ставляет одну обнаруженную ограничивающую рамку). 3. Затем объединяем их в одну строку, соответствующую этому файлу. Код выглядит следующим образом: with open('submission.csv', 'w') as myfile: # Подготовка к подаче wfolder = './yolov5/runs/detect/exp/labels/' for f in os.listdir(wfolder): fname = wfolder + f xdat = pd.read_csv(fname, sep = ' header = None) outline = f[:-4] + ' ' + ' '.join(list(xdat.apply(lambda s: convert(s), axis = 1))) myfile.write(outline + '\n') myfile.close() Посмотрим на результат: ’cat submission.csv 53f253011 0.100472 61 669 961 57 0.106223 0 125 234 183 0.1082 96 696 928 126 0.108863 515 393 86 161 0.11459 31 0 167 209 0.120246 517 466 89 147 аас893а91 0.108037 376 435 325 188 796707dd7 0.235373 684 128 234 113 cc3532ff6 0.100443 406 752 144 108 0.102479 405 87 4 89 0.107173 576 537 138 94 0.113459 256 498 179 211 0.114847 836 618 186 65 0.121121 154 544 248 115 0.125105 40 567 483 199 2fd875eaa 0.101398 439 163 204 860 0.112546 807 440 216 323 348a992bb 0.100572 0 10 440 298 0.101236 344 445 401 211 f5alf0358 0.102549 398 424 295 96 Созданный файл submission.csv завершает наш конвейер. В этом разделе мы продемонстрировали, как использовать YoloV5 для решения за- дачи обнаружения объектов: как работать с аннотациями в различных форматах, как настроить модель под конкретную задачу, обучить ее и оценить результаты.
Глава 10. Моделирование в компьютерном зрении 333 На базе полученных знаний вы сможете начать работать с задачами обнаружения объектов. Теперь мы переходим к третьему популярному классу задач компьютерного зре- ния — семантической сегментации. Семантическая сегментация Проще всего представить сегментацию так: она классифицирует каждый пиксел на изображении, относя его к соответствующему классу; после объединения эти пик- селы образуют интересующие области, например области с заболеваниями органа на медицинских изображениях. А обнаружение объектов (рассмотренное в преды- дущем разделе) классифицирует участки изображения по различным классам объ- ектов и создает вокруг них ограничивающие рамки. Мы продемонстрируем подход семантической сегментации к моделированию, используя данные конкурса Sartorius — Cell Instance Segmentation (https:// www.kaggle.com/c/sartorius-cell-instance-segmentation). В данном случае перед участниками была поставлена задача обучить модели для сегментации нейронных клеток с помощью набора выведенных из микроскопа изображений. Наше решение будет построено на основе Detectron2, библиотеки, созданной Facebook AI Research, которая поддерживает множество алгоритмов обнаружения и сегментации. Detectron2 — преемник оригинальной библиотеки Detection (https://github.com/facebookresearch/Detectron/) и проекта Mask R- CNN (https://github. com/facebookresearch/maskrcnn-benchmark/). Начнем с установки дополнительных пакетов: !pip install pycocotools !pip install 'git+https://github.com/facebookresearch/detectron2.git' Установим библиотеку pycocotools (https://github.com/cocodataset/cocoapi/tree/ master/PythonAPI/ pycocotools), которая нам понадобится для форматирования аннотаций, и фреймворк Detection? (https://github. com/facebookresearch/detectron2), который послужит рабочей лошадкой в решении этой задачи. Прежде чем можно будет обучить модель, необходимо немного подготовиться: ан- нотации должны быть преобразованы из формата кодирования длин серий (run- length encoding, RLE), предоставленного организаторами, в формат СОСО, по- скольку для Detection? требуется именно такой формат информации в качестве входных данных. Основная идея RLE заключается в экономии пространства: созда- ние сегментации означает маркировку группы пикселов определенным образом.
334 Часть II. Оттачивание соревновательных навыков Поскольку изображение можно представить в виде массива, эту область можно обозначить набором прямых линий (по строкам или столбцам). Можно закодировать каждую из этих строк, перечислив индексы или указав на- чальную позицию и длину последующего непрерывного блока. Визуальный пример приведен на рис. 10.15. Рис. 10.15. Визуальное представление RLE Формат Common Objects in Context (COCO) от Microsoft — это особая структура JSON, определяющая способ сохранения меток и метаданных для датасета изобра- жений. Ниже мы продемонстрируем, как преобразовать данные из формата RLE в формат СОСО и объединить результат с разбиением на валидацию по к блокам, чтобы получить необходимую пару JSON-файлов обучения/валидации для каждого блока. Приступим: # Импорт СОСО из pycocotooLs.coco import skimage.io as io import matplotlib.pyplot as pit from pathlib import Path from PIL import Image import pandas as pd import numpy as np
Глава 10. Моделирование в компьютерном зрении 335 from tqdm.notebook import tqdm import json,itertools from sklearn.model_selection import GroupKFold # Конфигурация class CFG: data_path = '../input/sartorius-cell-instance-segmentation/' nfolds = 5 Для перехода от RLE к COCO необходимы три функции. Первая требуется для преобразования RLE в двоичную маску: # Из https://MM.kaggLe.com/stainsby/fast-tested-rLe def rle_decode(mask_rle, shape): mask_rle: run-length as string formatted (start length) shape: (height, width) of array to return Returns numpy array, 1 - mask, 0 - background s = mask_rle.split() starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[l:][::2])] starts -= 1 ends = starts + lengths img = np.zeros(shape[0]*shape[l], dtype=np.uint8) for lo, hi in zip(starts, ends): img[lo:hi] = 1 return img.reshape(shape) # Необходимо выровнять no направлению RLE Вторая преобразует двоичную маску в RLE: # Из https ://newbedev. com/encode-numpy-array-using-uncompressed-rLe-for- # coco-dataset def binary_mask_to_rle(binary_mask): rle = {'counts': [], 'size': list(binaryjnask.shape)} counts = rle.get('counts') for i, (value, elements) in enumerate( itertools.groupby(binaryjnask.ravel(order='F'))): if i == 0 and value == 1:
336 Часть IL Оттачивание соревновательных навыков counts.append(0) counts.append(len(list(elements))) return rle Наконец, объединяем эти два показателя, чтобы получить результат в формате СОСО: def coco_structure(train_df): cat_ids = {name: id+1 for id, name in enumerate( train_df.cell_type.unique())} cats = [{'name': name, 'id': id} for name, id in cat-ids.items()] images = [{'id': id, 'width': row.width, 'height': row.height, 'file_name':f'train/{id}.png'} for id, row in train_df .groupby('id').agg('first').iterrowsQ] annotations = [] for idx, row in tqdm(train_df.iterrows()): mk = rle_decode(row.annotation, (row.height, row.width)) ys, xs = np.where(mk) xl, x2 = min(xs), max(xs) yl, y2 = min(ys), max(ys) enc =binary_mask-to_rle(mk) seg = { 'segmentation':enc, 'bbox': [int(xl), int(yl), int(x2-xl+l), int(y2-yl+l)], 'area': int(np.sum(mk)), 'image-id':row.id, 'category_id':cat_ids[row.cell_type], 'iscrowd':0, 'id':idx } annotations.append(seg) return {'categories':cats, 'images':images,'annotations':annotations} Мы разделили наши данные на непересекающиеся блоки: train_df = pd.read_csv(CFG.data_path + 'train.csv') gkf = GroupKFold(n_splits = CFG.nfolds) train_df["fold"] = -1 у = train_df.width.values
Глава 10. Моделирование в компьютерном зрении 337 for f, (t_, v_) in enumerate(gkf.split(X=train_df, y=y, groups=train_df.id.values)): train_df.loc[v_, "fold”] = f fold_id = train_df.fold.copy() Теперь можно выполнить перебор блоков при помощи цикла: all_ids = train_df.id.unique() # Для части в диапазоне (CFG.nfoLds): for fold in range(4,5): train_sample = train_df.loc[fold_id != fold] root = coco_structure(train_sample) with open('annotations_train_f' + str(fold) + '.json', 'w'} encodingsutf-8') as f: json.dump(root, f, ensure_ascii=True, indent=4) valid_sample = train_df.loc[fold-id == fold] print('fold ' + str(fold) + produced') for fold in range(4,5): train_sample = train_df.loc[fold-id == fold] root = coco_structure(train_sample) with open('annotations_valid_f' + str(fold) + '.json', 'w', encoding='utf-8') as f: json.dump(root, f, ensure_ascii=True, indent=4) valid_sample = train_df.loc[fold-id == fold] print('fold ' + str(fold) + ': produced') Причина, по которой цикл должен выполняться по частям, заключается в ограни- чении размера среды Kaggle: максимальный размер вывода Notebook ограничен значением 20 Гбайт, а 5 блоков с двумя файлами (обучение/валидация) для каждого из них дают в общей сложности 10 файлов JSON, что превышает этот лимит. Практические соображения такого плана стоит иметь в виду при выполнении кода в Kaggle Notebook, хотя для такой ’’подготовительной’’ работы вы, конечно, можете получить результаты в другой системе, а затем загрузить их как Kaggle Datasets.
338 Часть II. Оттачивание соревновательных навыков С полученными разделениями можно перейти к обучению модели Detectron2 для нашего датасета. Как обычно, мы начинаем с загрузки необходимых пакетов: from datetime import datetime import os import pandas as pd import numpy as np import pycocotools.mask as mask_util import detectron2 from pathlib import Path import random, cv2, os import matplotlib.pyplot as pit # Импорт некоторых общих утилит Detectron2 from detectron2 import model_zoo from detectron2.engine import DefaultPredictor, DefaultTrainer from detectron2.config import get_cfg from detectron2.utils.visualizer import Visualizer, ColorMode from detectron2.data import Metadatacatalog, DatasetCatalog from detectron2.data.datasets import register_coco_instances from detectron2.utils.logger import setup_logger from detectron2.evaluation.evaluator import DatasetEvaluator from detectron2.engine import Bestcheckpointer from detectron2.checkpoint import DetectionCheckpointer setup_logger() import torch Хотя количество инструкций импорта из Detectron2 поначалу может показаться пу- гающим, их назначение станет понятным по мере продвижения в постановке зада- чи; мы начинаем с указания путей к папке входных данных, папке аннотаций е YAML-файлу, определяющему предпочтительную архитектуру модели: class CFG: wfold = 4 data_folder = '../input/sartorius-cell-instance-segmentation/' anno_folder = '../input/sartoriusannotations/' model_arch = 'mask_rcnn_R_50_FPN_3x.yaml' nof_iters = 10000 seed = 45
Глава 10. Моделирование в компьютерном зрении 339 Здесь стоит упомянуть параметр итераций (nofjters в коде выше). Обычно обуче- ние модели параметризуется в терминах количества эпох, другими словами, пол- ных проходов через обучающие данные. Detection? спроектирована по-другому: один проход относится к одному мини-пакету, а в разных частях модели использу- ются разные размеры мини-пакетов. Для того чтобы обеспечить воспроизводимость результатов, мы фиксируем слу- чайные значения seed, используемые различными компонентами модели: def seed_everything(seed): random.seed(seed) os.environ['PYTHONHASHSEED'] = str(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed(seed) torch.backends.cudnn.deterministic = True seed_everything(CFG.seed) В качестве метрики на соревновании использовалась средняя точность при различ- ных порогах отношения площадей ограничивающих рамок (intersection over union, IoU). В качестве напоминания из главы 5, IoU предлагаемого набора пиксе- лов объекта и набора пикселов истинного объекта рассчитывается как: 1ои(л,в)=лпв/лив. Метрика перебирает диапазон пороговых значений IoU, в каждой точке рассчиты- вая среднее значение точности. Пороговые значения варьируются в диапазоне зна- чений от 0,5 до 0,95 с шагом 0,05. На каждом пороговом значении рассчитывается значение точности, основанное на количестве истинноположительных (true positives, ТР), ложноотрицательных (false negatives, FN) и ложноположительных (false positives, FP) результатов сравнения спрогнозированного объекта со всеми истинными объектами. В итоге оценка, по- лученная соревновательной метрикой, представляет собой среднее значение, взятое по отдельным средним точностям каждого изображения в тестовом датасете. Ниже мы определим функции, необходимые для вычисления метрики и использо- вания ее непосредственно в модели в качестве объективной функции: # Взято из https://мм. kaggLe.com/theovieL/competition-metric-map-iou def precision_at(threshold, iou): matches = iou > threshold true_positives = np.sum(matches, axis=l) == 1 # правильные объекты false__positives = np.sun^matches, axis=0) == 0 # пропущенные объекты false__negatives = np.sun^matches, axis=l) == 0 # дополнительные объекты
340 Часть II. Оттачивание соревновательных навыков return np.sum(true_positives), np.sum(false_positives), np.sum(false_negatives) def score(pred, targ): predjnasks = pred['instances'].pred_masks.cpu().numpy() enc_preds = [mask_util.encode(np.asarray(p, order='F')) for p in predjnasks] enc_targs = list(map(lambda x:x['segmentation'], targ)) ious = mask_util.iou(enc_preds, enc_targs, [0]*len(enc_targs)) prec = [] for t in np.arange(0.5, 1.0, 0.05): tp, fp, fn = precision_at(t, ious) p = tp / (tp + fp + fn) prec.append(p) return np.mean(prec) Когда метрика определена, ее можно использовать в модели: class MAPIOUEvaluator(DatasetEvaluator): def___init__(self, dataset jiame): dataset jdicts = DatasetCatalog.get(dataset jiame) self.annotations_cache = {item['image_id']:item['annotations'] for item in dataset_dicts} def reset(self): self.scores = [] def process(self, inputs, outputs): for inp, out in zip(inputs, outputs): if len(out['instances']) == 0: self.scores.append(0) else: targ = self.annotations_cache[inp['image_id']] self.scores.append(score(out, targ)) def evaluate(self): return {"MaP loll": np. mean (self .scores)}
Глава 10. Моделирование в компьютерном зрении 341 Это дает нам основу для создания объекта Trainer, который служит рабочей лошад- кой нашего решения, построенного на Detectron2: class Trainer(DefaultTrainer): @classmethod def build_evaluator(cls, cfg, dataset_name, output_folder=None): return MAPIOUEvaluator(dataset_name) def build_hooks(self): # Копия cfg cfg = self.cfg.clone() # Создание исходной модели хуков hooks = super().build_hooks() # Добавление лучшего хука для контрольного указателя hooks.insert(-1, Bestcheckpointer(cfg.TEST.EVAL_PERIOD, DetectionCheckpointer(self.model, cfg.OUTPUT_DIR), "MaP IoU", "max", )) return hooks Теперь переходим к загрузке данных для обучения/валидации в стиле Detectron2: dataDir=Path(CFG.data_folder) register_coco_instances('sartorius_train',{}, CFG.anno_folder + 'annotations_train_f' + str(CFG.wfold) + ’.json', dataDir) register_coco_instances('sartorius_val',{}, CFG.anno_folder + 'annotations_valid_f' + str(CFG.wfold) + '.json', dataDir) metadata = MetadataCatalog.get('sartoriusjtrain') train_ds = DatasetCatalog.get('sartorius_train')
342 Часть II. Оттачивание соревновательных навыков Прежде чем мы создадим модель Detectron2, необходимо ее настроить. Большинст- во значений можно оставить по умолчанию (по крайней мере, при первом проходе); если вы решите еще немного повозиться, начните со значений batch_size_per_image (для повышения эффективности обобщения) и SCORE_THRESH_TEST (для ограничения ложноотрицательных результатов): cfg = get_cfg() cfg.INPUT.MASK_FORMAT=’bitmask’ cfg.merge_from_file(model_zoo.get_config_file('COCO-Instancesegmentation/' + CFG.model_arch)) cfg.DATASETS.TRAIN = ("sartorius_train",) cfg.DATASETS.TEST = ("sartoriuS-Val”,) cfg.DATALOADER.NUM_WORKERS = 2 cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url('COCO-Instancesegmentation/' + CFG.model_arch) cfg. SOLVER. IMS_PER_BATCH = 2 cfg. SOLVER. BASE_LR = 0.001 cfg.SOLVER.MAX_ITER = CFG.nof_iters cfg.SOLVER.STEPS = [] cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 512 cfg.MODEL.ROI_HEADS.NUM_CLASSES = 3 cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = .4 cfg.TEST.EVAL_PERIOD = len(DatasetCatalog.get('sartoriusjtrain')) Ц cfg.SOLVER.IMS_PER_BATCH Обучение модели очень простое: os.makedirs(cfg.OUTPUT-DIR, exist_ok=True) trainer = Trainer(cfg) trainer.resume_or_load(resume=False) trainer.train() Можно заметить, что вывод во время обучения изобилует информацией о ходе процедуры (рис. 10.16). После обучения модели можно сохранить веса и использовать их для формирова- ния выводов (потенциально в отдельном блокноте — см. обсуждение ранее в этой главе) и подготовки материалов. Начинаем с добавления новых параметров, позво- ляющих регулировать предсказание, устанавливая пороговое значение уверенности и минимальные размеры маски: THRESHOLDS = [.18, .35, .58] MIN_PIXELS = [75, 150, 75]
Глава 10. Моделирование в компьютерном зрении 343 Loading ../input/sartorius-annotations/annotations t rain_f4.json takes 1.16 seconds. Loaded 485 images in COCO format from ./input/sarto rius annotations/annotations_train_f4.json Removed 0 images with no usable annotations 485 images lef t Distribution of instances among all 3 categories; [DatasetMapper] Augmentations used in training [Re sizeShortestEdge(short_edge_length~(640, 672. 704, 736 768, 800), max_size^1333, sample_sty le^’choice ), RandomFlip()] Using training sampler Trainingsampler Serializing 4B5 elements to byte tensors and concatenating them all ... Serialized dataset takes 6.79 MiB model final.fl 0217 pkl: 1/ЯМВ [00:04. 35.8MB/5J Puc. 10.16. Вывод результата обучения от Detectron2 Нам нужна вспомогательная функция для кодирования одной маски в формат RLE: def rle_encode(img): I I I img: numpy array, 1 - mask, 0 - background Returns run length as string formatted I I I pixels = img.flatten() pixels = np.concatenate([[0], pixels, [0]]) runs = np.where(pixels[1:] != pixels[:-l])[0] + 1 runs[l::2] -= runs[::2] return ' '.join(str(x) for x in runs) Ниже приведена основная функция создания всех масок для каждого изображения, отфильтровывающая сомнительные (с оценками уверенности ниже значения пара- метра thresholds) с маленькими областями (содержащими меньше пикселов, чем значение параметра min_pixels): def get_masks(fn, predictor): im = cv2.imread(str(fn)) pred = predictor(im)
344 Часть II. Оттачивание соревновательных навыков pred_class = torch.mode(pred['instances'].pred_classes)[0] take = pred['instances'].scores >= THRESHOLDS[pred_class] predjnasks = pred['instances'].pred_masks[take] predjnasks = predjnasks.cpu().numpy() res = [] used = np.zeros(im.shape[:2], dtype=int) for mask in predjnasks: mask = mask * (1-used) # Пропуск предсказаний с маленькой областью if mask.sumO >= MIN_PIXELS[pred_class]: used += mask res.append(rle_encode(mask)) return res Тепрь подготовим списки, в которых будут храниться идентификаторы изображе- ний и маски: dataDir=Path(CFG.data_folder) ids, masks=[],[] testjiames = (dataDir/'test').Is() Соревнования с большими наборами изображений, такие как описываются в этом разделе, часто требуют обучения моделей в течение более 9 часов, что является ог- раничением по времени, установленным в конкурсах категории Code (см https://www.kaggle.com/docs/competitions). Это означает, что обучение модели е выполнение выводов в одном блокноте невозможны. Типичным обходным решени- ем становится первоначальный запуск обучающего блокнота/скрипта как отдельно- го блокнота в Kaggle, Google Colab, GCP или локально. Выходные данные первогс блокнота (обученные веса) используются в качестве входа для второго блокнота, другими словами, для определения модели, используемой при прогнозировании. Мы действуем таким образом, загружая веса нашей обученной модели: cfg = get_cfg() cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/"+ CFG.arch+".yaml")) cfg.INPUT.MASK_FORMAT = 'bitmask' cfg.MODEL.ROI_HEADS.NUM_CLASSES = 3 cfg.MODEL.WEIGHTS = CFG.model_folder + 'model_best_f' + str(CFG.wfold) + '.pth' cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5 Cfg.TEST.DETECTIONS-PER-IMAGE = 1000 predictor = DefaultPredictor(cfg)
Глава 10. Моделирование в компьютерном зрении 345 Можем визуализировать некоторые из предсказаний: encodedjnasks = getjnasks (testjiames[0], predictor) axs = pit.subplots(1,2, figsize = (40, 15)) axs[l].imshow(cv2.imread(str(test_names[0]))) for enc in encodedjnasks: dec = rle_decode(enc) axs[0].imshow(np.ma.masked_where(dec == 0, dec)) На рис. 10.17 представлен пример. Рис. 10.17. Визуализация образца предсказания от Detectron2 рядом с исходным изображением При использовании вспомогательных функций, определенных выше, создание ма- сок в формате RLE для отправки не составляет труда: for fn in testjiames: encodedjnasks = get_masks(fn, predictor) for enc in encodedjnasks: ids.append(fn.stem) masks.append(enc) pd.DataFrame({'id':ids, 'predicted':masks}).to_csv('submission.csv', index=False) pd.read_csv('submission.csv').head() Первые несколько строк окончательного варианта представлены на рис. 10.18. Мы подошли к концу раздела. Приведенный выше конвейер демонстрирует, как создать модель семантической сегментации и обучить ее. Мы использовали не- большое количество итераций, но для достижения конкурентоспособных результа- тов необходимо более длительное обучение.
346 Часть II. Оттачивание соревновательных навыков id predicted О 7ae19de7bc2a 139541 4 140244 7 140948 8 141652 8 142356 9 1... 1 7ae19de7bc2a 96418 4 97121 6 97825 7 98529 8 99233 8 99937... 2 7ae19de7bc2a 26627 14 27329 17 28031 19 28733 21 29435 23 3... 3 7ae19de7bc2a 148230 2 148931 6 149633 9 150336 11 151039 13... 4 7ae19de7bc2a 224918 2 225620 7 226324 9 227027 12 227731 13.. Puc. 10.18. Форматированное представление от обученной модели Detectron2 Лора Финк https ://www.kaggle.com/allunia В завершение этой главы давайте посмотрим, что говорит о своем опыте работы на платформе Kaggle Лора Финк. По- мимо того, что она является гроссмейстером и создала множество высококлассных блокнотов, она также возглав- ляет отдел Data science в компании MicroMata. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задам? Больше всего я люблю те соревнования, в которых есть возможность принести что-то хорошее человечеству. Мне особенно нравятся все задачи, связанные со здравоохранением. Тем не менее каждый конкурс кажется мне приключением со своими головоломками, которые нужно решить. Мне очень нравится осваивать новые области, приобретать навыки и исследовать новые виды датасетов или за- дач. Именно поэтому я сосредоточена не на конкретных техниках, а на том, что- бы научиться чему-то новому. Думаю, я известна благодаря своим сильным сто- ронам в области разведочного анализа данных (exploratory data analysis, EDA). Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Когда я участвую в соревновании, то начинаю с чтения постановки задачи и опи- сания данных. Просмотрев форум и публичные блокноты для сбора идей, я обычно начинаю разработку собственных решений. На начальном этапе я трачу некоторое время на задачи EDA, чтобы найти скрытые группы и выработать не- которое интуивное понимание. Это очень помогает в создании правильной стра- тегии валидации, которая, как я считаю, является основой всех остальных шагов. Затем я начинаю итерации в различных частях конвейера машинного обучения, таких как построение признаков или предварительная обработка, улучшение ар- хитектуры модели, задаю вопросы о сборе данных, ищу утечки, делаю больше анализа EDA или создаю ансамбли. Пытаюсь улучшить свое решение ’’жадным подходом”. Соревнования Kaggle очень динамичны, и для того, чтобы остаться в них до конца, нужно пробовать разные идеи и различные решения.
Глава 10. Моделирование в компьютерном зрении 347 Это, безусловно, отличается от моей повседневной работы, где основное внима- ние уделяется получению информации из данных и поиску простых, но эффек- тивных решений для улучшения бизнес-процессов. Здесь задача часто оказыва- ется сложнее, чем используемые модели. Задача, которую необходимо решить, должна быть определена очень четко. Это означает, что необходимо обсудить с экспертами из разных сфер, какие цели нужно достичь, какие процессы задейст- вовать и по какому принципу нужно собрать или объединить данные. По сравне- нию с соревнованиями Kaggle моя повседневная работа требует гораздо больше общения, чем навыков машинного обучения. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шла к решению Соревнование G2Net Gravitational Wave Detection было одним из моих любимых. Цель заключалась в обнаружении имитированных сигналов гравитационных волн, которые были скрыты в шуме, исходящем от компонентов детектора и зем- ных сил. Важным моментом в ходе соревнования было то, что требовалось кри- тически взглянуть на стандартные способы анализа данных и попробовать собст- венные идеи. В работах, которые я читала, данные подготавливались в основном с помощью преобразования Фурье или Constant-Q после процесса ’’отбеливания” (whitening) данных и применения полосового фильтра. Очень быстро выяснилось, что ’’отбеливание” не помогает, поскольку оно исполь- зует сплайн-интерполяцию спектральной плотности мощности, которая сама по себе очень шумная. Подгонка полиномов к небольшим подмножествам зашумлен- ных данных добавляет еще один источник ошибок из-за чрезмерной подгонки. Отбросив метод ’’отбеливания”, я попробовала различные гиперпараметры пре- образования Constant-Q, которое было ведущим методом на форуме и в публич- ных блокнотах в течение длительного времени. Поскольку существуют два ис- точника гравитационных волн, которые могут быть охвачены различными диапазонами значений Q, я опробовала комплекс моделей, отличающихся по этим гиперпараметрам. Это оказалось полезным для улучшения моего результа- та, но затем я достигла предела. Преобразование Constant-Q применяет серию фильтров к временным рядам и преобразует их в частотную область. Я начала спрашивать себя, есть ли метод, который выполняет эти задачи фильтрации луч- шим, более гибким способом. В это же время в сообществе возникла идея ис- пользовать одномерную (Id) сеть CNN, и она мне понравилась. Мы все знаем, что фильтры двумерной сети CNN способны обнаруживать края, линии и тексту- ры в заданных изображениях. То же самое можно сделать с ’’классическими" фильтрами, такими как фильтр Лапласа или Собеля. По этой причине я спросила себя: нельзя ли использовать одномерную CNN для самостоятельного изучения наиболее важных фильтров вместо того, чтобы применять преобразования, кото- рые уже как-то зафиксированы? Мне не удалось получить работоспособное решение в виде одномерной сверточ- ной нейронной сети, но оказалось, что многие продвинутые команды справились с этим. Соревнование G2Net было одним из моих любимых, даже несмотря на то, что мне не удалось завоевать медаль. Однако знания, которые я приобрела в про- цессе решения задач, и урок, который я получила в отношении так называемых стандартных подходов, были очень ценными.
348 Часть IL Оттачивание соревновательных навыков Помог ли тебе Kaggle в карьере? Если да, то как? Свою первую работу после университета я начала в качестве разработчика про- граммного обеспечения на Java, хотя первое знакомство с машинным обучением у меня уже состоялось во время работы над магистерской диссертацией. Мне бы- ло интересно больше заниматься анализом данных, но в то время вакансий в об- ласти науки о данных почти не было, или это направление называлось по- другому. Когда я впервые услышала о Kaggle, эта платформа сразу меня зацепи- ла. С тех пор я часто заходила на Kaggle по вечерам в свое удовольствие. В то время я не собиралась менять свою должность, но потом возник исследователь- ский проект, в котором требовались навыки машинного обучения. У меня появи- лась возможность показать, что я подходящий кандидат для этого проекта благо- даря знаниям, полученным за время участия в Kaggle. Это стало отправной точкой для моей карьеры в области науки о данных. В моем случае Kaggle всегда был отличным местом для тестирования идей, изуче- ния новых методов и инструментов, а также получения практического опыта. При- обретенные таким образом навыки оказались весьма полезными для проектов в области науки о данных в моей профессиональной деятельности. Это как подпитка знаниями, поскольку Kaggle предоставляет песочницу, в которой вы можете опро- бовать различные идеи и проявить творческий подход без риска. Неудача в сорев- новании означает, что как минимум один урок был усвоен; а вот неудача в проекте может оказать огромное негативное влияние на вас самих и на других людей. Помимо участия в соревнованиях еще одним отличным способом пополнить свое портфолио является ведение блокнотов. При помощи этого инструмента можно показать всему миру, как вы подходите к решению задач и как доносите до лю- дей свои идеи и выводы. Последнее очень важно, когда вам приходится работать с руководством, клиентами и экспертами разного профиля. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотела бы знать, когда начинала участвовать в соревнованиях? Думаю, что многие новички, участвующие в соревнованиях, соблазняются пуб- личной таблицей лидеров и строят свои модели, не имея хорошей стратегии ва- лидации. Оценивая свои успехи в таблице лидеров, они, скорее всего, чрезмерно подстраиваются под общедоступные тестовые данные. После окончания сорев- нования их модели невозможно обобщить на невидимые закрытые тестовые дан- ные, и такие участники часто спускаются на сотни позиций в рейтинге. До сих пор помню, как я была расстроена во время соревнования экологически чистого производства Mercedes-Benz, т. к. не смогла подняться в таблице лидеров. Но ко- гда был подведен окончательный итог, стало большой неожиданностью, как мно- го людей переместились вверх и вниз в таблице лидеров. С тех пор я навсегда за- помнила, что правильная схема валидации очень важна для решения проблем недообучения и переобучения. Какие ошибки ты допускала на соревнованиях? До сих пор моей самой большой ошибкой была трата слишком большого количе- ства времени и усилий на детали моего решения в начале соревнования. На са- мом деле гораздо лучше проводить быстрые итерации различных идей после по-
Глава 10. Моделирование в компьютерном зрении 349 строения правильной стратегии валидации. Таким образом, легче и быстрее най- ти перспективные направления улучшений, а опасность застрять где-нибудь го- раздо меньше. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Существует множество общих инструментов и библиотек, которые вы можете изучить и применить на практике, став активным участником сообщества Kaggle, и я могу рекомендовать их все. Важно сохранять гибкость мышления и изучить их преимущества и недостатки. Таким образом, ваши решения будут зависеть не от инструментов, а от ваших идей и креативности. О мем важнее всего помнить, приступая к участию в соревновании? Наука о данных — это не построение моделей, а скорее понимание данных и способа их сбора. Многие соревнования, в которых я участвовала до сих пор, по- казали утечки в данных или наличие скрытых групп в тестовых данных, которые можно было обнаружить с помощью разведочного анализа данных. Резюме В этой главе мы представили вам обзор наиболее важных тем, связанных с компь- ютерным зрением, с точки зрения соревнований Kaggle. Представили аугмента- ции— важный класс методов, используемых для расширения обобщающих воз- можностей алгоритма, а затем продемонстрировали сквозные конвейеры для трех наиболее часто встречающихся задач: классификации изображений, обнаружения объектов и семантической сегментации. В следующей главе мы сосредоточимся на обработке естественного языка — еще одной чрезвычайно широкой и популярной категории задач. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
11 Моделирование для обработки естественного языка Обработка естественного языка (natural language processing, NLP) — это область, процессы в которой происходят на пересечении лингвистики, информатики и ис- кусственного интеллекта. Основное внимание уделяется алгоритмам для обработки и анализа больших объемов данных на естественном языке. В последние несколько лет эта тема набирает популярность в соревнованиях Kaggle. Хотя сама область очень широка и охватывает такие интересные темы, как чат-боты и машинный пе- ревод, в этой главе мы сосредоточимся на конкретных подгруппах задач, которыми часто занимаются участники соревнований Kaggle. Сентиментальный анализ (сентимент-анализ, анализ тональности текста— senti- ment analysis) как простая задача классификации чрезвычайно популярен и обсуж- дается повсюду, поэтому мы начнем с несколько более интересной вариации зада- чи: выявления фраз, поддерживающих настроения (тональность), в твите. Далее опишем пример решения задачи ответов на вопросы в открытом домене и завер- шим главу разделом об аугментации для задач NLP — теме, которой уделяется зна- чительно меньше внимания, чем компьютерному зрению. Итак, мы рассмотрим: • анализ тональности текста; • вопросы и ответы в открытом домене; • стратегии аугментации текста. Анализ тональности текста Twitter— одна из самых популярных платформ социальных сетей и важный инст- румент коммуникации для многих частных лиц и компаний.
Глава 11. Моделирование для обработки естественного языка 351 Улавливание тональности в языке особенно важно в контексте социальных сетей: позитивный твит может стать вирусным и распространить информацию, в то время как особенно негативный может нанести вред. Поскольку человеческий язык сло- жен, важно не просто определить тональность, но также иметь возможность иссле- довать то, как мы пришли к результату — какие слова на самом деле привели к описанию тональности? Мы продемонстрируем подход к решению этой задачи на примере данных конкур- са Tweet Sentiment Extraction (https://www.kaggle.eom/c/tweet-sentiment-extraction). Для краткости мы опустили операции импорта в следующем коде, но вы можете найти их в соответствующем блокноте в репозитории GitHub для этой главы. Для того чтобы лучше понять суть задачи, давайте для начала посмотрим на данные: df = pd.read_csv('/kaggle/input/tweet-sentiment-extraction/train.csv') df.head() Первые несколько строк показаны на рис. 11.1. text ID text selected-text sentiment 0 cb774db0d1 I’d have responded, if I were going I’d have responded, if I were going neutral 1 549e992a42 Sooo SAD I will miss you here in San Diego!!? Sooo SAD negative 2 088c60f138 my boss is bullying me... bullying me negative 3 9642c003ef what interview! leave me alone leave me alone negative 4 358bd9e861 Sons of **'*, why couldn’t they put them on t... Sons of ****, negative Рис. 11.1. Выборка строк из обучающих данных Сами твиты хранятся в текстовом столбце под названием text. Каждый из них име- ет ассоциированное настроение вместе с опорной фразой, хранящейся в столбце selected_text (часть твита, на основе которой было принято решение о назначении настроения). Начнем с определения основных функций очистки. Во-первых, мы хотим избавить- ся от URL-адресов сайтов и несимволов и заменить звезды, которые люди исполь- зуют вместо бранных слов, одним токеном, "swear". Для этого мы используем неко- торые регулярные выражения: def basic_cleaning(text): text=re.sub(r'https?://www\.\S+\.com','',text) text=re.sub(r'[AA-Za-z|\s]','',text) text=re.sub(r'\*+'J'swear',text) # Перехватывать бранные слова в виде **** return text
352 Часть II. Оттачивание соревновательных навыков Далее мы удаляем HTML из содержимого твитов, а также эмодзи: def remove_html(text): html=re.compile(г'<.*?>') return html.sub(r'text) def remove_emoji(text): emoji_pattern = re.compile("[" u"\U0001F600-\U0001F64F" # смайлики u"\U0001F300-\U0001F5FF" # символы и пиктограммы u"\U0001F680-\U0001F6FF" # транспорт # и картографические символы u"\U0001F1E0-\U0001F1FF" # флаги (iOS) и"\U00002702-\U000027B0" и”\U000024C2-\U0001F251” "]+", flags=re.UNICODE) return emoji_pattern.sub(r'', text) Наконец, необходимо удалить повторяющиеся символы (например, чтобы вместо "waaaayyyy" было "way"): def remove_multiplechars(text): text = re. sub(г' (.)г' \1' text) return text Для удобства объединяем эти четыре функции в одну функцию очистки: def clean(df): for col in ['text']: #, 'указанный_текст']: df[col]=df[col].astype(str).apply(lambda x:basic_cleaning(x)) df[col]=df[col].astype(str).apply(lambda x:remove_emoji(x)) df[col]=df[col].astype(str).apply(lambda x:remove Jrtml(x)) df[col]=df[col].astype(str).apply(lambda x:remove jnultiplechars(x)) return df Последняя часть подготовки включает написание функций для создания встраива- ний на основе предварительно обученной модели (аргумент tokenizer): def fast_encode(textSj tokenizer, chunk_size=256, maxlen=128): tokenizer.enable_truncation(max_length=maxlen)
Глава 11. Моделирование для обработки естественного языка 353 tokenizer.enable_padding(max_length=maxlen) all_ids = [] for i in range(0j len(texts), chunk_size): text_chunk = texts[i:i+chunk_size].tolist() encs = tokenizer.encode_batch(text-chunk) all_ids.extend([enc.ids for enc in encs]) return np.array(all-ids) Далее мы создаем функцию предварительной обработки, позволяющую нам рабо- тать со всем корпусом: def preprocess—news(dfj stop=stop, n=l, col=' text'): "'Функция для предварительной обработки и создания корпуса'" new_corpus=[] stem=PorterStemmer() lem=WordNetLemmatizer() for text in df[col]: words=[w for w in word_tokenize(text) if (w not in stop)] words=[lem.lemmatize(w) for w in words if(len(w)>n)] new__corpus. append (words) new_corpus=[word for 1 in new_corpus for word in 1] return new__corpus Используя наши ранее подготовленные функции, можно очистить и подготовить обучающие данные. Столбец sentiment будет нашей целью, и мы преобразуем его в фиктивные переменные (одноточечное кодирование) для повышения производи- тельности: df.dropna(inplace=True) df_clean = clean(df) df_clean_selection = df_clean.sample(frac=l) X = df_clean_selection.text.values у = pd.get_dummies(df_clean_selection.sentiment)
354 Часть II. Оттачивание соревновательных навыков Следующим необходимым шагом станет токенизация входных текстов, а также преобразование их в последовательности (вместе с дополнением, чтобы обеспечить одинаковую длину по всему датасету): tokenizer = text.Tokenizer(num_words=20000) tokenizer.fit_on_texts(list(X)) list_tokenized_train = tokenizer.texts_to_sequences(X) X_t = sequence.pad_sequences(list_tokenized_train, maxlen=128) Мы создадим встраивания для нашей модели с помощью модели DistilBERT и бу- дем использовать их как есть. DistilBERT— это облегченная версия сети BERT: компромиссом стало снижение производительности на 3% при меньшем на 40% количестве параметров. Мы могли бы обучить слой встраивания и повысить произ- водительность — ценой значительного увеличения времени обучения. tokenizer = transformers.AutoTokenizer.from_pretrained("distilbert-base-uncased") # Сохранение загруженного токенизатора локально save_path = '/kaggle/working/distilbert_base__uncased/' if not os.path.exists(save_path): os.makedirs(save_path) tokenizer.save_pretrained(save_path) # Перезагрузка с библиотекой токенизаторов huggingface fast_tokenizer = BertWordPieceTokenizer( 'distilbert__base_uncasedZvocab.txt', lowercase=True) fast_tokenizer Для кодирования твитов можно использовать ранее определенные функции fast_encode и fast_tokenizer: X = fast_encode(df_clean_selection.text.astype(str), fast_tokenizer_, maxlen=128) После подготовки данных можно построить модель. В рамках этого примера мы будем использовать довольно стандартную архитектуру для таких приложений: комбинация слоев LSTM, нормализованных с помощью глобального объединения и отсева, и полносвязный слой сверху. Для того чтобы добиться действительно кон- курентоспособного решения, необходимо внести некоторые изменения в архитек- туру: более "тяжелая" модель, большие встраивания, большее количество нейронов в слоях LSTM и т. д.
Глава 11. Моделирование для обработки естественного языка 355 transformer__layer = transf ormers. TFDistilBertModel.from_ pretrained('distilbert-base-uncased') embedding_size = 128 input_ = Input(shape=(100,)) inp = Input(shape=(128, )) embedding_matrix=transformer_layer.weights[0].numpy() x = Embedding(embedding_matrix.shape[0], embedding_matrix.shape[ 1 ], embeddings_initializer=Constant(embedding_matrix), trainable=False)(inp) x = Bidirectional LSTM( 50, return_sequences=True))(x) x = Bidirectional/LSTM(25, return_sequences=True))(x) x = GlobalMaxPoollD()(x) x = Dropout(0.5)(x) x = Dense(50, activation='relu', kernel_regularizer='L1L2')(x) x = Dropout(0.5)(x) x = Dense(3, activation='softmax')(x) model-DistilBert = Model(inputs=[inp], outputs=x) model_DistilBert.compile(loss='categorical_crossentropy', optimizer' adam', metrics=['accuracy']) Особой необходимости обращать внимание на временную размерность данных нет, поэтому нас вполне устраивает случайное разделение на обучение и валидацию, которого можно достигнуть внутри вызова метода fit: model_DistilBert.fit(X,у,batch_size=32,epochs=10,validation_split=0.1) Ниже приведен пример вывода: Epoch 1/10 27480/27480 [==============================] - 480s 17ms/step - loss: 0.5100 - accuracy: 0.7994 Epoch 2/10
356 Часть II. Оттачивание соревновательных навыков 27480/27480 [===================== 0.4956 - accuracy: 0.8100 =========] - 479s 17ms/step - loss Epoch 3/10 27480/27480 [===================== =========] - 475s 17ms/step - loss 0.4740 - accuracy: 0.8158 Epoch 4/10 27480/27480 [===================== =========] - 475s 17ms/step - loss 0.4528 - accuracy: 0.8275 Epoch 5/10 27480/27480 [===================== =========] - 475s 17ms/step - loss 0.4318 - accuracy: 0.8364 Epoch 6/10 27480/27480 [===================== =========] - 475s 17ms/step - loss 0.4069 - accuracy: 0.8441 Epoch 7/10 27480/27480 [===================== =========] - 477s 17ms/step - loss 0.3839 - accuracy: 0.8572 Генерация прогноза на основе прошедшей подгонку модели происходит простым образом. Для того чтобы использовать все имеющиеся данные, начинаем с повтор- ного обучения нашей модели на всех имеющихся данных (поэтому валидация не проводится): df_clean_final = df_clean.sample(frac=l) X_train = fast_encode(df_clean_selection.text.astype(str), fast_tokenizer, maxlen=128) y_train = у Повторно проверяем модель на всем датасете перед генерацией прогнозов: Adam_name = adam(lr=0.001) model_DistilBert.compile(loss='categorical_crossentropy', optimizer=Adam_ name,metrics=['accuracy']) history = model_DistilBert.fit(X_train,У-train,batch_size=32jepochs=10) Следующим шагом будет обработка тестовых данных в том же формате, который мы используем для обучающих данных, поступающих в модель: df_test = pd.read_csv('/kaggle/input/tweet-sentiment-extraction/test.csv') df_test.dropna(inplace=True) df_clean_test = clean(df_test)
Глава 11. Моделирование для обработки естественного языка 357 X_test = fast_encode(df_clean_test.text.values.astype(str), fast-tokenizer, maxlen=128) y_test = df_clean_test.sentiment Наконец, генерируем прогнозы: y_preds = model_DistilBert.predict(X_test) y_predictions = pd.DataFrame(y_preds, columns=['negative'3 'neutral'> 'positive']) y_predictions_final = y_predictions.idxmax(axis=l) accuracy = accuracy__score(y_testjyjoredictions_final) print(f"The final model shows {accuracy:.2f} accuracy on the test set.") Окончательная модель показывает точность 0,74 на тестовом наборе. На рис. 11.2 приведен пример результата. Как видно уже из этих строк, есть несколько случаев, когда тональность очевидна для человека, но модель не может ее уловить. textID text sentiment predicted„negative predictedjieutral predicted „positive 0 f87dea47db Last session of the day httptwitpicconnezh neutral 0.022949 0.967165 0.009886 1 96d74cb729 Shanghai is also really exciting precisely s... positive 0.000075 0.012165 0.987760 2 еее518ае67 Recession hit Veronique Branquinho she has to... negative 0.993622 0.006364 0.000014 3 01082688с6 happy bday positive 0.000020 0.005859 0.994122 4 33987а8ее5 httptwitpiccomwp I like it positive 0.006184 0.119946 0.873870 5 726е501993 thats great weee visitors positive 0.000165 0.019434 0.980401 6 261932614е I THINK EVERYONE HATES ME ON HERE | lol negative 0 916203 0.081649 0.002148 7 afa11da83f so wish i could but im in school and myspace. negative 0.877504 0.116624 0.005871 8 e64208b4ef and within a short time of the last clue j all... neutral I 0.116272 0.859304 0.024424 9 37bcad24ca What did you get My day is alright ha vent do... neutral 0223977 0.756474 0.019550 Рис. 11.2. Примеры строк из прогнозируемых результатов Мы только что продемонстрировали примерный конвейер для решения задач атри- буции тональностей (выявление частей текста, которые приводят к решениям анно- татора о классификации тональностей). Если вы хотите добиться конкурентоспо- собной производительности, следует применить некоторые улучшения. Они приведены ниже в порядке вероятного влияния: • более крупные встраивания — улучшение, позволяющее нам получить больше информации уже на уровне (обработанных) входных данных; • более крупная модель — больше нейронов в слоях LSTM; • более длительное обучение — другими словами, большее количество эпох.
358 Часть II. Оттачивание соревновательных навыков Хотя перечисленные выше усовершенствования, несомненно, повысят производи- тельность модели, основные элементы нашего конвейера являются многоразовыми: • очистка и предварительная обработка данных; • создание текстовых встраиваний; • включение рекуррентных слоев и регуляризации в архитектуру целевой мо- дели. Ну что ж, перейдем к обсуждению ответов на вопросы в открытой области — час- тая проблема, встречающаяся в соревнованиях по NLP. Абхишек Тхакур https://www.kaggle.com/abhishek Мы встретились с Абхишеком Тхакуром, первым в мире четырехкратным гроссмейстером Kaggle. В настоящее время он работает в компании Hugging Face, где создает AutoNLP; он также написал практически единственную книгу о Kaggle на английском языке (не считая этой!) — ’’Approaching (Almost) Any Machine Learning Problem’’ (’’Подход к (почти) любой задаче машинного обучения”). Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Никакой "специализации" нет. Все соревнования различаются, и на каждом из них можно многому научиться. Если бы у меня была "специализация", я бы вы- играл все соревнования в этой области. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Первое, что я делаю, — это смотрю на данные и пытаюсь их немного понять. Если я опаздываю на соревнования, я пользуюсь помощью общедоступных ядер EDA. Первое, что я делаю, когда подхожу к решению задачи на Kaggle (или вне его), — разрабатываю подход. Этот процесс очень важен, т. к. в результате мы получаем базовую модель, с которой можно сравнивать свои будущие модели. Если я опаздываю в игру, то для построения базовой модели я стараюсь не при- бегать к помощи публичных блокнотов. При их использовании мышление сужа- ется только до одного направления. По крайней мере, я так чувствую. После окончания работы с подходом я стараюсь выжать максимум возможного, не делая ничего сложного, например, выполняя стекинг или блендинг. Затем я снова просматриваю данные и модели и пытаюсь улучшить базовую модель, по одному шагу за раз. Повседневная работа иногда включает в себя много общих операций. В боль- шинстве случаев есть подход, а вы должны придумать технику, функции, моде- ли, которые превзойдут этот подход.
Глава 11. Моделирование для обработки естественного языка 359 Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Каждое соревнование интересно. Помог ли тебе Kaggle в карьере? Если да, то как? Конечно, помог. За последние несколько лет платформа Kaggle завоевала очень хорошую репутацию, если мы говорим о найме исследователей данных и инже- неров по машинному обучению. Рейтинг Kaggle и опыт работы с большим коли- чеством датасетов — это то, что, несомненно, так или иначе помогает при работе в данной отрасли. Чем больше у вас опыта в подходе к различным типам задач, тем быстрее вы сможете проводить итерации. И это очень полезный навык в на- шей сфере. Никому не хочется тратить несколько месяцев на то, что не приносит никакой пользы бизнесу. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Большинство новичков легко сдаются. Очень легко принять участие в соревно- вании Kaggle и испугаться недосягаемости лучших результатов. Если новички хотят добиться успеха на платформе Kaggle, им необходимо проявить настойчи- вость. На мой взгляд, главное — это настойчивость. Многие новички также не могут начать самостоятельно и придерживаются использования публичных ядер. Такое поведение заставляет их перенимать образ мышления создателей этих ядер. Мой совет — начать с самостоятельного участия в соревнованиях, изучать данные, создавать функции, строить модели, а затем погрузиться в область ядер и обсуждений, чтобы увидеть, что другие разработчики могут решать задачи иначе. Ну и в результате внедрите полученные знания в собственное решение. Вопросы и ответы в открытом домене В этом разделе рассмотрим конкурс Google QUEST Q&A Labeling (https:// www.kaggle.com/c/google-quest-challenge/overview/description). В нем пары "во- прос — ответ" оценивались экспертами-людьми по различным критериям, таким как "разговорный вопрос", "поиск фактов" или "полезный ответ". Задача заключа- лась в предсказании числового значения для каждого целевого столбца (соответст- вующего критериям). Поскольку метки были агрегированы по нескольким оценщи- кам, задача была фактически многомерной регрессией с целевыми столбцами, нормализованными до диапазона единиц данных. Прежде чем приступить к моделированию с помощью продвинутых методов (на- пример, модели на основе трансформеров для NLP), часто бывает полезно создать базовую модель с помощью более простых методов. Как и в предыдущем разделе, мы опустим операции импорта для краткости, но вы можете найти их в блокноте в репозитории GitHub.
360 Часть II. Оттачивание соревновательных навыков Начнем с определения нескольких вспомогательных функций, которые помогут нам извлечь различные аспекты текста. Во-первых, нам нужна функция, которая выводит количество слов, заданных длиной строки: def word_count(xstring): return xstring.split().str.len() В качестве метрики в соревновании использовалась корреляция Спирмена (линейная корреляция, рассчитанная по рангам: https://en.wikipedia.org/wiki/Spearman%27s_ rankcorrelationcoefficient). Поскольку мы собираемся построить конвейер Scikit-leam, полезно определить метрику как оценщик (метод make_scorei-------это обертка в библиотеке Scikit-leam, которая принимает функцию оценки, например точность или MSE, и возвращает вызываемый объект, который оценивает выходные данные оценщика): def spearman_corr(y_true, y_pred): if np.ndim(y_pred) == 2: corr = np.mean([stats.spearmanr(y_true[:, i], y_pred[:, i])[0] for i in range(y_true.shape[1])]) else: corr = stats.spearmanr(y_truej y_pred)[0] return corr custom_scorer = make_scorer(spearman_corr, greater_is_better=True) Затем добавляется небольшая вспомогательная функция для извлечения последова- тельных фрагментов размера п из 1. Это поможет нам в дальнейшем генерировать встраивания для нашего текста, избегая проблем с памятью: def chunks(l, n): for i in range(0, len(l), n): yield l[i:i + n] Часть набора признаков, которые мы будем использовать, — это встраивания из предварительно обученных моделей. Напомним, что идея данного раздела заклю- чается в построении базовой модели без обучения сложным моделям, но это не мешает нам использовать существующие. Начинаем с импорта токенизатора и модели, а затем обрабатываем корпус по час- тям, кодируя каждый вопрос-ответ во встраивание фиксированного размера: def fetch_vectors(string_list, batch__size=64): # Вдохновлено https://jaLammar.github.io/a-visuaL-guide-to-using-bert-for- # the-first-time/
Глава 11. Моделирование для обработки естественного языка 361 DEVICE = torch.device("cuda") tokenizer = transformers.DistilBertTokenizer.from_pretrained ("../input/distilbertbaseuncased/") model = transformers.DistilBertModel.from__pretrained ("../input/distilbertbaseuncased/") model.to(DEVICE) fin_features = [] for data in chunks(string_list, batch_size): tokenized = [] for x in data: x = " ".join(x.strip().split()[:300]) tok = tokenizer.encode(x, add_special_tokens=True) tokenized.append(tok[:512]) max_len = 512 padded = np.array([i + [0] * (max_len - len(i)) for i in tokenized]) attention_mask = np.where(padded 1=0, 1, 0) input_ids = torch.tensor(padded).to(DEVICE) attention_mask = torch.tensor(attention_mask).to(DEVICE) with torch.nojgrad(): last_hidden_states = model(input-ids, attention_mask=attention_mask) features = last_hidden_states[0][:, 0, :].cpu().numpy() fin_features.append(features) fin_features = np.vstack(fin_features) return fin_features Теперь можно приступить к загрузке данных: xtrain = pd.read_csv(data_dir + ’train.csv') xtest = pd.read_csv(data_dir + 'test.csv') xtrain.head(4) Первые несколько строк представлены на рис. 11.3.
362 Часть II. Оттачивание соревновательных навыков questionjitle question_body question_user_name question_user_page answer What am 1 losing when using extension tubes in... After playing around with macro photography on... ysap https://photo stackexchange com/users/1024 I just got extension tubes, so here’s the skin.. What is the distinction between a city and a s... 1 am trying to understand what kinds of places... russellpierce https://rpg.stackexchange.com/users/8774 It might be helpful to look into the defin itio. Maximum protusion length for through-hole comp... I‘m working on a PCB that has through- hole com... Joe Baker https://electronics.stackexchange.com/usersZ10157 Do you even need grooves? We make several pro... Can an affidavit be used in Beit Din? An affidavit, from what i understand, is basic... Scimonster https://judaism .stackexchange. com/users/5151 Sending an "affidavit" it is a dispute between.. Рис. 11.3. Выборка строк из обучающих данных Мы указываем 30 интересующих нас целевых столбцов: target_cols = ['question_asker_intent_understanding', 'question_body_critical', 'question_conversational', 'question_expect_short_answer’} 'question_fact_seeking'} ' questionJias_comrnonly_accepted_answer', 'question_interestingness_others', 'question_interestingness_self'} 'question_multi_intent', 'question_not_really_a_question'} 'question_opinion_seeking', 'question_type_choice’} 'question_type_compare'} ’question_type_consequence', 'question_type_definition’, 'question_type_entity', 'question_type_instructions'} 'question_type_procedure'3 'question_type_reason_explanation', 'question_type_spelling', 'question_well_written', 'answer_helpful', 'answer_level_of_information’} 'answer^plausible', 'answer_relevance', 'answer_satisfaction', 'answer_type_instructions's 'answer_type_procedure'3 'answer_type_reason_explanation', 'answer_well_written']
Глава И. Моделирование для обработки естественного языка 363 Для обсуждения их значения и интерпретации читатель может обратиться к страни- це данных соревнования по адресу https://www.kaggle.eom/c/google-quest-challenge/ data. Далее мы переходим к построению признаков. Начнем с подсчета слов в заголов- ке и теле вопроса, а также в ответе. Это простая, но удивительно полезная функция во многих приложениях: for colname in ['question_title', 'question_body', 'answer']: newname = colname + '_word_len' xtrain[newname] = xtrain[colname].str.split().str.len() xtest[newname] = xtest[colname].str.split().str.len() Следующим создаваемым признаком станет лексическое разнообразие, подсчи- тывающее долю уникальных слов во фрагменте текста: colname = 'answer' xtrain[colname+'_div'] = xtrain[colname].apply (lambda s: len(set(s.split())) / len(s.split()) ) xtest[colname+'_div'] = xtest[colname].apply (lambda s: len(set(s.split())) I len(s.split()) ) При работе с информацией, полученной из Интернета, можно извлечь потенциаль- но информативные признаки, изучив компоненты адреса сайта (где мы определяем компоненты как элементы адреса, разделенные точками). Подсчитаем количество компонентов и сохраним некоторые из них как признаки: for df in [xtrain, xtest]: df['domcom'] = df['question_user_page'].apply (lambda s: s.split('://')[l].split('/')[0].split('.')) # Подсчет компонентов df['dom_cnt'] = df['domcom'].apply(lambda s: len(s)) # Уменьшение длины в случае, если у некоторых доменов меньше # компонентов в имени df['domcom'] = df['domcom'].apply(lambda s: s + ['none', 'none']) # Компоненты for ii in range(0,4): df['dom_'+str(ii)] = df['domcom'].apply(lambda s: s[ii])
364 Часть II. Оттачивание соревновательных навыков Многочисленные целевые столбцы касаются того, насколько релевантным является ответ на данный вопрос. Одним из возможных способов количественной оценки этих отношений является оценка общих слов в паре строк: # Общие элементы for df in [xtrain, xtest]: df['q_words'] = df['question_body'].apply(lambda s: [f for f in s.split() if f not in eng_stopwords] ) df['a_words'] = df['answer'].apply(lambda s: [f for f in s.split() if f not in eng_stopwords] ) df['qa_word_overlap'] = df.apply(lambda s: len(np.intersectld(s['q_ words'], s['a_words'])), axis = 1) df['qa_word_overlap_norml'] = df.apply(lambda s: s['qa_word_overlap']/ (1 + len(s['a_words'])), axis = 1) df['qa_word_overlap_norm2'] = df.apply(lambda s: s['qa_word_overlap']/ (1 + len(s['q_words'])), axis = 1) df.drop(['q_words', 'a_words'], axis = 1, inplace = True) Стоп-слова и знаки препинания могут рассказать нам кое-что о стиле и намерениях: for df in [xtrain, xtest]: # # Количество символов в тексте ## df["question_title__num_chars"] = df["question_title"].apply(lambda x: len(str(x))) df["question_body_num_chars"] = df["question_body"].apply(lambda x: len(str(x))) df["answer_num_chars"] = df["answer"].apply(lambda x: len(str(x))) # # Количество стоп-слов в тексте ## df["question_title_num_stopwords"] = df["question_title"].apply(lambda x: len([w for w in str(x).lower().split() if w in eng_stopwords])) df["question_body_num_stopwords"] = df["question_body"].apply(lambda x: len([w for w in str(x).lower().split() if w in eng_stopwords])) df["answer_num_stopwords"] = df["answer"].apply(lambda x: len([w for w in str(x).lower().split() if w in eng_stopwords])) # # Количество знаков препинания в тексте ## df["question_title_num_punctuations"] =df['question_title'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]) ) df["question_body_num_punctuations"] =df['question_body'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]) ) df["answer jium_punctuations"] =df['answer'].apply(lambda x: len([c for c in str(x) if c in string.punctuation]) )
Глава 11. Моделирование для обработки естественного языка 365 ## Количество слов, написанных заглавными буквами, в тексте ## df[ "question jitle_num_words_upper"] = df["questionjitle"].apply(lambda x: len([w for w in str(x).split() if w.isupper()])) df[ "questionjody_num_wordsjipper"] = df["question_body"].apply(lambda x: len([w for w in str(x).split() if w.isupper()])) df["answer jium_words_upper"] = df["answer"].apply(lambda x: len([w for w in str(x).split() if w.isupper()])) Подготовив ’’винтажные” функции, в которых мы ориентируемся на простую свод- ную статистику текста, не обращая внимания на семантическую структуру, мы мо- жем перейти к созданию встраиваний для вопросов и ответов. Теоретически мож- но было бы обучить отдельную модель типа word2vec на наших данных (или доработать существующую), но в рамках рассматриваемого примера мы будем ис- пользовать предварительно обученную модель как есть. Хорошим выбором станет Universal Sentence Encoder от Google (https://tfhub.dev/google/universal-sentence- encoder/4). Эта модель обучается на различных источниках данных. Она принимает на вход фрагмент текста на английском языке и выдает 512-мерный вектор. module_url = "../input/universalsentenceencoderlarge4/" embed = hub.load(module_url) Код для превращения текстовых полей во встраивания представлен ниже: мы пере- бираем записи в обучающем/тестовом наборах по пакетам, встраиваем каждый па- кет (для экономии памяти), а затем добавляем их к исходному списку. Окончательные варианты фрейма данных строятся путем формирования стека спи- сков встраиваний на уровне пакетов: embeddings_train = {} embeddings jest = {} for text in ['questionjitle', 'question_body', 'answer']: trainjext = xt rain [text] .str. replace(' ?', '.') .str.replace('!', '.') .tolistQ testjext = xtest[text].str.replace('?', '.') .str.replace('!', '.') .tolistQ curr_train_emb = [] currjest_emb = [] batch_size = 4 ind = 0 while ind*batch_size < len(train jext): curr^_train_emb. append (embed (trainjext[ind*batch_size: (ind + l)*batch_size])["outputs"].numpy()) ind += 1
366 Часть II. Оттачивание соревновательных навыков ind = 0 while ind*batch_size < len(test_text): curr_test_emb.append(embed(test_text[ind*batch_size: (ind + l)*batch_size])["outputs"].numpy()) ind += 1 embeddings_train[text + '_embedding'] = np.vstack(curr_train_emb) embeddings_test[text + '_embedding'] = np.vstack(curr_test_emb) print(text) Учитывая векторные представления для вопросов и ответов, мы можем рассчитать семантическое сходство между полями путем применения различных метрик рас- стояния для пар векторов. Идея использования разнообразных метрик заключается в желании уловить различные типы характеристик. Аналогией в контексте класси- фикации было бы использование как точности, так и энтропии для получения пол- ной картины ситуации: 12_dist = lambda хл у: np.power(x - у, 2).sum(axis=l) cos_dist = lambda хл у: (х*у).sum(axis=l) dist_features_train = np.array([ 12_dist(embeddings_train['question_title_embedding'], embeddings_ train['answer_embedding']), 12_dist(embeddings_train['question_body_embedding'], embeddings_ train['answer_embedding']), 12_dist(embeddings_train['question_body_embedding'], embeddings_ train['question_title_embedding’]), cos_dist(embeddings_train['question_title_embedding'], embeddings_ train['answer_embedding'])3 cos_dist(embeddings_train['question_body_embedding'], embeddings_ train['answer_embedding']), cos_dist(embeddings_train['question_body_embedding'], embeddings_ train['question_title_embedding']) ]).T dist_features_test = np.array([ 12_dist(embeddings_test['question_title_embedding'], embeddings_ test['answer_embedding']),
Глава 11. Моделирование для обработки естественного языка 367 12_dist(embeddings_test['question_body_embedding'], embeddings_ test['answer_embedding'])s 12_dist(embeddings_test[’question_body_embedding'], embeddings_ test['question_title_embedding']), cos_dist(embeddings_test['question_title_embedding'], embeddings_ test['answer_embedding'])3 cos_dist(embeddings_test['question_body_embedding'], embeddings_ test['answer_embedding'])3 cos_dist(embeddings_test['question_body_embedding']3 embeddings_ test['question_title_embedding']) ]).T Соберем признаки расстояния в отдельные столбцы: for ii in range(0,6): xtrainCdist'+strCii)] = dist_features_train[: ,ii] xtest['dist'+str(ii)] = dist_features_test[: _»ii] Наконец, мы также можем создать TF-IDF-представления текстовых полей. Об- щая идея заключается в том, чтобы создать несколько признаков на основе раз- личных преобразований входного текста, а затем подать их в относительно про- стую модель. Таким образом, мы можем уловить характеристики данных без необходимости подгонки сложной модели глубокого обучения. Этого можно достичь, анализируя текст как на уровне слов, так и на уровне симво- лов. Для того чтобы лимитировать потребление памяти, мы установили верхнее ограничение на максимальное количество признаков обоих типов (в вашем случае при увеличении объема памяти эти границы можно расширить): limit_char = 5000 limit_word = 25000 Мы создаем векторизаторы на уровне символов и слов. Постановка данной задачи позволяет удобно использовать функциональность Pipeline из библиотеки Scikit- leam, позволяющую комбинировать несколько шагов в процедуре подбора модели. Начнем с создания двух отдельных трансформеров для столбца заголовка (на уров- не слов и символов): title_col = 'question_title' title_transformer = Pipeline([ ('tfidf, TfidfVectorizer(lowercase=False, max_df=0.3, min_df=l, binary=False, use_idf=True, smooth_idf=FalseJ
368 Часть II. Оттачивание соревновательных навыков ngram_range=(l,2), stop_words='english', token_pattern='(?u)\\b\\w+\\b', max_features=limit_word)) ]) title_transformer2 = Pipeline([ ('tfidf2', TfidfVectorizer(sublinear_tf=True, strip_accents='unicode', analyzer='char'} stop_words='english', ngram_range=(l, 4), max_features=limit_char)) ]) Для тела используем ту же логику (два разных конвейерных трансформера): body_col = 'question_body' body_transformer = Pipeline([ ('tfidf'jTfidfVectorizer(lowercase=False> max_df=0.3, min_df=l, binary=False, use_idf=True, smooth_idf=False, ngram_range=(l,2), stop_words='english', token_pattern='(?u)\\b\\w+\\b', max_features=limit_word)) ]) body_transformer2 = Pipeline([ ('tfidf2', TfidfVectorizer(sublinear_tf=True, strip_accents='unicode's analyzer='char', stop_words='english', ngram_range=(lJ 4), max_features=limit_char)) D И, наконец, для столбца ответов: answer_col = 'answer' answer_transformer = Pipeline([ ('tfidf', TfidfVectorizer(lowercase=False, max_df=0.3, min_df=lJ binary=False, use_idf=True, smooth_idf=False, ngram_range=(l,2), stop_words='english', token_pattern='(?u)\\b\\w+\\b', max_features=limit_word)) ])
Глава 11. Моделирование для обработки естественного языка 369 answer_transformer2 = Pipeline([ ('tfidf2', TfidfVectorizer(sublinear_tf=True, strip_accents='unicode', analyzer='char', stop_words='english'} ngram_range=(l, 4), max_features=limit_char)) D Мы завершаем часть работы по построению признаков обработкой числовых при- знаков. Используем только простые методы: заполнение пропусков в данных и си- ловой трансформер, чтобы стабилизировать распределение и сделать его ближе к гауссовскому (это часто бывает полезно, если вы используете числовые характери- стики в нейронной сети): num_cols = [ 'question_title_word_len'} 'question_body_word_len', 'answer_word_len', 'answer_div', 'question_title_num_chars','question_body_num_chars', 'answer_num_chars', 'question_title_num_stopwords','question_body_num_stopwords', 'answer_num_stopwords'} 'question_title_num_punctuations', 'question_body_num_punctuations','answer_num_punctuations', 'question_title_num_words_upper', 'question_body_num_words_upper','answer_num_words_upper'3 'dist0', 'distl', 'dist2', 'dist3', 'dist4', 'dist5' ] num_transformer = Pipeline([ ('impute', Simplelmputer(strategy='constant', fill_value=0)), ('scale', PowerTransformer(method='yeo-johnson')) ]) Полезной особенностью утилит Pipeline является то, что их можно комбинировать и встраивать. Далее мы добавляем функциональность для обработки категориаль- ных переменных, а затем объединяем все это в объект ColumnTransformer, чтобы уп- ростить логику предварительной обработки данных и построения признаков. Каж- дая часть входного сигнала может обрабатываться соответствующим образом: cat_cols = [ 'dom_0', 'dom_l', 'dom_2', ' dom_3', ' category',' is_question_no_name_user', ' is_answer_no_name_user',' dom_cnt' ]
370 Часть II. Оттачивание соревновательных навыков cat_transformer = Pipeline([ ('impute', Simplelmputer(strategy='constant', fill_value='')), ('encode', OneHotEncoder(handle_unknown='ignore’)) ]) preprocessor = ColumnTransformer( transformers = [ ('title', title_transformer, title_col), ('title2', title_transformer2, title_col), ('body', body_transformer, body_col), ('body2', body_transformer2, body_col), ('answer', answer_transformer, answer_col), ('answer2', answer_transformer2, answer_col), ('num', num_transformer, num_cols), ('cat', cat_transformer, cat_cols) ] ) Наконец, мы готовы использовать объект Pipeline, объединяющий предваритель- ную обработку и подгонку модели: pipeline = Pipeline([ ('preprocessor', preprocessor), ('estimator',Ridge(random_state=RANDOM_STATE)) D Всегда полезно оценить работу своей модели вне выборки: удобный способ сделать это— создать предсказания на контрольном множестве (out-of-fold (OOF) predictions), которые мы обсуждали в главе 6. Процедура включает в себя следую- щие этапы: 1. Разделите данные на блоки. В нашем случае мы используем метод GroupKFold, т. к. на один вопрос может быть несколько ответов (в отдельных строках фрей- ма данных). Для того чтобы предотвратить утечку информации, необходимо, чтобы каждый вопрос появлялся только в одном блоке. 2. Для обучения каждого блока используйте данные других блоков и создайте прогнозы для выбранного блока данных, а также для тестового набора. 3. Усредните прогнозы на тестовом множестве. Начнем с подготовки матриц ’’хранения”, в которых мы будем хранить предсказа- ния. В mvalid будут находиться предсказания, полученные вне блоков, а mfull послужит местом для предсказаний на всем тестовом наборе, усредненных по
Глава 11. Моделирование для обработки естественного языка 371 блокам. Поскольку несколько вопросов содержат более одного варианта ответа, мы разделим наше KFold-разбиение на фрагменты question_body: nfolds = 5 mvalid = np.zeros((xtrain.shape[0], len(target_cols))) mfull = np.zeros((xtest.shape[0], len(target_cols))) kf = GroupKFold( n_spl.it s= nfolds).split(X=xtrain.question_body, groups=xtrain.question_body) Перебираем блоки циклом и собираем отдельные модели: for ind, (train_index, test_index) in enumerate(kf): # Разделение данных на обучающие и валидационные х0, xl = xtrain.loc[train_index], xtrain.loc[test_index] y0, yl = ytrain.loc[train_index], ytrain.loc[test_index] for ii in range(0, ytrain.shape[l]): # Подгонка модели be = clone(pipeline) be.fit(x0, np.array(y0)[:,ii]) filename = 'ridge_f' + str(ind) + '_c' + str(ii) + '.pkl' pickle.dump(be, open(filename, 'wb')) # Матрицы хранения для OOF и тестовых прогнозов, соответственно mvalid[test_index, ii] = be.predict(xl) mfull[:,ii] += be.predict(xtest)/nfolds print('---') После завершения части подгонки можно оценить производительность в соответст- вии с метрикой, указанной в соревновании: corvee = np.zeros((ytrain.shape[l],l)) for ii in range(0, ytrain.shape[l]): mvalid[:,ii] = rankdata(mvalid[:,ii])/mvalid.shape[0] mfull[:,ii] = rankdata(mfull[:,ii])/mfull.shape[0] corvec[ii] = stats.spearmanr(ytrain[ytrain.columns[ii]], mvalid[:,ii])[0] print(corvee.mean())
372 Часть II. Оттачивание соревновательных навыков Итоговая оценка равна 0,34, что вполне приемлемо в качестве отправной точки. В этом разделе мы продемонстрировали, как построить описательные признаки текста. Хотя предложенный подход не является формулой победы на NLP- соревнованиях (оценка — это хорошо, но не гарантия попадания в призовую зону таблицы лидеров), это полезный инструмент, который нужно иметь в своем арсена- ле. А завершим данную главу разделом, в котором представлен обзор методов ауг- ментации текста. Шотаро Исихара https ://www.kaggle.com/sishihara Наше второе интервью в этой главе — с Шотаро Исихара, он же и++, мастер в соревновательных категориях Competi- tions и Notebooks, который был членом команды- победительницы в соревновании PetFinder.my Adoption Prediction. В настоящее время он работает исследователем данных в японской новостной медиа-компании, а также опубликовал книги на японском языке по Kaggle, включая перевод книги Абхишека Тхакура. Шотаро ведет еженедельный вестник на японском языке об инициативах Kaggle (https://www. getrevue.co/profile/upura). Где можно найти книги Kaggle, которые ты написал/перевел? https://www.kspub.co.jp/book/detail/5190067.htnil— это учебник Kaggle для на- чинающих, основанный на соревновании Titanic GettingStarted. https://book.rnynavi.jp/ec/products/detail/idM23641 — это японский перевод книги Абхишека Тхакура "Approaching (Almost) Any Machine Learning Problem" ("Подход к (почти) любой задаче машинного обучения"). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? В Kaggle мне нравится участвовать в соревнованиях с табличными или тексто- выми датасетами. Эти типы датасетов мне знакомы, поскольку они широко ис- пользуются в компаниях новостных СМИ. Я хорошо знаю подходы, применяе- мые для работы с ними. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Вначале процесс одинаков: размышления о том, как решить задачу с помощью разведочного анализа данных. Kaggle предполагает использование передового машинного обучения, но в бизнесе это не так. На практике я стараюсь найти спо- собы избежать машинного обучения. Даже когда я использую его, я предпочитаю работать с классическими методами, такими как TF-IDF и линейная регрессия, а не с продвинутыми методами, такими как BERT.
Глава 11. Моделирование для обработки естественного языка 373 Интересно узнать больше о том, как избежать использования машинного обучения в реальных проектах. Можешь привести несколько примеров? При работе над автоматизированными резюме статей мы используем более про- стой экстрактивный подход (https://www.jstage.jst.go.jp/article/pjsai/JSAI2021/0Z JSAI2021_lD20S3a03/article/-char/en), а не метод на основе нейронных сетей (https://www.jstage.jst.go.jP/article/pjsai/JSAI2021/0/JSAI2021_lD40S3c02/ _article/-char/еп). Трудно гарантировать 100% эффективность машинного обучения, поэтому ино- гда предпочтение отдается простым методам, которые легко понять и использо- вать человеку. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, что ты вынес из участия в нем В конкурсе PetFinder.my Adoption Prediction был предоставлен мультимодальный датасет. Многие участники пытались исследовать и использовать все типы дан- ных, и основным подходом было извлечение признаков из изображений и тек- стов, их конкатенация и обучение LightGBM. Я использовал тот же подход. Удивительно, но один из моих товарищей по команде, takuoko (https:// www.kaggle.com/takuok), разработал отличную нейронную сеть, которая обраба- тывает все датасеты от начала и до конца. Хорошо разработанные нейронные се- ти могут превзойти LightGBM в мультимодальных соревнованиях. Этот урок я усвоил в 2019 г. Будет ли этот опыт актуальным и сегодня? Я думаю, что ответ— да. По сравнению с 2019 г. нейронные сети все лучше и лучше справляются с мультимодальными данными. Помог ли тебе Kaggle в карьере? Если да, то как? Да. Kaggle помог мне приобрести большой опыт в анализе данных. Знания в об- ласти машинного обучения, которые я получил в рамках платформы Kaggle, ощутимо помогли мне успешнее работать. Мои достижения в Kaggle и работа в бизнесе стали одной из главных причин, по которым я получил премию ”30 Under 30” и главный приз в 2020 г. от Международной ассоциации новостных СМИ (International News Media Association). Kaggle также позволил мне познако- миться со многими людьми. Эти отношения, безусловно, способствовали моему карьерному росту. Использовал ли ты свои результаты на Kaggle в портфолио для работодателя и как именно? Получал навыки, добивался результатов на соревнованиях, публиковал блокно- ты, книги, информационные бюллетени и т. д. Как ты продвигаешь свои публикации? У меня есть различные каналы связи, и я использую соответствующие инстру- менты для продвижения. Например, Twitter, личные блоги и YouTube.
374 Часть II. Оттачивание соревновательных навыков По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Важность разведочного анализа данных. В области машинного обучения сущест- вует понятие "теорема о бесплатном обеде" (no free lunch theorem, NFL). Мы должны не только изучать алгоритмы, но и учиться решать задачи. Теорема о бесплатном обеде — это утверждение о том, что не существует универсальной модели, которая хорошо справляется со всеми задачами. В соревнованиях по машинному обучению очень важно найти модель, соответ- ствующую характеристикам датасета и задачи, чтобы улучшить свой результат. Какие ошибки ты допускал на соревнованиях? Слишком пристальное внимание уделял публичной таблице лидеров. В соревно- вании по прогнозированию землетрясений от LANL я набрал неплохие очки в публичной таблице лидеров и закончил соревнование на пятом месте. Однако в окончательном рейтинге я занял 211-ю позицию. Это означает, что я слишком сильно верил в ограниченный датасет. Переобучение — очень популярное поня- тие в машинном обучении, и я с болью осознал его важность благодаря Kaggle. Есть ли какой-нибудь конкретный способ избежать переобучения? Важно внимательно следить за тем, как разделены обучающий и оценочный да- тасеты. Я пытаюсь построить набор для валидации, который воспроизводит это разделение. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Мне нравится незаменимая библиотека для работы с табличными датасетами — pandas. Я использую ее для разведочного анализа данных для извлечения, агре- гирования и визуализации. Что ты посоветуешь читателям для освоения pandas? Вы можете ознакомиться с некоторыми учебными пособиями сообщества. Kaggle также предоставляет несколько обучающих курсов по pandas и построению при- знаков. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Иногда я использую японские платформы, такие как Signate, Nishika и т. д. (https://upura.github.io/projects/ data_science_competitions/). Они явно уступают Kaggle по функциональности и UX/UI, но интересно посмотреть на знакомые элементы, например, японский язык. Стратегии аугментации текста В предыдущей главе мы подробно обсудили стратегии аугментации для задач ком- пьютерного зрения. Но аналогичные подходы для текстовых данных — тема менее изученная (о чем свидетельствует отсутствие единого пакета albumentations). В дан-
Глава 11. Моделирование для обработки естественного языка 375 ном разделе мы продемонстрируем некоторые из возможных подходов к решению этой задачи. Основные приемы Как обычно, сначала полезно рассмотреть основные подходы, сосредоточившись на случайных изменениях и работе с синонимами. Систематическое исследование ос- новных подходов представлено в статье, написанной Вей (Wei) и Цзоу (Zou) в 2019 г.: https://arxiv.org/abs/1901.11196. Мы начнем с замены синонимов. При замене некоторых слов их синонимами по- лучается текст, близкий по смыслу к оригиналу, но слегка искаженный (см. страни- цу проекта по адресу https://wordnet.princeton.edu/, если вас интересуют подроб- ности, например, о том, откуда на самом деле берутся синонимы): def get_synonyms(word): synonyms = set() for syn in wordnet.synsets(word): for 1 in syn.lemmas(): synonym = l.name().replace("_", " ").replace" ").lower() synonym = join([char for char in synonym if char in 'qwertyuiopasdfghjklzxcvbnm']) synonyms.add(synonym) if word in synonyms: synonyms.remove(word) return list(synonyms) Мы создаем простую обертку вокруг рабочей функции, определенной выше, ука- зывая фрагмент текста (строку, содержащую несколько слов) и заменяя не более п слов: def synonym_replacement(words, n): words = words.split() new_words = words.copy() random_word_list = list(set([word for word in words if word not in stop_words])) random.shuffle(random_word_list) num_replaced = 0 for random_word in random_word_list: synonyms = get_synonyms(random_word)
376 Часть II. Оттачивание соревновательных навыков if len(synonyms) >= 1: synonym = random.choice(list(synonyms)) new_words = [synonym if word == random_word else word for word in new_words] num_replaced += 1 if num_replaced >= n: # Заменять только до n слов break sentence = ' '.join(new_words) return sentence Давайте посмотрим, как эта функция работает на практике: print(f" Example of Synonym Replacement: {synonym_replacement('The quick brown fox jumps over the lazy dog',4)}") Example of Synonym Replacement: The spry brown university fox jumpstart over the lazy detent Такой ответ нельзя назвать шекспировским, но он передает то же послание, замет- но меняя стиль.1 Можно расширить этот подход, создавая несколько новых пред- ложений в каждом твите: trial_sent = data['text'][25] print(trial_sent) the free fillin' app on my ipod is fun, im addicted for n in range(3): print(f" Example of Synonym Replacement: {synonym_replacement(trial_sent,n)}") Example of Synonym Replacement: the free fillin' app on my ipod is fun, im addict Example of Synonym Replacement: the innocent fillin' app on my ipod is fun, im addicted Example of Synonym Replacement: the relinquish fillin' app on my ipod is fun, im addict 1 Исходная фраза переводится как "Быстрая бурая лиса перепрыгивает через ленивую собаку", сино- нимичная фраза — "Резвый лис из университета Брауна сделал рывок вперед, преодолев ленивое пре- пятствие". — Прим. ред.
Глава 11. Моделирование для обработки естественного языка 377 Как видите, генерировать варианты фрагмента текста с помощью синонимов до- вольно просто. Далее, замена — это простой и эффективный метод. Мы создаем новое предложе- ние, меняя порядок слов в тексте случайным образом. При осторожном применении такой подход можно рассматривать как потенциаль- но полезную форму регуляризации, поскольку она нарушает последовательный характер данных, на который опираются модели типа LSTM. Первым шагом будет определение функции, меняющей слова местами: def swap__word(new_words): random_idx_l = random.randint(0, len(new_words)-l) random_idx_2 = random_idx_l counter = 0 while random_idx_2 == random_idx_l: random_idx_2 = random.randint(0, len(new_words)-l) counter += 1 if counter > 3: return new_words new_words[random_idx_l], new_words[random_idx_2] = new_words[random_idx_2], new_word s[random_idx_l] return new_words Затем мы напишем обертку вокруг этой функции: # п - количество cnoQj которые нужно поменять местами def random_swap(words, n): words = words.split() new_words = words.copy() for _ in range(n): new_words = swap_word(new_words) sentence = ' '.join(new_words) return sentence Синонимы и замена не влияют на длину изменяемого предложения. Если в кон- кретном случае понадобится подкорректировать этот признак, мы можем удалить слова из предложения или, наоборот, добавить их.
378 Часть II. Оттачивание соревновательных навыков В первом случае наиболее распространенным способом реализации можно считать случайное удаление слов: def random_deletion(words, p): words = words.split() # Очевидноj что если есть только одно слово, его удалять не следует if len(words) == 1: return words # Случайное удаление слов с вероятностью р new_words = [] for word in words: r = random.uniform(0, 1) if r > p: new__words. append (word) # Если в итоге вы удалите все слова, просто верните случайное слово if len(new_words) == 0: rand_int = random.randint(0, len(words)-l) return [words[rand_int]] sentence = ' '.join(new_words) return sentence Рассмотрим несколько примеров: print(random_deletion(trial_sent,0.2)) print(random_deletion(trial_sent,0. 3)) print(random_deletion(trial_sent,0.4)) the free fillin' app on my is fun, addicted free fillin’ app on my ipod is im addicted the free on my ipod is fun, im
Глава 11. Моделирование для обработки естественного языка 379 Если есть возможность удалять слова, разумеется, должна быть и возможность их добавлять: случайную вставку слов в предложение можно рассматривать как экви- валент NLP — добавление шума или размытия к изображению: def random_insertion(words, n): words = words.split() new_words = words.copy() for _ in range(n): add_word(new_words) sentence = ' '.join(new_words) return sentence def add_word(new_words): synonyms = [] counter = 0 while len(synonyms) < 1: random_word = new_words[random.randint(0, len(new_words)-l)] synonyms = get_synonyms(random_word) counter += 1 if counter >= 10: return random_synonym = synonyms[0] random_idx = random.randint(0, len(new_words)-l) new_words.insert(random_idx, random_synonym) А вот функция в действии: print(random_insertion(trial_sent,l)) print(random_insertion(trial_sent,2)) print(random_insertion(trial_sent,3)) the free fillin' app on my addict ipod is fun, im addicted the complimentary free fillin' app on my ipod along is fun, im addicted the free along fillin' app addict on my ipod along is fun, im addicted Мы можем объединить все рассмотренные выше преобразования в одну функцию, получив четыре варианта одного и того же предложения: def aug(sent,n,p): print(f" Original Sentence : {sent}")
380 Часть II. Оттачивание соревновательных навыков print(f" SR Augmented Sentence print(f" RD Augmented Sentence print(f" RS Augmented Sentence print(f" RI Augmented Sentence {synonym_replacement(sent,n)}") {random_deletion(sent,p)}") {random_swap(sent,n)}") {random_insertion(sent,n)}") aug(trial_sent,4,0.3) Original Sentence : the free fillin' app on my ipod is fun, im addicted SR Augmented Sentence : the disembarrass fillin' app on my ipod is fun, im hook RD Augmented Sentence : the free app on my ipod fun, im addicted RS Augmented Sentence : on free fillin' ipod is my the app fun, im addicted RI Augmented Sentence : the free fillin' app on gratis addict my ipod is complimentary make up fun, im addicted Рассмотренные выше методы аугментации не используют структуру текстовых данных; вот пример: даже анализ такой простой характеристики, как "часть речи", может помочь нам построить более полезные преобразования исходного текста. Именно на этом подходе мы сейчас и сосредоточимся. Пакет nlpaug В заключение этого раздела мы продемонстрируем возможности, предоставляемые пакетом nlpaug (https://github.com/makcedward/nlpaug). Он объединяет различные методы аугментации текста и разработан как легкий и простой для включения в рабочий поток. Далее мы представим некоторые примеры функциональности, со- держащейся в нем. ! pip install nlpaug Импортируем аугментаторы уровня символов и слов, которые будем использовать для подключения конкретных методов: import nlpaug.augmenter.char as пас import nlpaug.augmenter.word as naw test_sentence = "I genuinely have no idea what the output of this sequence of words will be - it will be interesting to find out what nlpaug can do with this!" Что произойдет, если мы применим имитацию опечатки к тестовому предложе- нию? Это преобразование может быть параметризовано несколькими способами — для получения полного списка параметров и их объяснений предлагаю читателю изу- чить официальную документацию: https://nlpaug.readthedocs.io/en/latest/augmenter/ char/keyboard.html.
Глава 11. Моделирование для обработки естественного языка 381 aug = па с keyboard Aug (name=‘Key boa rd-Aug', aug_char_min=l, aug_char_max=10J aug_char_p=0.3, augu_word_p=0.3, aug_word_min=l, aug_word_max=10, stopwords=None, tokenizer=None, reverse_tokeni/er=None, include_special_char=True, include_numeric=True, include_upper_case=True, lang='en', verbose=0, stopwords_regex=None, model_path=None, min_char=4) test_sentence_aug = aug.augment(test_sentence) print(test_sentence) print(test_sentence_aug) Результат будет таким: I genuinely have no idea what the output of this sequence of words will be - it will be interesting to find out what nlpaug can do with this! I geb&ine:y have no kdeZ qhQt the 8uYput of tTid sequsnDr of aorVs will be - it wi,k be jnterewtlHg to find out what nlpaug can do with this! Можно смоделировать ошибку оптического распознавания текста (OCR), вкрав- шуюся во входные данные: aug = nac.OcrAug(name='OCR_Aug', aug_char_min=l, aug_char_max=10, aug_char_p=0.3, aug_word_p=0.3, aug_word_min=l, aug_word_max=10, stopwords=None, tokenizer=None, reverse_tokenizer=None, verbose=0, stopwords_regex=None, min_char=l) test_sentence_aug = aug.augment(test_sentence) print(test_sentence) I print(test_sentence_aug) Получаем: I genuinely have no idea what the output of this sequence of words will be - it will be interesting to find out what nlpaug can do with this! I 9enoinely have no idea what the ootpot of this sequence of wokd8 will be - it will be inteke8tin9 to find out what nlpaug can du with this! Несмотря на свою полезность, возможности преобразования на уровне символов очень ограничены с точки зрения творческого изменения данных. Давайте узнаем,
382 Часть II. Оттачивание соревновательных навыков какие возможности предлагает пакет nlpaug, когда речь идет о модификациях на уровне слов. Наш первый пример — замена фиксированного процента слов их ан- тонимами: aug = naw.AntonymAug(name=,Antonym_Aug', aug_min=l, aug_max=10, aug p=0.3, lang='eng,J stopwords=None, tokenizer=None, reverse_tokenizer=None, stopword s_regex=None.> verbose=0) test_sentence_aug = aug.augment(test_sentence) print(test_sentence) print(test_sentence_aug) Получаем: I genuinely have no idea what the output of this sequence of words will be - it will be interesting to find out what nlpaug can do with this! I genuinely lack no idea what the output of this sequence of words will differ - it will differ uninteresting to lose out what nlpaug can unmake with this! nlpaug также предлагает нам возможность, например, заменять синонимы; такие преобразования можно осуществить и с помощью более базовых методов, рассмот- ренных ранее. Для полноты картины ниже мы продемонстрируем небольшой при- мер, в котором используется архитектура BERT: aug = naw.ContextualWordEmbsAug(modelj3ath=,bert-base-uncased', model_type='', action='substitute', # temperature=1.0j top_k=100, # top__p=NoneJ name='ContextualWordEmbs_Aug', aug_min=l, aug_max=10, aug p=0.3, stopwords=None, device='cpu', force_reload=False, # optimize=Nonej stopwords_regex=None, verbose=0, silence=True) test_sentence_aug = aug.augment(test_sentence) print(test_sentence) print(test_sentence_aug)
Глава 11. Моделирование для обработки естественного языка 383 Результат будет таким: I genuinely have no idea what the output of this sequence of words will be - it will be interesting to find out what nlpaug can do with this! i genuinely have no clue what his rest of this series of words will say - its will seemed impossible to find just what we can do with this! Как видите, пакет nlpaug предлагает широкий спектр возможностей для изменения вводимого текста с целью создания аугментаций. Какие из них следует выбрать, во многом зависит от контекста, и для принятия решения требуется немного знаний о домене, подходящих для конкретного приложения. Для дальнейшего изучения этой темы можно использовать конкурсы для начинающих, такие как Natural Language Processing with Disaster f Tweets (https://www.kaggle.eom/c/nlpgetting-started), а также промежу- VV точные или более продвинутые, например igsaw Rate Severity of Toxic z>4 Comments (https://www.nkaggle.com/c/jigsaw-toxicseverity-rating) или Google QUEST Q&A Labeling (https://www.kaggle.com/c/google-quest- challenge). Во всех этих случаях nlpaug широко использовалась, в том числе и в призовых решениях. Резюме В этой главе мы обсудили моделирование для соревнований NLP. Показали как "винтажные", так и современные методы, применяемые для решения разнообраз- ных задач, возникающих на конкурсах Kaggle. Кроме того, мы затронули часто иг- норируемую тему аугментации текста. В следующей главе мы обсудим конкурсы по моделированию — новый класс со- ревнований, набирающий популярность в последние несколько лет. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
12 Соревнования по моделированию и оптимизации Обучение с подкреплением (reinforcement learning, RL) представляет собой инте- ресный случай среди различных ветвей машинного обучения. С одной стороны, он довольно требователен с технической точки зрения: различные интуитивные реше- ния из обучения с учителем не работают, и соответствующий математический ап- парат является довольно продвинутым. С другой стороны, его легче всего объяс- нить постороннему человеку или неспециалисту. Простая аналогия: вы учите своего питомца (я намеренно стараюсь избегать дискуссии о собаках и кошках) вы- полнять трюки — вы даете лакомство за хорошо выполненный трюк, а в противном случае лишаете его вознаграждения. Обучение с подкреплением было поздним гостем в соревновательной тусовке на Kaggle, но ситуация изменилась за последние несколько лет с появлением конкур- сов по моделированию. В этой главе мы расскажем об этой новой и захватывающей части вселенной Kaggle. К настоящему времени — на момент написания книги — были проведены четыре конкурса в категории Featured (Избранные) и два в катего- рии Playground (Песочница). Этот список, хотя, конечно, и не очень внушительный, позволяет нам провести широкий обзор темы. В этой главе мы продемонстрируем решения задач, представленных в нескольких соревнованиях по моделированию: • начнем с игры Connect X; • далее рассмотрим игру "Камень, ножницы, бумага", для проектирования ко- торой показан двойной подход к созданию конкурентоспособного агента; • затем представим решение, основанное на многоруких бандитах, для конкур- са Santa\ • в заключение сделаем обзор остальных соревнований, которые немного вы- ходят за рамки этой главы.
Глава 12. Соревнования по моделированию и оптимизации 385 Если обучение с подкреплением — для вас концепция совершенно новая, вероятно, будет неплохо сначала получить некоторые базовые знания. Очень хорошим спосо- бом начать RL-приключение может стать учебный курс Kaggle, посвященный именно этой теме в контексте игрового искусственного интеллекта (https:// www.kaggle.com/learn/intro-to-game-ai-and-reinforcement-learning). Курс знако- мит с основными понятиями, такими как агенты и политики, а также обеспечивает (аварийное) введение в глубокое обучение с подкреплением. Во всех примерах кур- са используются данные соревнования Connect X в категории Playground (Песочни- ца), цель которого — обучение агента, способного обнаруживать фишки, выстро- енные в линию (https://www.kaggle.eom/c/connectx/overview). В более общем плане стоит отметить, что важным аспектом соревнований по моде- лированию и оптимизации является среда: в силу самой природы задачи ваше ре- шение должно обладать более динамичными характеристиками, чем просто пред- ставление набора чисел (как это было бы в случае "обычных" соревнований по обучению с учителем). Очень информативное и подробное описание среды, ис- пользуемой в соревнованиях по моделированию, можно найти на странице https://github.com/Kaggle/kaggle-environments/blob/master/README.md. Игра Connect X В этом разделе мы продемонстрируем, как можно подойти к решению простой за- дачи игры в шашки с помощью эвристики. Хотя это и не решение для глубокого обучения, мы считаем, что такое "голое" изложение концепций гораздо полезнее для людей без серьезного предварительного знакомства с RL. Если вы новичок в концепции использования искусственного интеллекта для на- стольных игр, то презентация Тома ван де Виле (Tom van de Wiele, https:// www.kaggle.com/tvdwiele) — это ресурс, который стоит изучить: https://tinyurl.com/ 36rdv5sa. Цель игры Connect X состоит в том, чтобы выстроить определенное количество (X) своих фишек в ряд — по горизонтали, вертикали или диагонали — на игровом поле раньше соперника (рис. 12.1). Игроки выполняют ход, сбрасывая свои фиш- ки в один из столбцов в верхней части доски. Это означает, что каждый ход мо- жет быть направлен на достижение вашей победы или на то, чтобы помешать по- беде противника. Игра Connect X была первым соревнованием, в котором были продемонстрированы агенты: вместо статичного представления (или блокнота, который оценивался по невидимому датасету) участники должны были представить агентов, способных играть в игру против других. Оценка проводилась поэтапно: 1. После загрузки проект играет сам с собой, чтобы убедить наблюдателя, что он работает правильно. 2. Если этот эпизод проверки прошел успешно, присваивается рейтинг мастерст- ва, и заявленный проект вступает в ряды всех конкурентов.
386 Часть II. Оттачивание соревновательных навыков 3. Ежедневно разыгрывается несколько эпизодов для каждого заявленного проек- та, и впоследствии рейтинги корректируются. Рис. 12.1. Доска Connect X Исходя из этого, давайте перейдем к демонстрации того, как заявить проект на уча- стие в соревновании Connect X. Представленный нами код предназначен для значе- ния X = 4, но может быть легко адаптирован для других значений или переменной X. Сначала установим пакет Kaggle environments: !pip install kaggle-environments --upgrad Определим среду, в которой будет оцениваться наш агент: from kaggle_environments import evaluate, make env = make("connectx", debug=True) env.render() Хотя часто возникает желание попробовать сложные методы, полезно начать с про- стого— как мы это сделаем здесь, используя простую эвристику. В сопроводи- тельном коде они объединены в одну функцию, но для наглядности мы опишем их по одной. Первое правило — проверка, есть ли у кого-либо из игроков шанс соединить четы- ре фишки по вертикали, и если есть, происходит возврат позиции, на которой это
Глава 12. Соревнования по моделированию и оптимизации 387 возможно. Мы можем достичь этого, используя в качестве входного аргумента про- стую переменную, способную принимать два возможных значения, указывая, воз- можности какого игрока анализируются: def my_agent(observation, configuration): from random import choice # me:me_or_enemy=lJ enemy:me_or_enemy=2 def check_vertical_chance(me_or_enemy): for i in range(0, 7): if observation.board[i+7*5] == me_or_enemy \ and observation.board[i+7*4] == me_or_enemy \ and observation.board[i+7*3] == me_or_enemy \ and observation.board[i+7*2] == 0: return i elif observation.board[i+7*4] == me_or_enemy \ and observation.board[i+7*3] == me_or_enemy \ and observation.board[i+7*2] == me_or_enemy \ and observation.board[i+7*l] == 0: return i elif observation.board[i+7*3] == me_or_enemy \ and observation.board[i+7*2] == me_or_enemy \ and observation.board[i+7*l] == me_or_enemy \ and observation.board[i+7*0] == 0: return i # шансов нет return -99 Мы можем определить аналогичный метод для шансов по горизонтали: def check_horizontal_chance(me_or_enemy): chance_cell_num = -99 for i in [0,7,14,21,28,35]: for j in range(0, 4): val_l = i+j+0 val_2 = i+j+1 val_3 = i+j+2 val_4 = i+j+3 if sum([observation.board[val_l] == me_or_enemy, \
388 Часть II. Оттачивание соревновательных навыков observation.board[val_2] == me_or_enemy, \ observation.board[val_3] == me_or_enemy, \ observation.board[val_4] == me_or_enemy]) == 3: for к in [val_l,val_2,val_3,val_4]: if observation.board[k] == 0: chance_cell_num = к # нижняя линия for 1 in range(35, 42): if chance_cell_num == 1: return 1-35 # другие if observation.board[chance_cell_num+7] != 0: return chance_cell_num % 7 # шансов нет return -99 Повторяем тот же подход для диагональных комбинаций: # me:me_or_enemy=lj епету:те_ог_епету=2 def check_slanting_chance(me_or_enemy, lag, cell_list): chance_cell_num = -99 for i in cell_list: val_l = i+lag*0 val_2 = i+lag*l val_3 = i+lag*2 val_4 = i+lag*3 if sum([observation.board[val_l] == me_or_enemy, \ observation.board[val_2] == me_or_enemy, \ observation.board[val_3] == me_or_enemy, \ observation.board[val_4] == me_or_enemy]) == 3: for j in [val_l,val_2,val_3,val_4]: if observation.board[j] == 0: chance_cell_num = j # нижняя линия for к in range(35, 42): if chance_cell_num == k: return к - 35
Глава 12. Соревнования по моделированию и оптимизации 389 # другие if chance_cell_num != -99 \ and observation.board[chance_cell_num+7] != 0: return chance_cell_num % 7 # шансов нет return -99 Можно объединить логику в одну функцию, проверяющую возможности (игра про- тив соперника): def check_my_chances(): # проверка шансов по вертикали result = check_vertical_chance(my_num) if result != -99: return result # проверка шансов no горизонтали result = check_horizontal_chance(my_num) if result != -99: return result # проверка шанса no диагонали 1 (справа-сверху вниз-влево) result = check_slanting_chance(my_num, 6, [3,4,5,6,10,11,12,13,17,18,19,20]) if result != -99: return result # проверка шанса no диагонали 2 (сверху-слева вниз-вправо) result = check_slanting_chance(my_num, 8, [0,1,2,3,7,8,9,10,14,15,16,17]) if result != -99: return result # шансов нет return -99 Эти блоки составляют основу логики. Несмотря на некоторую громоздкость фор- мулировок, они представляют собой полезное упражнение в преобразовании ин- туиции в эвристику, которую можно использовать в агенте, участвующем в игре. Полное определение агента в этом примере см. в сопроводительном коде в репозитории.
390 Часть II. Оттачивание соревновательных навыков Производительность нового агента можно оценить в сравнении с предварительно определенным агентом, например случайным: env.reset() env.run([my_agent, "random"]) env.render(mode="ipython", width=500, height=450) Приведенный выше код показывает, как создать решение с нуля для относительно простой задачи (есть причина, по которой Connect X относится к соревнованию ка- тегории Playgroun, а не к Featured). Интересно, что с этой простой проблемой мож- но справиться с помощью (почти) самых современных методов, таких как AlphaZero: https://www.kaggle.com/connect4alphazero/alphazero-baseline-connectx. Когда вводный пример позади, вы должны быть готовы погрузиться в более слож- ные (или, в любом случае, не основанные на игрушечных примерах) соревнования. Игра "Камень, ножницы, бумага" Не случайно несколько задач в соревнованиях по моделированию относятся к иг- рам: на разных уровнях сложности игры предлагают среду с четко определенными правилами, что естественным образом соответствует схеме "агент — действие — вознаграждение". Не считая игры крестики-нолики, соединение фишек — один из самых простых примеров соревновательной игры. Продвинемся вверх по лестнице сложности (игр) и рассмотрим игру "Камень, ножницы, бумага" и обсудим, как можно подойти к соревнованию Kaggle, основанному на этой игре. Идея конкурса Rock, Paper, Scissors ("Камень, ножницы, бумага") (https:// www.kaggle.com/c/rock-paperscissors/code)— это расширение базовой игры "Ка- мень, ножницы, бумага" (известной в некоторых частях света как "рошамбо"): вме- сто обычного счета "лучший из трех", мы используем "лучший из 1000". Опишем два возможных подхода к этой задаче: один основан на теоретико-игровом подходе, а другой больше сосредоточен на алгоритмической стороне. Мы начнем с равновесия Нэша. Википедия дает определение этого понятия как решения некооперативной игры с участием двух или более игроков, где предпола- гается, что каждый игрок знает равновесные стратегии остальных, и ни один игрок не может получить преимущество, изменив только собственную стратегию. —Отличное введение в игру "Камень, ножницы, бумага" в рамках теории игр можно найти здесь: https://www.youtube.com/watch7v-lGDMXoMdaY. Обозначим наших игроков как красных и синих, каждая ячейка в матрице выход- ных данных показывает результат данной комбинации ходов (рис. 12.2).
Глава 12. Соревнования по моделированию и оптимизации 391 Рис. 12.2. Матрица расчетов для игры "Камень, ножницы, бумага" Например, если оба агента выбрасывают Камень (левая верхняя клетка), оба полу- чают 0 очков; если синий выбрасывает Камень, а красный— Бумагу (клетка во втором столбце первой строки), красный выигрывает— таким образом, красный получает +1 очко, а синий---1 очко. Если мы сыграли каждое действие с равной вероятностью 1/3, то и противник дол- жен сделать то же самое; иначе если игроки все время будут выбрасывать Камень, они сыграют вничью с Камнем, проиграют Бумаге и выиграют у Ножниц — каж- дый с вероятностью 1/3 (или одну треть времени). Ожидаемое вознаграждение в этом случае равно 0, и тогда мы можем изменить стратегию на использование Бу- маги и постоянно выигрывать. Те же рассуждения можно провести для стратегий ’’Бумага против ножниц” и ’’Ножницы против камня”, для которых мы не будем по- казывать матрицу выходных данных, чтобы не перегружать текст информацией. Оставшийся вариант равновесия заключается в том, что оба игрока должны играть по случайной стратегии — это и есть равновесие Нэша. На основе этой идеи можно построить своего агента: %%writefile submission.ру import random def nash_equilibrium_agent(observation, configuration): return random. randint(0_, 2) Волшебство в самом начале (запись из блокнота прямо в файл) необхо- димо для того, чтобы удовлетворить ограничения на подачу материала в этом конкретном соревновании.
392 Часть II. Оттачивание соревновательных навыков Как наш агент Нэш ведет себя на фоне других? Можно выяснить это, оценив про- изводительность : !pip install -q -U kaggle_environments from kaggle_environments import make На момент написания книги после этого импорта появлялась ошибка (Failure to load a module named ’gfootball’ — Ошибка при загрузке модуля под названием ’gfootball’). Официальный совет Kaggle — игно- рировать ее. На практике этот сбой не оказывает никакого влияния на выполнение кода. Начинаем с создания среды ’’Камень, ножницы, бумага’’ и устанавливаем ограниче- ние в 1000 эпизодов на симуляцию: env = make( "грз", configuration^"episodeSteps": 1000} ) Будем использовать созданный в этом соревновании блокнот, в котором реализова- но множество агентов, основанных на детерминированной эвристике (https://www.kaggle.com/ilialar/multi-armed-banditvs-deterministic-agents), и им- портировать оттуда код для агентов, с которыми мы соревнуемся: %%writefile submission_copy_opponent.ру def copy_opponent_agent(observation? configuration): if observation.step > 0: return observation.lastOpponentAction else: return 0 # агент nash_equiLibrium_agent играет против агента copy_opponent_agent env.run( ["submission.py", "submission_copy_opponent.py"] ) env.render(mode="ipython", width=500, height=400)
Глава 12. Соревнования по моделированию и оптимизации 393 После выполнения предыдущего блока и запуска среды мы сможем наблюдать анимированное табло для 1000 эпох. Снимок экрана приведен на рис. 12.3. Player 1 Player 2 Action: 2 2 Name: Scissors Scissors Icon: Л Result: Tie Reward: 5 -5 > 160/1000 Рис. 12.3. Снимок из визуализированной среды, оценивающий производительность агента В обучении с учителем — как классификации, так и регрессии — часто полезно начинать решение любой проблемы с простого подхода, например с линейной мо- дели. Даже если такое решение не будет передовым, оно может обеспечить полез- ное ожидание и меру эффективности. В обучении с подкреплением действует ана- логичная идея. В этом качестве стоит испытать работу многорукого бандита — самого простого алгоритма, который можно честно назвать RL. В следующем раз- деле мы продемонстрируем, как этот подход можно использовать в соревнованиях по моделированию. Соревнование Santa 2020 За последние несколько лет на Kaggle сложилась своеобразная традиция: в начале декабря проводится соревнование на тему Санты. Фактическая алгоритмическая сторона меняется из года в год, но для наших целей соревнование 2020 г. представ- ляет собой интересный случай: https://www.kaggle.eom/c/santa-2020. Установка представляла собой классического многорукого бандита (multi-armed bandit, МАВ), пытающегося максимизировать вознаграждение путем повторного действия на игровом автомате, но с двумя дополнениями: • снижение вознаграждения — на каждом шаге вероятность получения воз- награждения от автомата уменьшается на 3%; • соревнование — вы ограничены не только временем (лимитированное коли- чество попыток), но и присутствием другого игрока, пытающегося достичь
394 Часть II Оттачивание соревновательных навыков той же цели. Мы упоминаем это ограничение в основном для полноты карти- ны, поскольку оно не является критичным для явного включения в наше де- монстрационное решение. Хорошее объяснение методов подхода к общей проблеме МАВ приве- дено в следующей статье: https://lilianweng.github.io/lil-log/2018/01/23/ the-multi-armed-bandit-problem-and-its-solutions.html. Решение, которое мы приведем, адаптировано из https://www.kaggle.com/ ilialar/simple-multiarmed-bandit, кода от Ильи Ларченко (https://www.kaggle.com/ ilialar). Наш подход основан на последовательном обновлении распределения воз- награждения: на каждом шаге мы генерируем случайное число из бета- распределения с параметрами (а + 1, b + 1), где: • а — общее вознаграждение от этого рычага (количество побед); • b — статистическое количество проигрышей. Когда нам нужно решить, за какой рычаг аппарата потянуть, мы выбираем рычаг с наибольшим сгенерированным числом и используем его для формирования сле- дующего шага; наше дальнейшее распределение рычагов становится предшест- вующим для очередного шага. На рис. 12.4 показана форма плостности вероятности бета-распределения для раз- личных пар значений (а, Ь). Рис. 12.4. Форма плотности вероятности бето-роспределения для различных комбинаций параметров (о, Ь)
Глава 12. Соревнования по моделированию и оптимизации 395 Как видите, изначально распределение плоское (Beta(0,0) — равномерное), но по мере того, как мы собираем больше информации, оно концентрирует массу вероят- ности вокруг состояния. Это означает, что неопределенность меньше, и мы более уверены в своем суждении. Можно включить снижение вознаграждения в зависи- мости от конкуренции, уменьшая параметр а каждый раз, когда используется рычаг. Мы начинаем создание агента с написания файла представления. Сначала импор- тируем необходимые модули и инициализируем переменные: %%writefile submission.ру import json import numpy as np import pandas as pd bandit_state = None total_reward = 0 last_step = None Определяем класс, характеризующий агента МАВ. Для того чтобы вы узрели кар- тину целиком, воспроизведем весь код и добавим пояснения в комментарии внутри него: def multi_armed_bandit_agent (observation, configuration): global history, history_bandit step = 1.0 # баланс разведка/эксплуатация decay_rate =0.97 # на сколько мы уменьшаем количество побед # после каждого вызова global bandit_state,total_reward,last_step if observation.step == 0: # начальное состояние бандита bandit_state = [[1,1] for i in range(configuration["banditCount"])] else: # обновление переменной bandit_state с использованием # результата предыдущего шага last_reward = observation["reward"] - total_reward total_reward = observation["reward"] # нам нужно понятьj кто мы - Игрок 1 или Игрок 2?
396 Часть IL Оттачивание соревновательных навыков player = int(last_step == observation.lastActions[1]) if last_reward > 0: bandit_state[observation.lastActions[player]][0] += last_reward * step else: bandit_state[observation.lastActions[player]][1] += step bandit_state[observation.lastActions[0]][0] = (bandit_state[observation.lastActions[0]][0] - 1) * decay_rate + 1 bandit_state[observation.lastActions[1]][0] = (bandit_state[observation.lastActions[l]][0] - 1) * decay_rate + 1 # генерируем случайное число из распределения Beta для каждого агента # и выбираем наиболее удачливого из них best_proba = -1 best_agent = None for к in range(configuration["banditCount”]): proba = np.random.beta(bandit_state[k][0],bandit_state[k][1]) if proba > best_proba: best_proba = proba best_agent = к last_step = best_agent return best_agent Как вы можете видеть, основная логика функции представляет собой простую реа- лизацию алгоритма МАВ. Корректировка, специфичная для нашего соревнования, происходит в переменной bandit_stat, где мы применяем множитель затухания. Как и в предыдущем случае, теперь мы готовы оценить работу нашего агента в ус- ловиях соревнования. Приведенный ниже фрагмент кода демонстрирует, как это можно реализовать: %%writefile random_agent.ру import random def random_agent(observation> configuration): return random.randrange(configuration.banditCount)
Глава 12. Соревнования по моделированию и оптимизации 397 from kaggle_environments import make env = такеС’таЬ’’^ debug=True) env.reset() env.run([”random_agent.py", ”submission.py"]) env.render(mode=,,ipython”J width=800, height=700) В результате увидим нечто подобное рис. 12.5. । Left / Right Arrow Increase / Decrease 0-9 Row Keys. Playback Space Pause ! Adversarial Multi-armed Step Speed Play Bandit Player 1 Player 2 Action: 2 42 Result: Win Reward: 261 342 и 681 / 2000 Рис. 12.5. Снимок экрана из визуализированной среды, оценивающий работу агента В этом разделе вы увидели, как старинный алгоритм многорукого бандита можно использовать в соревновании симуляторов на Kaggle. Хотя это и полезно в качестве отправной точки, все-таки оказалось недостаточным для попадания в медальную зону таблицы лидеров, где подходы глубокого обучения с подкреплением были бо- лее популярны. Далее мы обсудим подходы, основанные на других методах, в разнообразных со- ревнованиях. Такие разные игры Помимо относительно элементарных игр, о которых говорилось выше, соревнова- ния по моделированию включают в себя более сложную организацию. В этом раз- деле мы кратко их обсудим. Первым примером послужит Halite, определение кото- рого дано на странице соревнования (https://www.kaggle.eom/c/halite) следующим образом:
398 Часть II. Оттачивание соревновательных навыков Halite [...] это игра по управлению ресурсами, в которой вы строите небольшую армаду кораблей и управляете ими. Ваши алгоритмы опреде- ляют их движения для сбора галита (halite) — источника светящейся энергии. Побеждает тот, у кого в конце матча больше всего галита, но именно от вас зависит, как сделать эффективные и действенные ходы. Вы управляете своим флотом, строите новые корабли, создаете верфи и добываете возобновляющийся галит на игровом поле. Игра выглядит так, как представлено на рис. 12.6. Рис. 12.6. Игровое поле Halite Kaggle организовал два соревнования по этой игре: в категории Playground (https://www.kaggle.eom/c/halite-iv-playground-edition), а также обычный Featured (https://www.kaggle.eom/c/halite). Классический подход к обучению с подкрепле- нием был менее полезен в данном случае, поскольку при произвольном количестве юнитов (кораблей/баз) и динамическом пуле противников задача назначения очков становилась неразрешимой для людей с доступом к ’’нормальному” уровню вычис- лительных ресурсов. Объяснение задачи начисления очков в полном объеме выходит за рамки данной книги, но заинтересованному читателю рекомендуется начать со статьи в Википедии (https://en.wikipedia.org/wiki/ Assignmentjproblem), а в продолжение изучить замечательную ввод- ную статью Т. Меснарда и др.: https://proceedings.mlr.press/vl39/ mesnard21a.html.
Глава 12. Соревнования по моделированию и оптимизации 399 Описание победившего решения от Тома ван де Виле (https://www.kaggle.com/ c/halite/discussion/183543) содержит отличный обзор модифицированного подхода, который оказался успешным в данном случае (глубокое RL с независимым количе- ством очков по каждому юниту). Другим соревнованием, включающим относительно сложную игру, был конкурс LuxAI (https://www.kaggle.eom/c/lux-ai-2021). В нем участникам было поручено разработать агентов для решения многовариантной оптимизационной задачи, соче- тающей сбор и распределение ресурсов, соревнуясь с другими игроками. Кроме того, успешные агенты должны были анализировать ходы своих противников и реагировать соответствующим образом. Интересной особенностью этого соревно- вания стала популярность "метаподхода": имитационное обучение (https:// paperswithcode.com/task/imitation-learning). Это довольно новый подход в сфере RL, ориентированный на обучение политике поведения на основе демонстрации — без конкретной модели для описания генерации пар "состояние — действие". Кон- курентная реализация этой идеи (на момент написания книги) представлена поль- зователем Ironbar в Kaggle (https://www.kaggle.eom/c/lux-ai-2021/discussion/293911). Наконец, ни одно обсуждение соревнований по моделированию в Kaggle не будет полным без упоминания конкурса Google Research Football with Manchester City F. C. (https://www.kaggle.eom/c/googlefootball/overview). Мотивация в нем заключалась в том, чтобы исследователи изучили способность агентов искусственного интеллекта играть в сложных условиях, таких как футбол. В разделе Overview (Обзор соревнований) задача формулируется следующим образом: Этот вид спорта требует баланса краткосрочного контроля, вы- ученных понятий, таких как пас, и стратегии высокого уровня, чему бывает трудно научить агентов. В настоящее время существует среда для обучения и тестирования агентов, но другие решения мо- гут предложить лучшие результаты. В отличие от некоторых примеров, приведенных выше, в этом соревновании доми- нировали подходы обучения с подкреплением: • команда Raw Beast (3-е место) следовала методике, вдохновленной AlphaStar. https://www.kaggle. com/c/google-football/discussion/200709; • в команде Salty Fish (2-е место) использовали форму самостоятельной игры: https://www.kaggle.eom/c/google-football/discussion/202977; • победители соревнования— команда WeKick— использовали решение на основе глубокого обучения с творческим подходом к построению признаков и настройке структуры вознаграждения: https://www.kaggle.eom/c/google~ football/discussion/202232.
400 Часть II. Оттачивание соревновательных навыков Изучение приведенных выше решений является отличной отправной точкой для понимания того, как RL можно использовать для решения этого класса задач. Фират Гонен https://www.kaggle.com/frtgnn Для интервью в этой главе мы поговорили с Фиратом Го- неном, трехкратным гроссмейстером в категориях Datasets, Notebooks и Discussion, а также глобальным послом HP в области науки о данных (HP Data Science Global Ambassa- dor). Он рассказывает нам о своем подходе к решению за- дач Kaggle и о том, как со временем менялось его отноше- ние к ним. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Мой любимый вид соревнований эволюционировал со временем. Раньше я пред- почитал очень общие табличные соревнования, где для освоения тенденций дос- таточно хорошего блокнота и некоторого терпения. Мне казалось, что раньше я мог четко видеть отклоняющиеся тенденции между обучающими и тестовыми наборами. Со временем, став глобальным послом HP в области науки о данных (HP Data Science Global Ambassador) и получив оборудование для моей рабочей станции, я как бы переключился на соревнования по компьютерному зрению, хо- тя мне еще многому предстоит научиться. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Обычно я предпочитаю отложить часть моделирования на как можно более позднее время. Лучше потратить это время на разведочный анализ данных, вы- бросы, чтение форума и т. д., стараясь проявлять терпение. После того как я чув- ствую, что закончил с построением признаков, стараюсь формировать только эталонные модели, чтобы получить представление о результатах различных ар- хитектур. Техника, которой я придерживаюсь, очень похожа на мою профессио- нальную деятельность. Я считаю бесполезными попытки сделать все лучшее за огромное количество времени — между временем и успешностью должен быть баланс. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, что ты вынес из участия в нем Соревнование, проведенное Франсуа Шолле (Francois Chollet), было чрезвычайно сложным. Это был первый конкурс, заставивший нас заняться общим искусст- венным интеллектом (artificial general intelligence, AGI). Помню, я чувствовал се- бя довольно беспомощным в той ситуации, но научился нескольким новым приемам. Подозреваю, что все получили такой же опыт, помня, что наука о дан-
Глава 12. Соревнования по моделированию и оптимизации 401 ных — это не только машинное обучение. На Kaggle всплыло несколько других методов, таких как смешанное целочисленное программирование. Помог ли тебе Kaggle в карьере? Если да, то как? Конечно. Я узнал много новых методов и всегда был в курсе событий благодаря Kaggle. Я нахожусь на том этапе своей карьеры когда моя базовая деятельность относится в основном к сфере менеджмента. Вот почему Kaggle очень важен для меня — я хочу быть в курсе определенных вопросов. Использовал ли ты свои результаты на Kaggle в портфолио для работодателя? Я считаю, что преимущество реализовалось в более косвенной форме, когда лю- ди видели как практические навыки (благодаря Kaggle), так и более теоретиче- ские навыки в моих обычных образовательны »• лиф! сациях. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Я думаю, есть две вещи, которые новички делают неправильно. Первая — это страх перед участием в новом соревновании, кода они пасуют, думая, что полу- чат низкие баллы, и этот факт будет зафиксирован. Это глупость. У всех бывают плохие результаты. Все дело в том, как много своих сил вы отдаете новому со- ревнованию. Вторая заключается в том, что новички хотят как можно скорее пе- рейти к этапу построения модели, что очень неправильно — начинающие кэггле- ры хотят увидеть свои контрольные показатели, а затем разочаровываются. Я советую им не торопиться при создании и выборе признаков, а также на этапах разведочного анализа данных. Какие ошибки ты допускал на соревнованиях? Мои ошибки, к сожалению, очень похожи на ошибки новичков. Я был нетерпе- лив на нескольких соревнованиях, в рамках которых не уделял достаточно вни- мания ранним этапам, и спустя некоторое время осознал, что у меня нет возмож- ности вернуться назад. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Я бы рекомендовал PyCaret для создания эталонов, чтобы набрать скорость рабо- ты, и PyTorch для построения моделей О чем важнее всего помнить, приступая к участию в соревновании? Разведочный анализ данных и предыдущие обсуждения аналогичных соревнований. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Честно говоря, я не испытывал у у за прсд< ши Kaggle, но в качестве гостя мне пришлось столкнуться с ниь л Tpuuyci^ время. чтобы приспособиться к другим платформам.
402 Часть II. Оттачивание соревновательных навыков Резюме В этой главе мы обсудили соревнования по моделированию — новый вид конкур- сов, который становится все более популярным. По сравнению с соревнованиями по компьютерному зрению или NLP, соревнования по моделированию включают гораздо более широкий спектр методов (с несколько большим математическим со- держанием), что отражает разницу между обучением с учителем и обучением с подкреплением. Эта глава завершает техническую часть книги. В последней части мы поговорим о том, как превратить ваши блокноты Kaggle в портфолио проектов и использовать его для поиска новых профессиональных возможностей. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
Часть III— Использование соревнований в своей карьере

13 Создание портфолио проектов и идей Участие в Kaggle имеет свои преимущества: высокие результаты в четырех облас- тях и, соответственно, высокий рейтинг в глазах других участников Kaggle, безус- ловно, приносят удовлетворение и чувство выполненного долга. Однако ваша дея- тельность в рамках Kaggle имеет значение и за пределами платформы и может способствовать продвижению вашей карьеры. Это не только опыт, который вы по- лучаете, участвуя в соревнованиях, экспериментируя с данными, с которыми вы никогда раньше не работали, или повторяя эксперименты с новыми методами; это также связи, которые вы создаете с другими исследователями данных, и внимание, которое вы можете получить от компаний. Хотя Kaggle не признается многими компаниями в качестве оценки квалификации, работа, которую вы выполняете при участии в соревнованиях, может многое расска- зать о ваших способностях и помочь вам выделиться из толпы. В этой главе мы рас- смотрим, как вы можете выделиться, представив свою работу на самом Kaggle и дру- гих сайтах соответствующим образом. Мы рассмотрим следующие темы: • создание портфолио с помощью Kaggle; • организация своего присутствия в Интернете за пределами Kaggle; • отслеживание обновлений и информационных бюллетеней о соревнованиях. В следующей главе мы завершим книгу рассмотрением того, как Kaggle может не- посредственно повлиять на вашу карьеру, расширив вашу профессиональную сеть и предоставив вам карьерные возможности. Создание портфолио с помощью Kaggle Утверждение Kaggle о том, что эта платформа стала "домом науки о данных", сле- дует рассматривать в перспективе. Как мы уже подробно обсуждали, Kaggle открыт
406 Часть III. Использование соревнований в своей карьере для всех желающих соревноваться в определении лучших моделей в прогностиче- ских задачах в соответствии с заданной метрикой оценки. Нет никаких ограничений по вашему географическому местоположению в мире, по образованию или по знаниям в области прогностического моделирования. Иногда про- водятся и конкурсы, которые не носят предсказательного характера, например сорев- нования по обучению с подкреплением, алгоритмические состязания и аналитические соревнования, которые рассчитаны на более широкую аудиторию, чем просто специа- листы по анализу данных. Однако составление наилучших прогнозов на основе дан- ных в соответствии с метрикой является основной целью конкурсов Kaggle. Реальная наука о данных, напротив, имеет множество аспектов. Начнем с того, что ваш приоритет — решение задач, и метрика для оценки вашей модели — это про- сто более или менее точное измерение того, насколько хорошо она решает задачу. Вы можете учитывать несколько метрик. Кроме того, задачи можно решать по- разному, и многое зависит от того, как вы их сформулируете. Что касается данных, то редко можно получить спецификации данных, которые придется использовать, и вы можете изменить любой существующий датасет в со- ответствии с вашими потребностями. Иногда даже можно создать собственный да- тасет с нуля, если это необходимо. Нет никаких указаний в отношении того, как именно собирать данные вместе или обрабатывать их. При решении задачи также необходимо учитывать: • технический долг; • возможность сопровождения решения с течением времени; • время и вычислительные затраты на решение; • объяснимость работы модели; • влияние на операционный доход (если реальный проект является бизнес- проектом, то лейтмотивом станет увеличение прибыли и/или снижение затрат); • передача результатов на разных уровнях сложности и абстракции. Зачастую все эти аспекты имеют большее значение, чем сырая производительность по оценочным показателям. Технический долг— это термин, более распространенный в разра- ботке программного обеспечения, чем в науке о данных, хотя и акту- альный. При возникновении технического долга учитывается все, что нужно сделать, чтобы быстрее реализовать проект, но что впоследст- вии придется переделывать с большими затратами. Классическая ста- тья ’’Hidden Technical Debt in Machine Learning Systems”, написанная Дэвидом Скалли (David Sculley) и другими исследователями Google, должна просветить вас относительно актуальности этой проблемы для науки о данных: https://proceedings.neurips.cc/paper/2015/file/ 86df7dcfd896fcaf2674f757a2463eba-Paper.pdf
Глава 13. Создание портфолио проектов и идей 407 Не все эти знания могут быть дополнены соревнованиями Kaggle. Большая часть этих знаний должна быть получена путем непосредственной практики и накопле- ния опыта в корпоративной среде. Тем не менее знания и навыки, связанные с со- ревнованиями Kaggle, не полностью отделены от многих соображений, о которых мы говорили выше, и они являются хорошим дополнением ко многим процессам в сфере науки о данных на уровне предприятия. Соревнуясь на Kaggle, вы сталкивае- тесь с различными типами данных и задач; вам необходимо выполнять обширное построение признаков и быстрые итерации гипотез моделей. Вам также нужно раз- работать методы современных решений с использованием распространенных паке- тов с открытым исходным кодом. Это набор ценных навыков, и его следует про- двигать. Лучший способ сделать это — создать портфолио, представляющее собой коллекцию ваших решений и работ, основанных на конкурсах и других ресурсах Kaggle. Для того чтобы создать портфолио по результатам соревнований Kaggle, можно применить несколько подходов. Самое простое— использовать возможности, предлагаемые Kaggle, особенно в категориях Datasets, Notebooks и Discussions. Жилберту Титерич https://www.kaggle.com/titericz Прежде чем продолжить, обсудим карьерные возможности, предоставляемые платформой Kaggle, и приведем интер- вью с Жилберту Титеричем. Он гроссмейстер в конкурс- ных категориях Competitions и Discussions, бывший № 1 в рейтинге и нынешний № 1 по общему количеству золотых медалей в соревнованиях Kaggle. Он также является старшим специалистом по обработке данных в NVIDIA и не так давно был упомянут в статье на Wired на эту тему (https ://www.wired.com/ story/solve-these-tough-data-problems-and-watch-job-offers-roll-in/). Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? С тех пор как я начал участвовать в соревнованиях на Kaggle в 2011 г., я предпо- читаю те типы конкурсов, в которых используются структурированные таблич- ные данные. Техники, которые я чаще применяю в Kaggle, — это целевое коди- рование категориальных признаков (существует бесконечное количество способов сделать это неправильно) и пакетирование ансамблей. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Kaggle — это отличная площадка для машинного обучения. Основное отличие от реальных проектов заключается в том, что в Kaggle у нас уже есть четко опреде-
408 Часть III. Использование соревнований в своей карьере ленная и сформулированная задача, созданный датасет, построенная целевая пе- ременная и выбранная метрика. Поэтому я всегда начинаю соревнования Kaggle, экспериментируя с разведочным анализом данных. Понимание задачи и знание датасета — один из ключей к получению преимущества над другими игроками. После этого я трачу некоторое время на определение правильной стратегии ва- лидации. Это очень важно для корректной валидации вашей модели в соответст- вии с тем, как Kaggle оценивает закрытый тестовый набор. Помимо того, что ис- пользование Kfold-разбиения актуально для большинства задач бинарной классификации, мы должны оценить, нужно ли использовать сгруппированный Kfold или разбиение по времени, чтобы правильно провести валидацию, избе- жать переобучения и максимально имитировать закрытый тестовый набор. После этого важно потратить некоторое время на проведение экспериментов по по- строению признаков и оптимизации гиперпараметров. Кроме того, я всегда за- канчиваю соревнования, имея по крайней мере одну модель дерева градиентного бустинга и один подход на основе глубокого обучения. Сочетание таких различ- ных подходов очень важно для увеличения разнообразия в прогнозах и повыше- ния соревновательной метрики. Помог ли тебе Kaggle в карьере? Если да, то как? Да, конкурсы Kaggle стали главной причиной изменения направления моей карь- еры. До 2016 г. я работал инженером-электронщиком, и благодаря всему тому, чему я научился, соревнуясь с 2011 г., я смог перейти в область науки о данных. Kaggle помог мне понять концепции машинного обучения и применить все, что я узнал из теории. Кроме того, Kaggle — это отличное место для опытов, где вы можете загрузить датасет и поэкспериментировать с ним, чтобы извлечь из дан- ных максимум информации. Это, в сочетании с соревновательной средой, делает данную платформу идеальной для изучения программирования и машинного обучения, и в то же время она вызывает привыкание и желание узнавать все больше и больше. Победа в нескольких соревнованиях выводит ваше имя на вершину таблицы лидеров, а это бесценно для карьеры любого человека. Рекру- теры всего мира заглядывают на Kaggle, чтобы найти подходящие кандидатуры на вакантные должности, а знания и опыт, полученные в ходе соревнований, мо- гут способствовать развитию любой карьеры. Использовал ли ты свои результаты на Kaggle в портфолио для работодателя? Как только я присоединился к Kaggle, я несколько лет изучал все техники, алго- ритмы и хитрости, чтобы извлечь больше информации из данных и максимально повысить показатели. Высокая точность — главная цель большинства соревно- ваний, но добиться этого, полагаясь только на удачу, практически невозможно; знания и опыт играют большую роль, когда цель — это победа или хотя бы фи- ниш в зоне золотых медалей. Количество моих медалей за соревнования в Kaggle является моим портфолио. На данный момент (11/2021) оно составляет 58 золо- тых и 47 серебряных, что хорошо резюмирует опыт в области искусственного интеллекта, который я получил от Kaggle. Учитывая, что каждый конкурс длится не менее 1 месяца, это более 105 месяцев непрерывного получения опыта выпол- нения соревновательных задач в сфере искусственного интеллекта.
Глава 13. Создание портфолио проектов и идей 409 По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Новички часто упускают из виду правильную стратегию валидации. Это происхо- дит не только в Kaggle — я видел, как исследователи данных по всему миру строят модели и пренебрегают одним из самых важных моментов в теории эксперимен- тов. Не существует общего правила при определении корректной стратегии вали- дации, но исследователь данных должен учитывать, как модель будет использо- ваться в будущем, и сделать валидацию максимально приближенной к этому. Какие ошибки ты допускал на соревнованиях? Различные, но невозможно перечислить их все. Я совершил, наверное, все воз- можные комбинации ошибок. Ошибки хороши тем, что на них можно учиться. Как только вы совершите ошибку и обнаружите ее, вполне вероятно, что больше вы ее не повторите. Основная ошибка, которую люди допускают в Kaggle, — это дове- рие к результатам в таблице лидеров, а не к результатам локальной валидации. Со- средоточение внимания на таблице лидеров — это постоянное явление в Kaggle, и это главное отличие от реального мира. В реальном проекте мы должны построить сильную стратегию валидации, которой можно доверять, потому что в реальном мире модели будут тестироваться на реальных данных, и у вас есть только один шанс попасть в цель, а не отправлять несколько предложений в день. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Несколько лет назад я бы рекомендовал R, но, учитывая, как быстро Python раз- вивается в пространстве машинного обучения и насколько он универсален и прост в использовании в производстве, я рекомендую всем, кто начинает зани- маться ML, изучать именно этот язык. Что касается библиотек для табличных данных, то я рекомендую pandas для манипуляций, а если вам нужна скорость, то выбирайте cuDF (GPU-версия pandas для RAPIDS.ai). Для EDA я рекомендую использовать DataFrame с библиотеками Seaborn или Matplotlib, а для машинного обучения— Scikit-leam, SciPy, cuML (GPU), XGBoost, LightGBM, CatBoost и PyTorch. Помните, что построение простой модели XGBoost с использованием необработанных признаков происходит быстро и может дать вам хороший ре- зультат для сравнения с другими моделями. О чем важнее всего помнить, приступая к участию в соревновании? Принять участие в соревновании Kaggle и представить публичный блокнот лег- ко, но завершить соревнование в зоне золотых медалей может быть чрезвычайно сложно. Поэтому самое важное, по крайней мере для меня, — помнить, что неза- висимо от итогового рейтинга стоит использовать Kaggle, чтобы получать удо- вольствие и узнавать как можно больше из форумов обсуждений, из публичных блокнотов и даже из сообщений победителей после наступления дедлайна, опи- сывающих свои идеи и то, что получилось. Помните также, что победителем соревнования становится не просто копирова- ние того, что делают остальные, а нестандартное мышление и выдвижение новых идей, стратегий, архитектур и подходов.
410 Часть III. Использование соревнований в своей карьере Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я выиграл пару соревнований на других соревновательных платформах, но глав- ное отличие по сравнению с Kaggle — это количество пользователей. По состоянию на ноябрь 2021 г. Kaggle насчитывает 171 тыс. активных пользова- телей, что делает форумы, блокноты и взаимодействие с датасетами гораздо бо- лее насыщенными в плане содержания. Кроме того, Kaggle предлагает нечто уникальное: блокноты, в которых можно бесплатно писать и выполнять код, ис- пользуя серверы Google, что может оказаться бесценным, если у вас нет доступа к хорошему оборудованию. Использование блокнотов и обсуждений Помимо самих рейтингов, блокноты — это способ привлечь к себе внимание на платформе Kaggle, поскольку они одновременно демонстрируют, как вы решаете задачи, как вы представляете идеи и как вы их программируете. Задуманные как способ легкого и открытого обмена решениями и идеями между участниками, блокноты являются самым важным инструментом (после рейтингов) для демонст- рации способностей, которые ценятся работодателями. Фактически, одним из самых важных изменений в мире науки о данных за послед- ние годы стал ее переход от игры выдающихся талантов (уникальных исследовате- лей данных) к командной игре, где специалисты должны сотрудничать друг с дру- гом и с другими отделами, чтобы обеспечить успех проекта. Следовательно, при приеме на работу компании часто больше заботятся о том, чтобы вы умели доно- сить идеи и результаты, а также чисто и эффективно программировать. В предыдущем разделе мы обсудили, как реальные проекты требуют более широ- кого спектра навыков, начиная от работы с техническим долгом и заканчивая раз- работкой экономически эффективных решений. Вы все равно можете продемонст- рировать эти навыки на Kaggle, даже если они не помогут вам победить в соревновании. Блокноты — лучшие инструменты для этого. См. главу 3 для ознакомления с блокнотами Kaggle. На Kaggle можно найти различные типы блокнотов. Можно приблизительно разде- лить их на четыре категории: • решения и идеи для ранжирования в конкурсе; • разведочный анализ данных (exploratory data analysis, EDA);
Глава 13. Создание портфолио проектов и идей 411 • учебники, объясняющие модели машинного обучения или принципы науки о данных; • свежие реализации моделей, полученных из статей или других оригинальных решений. Каждый тип может дать вам преимущество за счет интересного набора навыков. Если решения и идеи для соревнований — это классический способ продемонстри- ровать, что вы знаете, как решить сложную задачу в области науки о данных, то остальные три способа могут показать миру, что вы можете: • манипулировать, представлять и извлекать визуализированные и невизуали- зированные идеи из данных (EDA) — этот навык считается очень важным в любой сфере, от научных исследований до бизнеса; • обучение науке о данных, открывающее двери для ролей в сфере образова- ния, наставничества и защиты интересов разработчиков; • переводить исследования в практику, что является ключевым навыком в то время, когда инновации в области науки о данных (особенно в глубоком обу- чении) появляются ежедневно и требуют быстрого воплощения в рабочие решения. Даже если вы не занимаете высоких мест в соревнованиях Kaggle или не имеете потрясающих решений для презентации, эти три вида блокнотов (EDA, учебники и реализации на бумаге) способны предоставить вам возможности в реальном мире, если вы сможете продвигать их наилучшим образом. Для этого вам нужно понять, как писать код приятных для чтения и интересных блокнотов, а это то, чему вы научитесь с практикой и опытом. Поскольку это искусство, мы предлагаем учить- ся у других, особенно у гроссмейстеров, которые занимают высокие места в рей- тинге пользователей в разделе Notebooks (https://www.kaggle.com/rankings?group= notebooks&page=l&pageSize=20). Мы рекомендуем вам посмотреть, какие блокноты они разработали, как организо- вали свою работу с помощью рисунков, как структурировали свой код, и, наконец, исходя из ваших навыков и интересов, попытаться скопировать один из их блокно- тов. Мы также советуем для достижения успеха не делать ставку лишь на код и графики, а постараться сосредоточиться на изложении материала. Независимо от того, демонстрируете ли вы решение, обучаете или реализуете нейронную архитек- туру в TensorFlow, то, как вы объясните ячейки блокнота словами, очень важно для того, чтобы оставить неизгладимое положительное впечатление. Помимо просмотра блокнотов лидеров есть также возможность получать уведом- ления о менее популярных, но все же прекрасно составленных блокнотах, которые недавно появились на Kaggle. Астрофизик и увлеченный пользователь Kaggle под ником Heads or Tails, Мартин Хенце (Martin Henze, https://www.kaggle.com/ headsortails), публикует на форумах обсуждений еженедельные записи Notebooks of the Week: Hidden Gems. Здесь он размещает коллекцию самых интересных блок- нотов. На данный момент уже имеется более 100 томов, и автор продолжает искать в Kaggle все, что может оказаться интересным. Если вы хотите получать свежие
412 Часть III. Использование соревнований в своей карьере новости о крутых блокнотах, просто следите за профилем Мартина Хенце на Kaggle или проверяйте время от времени, не опубликовал ли он что-то новое в сво- их обсуждениях. Если вы любите копаться в блокнотах в поисках идей и учиться на них, мы не уста- ем повторять, что не стоит бездумно копировать чужие работы. На платформе Kaggle существует множество блокнотов, и часто кто-то копирует один из них, вносит небольшие изменения и повторно представляет работу другим участникам Kaggle, как будто это его собственная оригинальная идея. Также принято брать функцию или часть кода из блокнота и вставлять ее в собственный. В обоих случа- ях не забывайте всегда цитировать источник и автора. Если вы не можете отследить что-то до первоначального автора, достаточно даже ссылки на последнюю работу, где вы нашли использованный код. Хотя основная цель демонстрации — показать ваши собственные труды и навыки, очень важно признать, что некоторые части вашего кода или некоторые идеи взяты из других мест. Помимо того, что это знак уважения к коллегам-кэгглерам, указание источника подчеркивает, что вы доста- точно осведомлены и признаете труд и изобретения других людей и знаете, как ис- пользовать их достижения в своей работе. В меньшей степени обсуждения на форумах Kaggle способны помочь вам быть за- меченными для получения конкретной должности в области науки о данных и раз- работки программного обеспечения. Изначально обсуждения на Kaggle были пред- назначены только для общения с организаторами или для того, чтобы задать насущные вопросы о самом соревновании. В конце соревнований участники редко чувствовали себя обязанными представить или обсудить свои решения. Однако с тех пор, как обсуждения получили собственные рейтинги пользователей и оценки мастерства, на форумах стало возможным найти намного больше информации. Л. Об обсуждениях на Kaggle читайте в главе 4. По нашему опыту, обсуждения на Kaggle можно разделить на четыре категории: • соревновательные решения, которые подробно объясняют (иногда с помо- щью соответствующего блокнота), как команде удалось достичь определен- ной позиции в личной таблице лидеров; • помощь и разъяснение требований во время соревнований; • благодарности, комплименты и болтовня; • посты, которые помогают и наставляют других участников, объясняя им суть вещей. По нашим наблюдениям, если вы преуспели в написании постов последнего типа и получили широкую известность, это может помочь вам добиться роли адвоката разработчиков, особенно если у вас есть и другие активные каналы, где вы общае-
Глава 13. Создание портфолио проектов и идей 413 тесь с коллегами-исследователями данных (например, канал на Twitch или YouTube, аккаунт в Twitter или блог на Medium). В связи с ростом числа должностей адвокатов разработчиков как в крупных компа- ниях, так и в стартапах, существует значительный спрос на специалистов, умеющих помогать другим специалистам по работе с данными и разработчикам в их проек- тах. Если вы хотите узнать больше об этой специализации, прочтите следующую статью на draftdev, она достаточно толковая и исчерпывающая: https://draft.dev/ learn/what-is-a-developer-advocate. Использование датасетов Соревнования Kaggle часто критикуют за то, что на них представляются данные, которые уже очищены, хорошо упорядочены и далеки от репрезентативности ре- альных данных. Наша точка зрения немного отличается: мы считаем, что данные, которые Kaggle предоставляет на конкурсах, могут быть довольно грязными или зашумленными. Иногда представленных данных недостаточно по качеству и коли- честву для получения высшего балла, и вам придется искать дополнительные дан- ные в Интернете. Что Kaggle упускает в отношении данных в проекте науки о данных, так это про- цесс их сбора и накопления в организованных хранилищах и файлах, процесс, ко- торый в реальных условиях невозможно стандартизировать, поскольку он отлича- ется от компании к компании и от задачи к задаче. Работа с данными в реальном мире должна в основном изучаться в полевых условиях. Введение датасетов в Kaggle было направлено на смягчение представления о том, что Kaggle сосредоточен только на задачах моделирования. Датасеты раздела Kaggle Datasets очень полезны в этом смысле, поскольку они позволяют создавать и загружать собственные данные, документировать признаки и их значения; они так- же требуют от вас умения управлять данными во времени, планируя частоту их об- новления или полной замены. Для ознакомления с Kaggle Datasets обратитесь к главе 2. Что еще более интересно, в Kaggle Datasets вам также предоставляется возмож- ность прикрепить различные анализы и модели, построенные с помощью Kaggle Notebooks, загруженные из ваших данных или из соревнования. Эти модели могут быть работой, к которой вы пришли во время конкурса, или вашим ноу-хау, по- явившимся потому, что вы внимательно изучили загруженные данные и нашли на- бор интересных задач, которые можно решить с их помощью. Кроме того, Kaggle Datasets предлагает шаблон для проверки полноты метаинфор- мации, сопровождающей ваши данные. Описание, теги, лицензия, источники и час-
414 Часть III. Использование соревнований в своей карьере тота обновлений — это лишь некоторые из необходимых частей информации (ис- пользуемых для расчета оценки удобства использования), которые помогут любо- му, кто использует ваши данные, понять, как ими пользоваться. Вы можете даже указать (в описании или в обсуждениях) задачи для датасета, связанные с пред- стоящей работой, которую вы хотели бы с ним выполнить. Это хороший способ сообщить о своем полном понимании потенциальной ценности загруженных вами данных. Ранее задачи (Tasks) были частью функциональности Kaggle Dataset, но г—недавно они были удалены: https://www.kaggle.com/product- feedback/292674. Тем не менее вы можете использовать описание и об- суждение данных, чтобы указать, для чего, по вашему мнению, могут быть использованы ваши данные. Все эти характеристики делают датасеты Kaggle очень хорошим способом проде- монстрировать ваш опыт решения задач на платформе Kaggle и в целом ваши спо- собности в работе с данными и алгоритмами машинного обучения, поскольку они позволяют: • публиковать и выполнять поддержку датасета; • продемонстрировать, что вы поняли ценность данных с помощью дорожной карты задач; • показать запрограммированные и полностью рабочие решения (поскольку блокноты Kaggle могут сразу работать с одними и теми же данными без ка- кой-либо подготовки), начиная от подготовки данных и заканчивая объясни- тельным анализом данных и предиктивным моделированием. Мы настоятельно рекомендуем использовать раздел Kaggle Datasets для демонстра- ции работы, проделанной вами во время соревнований Kaggle или над любым дру- гим проектом, поскольку они отделяют вашу работу от чужих и объединяют дан- ные и блокноты. Одним словом, Kaggle Datasets могут продемонстрировать любому человеку рабо- чее решение, которое вы внедрили. Однако есть и обратная сторона: вы по большей части привязаны к среде Notebook (даже при использовании скриптов), которая не совсем прозрачна с точки зрения требований к пакетам и версиям, необходимых для того, чтобы кто-то знал, как запустить код в других средах. На самом деле блокноты Kaggle зависят от среды Docker (https:// www.docker.com/), а она задается конфигурационным файлом, Dockerfile, который определяет, какие версии были установлены. При просмотре блокнота не сразу видно, какая версия пакетов используется, пока вы не просмотрите этот файл кон- фигурации. Для этой цели, а также для тиражирования настроек отыскать Dockerfile можно в репозитории Kaggle на GitHub (https://github.com/KaggIe/
Глава 13. Создание портфолио проектов и идей 415 docker-python/blob/main/Dockerfile.tmpl), хотя он меняется со временем, и вам может понадобиться найти подходящий для своей работы. Наконец, в дополнение к этому аспекту не забывайте: для того чтобы хотя бы мельком взглянуть на датасет и связанные с ним блокноты, требуется доступ к со- обществу Kaggle. Габриель Пре да https ://www. kaggle.com/gpr eda У нас была вдохновляющая беседа о карьере с Габриелем Предой, гроссмейстером Kaggle в категориях Datasets, Notebooks и Discussions и ведущим исследователем данных в Endava. У Габриеля докторская степень в области вычис- лительной электромагнетики, и он долгое время занимался разработкой программного обеспечения, прежде чем решил полностью посвятить себя науке о данных. Открыв для себя Kaggle, он почувствовал себя на этой платформе как дома и вложил в нее много времени и усилий, что принесло ему дивиденды в профес- сиональном плане. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle помог мне ускорить процесс обучения в области науки о данных. До Kaggle я повсюду искал источники информации или задачи для решения, но это было не очень методично и эффективно. На платформе Kaggle я нашел сообще- ство людей, интересующихся теми же вопросами, которые интересны мне. Я смог увидеть работу ведущих экспертов в этой области, изучить их опублико- ванные блокноты с анализами или моделями, получить от них информацию, за- дать им вопросы и даже посоревноваться с ними. В то время, когда я присоеди- нился к Kaggle, я занимался в основном анализом данных, но очень быстро я начал участвовать в конкурсах; а это потребовало от меня научиться строить, проверять и итеративно улучшать модели. После примерно двух лет работы в Kaggle я изменил свой основной вид деятельности— перешел от управления проектами программного обеспечения к работе в области науки о данных с пол- ной занятостью. Kaggle также дал мне некоторую известность, и во время собе- седований с кандидатами в моей нынешней компании они упоминали, что хотели бы работать со мной, поскольку заочно знакомы со мной через платформу. Использовал ли ты свои результаты на Kaggle в портфолио для работодателя? Я использую свое портфолио Kaggle в качестве основного источника информа- ции для потенциальных работодателей, а мой профиль LinkedIn указывает на мой профиль Kaggle. Кроме того, в последние годы круг работодателей, которым из- вестно о существовании Kaggle, расширился, и некоторые из них целенаправлен- но спрашивают о вашем профиле Kaggle. Есть также потенциальные работодате-
416 Чисть III. Использование соревнований в своей карьере ли, которые ясно дают понять, > н считают Kaggle актуальным. Я не согласен с этим мнением; лично я, пре • вводить собеседование с кандидатами, обычно проверяю их профит» i ЛаЬ и Kaggle. Я считаю их чрезвычайно по- казательными. Хороший профи п Kaggle пропечонстпчрует не только технические навыки и опыт работы с определенными языками, инструментами, методами или навыки решения проблем, но и го, нас ас ibko хорошо человек умеет общаться через об- суждения и блокноты. Это очень важное качество для исследователя данных. Ты стал гроссмейстером в категории Notebooks (Kernels), затем в категории Discussion и, наконец, в Datasets. Расскажи о пройденном пути Я стал седьмым гроссмейстером в категории Kernels и дошел до третьего ранга. В течение, наверное, двух лет я был в первой десятке в иерархии Kernels. Я начал писать ядра в первую очередь для того, чтобы улучшить свои знания языка R при анализе датасетов, которые показались мне более интересными. Я также экспе- риментировал со всеми видами техники, включая полигональные клипы, по- строение двойных сеток из полигонов Вороного и 2В-тесселяцию Делоне. По- степенно я переключил свое внимание на разведочный анализ данных, потом на построение моделей для датасетов, а затем и для соревнований. Также, когда я начал больше соревноваться, я стал писать ядра для конкурсов на Python. При- мерно в то же время я начал замечать, что некоторые из моих ядер привлекают внимание кэгглеров, в первую очередь это выражалось голосованием и форками, но также были и блаз оприятные комментарии. Некоторые из моих ядер, напи- санных для исследования данных в активных соревнованиях, получили популяр- ность очень широкой аудитории и принесли мне много золотых медалей; таким образом, я достиг уровня мастер^. a затем и iроссмейстера. В настоящее время я не публикую много ядер связанных с соревнованиями; в основном я создаю и публикую стартовые ядра для работы с датасетами. Чуть позже 1 получил вгние гроссмейстера в катерории Discussions. Вот уж ни- когда не пре щолагал, чго достигни этого уровня в обсуждениях! Я начал с ком- ментирования ядер других люд^.* Затем, постепенно, по мере того, как я все больше вов юкашя в сиревноьаонж большинство моих комментариев оказыва- лось в разделах обсуждения активных конкурсов. Там я либо задавал вопросы на интересующие меня темы этих соревнований, либо начинал новые темы, напри- мер предлагав решение лля одной задачи или подбирки ресурсов для решения различных открытых вопрос. о, с конкурсом. Хочу отметить особый набор комментариев, которые au а ь a. i россмейстером Kaggle Kernels (одним из первых) я шг новых б. юкнотов кэгглеров, когда обнаруживал очень хороший кошечт. В таких случая> я схараюсь уде ш:ь * сколько минут, чтобы также похвалить (тем боле . е ли t ш л 1 сижения автора. Особенно это касается нори ’ког ‘огпа р т ч п т "о г^лпяжаете свою признательность, по- вышая рейтиш их работы, но и .. itcKO 1ько положительных отзывов об их вкладе жет при. д сы чюоы они грагили больше време- ни и сил и а ' ci ii н ы: t . Kaggle. Мне нравится это
Глава 13. Создание портфолио проектов и идей 417 делать, и я надеюсь, что это помогает. Однажды я также составил список реко- мендаций о том, как комментировать на Kaggle. Вот он: быть кратким (но не слишком); быть конкретным; предоставлять информацию, а не мнения; хвалить работу других людей, когда у вас есть возможность; сохранять спокойствие и стараться быть полезным; не отмечать людей в своих комментариях, если это не имеет смысла (например, если это обсуждение, и вам нужно направить свой комментарий тому, кто обратился к вам в этой теме). Последнее звание гроссмейстера, которого я достиг, относится к категории Datasets. Это также звание, на котором я достиг наивысшего рейтинга — второго. Мое продвижение по лестнице рангов было медленным. Я начал с того, что мне нравилось. Получение высокого статуса в Datasets требует вложений в курирова- ние, очистку и документирование данных. Если это не то, что вам действительно нравится, вы, скорее всего, не будете продолжать деятельность в этой сфере. Я занимался тем, что было важно не только для меня, но и для более широкого круга людей: для моей страны, континента или всего мира. Я опубликовал дата- сеты о выборах в моей стране, а также о различных социальных, демографиче- ских и экономических темах в Европе. Сосредоточился на актуальных темах, ко- торые были значимы и важны для сообщества. Например, во время пандемии я опубликовал данные о случаях заболевания COVID-19, о вакцинации, тестах и вариантах вируса как в моей стране, так и во всем мире. Я собирал данные, которые выходили за рамки простых числовых, табличных зна- чений. Текстовые данные, особенно полученные в результате непосредственного участия людей, позволили многим людям получить важные сведения. Одна из мо- их самых популярных подборок данных состоит из коллекций сообщений и ком- ментариев на Reddit или постов в Twitter (твитов) на такие разные темы, как мифы о вакцинах, крикет, пандемии, спортивные события и политические деятели. Я вложил значительные средства в автоматизацию сбора, очистки и скриптов обра- ботки данных. Это сэкономило мне драгоценное время (особенно для часто обнов- ляемых датасетов — некоторые из них собирались непрерывно, а скрипты запус- кались каждый час), но также позволило лучше контролировать процесс. Каждый раз, когда я публикую новый датасет, я также пишу одно или несколько стартовых ядер. Эти ядра не предназначены для широкой аудитории. Я создаю их как вспо- могательные ядра для потенциальных пользователей моих датасетов, чтобы им было легче использовать данные. Во многих случаях я предпочитаю сохранить ис- ходные данные (в том виде, в котором я их собрал или загрузил из альтернативно- го источника) и включить ядро для очистки, преобразования и предварительного анализа данных, а также результат этого процесса — данные в более доступном формате. Таким образом, я пытаюсь отразить в датасете больше, чем сами дан- ные, — я также предоставляю информацию о методах преобразования данных. Организация своего присутствия в Интернете за пределами Kaggle Поскольку датасеты и блокноты Kaggle требуют наличия учетной записи на этой платформе, необходимо учитывать, что не все заинтересованные пользователи мо
418 Часть IIL Использование соревнований в своей карьере гут иметь такую учетную запись или захотеть создать ее только для того, чтобы посмотреть на вашу работу. Вы также должны рассмотреть более доступные аль- тернативы. Чаще всего кэгглеры предпочитают создавать проект на GitHub (https://github.com/), писать статью на Medium (https://medium.com/), а также на других издательских платформах, или публикуют в собственном блоге. Однако есть и другие возможности для продвижения своей работы и навыков, например: • публикация кода, относящегося к соревнованиям Kaggle, который может быть выполнен из браузера на https://deepnote.com/; • создание сообщества Discord, объединяющего кэгглеров, например MLSpace Абхишека Тхакура (Abhishek Thakur; https://discord.com/invite/4RMwz64gdH), или ведение канала на YouTube (также за авторством Абхишека Тхакура: https://www.youtube.com/channel/UCBPRJjIWfyNG4X-CRbnv78A); • создание канала на Twitch, как у Роба Муллы (Rob Mulla), где он демонстри- рует программирование, имеющее отношение к соревнованиям Kaggle: https://www.twitch.tv/medallionstanion (также на GitHub: https://github.com/ RobMulla/twitch-stream-projects); • делать еженедельную рассылку новостей Kaggle, как Шотаро Исихара (Shotaro Ishihara): https://www.getrevue.co/profile/upura; • интервьюирование кэгглеров и других экспертов в области науки о данных, как это делает Саньям Бхутани (Sanyam Bhutani), и трансляция интервью с помо- щью видео, подкастов и записей в блоге: https://chaitimedatascience.com/ (вы можете просмотреть датасет, содержащий все данные о проведенных на те- кущий момент интервью, подготовленный Роханом Рао (Rohan Rao): https://www.kaggle.com/rohanrao/chai-time-data-science). Мы приходим к выводу, что существует довольно много возможностей и средств, с помощью которых вы можете распространить свою работу и продемонстрировать навыки на Kaggle, в зависимости от того, чего вы хотите достичь. В этой главе мы сосредоточимся только на блогах и присутствии на GitHub (это наиболее распро- страненные и довольно эффективные варианты), но вы можете выбрать любой дру- гой подход, который сочтете подходящим для своих целей. Блоги и публикации Написание статей может быть способом отточить свои знания (ведь для того, чтобы написать о какой-то теме, нужно ее изучить) и дать возможность другим узнать о вас и ваших навыках. Обрести известность благодаря своей писательской деятель- ности можно разными способами: от привлечения внимания рекрутеров и компа- ний до налаживания связей как для участия в соревнованиях Kaggle, так и для бо- лее широкой профессиональной деятельности. Социальные сети позволяют публиковать идеи и короткие фрагменты текста, и мы рекомендуем их использовать. Учитывая, что темы по науке о данных и соревнова- ниям Kaggle требуют длительного обсуждения и рассуждений, лучший подход —
Глава 13. Создание портфолио проектов и идей 419 писать длинные статьи и размещать их с помощью блога или сайта, публикующе- го письменные работы. В идеале мы предлагаем вам координировать взаимосвязь между социальными сетями и вашими статьями, чтобы продвигать их с помощью специальных постов, анонсирующих статьи или обсуждающих ключевые моменты в них. Давайте сначала обсудим, как и где вы можете публиковать свои статьи. Статья на Medium, особенно в Medium publications, таких как Towards Data science (https://towardsdatascience.com/), может привлечь большое внимание. Medium publications — это совместно используемые пространства для рассказов, написан- ных на общую тему обычно несколькими авторами. Будучи веб-сайтом, Medium может охватить широкую аудиторию читателей, а некоторые публикации имеют очень хорошую репутацию в сообществе специалистов по науке о данных благода- ря качеству своих статей. У публикации может быть один или несколько редакто- ров, которые отбирают материалы и следят за тем, чтобы их содержание соответст- вовало политике издания и уровню его качества. Издания Medium, в которых вы можете размещать свои статьи, — это: • Towards Data science, как уже упоминалось ранее (https://towardsdatascience.com/questions-96667b06af5); • Better Programming (https://betterprogramming.pub/write-for-us-5c4bcba59397); • Mleaming.ai (https://medium.com/mlearning-ai/mlearning-ai- submissionsuggestions-b51e2bl30bfb); • Becoming Human (https://becominghuman.ai/write-for-us-48270209de63); • Towards AI (https://pub.towardsai.net/submit-your-medium-story-to- towardsai-a4fa7e8bl41d). Преимущество каждого из этих изданий заключается в том, что они уже имеют большую аудиторию, возможно, превышающую вашу аудиторию в социальных сетях. Вы получите больше читателей, чем можно было бы ожидать, охватив людей в компаниях, а также других профессионалов, с которыми сможете наладить кон- такты. Помимо Medium, другие сайты также могут принимать и размещать ваши публикации. • Hacker Noon (https://www.publish.hackernoon.com/). Достаточно популярен среди технических блоггеров и содержит все, что связано с техникой (он до- вольно универсален). С ежемесячной аудиторией в 4 млн человек это подхо- дящее место, если вы хотите привлечь внимание многих любителей технологий к чему-либо, связанному с техникой. Попасть на первые страницы чрезвы- чайно сложно, и это палка о двух концах: вы получите как много внимания, так и много критики. • Dev.to (https://dev.to/). Основную часть аудитории составляют разработчики (почти 800 тыс.), и здесь содержатся статьи и учебники по программирова- нию. В сообщениях, публикуемых здесь, акцент должен быть сделан на каче- стве и эффективности вашего кода (моделирование отходит на задний план).
420 Часть III. Использование соревнований в своей карьере • FreeCodeCamp (https://www.freecodecamp.org/news/developer-news-styleguide/). Больше ориентирован на учебные пособия; люди приходят туда, чтобы нау- читься программировать. Ресурс идеально подходит для продвижения курсов по машинному обучению и рекламы новых пакетов. • Analytics Vidhya (https://www.analyticsvidhya.com/about/write/). Довольно популярный сайт в Индии, он в большей степени сосредоточен на статьях, объясняющих машинное обучение и строительные блоки глубокого обучения. • KDnuggets (https://www.kdnuggets.com/news/submissions.html). Одно из ста- рейших изданий в области добычи данных. У него по-прежнему довольно много последователей (миллион уникальных посетителей в марте 2021 г.) среди старой гвардии ученых, изучающих данные, и академиков. Статья, пост, блог или обсужение имеют сильные и слабые стороны и различаются по охватываемой аудитории, поэтому вы должны решить, что из них лучше подхо- дит для вашего контента. Начните с просмотра публикаций, размещенных на ре- сурсах, чтобы понять, как ваша статья может вписаться в них. Конечно, при желании вы можете использовать собственный блог. Его наличие имеет свои преимущества, например отсутствие рекламы или редакторского кон- троля того, что вы пишете. С другой стороны, вы не сможете использовать уже су- ществующую аудиторию, и вам придется работать над ее созданием, продвигая свои статьи в социальных сетях. Вы можете создать собственный сайт с нуля на выбранном вами веб-домене или свой блог на GitHub. ( Если вы решите прибегнуть к помощи GitHub (поскольку он бесплат- УлС ный и, возможно, вы уже используете его в качестве хранилища для zg 4 своего кода), вот простое и быстрое руководство по созданию записей в блоге GitHub: http://jmcglone.com/guides/github-pages/. Если вам нужно что-то еще более автоматизированное, то использование такой платформы, как fastpages (https://github.com/fastai/fastpages) Джереми Ховарда (Jeremy Howard), может упростить процесс написания контента вместе с примера- ми кода, поскольку она автоматически преобразует блокноты и документы Word в страницы блога и публикует их за вас. Если вы предпочитаете быть полностью независимым и создать свой веб-сайт, это потребует больше усилий и некоторых затрат; доменные имена и веб-пространство не бесплатны. В этом случае реклама вашего контента становится критически важной. Основным преимуществом написания текста о собственных решениях является элемент повествования, поскольку вам придется сопровождать свои фрагменты ко- да описаниями и пояснениями и формулировать свои мыли более многословно, чем это можно было бы сделать в блокноте. В некотором смысле, литературный стиль описания вашей работы становится таким же важным, как и код, который вы пише-
Глава 13. Создание портфолио проектов и идей 421 те. Изменяя тон своей публикации, вы сможете охватить разные типы аудитории. Изложение концепций в доступной форме означает, что вы расширите свою ауди- торию и установите контакты с большим количеством профессионалов. Высоко- техническая манера письма может произвести впечатление на большее количество потенциальных компаний, которые могут рассмотреть возможность вашего найма, хотя и ограничит количество привлекаемых читателей. Поскольку написание статьи — это очень индивидуальный акт, и наши советы и рекомендации не будут применимы к каждому сценарию, мы советуем заранее оп- ределиться с целью, которую вы желаете достичь, и категорией читателей, к кото- рым вы хотите обратиться. GitHub Помимо написания статей и наличия репозитория с кодом, на который вы можете направить читателей, наличие вашего кода на GitHub также поможет вам не изо- бретать колесо в каждом соревновании, в котором вы участвуете. Вы можете хра- нить код, который хотите повторно использовать, в проекте или в сервисе Gists (https://docs.github.com/en/github/writing-on-github/editing-and-sharing-content- with-gists). Эти формы представляют собой небольшие фрагменты кода, доступ к которым можно получить по отдельности. Даже если вам нравится оставлять весь свой код на Kaggle, со временем вы замети- те, что доступ к нему затруднен, а возможно, вам даже будет сложно найти его во- обще. Это связано с тем, что разделить блокноты Kaggle на отдельные проекты нельзя — они будут представлены в виде длинного списка, который можно упоря- дочить по нескольким признакам, таким как количество голосов или время послед- него запуска блокнота. GitHub значительно облегчает поиск необходимой инфор- мации и повторное ее использование. Например, вы можете создавать скрипты, содержащие весь ваш код, а затем загружать и импортировать их в блокнот Kaggle без необходимости копировать что-либо. В следующем примере мы загружаем и повторно используем вспомогательные функции для нейронной сети tabular: !wget https://raw.githubusercontent.com/lmassaron/deep_learning_for_ tabular_data/master/tabular.py # Импорт из TabuLar from tabular import gelu, Mish, mish from tabular import TabularTransformer, DataGenerator Команда wget получит прямой доступ к коду на GitHub и загрузит его на диск блок- нота; после этого вы сможете просто импортировать из него нужные вам функции и классы. Для того чтобы получить ссылку, предоставляющую прямой доступ к
422 Часть III. Использование соревнований в своей карьере вашему коду, достаточно найти содержащий его файл в репозитории GitHub, а за- тем нажать кнопку Raw в заголовке страницы (рис. 13.1). Raw Blame jp [р с? U Рис. 13.1. Заголовок визуализированного файла но GitHub. Обратите внимание на кнопку Raw в провой верхней части панели заголовка После нажатия кнопки Raw вы будете перенаправлены по веб-адресу, по которому файл хранится на GitHub. Можно использовать этот веб-адрес для обращения к файлу за пределами GitHub. GitHub также полезен для хранения изображений, которые вы можете использовать в обсуждениях Kaggle (таким образом, вы больше можете не загружать изображе- ния на форумы Kaggle). В случае с изображениями у вас не будет кнопки Raw, но вы можете щелкнуть правой кнопкой мыши на изображении и открыть файл в дру- гой вкладке — это даст тот же эффект. GitHub — еще один отличный способ продемонстрировать свою работу, но учиты- вая характер сайта (он ориентирован на разработчиков) и содержимое, которое вы можете на нем разместить (файлы с кодом), вам следует ожидать, что аудитория будет очень специфическая. В компаниях кадровые службы, вероятно, не будут слишком глубоко изучать ваш аккаунт на GitHub, а остановятся на README.md, который должен быть хорошо написан и визуально привлекателен. Менеджеров по подбору персонала больше будет интересовать код в ваших проектах. Вы должны приложить некоторые усилия, чтобы код был хорошо структурированным в ваших файлах, процедурах и классах, включая также инструкции, необходимые для уста- новки и воспроизведения ваших результатов. Вам придется использовать такие инструменты, как conda (https://docs.conda.io/ en/latest/) или poetry (https://python-poetry.org/), чтобы убедиться, что для работы вашего кода установлены нужные пакеты. Для того чтобы сформировать наилучшую структуру своего проекта, вам, вероятно, понадобится что-то вроде CookieCutter (https://drivendata.github.io/cookiecutter- data-science/). Использование template для проектов, подобных тем, которые пре- доставляет CookieCutter, позволяет легко расположить код в определенных катало- гах и предоставить файлы, позволяющие использовать и понимать его. Шаблон CookieCutter сделает ваш проект более легким для чтения, понимания и сопровож- дения. Наконец, вам также понадобится система контроля версий для управления экспе- риментами и источниками данных, а не только для вашего кода. Например, можно использовать Data Version Control (DVC: https://dvc.org/). Все эти ресурсы и на- выки, необходимые для их правильного использования (создание среды, структу- рирование проекта, версионирование данных и моделей), ближе к программной
Глава 13. Создание портфолио проектов и идей 423 инженерии, чем к навыкам из области науки о данных. Они не так актуальны на Kaggle — или могут быть выполнены простыми способами — и потребуют усилий и обучения. Тем не менее они станут частью возможностей, которые вы представи- те вместе со своими проектами на GitHub, что повысит ваши шансы произвести хорошее впечатление на интервьюеров. Если вы хотите устроить живую демонстрацию своих моделей, у вас есть несколь- ко вариантов. Проще всего иметь код, работающий на оригинальных блокнотах (просто поместив ссылку на ваш блокнот Kaggle в файл README.md своего про- екта на GitHub) или на сервисе Google Colab. Для того чтобы блокнот, сохранен- ный на GitHub, автоматически запускался в Google Colab, всего лишь опубликуйте его ссылку, изменив домен с github.com на githubtocolab.com: ссылка откроет ваш блокнот в Colab. Однако самое впечатляющее представление вы можете подготовить в HuggingFace Spaces (https://huggingface.co/spaces). Здесь вы продемонстрируете, как вашу мо- дель Kaggle можно использовать в онлайн-приложении. Spaces — это простой спо- соб размещения демонстраций машинного обучения и создания онлайн-портфолио ваших работ, как объясняется в документации (https://huggingface.co/docs/ hub/spaces). Выделяемые ресурсы имеют ограничение: 16 Гбайт оперативной па- мяти и 8 ядер процессора, — но реализация бесплатна, и этого достаточно для де- монстрации того, как ваша модель может работать в специализированном прило- жении. Вы можете установить свои зависимости на удаленной машине HuggingFace, синхронизировать код и модели с GitHub либо создать приложение, используя Streamlit (https://streamlit.io/) или Gradio (https://gradio.app/). В качестве примера Рашми Бантия (Rashmi Banthia), эксперт Kaggle и преподава- тель Гарвардского университета (https://www.kaggle.com/rashmibanthia), размес- тила демонстрацию своей модели с конкурса Sartorious Cell Instance Segmentation: https://huggingface.co/spaces/rashmi/Cell-Instance-Segmentation-OMMDetection. Представив свою модель вместе с несколькими примерами в демонстрации в ре- жиме реального времени, вы сможете сразу же донести ее эффективность даже до аудитории, не занимающейся машинным обучением. Мониторинг обновлений и информационных бюллетеней о соревнованиях Теперь вы понимаете, что важно демонстрировать свою работу на Kaggle, чтобы сообщить миру о своем интересе к определенным типам моделей и проблемам дан- ных. С этой точки зрения важно, чтобы вы всегда знали о возможностях, которые предоставляют соревнования. Основной способ сделать это — часто посещать сайт Kaggle и согласиться полу- чать от администраторов платформы электронные письма (рис. 13.2). Активируйте эту возможность из своего профиля на странице Notification and e-mail settings
424 Часть III. Использование соревнований в своей карьере (Настройки уведомлений и электронной почты), где вы можете согласиться полу- чать уведомления как на сайте, так и по электронной почте. Еще вы можете вы- брать получение электронных писем, содержащих информацию о новых функциях и инициативах на Kaggle, а также новости о недавно запущенных соревнованиях. kaggle Hi lucamassaron! Calculating word frequency just scratches the surface of natural language processing In this Snapshots video, Product Manager Meg Risdal walks us through her analysis of Animal Crossing reviews while exploring the Shifterator package’s word shift graphs, an alternative to word clouds. She also provides an overview of the Quick Save and Version Naming features in Notebooks? Puc. 13.2. Электронное письмо Kaggle, анонсирующее серию видеороликов от команды Kaggle Если вы пользуетесь Twitter, то полезно следить за парой профилей, которые будут держать вас в курсе всего нового на Kaggle. Kagoole (https://twitter.com/kagoole) — это веб-приложение, которое может информировать вас о новых соревнованиях, а также в форме приложения для Heroku (https://kagoole.herokuapp.com/) предос- тавляет вам решения для прошедших соревнований. Оно было создано Doarakko (https://github.com/Doarakko/). Другой профиль в Twitter, за которым вы можете следить,— Is he Kerneler? (https://twitter.com/HKerneler). Он создан пользователем Regonn (https://github.com/ regonn/), который подскажет вам, сколько времени осталось до закрытия каждого активного соревнования Kaggle. Как мы знаем из главы /, Kaggle не единственная платформа, которая проводит со- ревнования по науке о данных. Для того чтобы лучше следить за происходящим на Kaggle и других сайтах, посвященных соревнованиям в этой сфере, мы предлагаем использовать такие сайты, как https://mlcontests.com/ или https://ods.ai/competitions. Они отслеживают все текущие конкурсы на Kaggle, а также на других платформах, таких как AlCrowd и DrivenData. Например, сайт mlcontests.com предоставляет информацию о призах, сроках и полезных ссылках для каждого соревнования. Он также позволяет сравнить облачные GPU по производительности, машинам и це- нам. Вы можете зарегистрировать свою электронную почту и получать большую часть этой информации прямо на свой почтовый ящик.
Глава 13. Создание портфолио проектов и идей 425 Резюме В этой главе мы обсудили подходы к демонстрации своей работы и выяснили, ка- кую пользу можно извлечь из этого при продвижении по карьерной лестнице. Это поможет вам продемонстрировать возможности, которые, хотя (конечно же) и не охватывают весь объем ваших знаний и опыта в области науки о данных, все же станут большим преимуществом. Для демонстрации своей работы вы можете использовать либо ресурсы Kaggle, ли- бо сторонние сервисы. Ресурсы Kaggle предлагают вам интегрированную среду и, если у вас все под рукой, вполне доступны и быстро настраиваются. Сторонние ре- сурсы (публикации на Medium, GitHub, HuggingFace Spaces и т. д.) более широко известны и доступны для большинства рекрутеров, сотрудников кадровых служб и менеджеров по найму, потому что они пользуются ими регулярно. В следующей главе мы завершим обсуждение возможностей, которые открывают перед вами соревнования Kaggle, рассказом о создании сети и о том, как использо- вать свои труды в Kaggle для получения приглашения на собеседование. Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
14 Поиск новых профессиональных возможностей После того как в предыдущей главе мы рассказали о том, как лучше освещать свою работу и достижения в соревнованиях, завершим обзор того, как Kaggle может по- ложительно повлиять на вашу карьеру. В последней главе обсуждаются наилучшие способы использования всех ваших трудов для поиска новых профессиональных возможностей. Мы полагаем, что теперь у вас есть все ранее описанные инструмен- ты (обсуждения Kaggle, блокноты и датасеты, а также аккаунт на GitHub, где пред- ставлено довольно много проектов, созданных на основе Kaggle), поэтому в этой главе мы перейдем к более мягким аспектам: как наладить связи и как представить свой опыт Kaggle рекрутерам и компаниям. Общеизвестно, что нетворкинг (работа по сети) открывает массу возможностей: от получения информации о новых вакансиях, не появляющихся на публичных пло- щадках объявлений, до того, что вам есть на кого положиться в решении задач, свя- занных с наукой о данных, в которых вы не являетесь экспертом. Работа по сети на платформе Kaggle в основном связана с командным сотрудничеством во время со- ревнований и связями, установленными во время встреч и других мероприятий, организованных кэгглерами. Когда речь идет о вакансиях, как мы часто повторяли ранее, Kaggle не является широко признанным источником, используемым отделами 4i z кадров и менеджерами по найму для отбора кандидатов. Некоторые /Нч компании действительно принимают во внимание ваши рейтинги и дос- 5 тижения в Kaggle, но это особый случай, а не общее правило. В основ- ном следует ожидать, что ваш опыт работы на платформе Kaggle будет проигнорирован, а иногда даже раскритикован.
Глава 14. Поиск новых профессиональных возможностей 427 Однако мы можем утверждать, что полученные на практике в Kaggle знания очень ценные, а профессиональную деятельность можно про- двигать, демонстрируя свои труды по программированию и моделиро- ванию и рассказывая о своем опыте работы в одиночку или в команде. В данной главе мы рассмотрим: • налаживание связей с другими исследователями данных на соревнованиях; • участие в Kaggle Days и других встречах Kaggle; • привлечение к себе внимания и другие возможности трудоустройства. Налаживание связей с другими исследователями данных на соревнованиях Связи очень важны для поиска работы, т. к. они помогают установить контакт с людьми, которые могут знать о вакансии до того, как она станет достоянием обще- ственности и начнется поиск потенциальных кандидатов. В последние годы Kaggle все больше превращается в место, где можно общаться с другими исследователями данных, сотрудничать и заводить друзей. Раньше соревнования не вызывали боль- шого количества обменов мнениями на форумах, и команды сильно ущемлялись в глобальном рейтинге, поскольку очки соревнований делились поровну между чле- нами команды. Улучшение системы рейтинга (см. https://www.kaggle.com/general/ 14196) помогло многим кэгглерам увидеть объединение в более выгодном свете. Объединение в команду для участия в конкурсе Kaggle отлично подходит, если вы уже знакомы с другими членами команды и у вас уже есть устоявшийся подход к распределению задач и удаленному сотрудничеству. В таких ситуациях каждый член команды уже знает, как совместно выполнять работу: • взять на себя часть экспериментов, согласованных с членами команды; • совместно работать с другим членом команды над созданием решения; • искать новые решения на основе своих навыков и опыта; • подготовить модели и материал, чтобы легко можно было проводить стекинг и блендинг. Однако если вы новичок в командной работе, вам будет трудно влиться в команду или организовать ее самостоятельно. Если у вас нет налаженных контактов, вам будет сложно связаться с другими людьми, чьи имена указаны в таблице лидеров. Поначалу многие из них не захотят объединиться, потому что предпочитают участ- вовать в соревнованииях в одиночку. Более того, некоторые участники могут быть заинтересованы в объединении, но будут слишком осторожны, чтобы принять ваше предложение.
428 Часть III. Использование соревнований в своей карьере При формировании команды из незнакомых вам кэгглеров есть несколько причин для беспокойства: • человек, пришедший в команду, не принесет никакой пользы команде; • человек, пришедший в команду, на самом деле не будет сотрудничать, а бу- дет просто нахлебником; • человек, пришедший в команду, нарушил (или нарушит) правила Kaggle, что приведет к дисквалификации всей команды; • человек, пришедший в команду, на самом деле заинтересован в шпионаже и утечке информации в другие команды. Большинство из этих ситуаций являются патологическими в соревновании, и вы должны знать, что это обычные соображения, которые приходят на ум многим при оценке разумности объединения с другим кэгглером. Вы можете развеять эти пред- полагаемые потенциальные страхи, только представив себя как профессионала с большим опытом работы в Kaggle. То есть вы должны быть человеком, который самостоятельно принимал участие в некоторых соревнованиях и, в частности, пуб- ликовал блокноты и участвовал в обсуждениях. Это придаст вашему предложению большую убедительность и, скорее всего, позволит принять вас в команду. Когда вы наконец-то присоединитесь к команде, важно установить эффективные и целенаправленные формы общения между ее членами (например, создать канал в Slack или Discord). Также необходимо договориться о ежедневных операциях, которые включают в себя: • решение о том, как разделить ваши усилия по проведению экспериментов; • решение о том, как использовать ежедневные отправки предложений, коли- чество которых ограничено (часто становится причиной конфликтов в ко- манде). В конце концов, только руководитель группы выбирает два послед- них предложения, но процесс достижения этой цели, естественно, включает в себя обсуждение и разногласия. Будьте готовы продемонстрировать своим сокомандникам аргументы в пользу того, почему вы выбрали определенные представления в качестве окончательных, показав им стратегию и результаты локальной перекрестной валидации. Получив положительный опыт совместной работы в команде, вы, несомненно, за- воюете уважение и доверие других членов команды. В будущих соревнованиях вам, вероятно, будет легче снова объединиться с теми же людьми или с их помо- щью присоединиться к другой команде, в которую они входят. Среди людей, с которыми вы встретитесь и сможете поработать на Kaggle, есть ис- следователи данных, энтузиасты в области данных, студенты, специалисты в этой области и многие другие. Ниже мы приводим интервью с различными кэгглерами, которые рассказали о своей работе и о том, как Kaggle вписывается в их жизнь.
Глава 14. Поиск новых профессиональных возможностей 429 Иран Чзан https://www.kaggle.com/gogo827jz Иран Чзан— аспирант последнего курса в Королевском колледже Лондона (King’s College London). Гроссмейстер в категориях Notebooks и Discussion, он был членом коман- ды-победительницы в соревновании Street Market Prediction (https://www.kaggle.eom/c/jane-street-market-prediction). Расскажи немного о себе Сфера моих исследований лежит в области применения алгоритмов машинного обучения для решения сложных задач в современных беспроводных сетях связи, таких как прогнозирование временных рядов, распределение ресурсов и оптими- зация. Я также участвовал в проектах по изучению конфиденциальности искус- ственного интеллекта, федеративного обучения, сжатия и передачи данных. Помимо ежедневных исследований в рамках работы над диссертацией, я активно работаю на Kaggle уже почти два года, начиная со второго года обучения в аспи- рантуре. Первым соревнованием, в котором я участвовал на Kaggle, было Instant Gratification, в котором я использовал различные методы машинного обучения и статистики из библиотеки sklearn. Этот конкурс помог мне выработать общее представление о том, что такое конвейер моделирования машинного обучения для соревнований Kaggle. Я активно делился своими знаниями с сообществом в виде блокнотов и постов в обсуждениях на Kaggle и теперь стал гроссмейстером Kaggle в категориях Note- books и Discussion. Делясь информацией и обсуждая проблемы с другими участ- никами на форуме, я получил ценные отзывы и новые знания, которые также по- могли мне недавно стать победителем соревнования Kaggle. Расскажи о соревновании, в котором ты победил Соревнование Jane Street Market Prediction было очень сложным. Причина в том, что было трудно создать надежную стратегию кросс-валидации (cross-validation, CV), и многие люди просто использовали публичную таблицу лидеров в качестве набора для валидации. Они обучали нейронную сеть в течение сотен эпох, не ис- пользуя стратегию валидации, чтобы превысить показатели публичной таблицы лидеров. Наша команда изо всех сил старалась сохранить собственную стратегию CV и выжила в этой гонке. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Соревнования Kaggle сильно отличаются от моих ежедневных исследований в рамках докторской диссертации. Первое — очень напряженная работа, и она дает мгновенную обратную связь, а второе — это длительный процесс. Однако я об- наружил, что новые знания и методология, которые я получаю на конкурсах Kaggle, также очень полезны в моих исследованиях в рамках диссертации.
130 Часть III. Использование соревнований в своей карьере Осаму Аки яма https://www.kaggle.com/osciiart Осаму Акияма, он же OsciiArt,— кэгглер, чья основная работа не связана с наукой о данных. Он врач в больнице Университета Осаки и мастер в категории Competitions. Расскажи немного о себе Я ординатор второго года обучения, работаю в больнице Университета Осаки. Я получил степень магистра в области биологии в Киотском университете. После работы в научно-исследовательском отделе фармацевтической компании я пере- велся на медицинский факультет Университета Осаки и получил медицинскую лицензию для работы в Японии. Я начал изучать науку о данных и искусственный интеллект самостоятельно, по- тому что был потрясен программой AlphaGo. Я стал участником платформы Kaggle, чтобы научиться и проверить свои навыки в области науки о данных и искусственного интеллекта. Моим первым соревнованием было NOAA Fisheries Steller Sea Lion Population Count в 2017 г. Я постоянно участвую в конкурсах Kaggle, и у меня три золотые медали. Помог ли тебе Kaggle в карьере? Если да, то как? Поскольку я не получал образования в области информационных наук, я исполь- зовал свои результаты в Kaggle, чтобы продемонстрировать свои навыки, когда подавал заявку на стажировку в компании, занимающейся искусственным интел- лектом, и заявку на краткосрочную стажировку в лаборатории искусственного интеллекта. Поскольку я врач, я никогда не использовал свои навыки работы с данными в сво- ей основной работе. Однако благодаря моим результатам в Kaggle у меня иногда появляется возможность участвовать в исследован ях мсдицинских данных. Какой вид соревнований у тебя самый любимый и почему? Мой любимый вид соревнований — это конкурсы по медицинским данным. Мне нравится пытаться найти какую-то информации и медицинских данных, ис- пользуя свои знания в области медицины. Опиши свой подход к соревнованиям Kaggle Мне нравится находить секретную характеристику данных соревнования, о кото- рой не знают большинство конкурентов, или пробовать уникальный подход, адаптированный к характеристикам данных конкурса. На самом деле, в боль- шинстве случаев такой подход не приносит успеха, но все же попробовать инте- ресно. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Я хотел бы упомянуть соревнование Freesound Audio Tagging 2019, в рамках ко- торого требовалось решить задачу классификации звуковых данных по несколь-
Глава 14. Поиск новых профессиональных возможностей 431 ким меткам. Данные для обучения состояли из небольшого количества надежно помеченных данных (чистые данные) и большего количества данных с ненадеж- ными метками (зашумленные данные). Кроме того, наблюдалась разница между распределением данных в обработанных и зашумленных наборах. Для того что- бы справиться с этой проблемой, мы использовали две стратегии. Первой стало многозадачное обучение, в котором обучение на зашумленных данных рассмат- ривалось как задача, отличная от обучения на чистых данных. Вторая страте- гия— псевдомаркировка (разновидность обучения с частичным привлечением учителя), при которой зашумленные данные перемаркируются предсказанными метками из модели, обученной на чистых данных. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я использую Signate (https://signate.jp/) и guruguru (https://www.gurugurii.science/). Это японские платформы для проведения соревнований по науке о данных. Они не такие большие, как платформы типа Kaggle; в конкурсах на этих площадках используются меньшие датасеты, чем обычно бывает в Kaggle, поэтому участво- вать в них проще. Кроме того, иногда проводятся интересные соревнования, от- личные от тех, что есть на Kaggle. Микель Бобер-Иризар https://www.kaggle.com/anokas Микель Бобер-Иризар, он же Anokas, — гроссмейстер со- ревнований, мастер в категориях Notebooks и Discussion, а также специалист по машинному обучению в ForecomAI. Он также является студентом факультета компьютерных наук Кембриджского университета и самым молодым гроссмейстером на Kaggle. Расскажи немного о себе Я присоединился к Kaggle в 2016 г., когда мне было 14 лет и я понятия не имел, чем занимаюсь — я просто прочитал в Интернете о машинном обучении, и это показалось мне крутым. В своих первых конкурсах я начинал с копирования публичного кода других людей с форумов и внесения в него небольших измене- ний. На протяжении нескольких соревнований я постепенно начинал понимать, как все работает, черпая мотивацию в стремлении подняться в таблице лидеров. Все так и происходило, пока я не начал делать успехи, кульминацией которых стало второе место в соревновании Avito Duplicate Ads Competition в том же году. С тех пор я принял участие в 75 соревнованиях, в 2018 г. стал самым молодым гроссмейстером соревнований и первым в истории трехкратным мастером. После этого я был приглашенным научным сотрудником в Университете Суррея, а сей- час изучаю компьютерные науки в Кембриджском университете, где также про- вожу исследования в области машинного обучения и безопасности.
2 Часть III. Использование соревнований в своей карьере Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Мне очень нравятся конкурсы с большим количеством возможностей для по- строения признаков, а также соревнования с большим количеством различных типов данных, которые позволяют вам действительно творчески подойти к ре- шению задачи. Это гораздо веселее, чем состязание, где все должны использо- вать один и тот же подход, и вы боретесь за последний знак после запятой. Я бы не сказал, что у меня есть какая-то специализация в плане подхода, но мне нравится пробовать разные методы работы. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Пару лет назад компания Google провела соревнование на определение объектов на изображениях и связей между ними (например, ’’стул за столом”). Другие ко- манды потратили целую вечность, используя традиционный подход и обучая большие нейронные сети для решения задач, и у меня не было ни знаний, ни вы- числительной техники, чтобы конкурировать с ними. Я решил подойти к про- блеме с другой стороны и, используя некоторые аккуратные эвристики и древо- видные модели, занял седьмое место всего за несколько часов работы. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle открыл для меня множество возможностей, и на этой платформе оказа- лось действительно замечательное сообщество, с которым мне удалось познако- миться. Я познакомился со многими людьми и получил внушительный объем знаний во всех соревнованиях, в которых участвовал. Но Kaggle — это еще и мой путь в машинное обучение, и я не думаю, что без этой платформы я работал бы в данной области. Так что да, эта площадка мне очень помогла. Какие ошибки ты допускал на соревнованиях? Очень легко получить сложное решение, которое невозможно повторить с нуля, поскольку есть вероятность, что вы будете использовать различные версии кода и промежуточные датасеты в своем окончательном решении. Затем, если вам по- счастливилось выиграть, может оказаться очень сложной задачей доставить ра- ботающий код на хост! Если у вас все в порядке, хорошо бы выяснить, в чем за- ключается ваше решение, и почистить код. Также легко попасть в ситуацию, когда вы используете различные валидацион- ные наборы для разных моделей или не сохраняете валидационные прогнозы, что может затруднить их сравнение или метаобучение на более поздних этапах со- ревнования. Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? Мне очень нравится XGBoost. Эта модель по-прежнему превосходит нейронные сети на табличных данных (а также ее более новый родственник, LightGBM). Метод SHAP действительно хорош для объяснения моделей (даже сложных), что позволит вам яснее понять, что еще попробовать дальше.
Глава 14. Поиск новых профессиональных возможностей 433 О чем важнее всего помнить, приступая к участию в соревновании? Я думаю, что важно не увязнуть в реализации сверхсложных решений, а попы- таться реализовать процесс постепенно. Сейчас конкурсы намного сложнее, чём когда я только начинал, поэтому полезно посмотреть на код других участников (многие делают его общедоступным во время соревнования) и попытаться научиться у них. Возможно, вам стоит поду- мать о том, чтобы присоединиться к команде кэгглеров: командные состязания были для меня самыми веселыми и всегда сопровождались фантастическим опы- том обучения. И наконец, большинство идей, как правило, не работает: если вы хотите выиг- рать соревнование, вам нужно упорствовать и продолжать экспериментировать! Kaggle, безусловно, оказал влияние на насыщенную жизнь и карьеру трех преды- дущих интервьюеров, а ведь они только в начале своего профессионального пути. Ниже мы поговорим с двумя кэгглерами, которые сейчас занимают руководящие должности в своих компаниях и прошли долгий и плодотворный путь также благо- даря Kaggle. Дэн Беккер https ://www. kaggle.com/dansbecker Первым у нас в гостях побывал Дэн Беккер, гроссмейстер в категории Notebooks и вице-президент по продукту, спе- циалист в сфере Decision Intelligence компании DataRobot. Kaggle сыграл важную роль в карьере Дэна. Расскажи немного о себе Впервые я попробовал использовать машинное обучение в стартапе из трех че- ловек в 2000 г., где мы пытались с помощью нейронных сетей помочь розничным торговцам оптимизировать резервные цены, которые они устанавливали для то- варов на eBay. Мы понятия не имели, что делаем, и не справились с задачей. К 2002 г. я был уверен, что машинное обучение никогда не сможет работать. Я получил степень по экономике и устроился на работу экономистом в правитель- ство США. Я хотел переехать в Колорадо, но там было не так много рабочих мест для кандидатов экономических наук. Поэтому я искал менее академический диплом. В 2010 г. я увидел в газете статью о премии Heritage Health Prize. Это было одно из первых соревнований Kaggle с призом в 3 млн долларов. Я по-прежнему счи- тал, что более простые модели, подобные тем, которые я использовал в качестве экономиста, дают лучшие прогнозы, чем причудливые модели машинного обу- чения. Поэтому я принял участие в соревновании, думая, что хороший результат станет тем дипломом, который мне нужен, чтобы найти интересную работу в Ко-
434 Часть III. Использование соревнований в своей карьере лорадо. Моя первая работа на этом соревновании заняла не последнее место, но была довольно близка к этому. Мое сердце сжалось, когда я увидел, что мою мо- дель оценили, а затем увидел, что все остальные намного опередили меня. На ка- кое-то время я оставил всякую надежду занять хорошую итоговую позицию на соревновании, но главное расстройство было вызвано даже не средним результатом. Я проводил все свои вечера и выходные, работая над конкурсным решением, чтобы подняться в таблице лидеров. Заново изучал машинное обучение, которое получило мощное развитие за 10 лет, прошедших с тех пор, как я впервые по- пробовал работать с ним. Я изучал все больше и каждый день загружал новую модель. Это заняло много времени, но было очень приятно каждый день подни- маться вверх по таблице лидеров. К тому времени, когда мой результат был в се- редине этой таблицы, я подумал, что дальнейшая работа может привести меня в 10% лучших. Поэтому я продолжал работать и вскоре оказался в 10% лучших. Потом я решил, что смогу попасть в десятку лучших участников соревнования. Когда я был в первой десятке, одна аналитическая консалтинговая компания свя- залась со мной, чтобы спросить, не хочу ли я оформиться к ним на работу и уча- ствовать в конкурсе под названием их компании, а они будут использовать это для маркетинга. Я сказал им, что согласен, если смогу работать из Колорадо. Та- ким образом, конкурс Kaggle помог мне достичь моей первоначальной цели. Мы заняли 2-е место. Приза за второе место не было, но всё, что я сделал в своей карьере с тех пор, стало возможным благодаря этому единственному соревнова- нию Kaggle. Это был больший успех, чем я мог себе представить. Помог ли тебе Kaggle в карьере? Если да, то как? Kaggle почти полностью сделал мою карьеру. Моя первая работа в качестве ис- следователя данных появилась, когда кто-то нанял меня из-за позиции в списке лидеров. Следующей моей работой после этого была работа в компании Kaggle. Затем я работал в компании DataRobot, чья стратегия подбора персонала в то время заключалась в том, чтобы нанимать людей, добившихся хороших резуль- татов на конкурсах Kaggle. Потом я вернулся в компанию Kaggle и основал Kaggle Learn, которая стала образовательной платформой Kaggle по науке о дан- ных. Список можно продолжать. Каждая работа, которую я получил за последние 10 лет, явно связана с моим первоначальным успехом на Kaggle. Поскольку я перешел от экономики к науке о данных, мои достижения в Kaggle стали основой того, почему меня взяли на работу. Сейчас, находясь выше по карьерной лестнице, я не думаю о портфолио... и мне повезло, что меня чаще хо- тят нанять на работу, чем я ищу работу. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Я давно работаю в сообществе, но уже 7 или 8 лет не уделял время конкурсам. Мне нравятся новые виды соревнований. Например, я впервые познакомился с глубоким обучением в 2013 г. в рамках первых состязаний Kaggle, где глубокое обучение было конкурентоспособным. Это было до появления Keras, TensorFlow, PyTorch или любого из существующих сегодня фреймворков глубокого обуче-
Глава 14. Поиск новых профессиональных возможностей 435 ния. Никто в сообществе не знал, как реализовать глубокое обучение, поэтому все учились чему-то новому. На Kaggle также проводилось соревнование по состязательному моделированию, где некоторые люди строили модели, пытавшиеся немного манипулировать изо- бражениями, чтобы обмануть другие модели. Это был очень экспериментальный подход, и я не знаю, запустят ли они что-нибудь подобное снова. Но мне очень нравятся экспериментальные вещи, когда все члены сообщества вместе разбира- ются в форумах. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? В последние несколько раз, когда я участвовал в соревнованиях, я сосредоточил- ся на мысли: ’’Какие я могу создать для этого соревнования инструменты, спо- собные автоматизировать мою работу по всем проектам?" Задумка не была осо- бенно успешной, но стала интересным вызовом. Это очень отличается от того, как я подхожу к решению всех остальных задач в профессиональном плане. Вне конкурсов я обожаю аналитику и мне нравится просто изучать данные по интересным темам. Иногда я говорю, что моя сила как исследователя данных за- ключается в том, что я всего лишь смотрю на данные (без фильтрации с помо- щью моделей машинного обучения). Я также провожу много времени, размышляя о том, как выполнить переход от прогноза модели машинного обучения к принятию решения. Например, если мо- дель машинного обучения предсказывает, что продуктовый магазин продаст 1000 манго до того, как поступит следующая партия, сколько манго он должен дер- жать на складе? Некоторые считают, что ответ— 1000... именно столько, сколь- ко, по вашим прогнозам, вы сможете продать. Но это неверно. Необходимо подумать о компромиссе между стоимостью испорченного манго, если вы купите его слишком много, и стоимостью того, что он закончится. А ка- кой у них срок годности? Можете ли вы хранить дополнительные запасы до сле- дующей поставки? В этой модели можно выполнить много оптимизации, которая является частью моей повседневной работы, и задачи такого плана не появляют- ся на соревнованиях Kaggle. Расскажи о каком-нибудь сложном и интересном конкурсе и о том, как ты шел к решению Я пытался создать автоматизированную систему, которая занималась соединени- ем и построением признаков для задачи классификации сахарного диабета по ти- пу в рамках соревнования Practice Fusion Diabetes Classification. Главное, что я понял: если у вас больше, чем несколько файлов, вам все равно нужен человек, который будет смотреть на данные и понимать, какое построение признаков име- ет смысл. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Новые участники не понимают, насколько высока планка для успешного участия в соревнованиях Kaggle. Они думают, что могут вскочить и попасть в 50% луч-
436 Часть III. Использование соревнований в своей карьере ших, используя довольно общий подход... и это, как правило, не так. Больше все- го меня удивила значимость использования оценок лидеров для разных моделей при распределении весов при составлении ансамбля предыдущих представлений. Какие ошибки ты допускал на соревнованиях? Я несколько раз ошибался в деталях заявок в последнюю минуту на многоэтап- ных соревнованиях (и в результате занимал последнее или почти последнее место). Есть ли какие-то инструменты или библиотеки для анализа данных и машинного обучения, которые ты можешь порекомендовать? В основном стандартные вещи. За пределами конкурсов Kaggle мне лично нра- вится Altair для визуализации... и я пишу много SQL-кода. SQL предназначен для просмотра простых агрегаций или тенденций, а не для построения сложных мо- делей, но я думаю, что это скорее особенность, чем ошибка. Чжон Юн Ли https://www.kaggle.com/jeongyoonlee Наконец, у нас в гостях Чжон Юн Ли, многократно отме- ченный медалями мастер в категории Competitions и стар- ший научный сотрудник группы разработки алгоритмов ранжирования и поиска в Netflix Research. Расскажи немного о себе Меня зовут Чжон, я старший научный сотрудник компании Netflix. На платфор- ме Kaggle я с 2011 г., когда закончил аспирантуру и начал работать в консалтин- говой компании Opera Solutions, специализирующейся на аналитическом консал- тинге. Там я познакомился с заядлыми участниками соревнований Kaggle, включая Михеля Ярера (Michael Jahrer), и мы вместе участвовали в KDD Cups и соревнованиях Kaggle. С тех пор, даже после ухода из компании, я продолжаю работать на соревнова- ниях и как участник, и как организатор. В последнее время я не так много време- ни провожу на Kaggle, как раньше, но все же периодически заглядываю туда, чтобы узнать о новейших инструментах и подходах в области машинного обучения. Помог ли тебе Kaggle в карьере? Если да, то как? Невероятно. Во-первых, он предоставляет своего рода диплом в области машин- ного обучения. Многие менеджеры по найму (когда я проходил собеседование), а также кандидаты (когда я проводил собеседование) упоминали, что мои дости- жения в Kaggle привлекли их внимание. Во-вторых, эта платформа обеспечивает обучение самым современным подходам в ML. Благодаря работе над более чем 100 соревнованиями в различных областях, я знаком с большим количеством подходов к решению практически любой задачи машинного обучения, чем мои коллеги. В-третьих, эта платформа дает доступ к целой сети высококлассных ис- следователей данных по всему миру. В Kaggle я познакомился с огромным коли-
Глава 14. Поиск новых профессиональных возможностей 437 чеством талантливых исследователей данных, и мне нравится с ними работать. Я перевел книгу Абхишека Тхакура, организовал панель на KDD с Марио, Гибой и Абхишеком и сейчас даю интервью для книги Луки.;) В 2012 г. я использовал Factorization Machine, которая была представлена Штеф- феном Рендлом (Steffen Rendle) на KDD Сир 2012, и улучшил производитель- ность предсказания на 30% по сравнению с существующей SVM-моделью через месяц после моего прихода в новую компанию. В стартапе, соучредителем кото- рого я был, нашим основным предложением был ансамблевый алгоритм, кото- рый должен был победить стандартную для рынка линейную регрессию. В ком- пании Uber я ввел проверку на состязательность для решения проблемы ковариационных сдвигов в признаках в конвейерах машинного обучения. Какой вид соревнований ты любишь больше всего и почему? Есть ли у тебя какая-то специализация на Kaggle в плане методов и подходов к решению задач? Мне нравятся соревнования с небольшими и средними датасетами, в основном с табличными данными, потому что я могу быстро итерировать различные подхо- ды даже на своем блокноте в любое время в любом месте. Во время пика моей работы в Kaggle в 2015 г. я часто создавал свои решения в самолете или в пере- рывах между сменами няни. Мои тройняшки родились в конце 2014 г., и я рабо- тал в новом стартапе, в котором был одним из основателей. Я не думаю, что у меня есть какие-то особые методы моделирования, но моя специализация больше связана с управлением соревнованиями, что включает в себя набор членов команды, создание системы совместной работы (например, Git, S3, Messenger, Wiki, внутренняя таблица лидеров, кросс-валидационные раз- деления), помощь команде в эффективной работе на протяжении всего соревно- вания и т. д. Так что я сам не стал гроссмейстером соревнований, но смог дос- тичь уровня топ-10, потому что другим гроссмейстерам нравилось со мной работать. Опиши свой подход к соревнованиям. Как он отличается от твоей обычной работы? Я стараюсь построить конвейер, который позволяет быстро проводить итерации и инкрементные улучшения. Чем больше идей вы постараетель реальзовать, тем больше у вас шансов на хороший результат по итогам конкурса. Этот принцип применим и к моей повседневной работе. Однако масштабы разные. На работе мы начинаем с определения проблем и выявления данных, в то время как на Kaggle и то и другое дано, и мы начинаем с разведочного анализа данных. По твоему опыту, какие ошибки делают начинающие кэгглеры? Что ты хотел бы знать, когда начинал участвовать в соревнованиях? Недавно я заметил, что многие пользователи просто делают форк блокнота, ко- торым поделились другие пользователи, и дорабатывают его, чтобы получить более высокие оценки. В конечном счете важны полученные знания, а не рейтинг Kaggle или баллы. Я рекомендую новичкам-кэгглерам уделять больше времени созданию собственных решений.
438 Часть III. Использование соревнований в своей карьере О чем важнее всего помнить, приступая к участию в соревновании? Главное — обучение, а не победа. Пользуешься ли ты другими соревновательными платформами? Сравни их с Kaggle Я консультирую Dacon AI — корейскую компанию-платформу для проведения соревнований по машинному обучению. Она начала работать в 2018 г. и на дан- ный момент провела 96 конкурсов. Эта платформа все еще находится на ранней стадии развития по сравнению с Kaggle, но позволяет приобрести схожий опыт корейским пользователям. Участие в Kaggle Days и других встречах Kaggle Хороший способ наладить связи с другими кэгглерами (а также упростить процесс принятия в команду) — просто встретиться с ними. Встречи и конференции всегда были хорошим способом знакомства и укрепления взаимоотношений, даже если они не касаются конкретно конкурсов Kaggle, потому что докладчики рассказыва- ют о своем опыте работы на платформе или потому что рассматривались темы, свя- занные с соревнованиями Kaggle. Например, многие исследовательские соревнова- ния требуют от успешных участников написать о своем опыте доклад, который может быть представлен или процитирован во время выступления на конференции. Специальных мероприятий, напрямую связанных с Kaggle, не было до 2018 г., когда компания LogicAI, созданная Марией Парыш (Maria Parysz) и Павлом Ян- кевичем (Pawel Jankiewicz), в сотрудничестве с Kaggle организовала первое меро- приятие Kaggle Days в Варшаве (Польша). Они собрали более 100 участников и 8 гроссмейстеров Kaggle в качестве докладчиков. Затем последовали другие мероприятия в формате Kaggle Days. Далее перечислены мероприятия, которые были организованы, а также ссылки на материалы и выступ- ления: • Варшава, май 2018 г. (https://kaggIedays.com/events/warsaw2018); • Париж, январь 2019 г. (https://kaggledays.com/events/paris2019); • Сан-Франциско, апрель 2019 г. (https://kaggledays.com/event/sanfrancisco2019); • Дубай, апрель 2019 г. (https://kaggIedays.com/events/dubai2019); • Пекин, октябрь 2019 г. (https://kaggledays.com/events/beijing2019); • Токио, декабрь 2019 г. (https://kaggledays.com/events/tokyo2019). Начиная со второго мероприятия в Париже, в разных городах проводились более мелкие мероприятия в формате встреч (более 50 встреч в 30 различных местах). Участие в крупномасштабном мероприятии или во встрече — очень хорошая воз- можность познакомиться с другими кэгглерами и завести друзей, что может быть
Глава 14. Поиск новых профессиональных возможностей 439 полезно как для карьеры, так и для объединения в команды для будущих соревно- ваний Kaggle. На самом деле, один из авторов нашел свою следующую работу именно таким об- разом. Привлечение к себе внимания и другие возможности трудоустройства В течение некоторого времени Kaggle был горячей точкой, где работодатели могли найти людей редкой компетенции в области анализа данных и моделирования ма- шинного обучения. Сама платформа Kaggle предлагала доску вакансий среди фо- румов обсуждений, и многие рекрутеры просматривали таблицу лидеров в поисках профилей людей, с которыми можно было бы связаться. Компании сами проводили конкурсы специально для поиска кандидатов (Facebook, Intel и Yelp устраивали со- ревнования по подбору персонала с этой целью) или для удобства отбора лучших участников, увидев, что те отлично справляются с определенными видами задач (как это сделала страховая компания АХА после проведения состязаний по телема- тике). Пиком всего этого стало интервью Wired с Жилберту Титеричем (Gilberto Titericz), в котором говорилось, что "высококлассные специалисты по решению задач завалены предложениями о работе" (https://www.wired.com/story/solve-these- tough-data-problems-and-watch-job-offers-roll-in/). В последнее время ситуация несколько изменилась, и многие кэгглеры сообщают, что лучшее, на что вы можете рассчитывать после победы или высоких результатов в соревновании, — это контакты с рекрутерами в течение нескольких месяцев. Да- вайте посмотрим, как все изменилось и почему. В настоящее время редко можно встретить предложения о работе, предполагающие наличие опыта профессиональной деятельности в рамках Kaggle, поскольку чаще всего компании требуют предыдущий опыт работы в этой области (еще лучше — в той же отрасли или области знаний), академическую подготовку по математиче- ским дисциплинам или сертификаты Google, Amazon или Microsoft. Ваше присут- ствие на Kaggle все равно будет иметь определенный эффект, потому что это по- зволит вам: • быть замеченными рекрутерами, которые следят за рейтингами и соревнова- ниями Kaggle; • быть замеченными самими компаниями, поскольку многие менеджеры и от- делы кадров следят за профилями Kaggle; • у вас будут доказательства ваших способностей к программированию и ма- шинному обучению, которые могут помочь компаниям выбрать вас, возмож- но, не требуя от вас прохождения каких-либо дополнительных тестов; • иметь конкретный опыт в решении задач, актуальных для определенных компаний, которые невозможно решить иным способом, поскольку данные не всем доступны (например, телематика, выявление мошенничества или дипфейков, которые были темами конкурсов Kaggle).
440 Часть III. Использование соревнований в своей карьере Однако редко ваши результаты и рейтинги будут приниматься во внимание по но- миналу, поскольку трудно отделить ваше мастерство от других влияющих на ре- зультаты факторов, которые представляют меньший интерес для компании, ду- мающей о приеме вас на работу (например, время, которое вы можете посвятить соревнованиям, доступность оборудования или удача). Ваши рейтинги и результаты Kaggle скорее всего будут замечены в следующих случаях: • вы показали высокие результаты в соревновании, проблема которого особен- но важна для компании; • вы систематически демонстрируете высокие результаты в многочисленных конкурсах по темам, представляющим интерес для компании, что является признаком реальной компетентности и означает, что вы не просто навеши- ваете на себя ярлык ’’исследователь данных’’ или ’’инженер машинного обу- чения’’, не имея на то веских оснований; • своим участием в Kaggle вы демонстрируете истинную страсть к анализу данных настолько, что тратите свое свободное время бесплатно. Это положи- тельный момент, но он также может стать палкой о двух концах и привести к получению более низких денежных предложений, если вы не покажете, что осознаете свою ценность. Хотя сами по себе они могут не иметь решающего значения, ваши рейтинги и ре- зультаты Kaggle могут выступать в качестве дифференцирующих факторов. Рек- рутеры и компании могут использовать рейтинги Kaggle для составления списков потенциальных кандидатов. Два наиболее заметных рейтинга — это рейтинги в ка- тегориях Competitions и Notebooks соответственно (поэтому в них также более ин- тенсивная конкуренция и большее количество гроссмейстеров из четырех рейтин- говых областей), но иногда они также следят за рейтингами для определенного соревнования. Когда востребованы определенные редкие специалисты (например, в NLP или компьютерном зрении), их легче найти среди участников конкурсов, ко- торые требуют умелого использования этих навыков для достижения успеха. Еще одним важным отличительным признаком является время собеседования. Мо- жете цитировать свои достижения в соревнованиях, чтобы показать, как вы решали задачи, как программировали решения, как взаимодействовали и сотрудничали с товарищами по команде. В таких случаях, помимо рейтинга или медали, которую вы получили от Kaggle, важно рассказать о специфике соревнования. Например, о том, к какой отрасли оно относится, с каким типом данных вам пришлось работать и почему оно вас заинтересовало, а также представить свои действия во время кон- курса, используя методику STAR, которая часто используется на собеседованиях при приеме на работу. Методика STAR В методике STAR вы должны структурировать то, что вы сделали в соревновании, основываясь на схеме: ситуация, задача, действие и результат. Этот метод на-
Глава 14. Поиск новых профессиональных возможностей 441 правлен на то, чтобы вы больше говорили о поведении, чем о технике, тем самым делая акцент на ваших возможностях, а не на возможностях выбранного вами алго- ритма; любой другой мог бы использовать тот же алгоритм, но именно вам удалось применить его так успешно. Этот метод главным образом помогает при работе с историями успеха, но его можно применять и к неудачным историям, особенно в ситуаци- ях, когда вы получили важные знания о причинах неудачи, и эти знания не позволили вам допустить повторения неудачного решения. Для того чтобы применить этот метод, необходимо разбить свою историю работы на четыре составляющие: • ситуация: опишите контекст и ее детали, чтобы интервьюер мог с первого взгляда понять задачи и возможности; • задача: опишите свою конкретную роль и обязанности в данной ситуации, акцентируя внимание на своем личном вкладе с точки зрения навыков и по- ведения; • действие: объясните, какие действия вы предприняли, чтобы справиться с задачей; • результат: проиллюстрируйте результаты ваших действий, а также общий результат. Некоторые компании прямо просят использовать методику STAR (или ее аналог, метод "цель — воздействие — проблемы — поиск", где больше внимания уделяет- ся результатам); другим это не нужно, но они ожидают чего-то похожего. Лучшими ответами будут те, что соответствуют ценностям и целям компании, в которой вы проходите собеседование. Поскольку простого сообщения о рейтингах и медалях, полученных вами на сорев- нованиях, может быть недостаточно, чтобы произвести впечатление на интервьюе- ра, переформулируйте свой успешный опыт участия в соревнованиях Kaggle. Такой подход может работать как в одиночных соревнованиях, так и в команде. В послед- нем случае важным аспектом для описания является то, как вы взаимодействовали с другими членами команды и оказывали на них положительное влияние. Давайте обсудим некоторые способы решения этой задачи. Сначала вы описываете ситуацию, которая возникла в ходе соревнования. Она мо- жет происходить на начальных этапах, на этапах экспериментов или на этапе под- ведения итогов. Важно предоставить четкий контекст, чтобы слушатель мог оце-
442 Часть III. Использование соревнований в своей карьере нить, было ли ваше поведение правильным для данной ситуации. Описание должно быть очень подробным. Также необходимо объяснить ситуацию, почему она по- требовала вашего внимания и действий. Затем следует объяснить, за какую задачу вы взялись. Например, это может быть очистка данных, разведочный анализ данных, создание эталонной модели или по- стоянное совершенствование вашего решения. Далее вы описываете, как выполняли задание. Здесь будет весьма кстати, если вы сможете представить статью на Medium или проект на GitHub в поддержку своего описания (как мы обсуждали в предыдущей главе). Систематическое представление своего опыта и компетенции с помощью хорошо написанной документации и пра- вильного программирования позволит усилить ценность вашего предложения пе- ред интервьюером. Наконец, вы должны объяснить полученный результат, который может быть как качественным (например, как вы координировали работу команды, участвующей в соревновании Kaggle), так и количественным (скажем, как сильно ваш вклад по- влиял на конечный результат). Резюме (и несколько напутственных слов) В этой главе мы обсудили, как участие в соревнованиях на платформе Kaggle мо- жет помочь улучшить ваши карьерные перспективы. Мы затронули тему создания связей как путем объединения в команды для участия в соревнованиях и участия в мероприятиях, связанных с прошедшими соревнованиями, так и путем использова- ния вашего опыта Kaggle для поиска новой работы. Мы уже говорили о том, что, исходя из нашего опыта и опыта других кэгглеров, результаты на Kaggle сами по себе не могут гарантировать получение желаемой должности. Однако они способ- ны помочь вам привлечь внимание рекрутеров и отделов кадров, а затем подкре- пить ваши представления о компетенции в области науки о данных (если знания сопровождаются тщательно составленным портфолио, как мы описали в предыду- щей главе). Эта глава также завершает книгу. В четырнадцати главах мы обсудили конкурсы Kaggle, датасеты, блокноты и обсуждения. Мы рассмотрели технические темы ма- шинного обучения и глубокого обучения (от метрик оценки до симуляционных со- ревнований) с целью помочь вам добиться большего как на Kaggle, так и вне этой платформы. Участвуя в соревнованиях Kaggle в течение десяти лет, мы хорошо усвоили, что на этой площадке можно найти все, что вам нужно знать, но все разбросано по сотням конкурсов и тысячам блокнотов, обсуждений и датасетов. Поиск в момент необхо- димости того, что вам нужно, может оказаться сложной задачей для тех, кто только начинает свой путь на платформе Kaggle. Мы собрали все необходимые, на наш взгляд, знания, способные помочь вам сориентироваться во всех соревнованиях, в которых вы, возможно, захотите принять участие. Поэтому это книга не о науке о данных в строгом смысле слова, а именно о науке о данных на платформе Kaggle.
Глава 14. Поиск новых профессиональных возможностей 443 Помимо технических и практических советов мы также хотели донести до вас, что за более чем десять лет мы всегда находили способ превратить наш опыт на Kaggle в положительный. Вы можете перечитать эту книгу, в которой описано наше бес- конечное путешествие по миру соревнований в сфере науки о данных. Путешествие в Kaggle не заканчивается, когда вы получаете все титулы гроссмейстера и зани- маете первое место в мире. На самом деле оно никогда не заканчивается, потому что вы можете изобретать новые способы участия и использовать свой опыт в со- ревнованиях бесконечным числом способов. После перелистывания последней страницы начинается ваше путешествие по Kaggle, и мы желаем вам долгого, бога- того и плодотворного опыта — как это было в нашем случае. Приятного путешествия! Присоединяйтесь к нашему сообществу в Discord! Присоединяйтесь к обсуждению книги в Discord: https://packt.link/KaggleDiscord
Предметный указатель А Accuracy 116 Adversarial validation 153,169 albumentations 309 Area under curve (AUC) 108 AutoGluon 295 AutoViz 188 Average precision 119 в Batch 103 Bias 151 Boruta 203 BorutaShap 203 c CatBoost 231 Central processing unit (CPU) 45 Cohen Kappa 125 Common Objects in Context (COCO) 334 Common Task Framework (CTF) 41 Concept drift 173 Connect X 385 Cost function 103 CTGAN, нейросеть 183 D Data leakage 176 Denoising autoencoders (DAEs) 207 Detectron 333 Detectron2 333 Dice coefficient 132 DistilBERT 354 E Error function 103 Evaluation metric 102 Exploratory data analysis (EDA) 182,188 F Fp-мера 120 Fi-мера 120 fastpages 420 Feature engineering 193 Forking 71 G gc, библиотека 193 GitHub 73,421 Google Cloud Platform (GCP) 76 Google Colab 63 Gradient boosting decision trees (GBDT) 228 Grid search 219 H Halving algorithm 219 High-cardinality feature 198 HistGradientBoosting 232 HuggingFace Spaces 423 Hyperopt 265 I International Collegiate Programming Contest (ICPC) 26 Interquartile range (IQR) 196 Intersection over union (loU) 131,339
Предметный указатель 445 К Kaggle Learn 82 Kaggle Notebooks 45,63,67 KDD Cup 26 Keras 305 KerasTuner 256 L Leave-one-out (LOO) 153,155,162,167 LightGBM 228 Log Loss 108,120,124,139 Loss function 103 Lossless compression 192 M MAP@{K} 108,133 Mean absolute error (MAE) 115 Mean squared error (MSE) 112 Meta Kaggle 105,135 N Natural language processing (NLP) 350 Neural Oblivious Decision Ensembles (NODE) 213 nlpaug 380 No free lunch theorem (NFL) 27,372 о Objective function 102,103 One-hot encoding 195 Open Data Science, сообщество 32 Optuna 266 Out-of-fold (OOF) predictions 161,370 Overfitting 151 p Pandas Profiling 189 Pixel accuracy 130 Precision 118 Q Quadratic Weighted Kappa 108,110,124,138,139 R Random search 219 RAPIDS 190 Recall 118,119 Receiver operating characteristic curve (ROC curve) 121 Rectified Adam 259 Recurrent neural networks (RNN) 258 Reinforcement learning (RL) 103, 384 ROC-AUC 121 ROC-кривая 121 Root mean squared error (RMSE) 113 Root mean squared logarithmic error (RMSLE) 108, 114 Я-квадрат (R2) 112 s Scikit-multilearn 157 Scikit-optimize 236 Scoring function 103 Sentiment analysis 350 Stability selection 202 Stochastic Weighted Averaging (SWA) 259 Sum of squared errors (SSE) 112 Sum of squares total (SST) 112 Support-vector machine classification (SVC) 219 Support-vector machines (SVM) 219 Swap noise 209 Sweetviz 189 Symmetric mean absolute percentage error (sMAPE) 116 TabNet 213 Tabular Playground Series 183 Tensor processing unit (TPU) 45,302 Tree-structured Parzen estimators (TPE) 235 t-SNE 190 u UMAP 190 Universal Sentence Encoder 365 V Validation loss 151 Variance 151 W,X,Y Weighted Root Mean Squared Scaled Error 116 XGBoost 230 Yolov5 320
446 Предметный указатель А Автокодировщик 207 Автокорреляция 158 Алгоритм сокращения вдвое 219 Анализ: данных разведочный 182,188 кластерный 157 сентиментальный 350 тональности текста 350 Аугментация данных 299 Б Блендинг 283 Блокнот: запуск 71 создание 68 сохранение в GitHub 73 Бустинг градиентный 272 над решающими деревьями 228 Бутстрэп 153,162 Бэггинг 272 в Валидация 144,148 с имитацией тестового множества 173 стратегия 152 Выбросы данных 195 Вычисление частот и статистик по группам 196 г Голосование 277 "Горлышко бутылочное" 208 д Данные: аугментация 299 выбросы 195 значение пропущенное 195 сбор 57 уменьшение размера 191 Дерево экстремально рандомизированное 227 Детектирование объекта 129 Дискретизация численных признаков 194 Дисперсия ответов 112 Доля: верно классифицированных пикселов 130 правильных ответов 116,118 Е Емкость 150 3 Задача: классификации 103,104 регрессии 103,104 Закон больших чисел 154 Зондирование решений 43 и Индекс: Жаккара 131,132 удобства использования 57 Интервал межквартильный 196 к Калибровка: вероятностей 283 Плата 141 Камень, ножницы, бумага 390 Каппа Коэна 125 Каркас для общих задач 41 Квадратично взвешенная каппа 108,110,124, 138,139 Классификация 104 бинарная 104 изображений 312 многоклассовая 104,105,123 объектов 319 с пересекающимися классами 104 со многими метками 104 Кодирование: категориальных признаков 195 прямое 195 целевое 231 частотное 196 Конкурс табличный 211 Контроль: по к блокам 154,156 стратифицированный 157 по отдельным объектам 153, 155, 162 Корреляция Спирмена 360 Коэффициент: Дайса 132 детерминации 112 корреляции Мэтьюса 122
Предметный указатель 447 Кривая рабочей характеристики приемника 121 Кросс-валидация 153 вложенная 160 Кросс-энтропия 120 Курс учебный 82 л Лес случайный 227, 272 м Матрица: Гессе 137 несоответствий 117 Машина опорных векторов 219,225 Медаль 50 Метамодель 283 Метапризнак 196 Метод: лассо 202 опорных векторов 219 сигмоиды 141 сокращения вдвое 222 Метрика 102 632+ 163 AUC108 Fp-мера 120 FrMepa 120 IoU 133 Log Loss 108,120,124,139 МАЕ 115 MAP@{K} 108,133 Quadratic Weighted Kappa 108,110,124, 138,139 RMSLE 108 ROC-AUC 121 ROC-кривая 121 каппа Коэна 125 коэффициент Дайса 133 кросс-энтропия 120 оптимизация 134 полнота 118,119 специфичность 118 точность 118 чувствительность 119 Множество: контрольное 160 тестовое 160 Модель линейная 225 Мошенничество 43 н Нахождение объекта 129 Нейросеть 210 о Обнаружение объектов 319 Обработка естественного языка 350 Обучение: глубокое 129 на примерах 173 с подкреплением 103, 384 Оптимизация байесовская 235 Остановка ранняя 317 Отбор стабильный 202 Ответвление 71 Отношение площадей ограничивающих рамок 131,339 Ошибка: абсолютная средняя 115 симметричная процентная 116 среднеквадратичная 113 логарифмическая 114 п Пакет 103 Переобучение 151 Платформа конкурсная 31 Площадь под кривой 108 Подавление 172 Подход эмпирический байесовский 200 Поиск: по сетке 219 случайный 219, 221 Полнота 118,119 Портфолио 405,407 Постобработка 138 Потеря логарифмическая 108,120,124,139 Правило Стерджеса 157 Предсказание: на контрольном множестве 161, 370 на тестовом множестве 161 усреднение 279 Преобразование: нелинейное 113 признаков 182,193 Признак объекта 193 большой мощности 198 возведение в степень 195 временной 194 выброс данных 195
448 Предметный указатель дискретизация 194 значение пропущенное 195 категориальный 198 объединение 195 отбор 202 перемешивание 203 преобразование 194 производный 194 разделение 195 рандомизация 203 Программирование спортивное 26 Стратификация 154 Стэкинг156,198 т Теорема о бесплатном обеде 27,372 Токенизация 354 Точность 118 средняя 119 У Процессор: тензорный 45, 302 центральный 45 Псевдометка 205 Усреднение предсказаний 279 Утечка в данных 42,176 золотая 43 на уровне объектов 177 р на уровне признаков 177 протекающие примеры 178 Равновесие Нэша 390 Разбиение случайное 162 Разброс 151 Регрессия 104,105 изотоническая 141 Рейтинг общий 49 ф Форкинг 71 Форум 87 Функция: выбора 265 с калибровки 141 оценочная 103 Сегментация 130 семантическая 130, 333 экземпляров 130 Семплирование 153 случайное 156 Сеть нейронная 210 рекуррентная 257 Сжатие без потерь 192 Сигмоида 141 Сложность 150 Смещение 151 Согласованность аннотаций 125 Сокращение вдвое 222 Соревнование, категория 36 Специфичность 118 Стек глубокий 209 Стекинг 272, 289 Стратегия: ошибки 103 потерь 103 при валидации 151 стоимости 103 суррогатная £65 целевая 102,103 ч Чувствительность 119 ш Шум 151 добавление 209 э валидационная 152 разделения данных 152 Экспериментирование систематическое 147 Этикет сетевой 97
Книга Kaggle Конкурсы Kaggle — это поле для состязаний, где меряются силами миллионы специалистов по науке о данных (data science), которые сами себя именуют «кэгглерами». Участие в таких конкурсах — вер- ный способ профессионально вырасти в области анализа данных, влиться в замечательное сообще- ство единомышленников и приоб- рести бесценный опыт для развития карьеры. Авторы книги — гранд- мастера Kaggle. Они познакомят вас со стратегиями моделирования, которые более нигде не рассмо- трены, и подскажут, как удобнее всего обрабатывать изображения, тексты, таблицы, как правильно реализовать обучение с подкре- плением. Вы освоите качественные схемы валидации и станете уверен- но ориентироваться в самых раз- ных оценочных метриках. В книге рассказано: • Как устроена соревновательная платформа Kaggle • Как выжать максимум из ноутбуков, датасетов и форумов Kaggle • Как правильно собирать портфолио проектов и идеи для развития карьеры • Как проектировать к-мерные и вероятностные схемы валидации • Как освоить наиболее распространенные и экзотические оценочные метрики • Как устроена бинарная и многоклассовая классификация объектов, а также их обнаружение • Как эффективно обращаться с временными рядами и обработкой естественного языка (NLP) • Как преуспеть в задачах на имитационное моделирование и оптимизацию Лука и Конрад рассказали о Kaggle максимально доступно. Оба они — первоклассные профессионалы, пользующиеся большим авторитетом и уважением в сообществе Kaggle. Проштудировав эту книгу, можете смело регистрироваться на Kaggle и рассчитывать на высокие результаты. Энтони Голдблум, основатель и генеральный директор Kaggle ISBN 978-5-9775-1903-8 9 785977 519038 191036, Санкт-Петербург, Гончарная ул., 20 Тел.: (812) 717-10-50, 339-54-17, 339-54-28 E-mail: mail@bhv.ru Internet: www.bhv.ru Packt>