BigQuery ML все еще находится в стадии бета-тестирования и доступен с середины прошлого года; однако до недавнего времени мне не удавалось работать с этим предложением Google для облачного машинного обучения. Мое первое впечатление как не специалиста по данным - что не нравится? В конце концов, возможность запускать модели машинного обучения из удобного веб-редактора SQL - это мечта любого аналитика. Не только эта платформа избавляет от необходимости изучать язык программирования, будь то R, Python или SAS; он также оптимизирует процесс разработки данных, используя существующие источники данных BigQuery, вместо того, чтобы добавлять внешние данные в вашу модель. По сути, этот продукт устраняет ряд препятствий на пути к этой желанной специальности в области науки о данных и демократизирует сферу машинного обучения, позволяя любому аналитику с достаточным знанием SQL работать линейно и логистические регрессионные модели без необходимости инвестировать в дорогостоящее оборудование, такое как многоядерные графические процессоры, которые обычно необходимы для поддержки масштабируемого проекта машинного обучения. Изображение ниже отлично демонстрирует возможности платформы:

Многие начинающие студенты, изучающие науку о данных, обращаются к надежному набору данных Титаник: машинное обучение после катастрофы из одного из самых популярных конкурсов Kaggle, чтобы попрактиковаться в работе с двоичными классификационные модели. Фактически, для новичка модель бинарной классификации представляет собой довольно простую концепцию для понимания: ваша задача - просто предсказать, произойдет ли определенное событие или не произойдет; или будет ли определенное условие оцениваться как истинное или ложное. В отношении этой проблемы любой может представить себе концепцию предсказания того, выживет ли конкретный пассажир корабля Титаник при одной из самых грандиозных кораблекрушений всех времен: здесь есть только две возможности. Чтобы продолжить, вам просто нужно войти в существующую учетную запись Kaggle или создать новую и загрузить все три файла. Ирония использования веб-сайта Kaggle (купленного Google еще в 2017 году) и платформы BigQuery (еще одного продукта Google) не ускользает от меня. Давайте рассмотрим эту проблему на примере набора данных и работающего экземпляра BigQuery.

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

  1. Анализируйте свои данные
  2. Измените свои данные
  3. Выполните анализ

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

Шаг 1. Изучение набора данных "Титаник"

А. Определение данных

Прежде всего, давайте посмотрим на данные, которые Kaggle предоставляет нам. Мы можем представить себе три CSV-файла: обучающие и тестовые наборы данных, а также пол_представления как три таблицы базы данных, доступные для нашего анализа. Мы будем использовать обучающий набор для построения нашей модели машинного обучения, в то время как мы запустим модель на тестовом наборе, чтобы предсказать результат (выживаемость после крушения). Таблица представления может служить шаблоном, которому мы будем следовать для проверки точности наши прогнозы, отправив результаты в Kaggle для оценки. Согласно словарю данных, в нашей обучающей таблице есть несколько вариантов , которые мы могли бы рассмотреть в нашем решении для прогнозирования выживаемости:

PasserngerID - уникальный идентификатор, присваиваемый каждому пассажиру;

Survived - флаг выживания, где значение 1 указывает, что пассажир выжил, а 0 определяет погибших пассажиров - это целевое значение, которое мы пытаемся предсказать. ;

Pclass - класс билета пассажира, который также можно интерпретировать как показатель социально-экономического статуса: 1 означает билет первого класса / гражданин высшего класса, 2 для билетов второго класса / среднего класса и 3 для владельцев билетов третьего класса / граждан низшего класса;

Имя - имя пассажира;

Пол - пол пассажира, обратите внимание на то, что для целей построения модели нам потребуется преобразовать этот строковый тип записи в числовой тип данных;

Возраст - возраст пассажира (в годах);

SibSp - количество братьев и сестер / супругов, путешествующих вместе;

Parch - количество родителей / детей, путешествующих вместе;

Билет - номер билета пассажира;

Fare - тариф для пассажира, сколько этот пассажир заплатил за свой билет;

Кабина - номер кабины, присвоенный пассажиру;

Посадка - порт посадки (C = Шербур, Q = Квинстаун, S = Саутгемптон).

Б. Как определить, чего не хватает

Мы можем начать с поиска отсутствующих значений в нашем наборе данных. Быстрая выборочная проверка обычно бывает достаточной при работе с небольшим набором данных, таким как наш. Фактически, просто просматривая записи, мы можем определить только три поля с пропущенными значениями: Возраст, Cabin и Embarked. Чтобы количественно оценить влияние пропущенных значений, давайте запустим наш самый первый запрос SQL к этим данным:

Похоже, что в каждой пятой записи отсутствует значение Age, а три из четырех записей Cabin не могут быть найдены, и только 2 из 891 записей отсутствуют Embarked флаг:

Обратите внимание, что я использую стандартный SQL в запросе и импортировал наши обучающие данные в таблицу tbl_train, сохраненную в наборе данных dataset_Titanic в prj -titanic в моем экземпляре BigQuery.

С практической точки зрения, не все доступные переменные (или функции, если мы решим использовать их в модели) должны использоваться в любой данной модели прогнозирования; В случае набора данных Титаник мы можем вспомнить из второго по прибыльности фильма всех времен, что политика прежде всего женщины и дети работала в пользу женщин и детей, которым отдавался приоритет с точки зрения доступа к спасательным шлюпкам. Пассажиры первого класса, казалось, были следующей группой предпочтений. Давайте исследуем наши данные, чтобы увидеть, действительно ли пол, возраст и класс могут быть хорошими предикторами выживаемости пассажиров.

С. Какие данные актуальны?

Быстрый запрос ниже подтверждает сделанное выше предположение для измерения Пол. Судя по предоставленным данным, женщины были почти в 4 (!) раза больше шансов выжить после этого крушения, чем мужчины:

Обратите внимание, что приведенная выше диаграмма является результатом бесшовной интеграции BigQuery и DataStudio; поистине комплексное решение для исследовательского анализа данных от Google.

При запросе коэффициента выживаемости для переменной Pclass мы также можем подтвердить, что класс пассажира на самом деле должен быть одной из функций / предикторов нашей модели:

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

Ребенок - до 13 лет

Подросток - от 13 до 18 лет.

Молодые люди - от 19 до 35 лет.

Взрослые от 36 до 55 лет

Пожилой гражданин - старше 55 лет.

Когда мы запускаем наш новый запрос, становится очевидным, что дети выживали значительно быстрее, чем другие возрастные группы. На дальнем втором месте оказались подростки:

Естественно, трудно представить, что такие поля, как Name, PassengerID, Ticket и подобные, могут иметь какое-либо отношение к выживанию, хотя другие менее на самом деле могут быть полезны интуитивно понятные поля. Что произойдет, если мы посмотрим на выживаемость по категории вышедших? Игнорируя две отсутствующие записи, которые показывают 100% выживаемость, Шербур отличается от двух других портов более высокой выживаемостью, причем Квинстаун более благоприятен, чем Саутгемптон:

Шаг 2. Очистка данных

А. Обработка отсутствующих значений

После завершения процесса EDA пора заняться некоторыми основными задачами обработки данных. Предполагая, что мы хотим использовать все четыре поля, описанные выше: Возраст, Пол, PClass и Начал, нам понадобится для учета 177 отсутствующих значений Age и 2 начальных значений.

Давайте попробуем условно исчислить порт посадки на основе всего, что нам известно о пассажирах. Самым простым решением было бы посмотреть на распределение пассажиров по пунктам посадки, в результате чего на Саутгемптон приходится 72% всех пассажиров:

Кроме того, мы можем рассмотреть возможность использования информации PClass, чтобы увидеть, вышло ли большинство владельцев билетов первого класса на борт из определенного порта. С помощью следующего запроса мы можем определить, что 59% таких пассажиров тоже вылетели из Саутгемптона:

Другой способ выполнить эту задачу - проверить, можно ли использовать информацию Cabin для заполнения этих недостающих значений. После элементарного поиска мы можем узнать, что первая буква поля cabin относится к палубе, что, естественно, сильно коррелирует со значением класса пассажира. В нашем случае B обозначает колоду Променад (не путать с Верхней Променад). Глядя на распределение пассажиров по известному порту посадки для этой палубы, можно сказать, что примерно половина людей (51,11%, если быть точным) начинают свое путешествие. в Саутгемптоне, а оставшаяся половина - из Шербура.

Обобщая все вышеперечисленные выводы, давайте сделаем шаг (несколько расчетливую) веру и предположим, что отсутствующим значениям Embarked следует присвоить значение S [Southampton.] Работа с Отсутствие 177 значений возраста не так тривиально, отчасти из-за размера этой выборки, отчасти из-за отсутствия надежных предикторов в наборе данных. Возможно, мы сможем взглянуть на имена пассажиров, чтобы расшифровать их титулы и сделать надежное предположение, что все состоящие в браке пассажиры (миссис и т. Д.) Определенно не дети. Стало бы труднее увеличивать масштаб их фактического возраста, кроме, возможно, просмотра средних или модовых значений в данных. Давайте упростим нашу жизнь и выберем легкий путь: давайте проигнорируем все записи с отсутствующими значениями Age в надежде получить достаточно большой оставшийся набор данных для использования в нашей модели прогнозирования.

Б. Подготовка данных для модели

Говоря о моделях, они не очень хорошо работают с текстовыми / строковыми типами данных, нам нужно будет преобразовать все такие поля в числовые значения. Например, для поля Пол мы можем присвоить значение 1 всем мужчинам и значение 0 всем женщинам.

Переходя к полю Pclass, мы можем вспомнить из предыдущих наблюдений, что у пассажиров первого класса была 1,33 больше шансов выжить, чем у владельцев билетов второго класса. Однако, если мы просто используем номинальные значения 1 и 2 для соответствующих классов билетов, эта взаимосвязь будет неправильно интерпретирована, поскольку вероятность гибели пассажиров второго класса в два раза выше, чем у пассажиров обладатели билетов первого класса. Мы могли бы масштабировать эту взаимосвязь, создав три поля (по одному для каждого класса пассажиров) и пометив записи соответствующим образом. Держатель билета первого класса будет иметь значение True (чтение: 1) в поле PClass1_Flg и значения False (чтение: 0 ) для столбцов PClass2_Flg и PClass3_Flg:

Мы применим аналогичный принцип к полям категории Возраст и создадим пять новых полей, чтобы отмечать записи в соответствии с возрастной группой пассажиров.

Шаг 3. Запустите нашу модель машинного обучения "Титаник"

А. Создайте нашу модель

Мы, наконец, закончили все подготовительные работы и готовы перейти к завершающей фазе нашего проекта. Чтобы продемонстрировать, насколько легко создать нашу модель, давайте воспользуемся синтаксисом BigQuery ML ниже и запустим нашу первую модель логистической регрессии на основе одной функции - пола:

CREATE OR REPLACE MODEL `ModelName`
      OPTIONS (model_type = 'logistic_reg') AS 
SELECT field(s) FROM TableName

Б. Оцените результаты модели

Для оценки нашей модели требуется всего одна строчка кода, и результаты выглядят многообещающими.

SELECT * FROM ml.evaluate(model `ModelName`)

С. Запустим нашу модель

Момент истины настал, давайте запустим нашу модель на основе данных test, давайте создадим таблицу с результатами модели, пока мы работаем над этим:

Работать с одной характеристикой / столбцом было не так сложно, но, как мы помним из нашего EDA, пол, по-видимому, является лучшим предиктором выживания. Пришло время сохранить эту таблицу как CSV и сделать нашу отправку Kaggle. Это довольно простое упражнение с точностью 76,55% поставило нас в число лучших 74% всех участников Kaggle. Не требуется много аналитических возможностей, чтобы увидеть, что этот результат фактически разделяется с другим 1481 участником конкурса, так что фактически мы находимся в лучших 60%! Здесь определенно есть куда расти, но не так уж плохо для первой попытки.

Д. Экспериментируйте и оптимизируйте

Тестирование и повторение - это определенно дух здесь. Мы можем в дальнейшем поэкспериментировать с моделью, приспособив ее к нашим потребностям, будь то изменение скорости обучения, установка регуляризации, ограничение количества итераций и т. Д. Все эти параметры можно найти в разделе ОПЦИИ Часть модельного заявления.

Кроме того, мы можем попытаться повысить точность нашей модели, изменив используемые функции; давайте воспользуемся этим подходом. Мне было очень грустно осознавать, что добавление дополнительных функций (возрастная категория, класс пассажира и порт посадки) фактически снизило точность модели:

Но у нас должно получиться лучше, верно? Что, если мы примем во внимание тот факт, что у семей может быть больше шансов на выживание, если они будут вместе и помогать друг другу. К счастью, мы можем сложить количество родителей / детей, путешествующих вместе (parch) и количество братьев и сестер / супругов (sibsp), чтобы подсчитать общий размер семьи. Полезно знать, что в соответствии с нашим предыдущим EDA в этих двух полях нет пропущенных значений. Также обратите внимание, что пассажиры, путешествующие в одиночку, будут иметь значения 0 в любом из полей. Тогда давайте построим новую, более полную и, надеюсь, более точную модель:

Эта тактика оказалась правильной, мы немного повысили точность нашей заявки до 77% и поднялись на 1476 позиций вверх, обойдя всех тех, кто использовал пол в качестве единственного предиктора. Сейчас мы разделяем нашу позицию только с 583 конкурентами, что фактически помещает нас в топ 54%!

Я не уверен, какого реалистичного уровня точности мы можем достичь (все эти 95% + баллы в таблице лидеров кажутся подозрительными), однако следует помнить о том, что тип модели может играть здесь роль. , может быть, случайный лес может дать лучшие результаты, чем классификация? Тем не менее, есть еще над чем поработать, чтобы улучшить наш результат.

Если вы ищете дальнейшие шаги, Google предоставляет руководства по началу работы BigQuery ML как для треков аналитик данных, так и специалист по данным. Удачи в пути к машинному обучению! Пожалуйста, поделитесь своими мыслями и используемой методикой, если вы добьетесь большего успеха в своих результатах!

31.03.19 Изменить - благодаря очень информативному комментарию Фелипе Хоффа я узнал, что часть моего кода, использованного выше, на самом деле избыточна; на самом деле BigQuery упрощает работу.

Замените этот код:

CREATE OR REPLACE MODEL `xxx.xx`
OPTIONS (model_type='logistic_reg') AS
SELECT Survived AS label,
CASE WHEN Sex = 'male' THEN 1 ELSE 0 END AS Gender

С этим заявлением:

CREATE OR REPLACE MODEL `xxx.xx`
OPTIONS (model_type='logistic_reg') AS
SELECT Survived AS label,
Sex

Если вы хотите узнать больше советов и приемов BigQuery и BigQuery ML, обратитесь к отличному посту Фелипе здесь и ко всем другим статьям, которыми он поделился до сих пор.

P.S. Извините, Фелипе, от старых привычек трудно избавиться: я заменил ваш пример ведущей запятой на свой переход от конечной запятой.