Несколько месяцев назад Google анонсировал новую функцию Google BigQuery под названием BigQuery ML, которая в настоящее время находится в стадии бета-тестирования. Он состоит из набора расширений языка SQL, который позволяет создавать модели машинного обучения, оценивать их прогнозную производительность и делать прогнозы для новых данных непосредственно в BigQuery.

Одним из преимуществ BigQuery ML (BQML) является то, что для его использования достаточно знать только стандартный SQL (без использования R или Python для обучения моделей), что делает машинное обучение более доступным. Он даже обрабатывает преобразование данных, разделение обучающих / тестовых наборов и т. Д. Кроме того, он сокращает время обучения моделей, поскольку работает непосредственно там, где хранятся данные (BigQuery), и, следовательно, нет необходимости экспортировать данные в другие инструменты.

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

В этом посте я объясню основные функции BQML и то, как их использовать для создания нашей модели, оценки и использования ее для составления прогнозов. Этот процесс будет состоять из следующих шагов:

  1. Создайте набор данных (необязательно)
  2. Создать модель
  3. Информация о модели (необязательно)
  4. Оцените модель
  5. Предсказывать

Создайте набор данных (необязательно)

Как и в случае с таблицами BigQuery (BQ), модель должна быть сохранена в наборе данных, поэтому сначала вы должны решить, в каком наборе данных вы хотите сохранить модель: в существующем или в новом.

Если в вашем случае последнее, создать новый набор данных так же просто, как:

  1. В интерфейсе BQ выберите проект, в котором вы хотите создать набор данных, и нажмите кнопку создать набор данных.

2. Назовите новый набор данных и выберите место, где данные будут храниться, и срок действия. Более подробную информацию об этих полях вы можете найти по этой ссылке.

Создать модель

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

BQML позволяет выполнять этот процесс непосредственно в BigQuery. В настоящее время он поддерживает три типа моделей:

  1. Линейная регрессия. Он используется для прогнозирования результата непрерывной числовой переменной, например дохода.
  2. Бинарная логистическая регрессия. Он используется для прогнозирования результата категориальной переменной с двумя возможными классами, например, когда вы хотите определить, купит пользователь или нет.
  3. Полиномиальная логистическая регрессия (или мультикласс). Он используется для прогнозирования результата категориальной переменной с более чем двумя классами.

Чтобы создать (и обучить) модель с помощью BQML, необходимо использовать следующий синтаксис:

#standardSQL
{CREATE MODEL | CREATE MODEL IF NOT EXISTS | CREATE OR REPLACE MODEL} `project.dataset.model_name`
OPTIONS(model_option_list)
AS query_statement

Этот запрос создаст модель (CREATE MODEL) с указанными параметрами (OPTIONS) и будет использовать результат запроса (AS) в качестве обучающих данных. Мы должны указать:

1) Название модели и место для сохранения. CREATE MODEL создает и обучает модель (которая будет сохранена с именем «model_name» внутри указанного набора данных) до тех пор, пока нет модели, уже созданной с таким же имя. Если название модели существует, запрос с CREATE MODEL вернет ошибку. Чтобы избежать этой ошибки, мы можем использовать две альтернативы:

  • СОЗДАТЬ МОДЕЛЬ, ЕСЛИ НЕ СУЩЕСТВУЕТ, который создает и обучает модель только в том случае, если модель с таким именем уже не создана.
  • СОЗДАТЬ ИЛИ ЗАМЕНИТЬ МОДЕЛЬ, которая создает модель (если она не существует) или заменяет ее (если она существует) и обучает ее.

2) model_option_list. Список с указанием некоторых опций, связанных с моделью и процессом обучения. Формат следующий: option1 = value1, option2 = value2,… Двумя наиболее важными параметрами являются:

  • model_type (обязательный): указывает тип модели, которую мы хотим обучить: linear_reg для линейной регрессии или logistic_reg для бинарной или многоклассовой логистической регрессии.
  • input_label_cols: указывает имя столбца таблицы с обучающими данными, которые содержат переменную ответа. Если столбец называется label, это поле является необязательным; в противном случае он должен быть указан как [‘column_name’].

Хотя BigQuery ML имеет параметры по умолчанию для обучения модели, он предлагает некоторую гибкость для выбора параметров, связанных с предотвращением переобучения и оптимизацией параметров модели. Например, мы можем применить регуляризацию L1 или L2, разделить данные в обучающем наборе и наборе проверки или установить максимальное количество итераций градиентного спуска. Вы можете найти все доступные варианты по этой ссылке.

3) query_statement. Запрос, который генерирует таблицу, которая будет использоваться в качестве обучающих данных. Одним из преимуществ BigQuery ML является то, что он отвечает за преобразование данных для обучения модели. Особенно:

  • Категориальные функции (типа BOOL, STRING, BYTES, DATE, DATETIME или TIME) быстро объединяются (т. Е. Преобразуются в двоичную переменную для каждого класса). Из-за проблемы, известной как мультиколлинеарность, это не рекомендуется, если вы хотите делать выводы о взаимосвязях между функциями и переменной ответа.
  • Числовые функции (тип NUMERIC, FLOAT64 или INT64) стандартизированы как для обучающих данных, так и для будущих прогнозов.
  • Значения NULL заменяются средним значением в случае числовых переменных или новым классом, который группирует все эти недостающие данные в случае категориальных характеристик.

Что касается переменной ответа, необходимо учитывать, что:

  • В линейной регрессии не может быть бесконечных или NaN значений.
  • В бинарной логистической регрессии у него должно быть ровно два возможных значения.
  • В многоклассовой логистической регрессии у вас может быть максимум 50 различных категорий.

Например, давайте представим, что мы хотим предсказать, завершится ли веб-сеанс покупкой или нет, в зависимости от нескольких функций, связанных с активностью просмотра пользователем (количество просмотров страниц, продолжительность сеанса, тип пользователя, используемое им устройство и платный трафик или нет). Если вы хотите последовать этому примеру, мы будем использовать набор тестовых данных Google Analytics, предлагаемый BigQuery. Чтобы создать модель, мы будем использовать следующий запрос:

#standardSQL
CREATE MODEL `project.dataset.sample_model`
OPTIONS(model_type='logistic_reg',
       input_label_cols=['isBuyer'])
AS
SELECT
 IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
 IFNULL(totals.pageviews, 0) AS pageviews,
 IFNULL(totals.timeOnSite, 0) AS timeOnSite,
 IFNULL(totals.newVisits, 0) AS isNewVisit,
 IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
 IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
 IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
 `bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
 _TABLE_SUFFIX BETWEEN '20160801' AND '20170630'

Поскольку наша переменная ответа категориальна с двумя классами (1 = «с покупкой» или 0 = «без покупки»), нам пришлось указать в вариантах, что тип модели является логистической регрессией (logistic_reg). Также обратите внимание, что переменная ответа называется isBuyer, поэтому нам также пришлось указать это в параметрах.

Информация о модели (необязательно)

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

В BigQuery ML мы можем получить веса обученной модели с помощью следующего запроса:

#standardSQL
SELECT *
FROM ML.WEIGHTS(MODEL `project.dataset.model_name`)

Как упоминалось ранее, если вы не конвертируете категориальные переменные в двоичные «вручную» в своем запросе (как мы, например, сделали с isMobile и isDesktop), каждая возможная категория будет иметь вес, а надежность коэффициентов будет скомпрометирован из-за мультиколлинеарности.

Например, модель, которую мы создали в предыдущем разделе, имеет следующие коэффициенты:

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

Оцените модель

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

BQML предоставляет несколько функций для оценки наших моделей:

  • ML.TRAINING_INFO. Предоставляет информацию об итерациях во время обучения модели, включая потери как при обучении, так и при проверке, установленной на каждой итерации. Ожидаемый результат состоит в том, что потери уменьшаются в обоих наборах (в идеале до 0, что означает, что модель всегда верна).
  • ML.ОЦЕНКА. Предоставляет наиболее распространенные метрики для оценки прогностической эффективности модели. Эта функция может использоваться для любого типа модели (линейная регрессия, двоичная логистическая регрессия, многоклассовая логистическая регрессия), но метрики будут разными в зависимости от того, является ли это регрессией или задачей классификации.
  • ML.CONFUSION_MATRIX. Возвращает матрицу неточностей для заданного набора данных, что позволяет нам знать правильные прогнозы и ошибки для каждого возможного класса в модели классификации. Его можно использовать только для моделей классификации, то есть логистической регрессии и многоклассовой логистической регрессии.
  • ML.ROC_CURVE. Эта функция позволяет нам построить кривую ROC, которая представляет собой графическую визуализацию, используемую для оценки прогностической способности модели двоичной классификации. В этом случае его можно использовать только для моделей бинарной логистической регрессии.

В этом посте мы сосредоточимся на ML.EVALUATE, но мы дадим синтаксис и примеры для других функций на тот случай, если кто-то заинтересован в их использовании.

ML.ОЦЕНКА

Чтобы оценить ранее созданную модель, необходимо использовать следующий синтаксис:

#standardSQL
SELECT *
FROM ML.EVALUATE(MODEL `project.dataset.model_name`,
          {TABLE table_name | (query_statement)}
          [, STRUCT(XX AS threshold)])

Где мы должны указать:

  • Модель.
  • Таблица, для которой мы хотим вычислить показатели оценки, которые могут быть результатом запроса. Очевидно, что этот тестовый набор должен иметь те же столбцы, что и обучающий набор, включая переменную ответа (для сравнения прогнозов модели с фактическими значениями). Если таблица или запрос не указаны, он будет использовать набор проверки (если он указан при создании модели) или обучающий набор (если набор проверки не был указан).
  • В случае логистической регрессии порог. Это значение является необязательным и указывает значение, исходя из которого прогнозы нашей модели (которые представляют собой значения от 0 до 1, которые можно интерпретировать как вероятности того, что это наблюдение относится к классу 1) будут для класса 0 или для класса 1. По умолчанию порог составляет 0,5.

Результатом этого запроса является одна строка с наиболее распространенными метриками для оценки прогнозов модели, которые будут зависеть от типа используемой модели.

В частности, BigQuery ML предоставляет следующие метрики для моделей логистической регрессии и многоклассовой логистической регрессии:

  • точность
  • отзывать
  • точность
  • f1_score
  • log_loss
  • roc_auc

В случае линейной регрессии это:

  • mean_absolute_error
  • mean_squared_error
  • mean_squared_log_error
  • median_absolute_error
  • r2_score
  • объясненная_вариантность

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

#standardSQL
SELECT *
FROM ML.EVALUATE(MODEL `project.dataset.sample_model`,
   (
     SELECT
        IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
        IFNULL(totals.pageviews, 0) AS pageviews,
        IFNULL(totals.timeOnSite, 0) AS timeOnSite,
        IFNULL(totals.newVisits, 0) AS isNewVisit,
        IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
        IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
        IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
     FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_*`
     WHERE
        _TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
   ),
   STRUCT(0.5 AS threshold)
   )

Обратите внимание, что даты, используемые для создания данных, отличаются от дат, используемых для создания модели. Результат предыдущего запроса:

Другие функции для оценки моделей

1. ML.TRAINING_INFO

Синтаксис:

#standardSQL
SELECT *
FROM ML.TRAINING_INFO(MODEL `project.dataset.model_name`)

Пример:

#standardSQL
SELECT *
FROM ML.TRAINING_INFO(MODEL `project.dataset.sample_model`)

2. ML.CONFUSION_MATRIX

Синтаксис:

#standardSQL
ML.CONFUSION_MATRIX(MODEL `project.dataset.model_name`,
          {TABLE table_name | (query_statement)}
          [, STRUCT(XX AS threshold)])

Пример:

#standardSQL
SELECT *
FROM ML.CONFUSION_MATRIX(MODEL `project.dataset.sample_model`,
   (
     SELECT
        IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
        IFNULL(totals.pageviews, 0) AS pageviews,
        IFNULL(totals.timeOnSite, 0) AS timeOnSite,
        IFNULL(totals.newVisits, 0) AS isNewVisit,
        IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
        IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
        IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
     FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_*`
     WHERE
        _TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
   ),
   STRUCT(0.5 AS threshold)
   )

3. ML.ROC_CURVE

Синтаксис:

#standardSQL
ML.ROC_CURVE(MODEL `project.dataset.model_name`,
           {TABLE table_name | (query_statement)},
           [GENERATE_ARRAY(thresholds)])

Пример:

#standardSQL
SELECT *
FROM ML.ROC_CURVE(MODEL `project.dataset.sample_model`,
   (
     SELECT
        IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
        IFNULL(totals.pageviews, 0) AS pageviews,
        IFNULL(totals.timeOnSite, 0) AS timeOnSite,
        IFNULL(totals.newVisits, 0) AS isNewVisit,
        IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
        IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
        IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
     FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_*`
     WHERE
        _TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
   ),
   GENERATE_ARRAY(0.0, 1.0, 0.01)
   )

Предсказывать

Чтобы использовать модель, созданную с помощью BigQuery ML, для прогнозирования, необходимо использовать следующий синтаксис:

#standardSQL
ML.PREDICT(MODEL model_name,
         {TABLE table_name | (query_statement)}
          [, STRUCT(XX AS threshold)])

Этот запрос будет использовать модель (МОДЕЛЬ) и будет делать прогнозы для нового набора данных (ТАБЛИЦА). Очевидно, что таблица должна иметь те же столбцы, что и обучающие данные, хотя нет необходимости включать переменную ответа (поскольку она нам не нужна для прогнозирования новых данных). В логистической регрессии вы можете дополнительно указать порог, определяющий, от которого оценочная вероятность считается окончательным прогнозом того или иного класса.

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

И продолжаем наш пример:

#standardSQL
SELECT *
FROM ML.PREDICT(MODEL `project.dataset.sample_model`,
   (
     SELECT
        IFNULL(totals.pageviews, 0) AS pageviews,
        IFNULL(totals.timeOnSite, 0) AS timeOnSite,
        IFNULL(totals.newVisits, 0) AS isNewVisit,
        IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
        IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
        IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
     FROM
        `bigquery-public-data.google_analytics_sample.ga_sessions_*`
     WHERE
        _TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
   )
   )

Обратите внимание, что столбец с ответом (isBuyer) не требуется. Результат предыдущего запроса:

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