В этом проекте мы собираемся предсказать, вернется ли посетитель на сайт, чтобы купить продукт, используя его историю в BigQuery.
Сначала мы начнем с изучения нашего набора данных.
Из общего числа посетителей, посетивших наш веб-сайт, % совершили покупку
#standardSQL WITH visitors AS( SELECT COUNT(DISTINCT fullVisitorId) AS total_visitors FROM `data-to-insights.ecommerce.web_analytics` ), purchasers AS( SELECT COUNT(DISTINCT fullVisitorId) AS total_purchasers FROM `data-to-insights.ecommerce.web_analytics` WHERE totals.transactions IS NOT NULL ) SELECT total_visitors, total_purchasers, total_purchasers / total_visitors AS conversion_rate FROM visitors, purchasers
Результат: 2,69%.
Каковы 5 самых продаваемых продуктов?
#standardSQL SELECT p.v2ProductName, p.v2ProductCategory, SUM(p.productQuantity) AS units_sold, ROUND(SUM(p.localProductRevenue/1000000),2) AS revenue FROM `data-to-insights.ecommerce.web_analytics`, UNNEST(hits) AS h, UNNEST(h.product) AS p GROUP BY 1, 2 ORDER BY revenue DESC LIMIT 5;
Это даст вам 5 самых продаваемых продуктов на этом сайте электронной коммерции.
Чтобы проверить, являются ли эти два поля хорошими входными данными для вашей модели классификации:
totals.bounces (покинул ли посетитель сайт сразу)
totals.timeOnSite (сколько времени посетитель находился на нашем сайте)
Для создания модели BigQuery ML нам нужно сначала создать набор данных в нашем проекте gcp.
— Я называю свой идентификатор набора данных электронной коммерцией.
Поскольку мы разделяем посетителей на группы «будут покупать в будущем» или «не будут покупать в будущем», используйте logistic_reg в модели классификации.
Теперь давайте создадим и обучим нашу модель машинного обучения.
#standardSQL CREATE OR REPLACE MODEL `ecommerce.classification_model` OPTIONS ( model_type='logistic_reg', labels = ['will_buy_on_return_visit'] ) AS #standardSQL SELECT * EXCEPT(fullVisitorId) FROM # features (SELECT fullVisitorId, IFNULL(totals.bounces, 0) AS bounces, IFNULL(totals.timeOnSite, 0) AS time_on_site FROM `data-to-insights.ecommerce.web_analytics` WHERE totals.newVisits = 1 AND date BETWEEN '20160801' AND '20170430') # train on first 9 months JOIN (SELECT fullvisitorid, IF(COUNTIF(totals.transactions > 0 AND totals.newVisits IS NULL) > 0, 1, 0) AS will_buy_on_return_visit FROM `data-to-insights.ecommerce.web_analytics` GROUP BY fullvisitorid) USING (fullVisitorId) ;
Теперь мы оценим нашу модель ML.
#standardSQL SELECT roc_auc, CASE WHEN roc_auc > .9 THEN 'good' WHEN roc_auc > .8 THEN 'fair' WHEN roc_auc > .7 THEN 'decent' WHEN roc_auc > .6 THEN 'not great' ELSE 'poor' END AS model_quality FROM ML.EVALUATE(MODEL ecommerce.classification_model, ( SELECT * EXCEPT(fullVisitorId) FROM # features (SELECT fullVisitorId, IFNULL(totals.bounces, 0) AS bounces, IFNULL(totals.timeOnSite, 0) AS time_on_site FROM `data-to-insights.ecommerce.web_analytics` WHERE totals.newVisits = 1 AND date BETWEEN '20170501' AND '20170630') # eval on 2 months JOIN (SELECT fullvisitorid, IF(COUNTIF(totals.transactions > 0 AND totals.newVisits IS NULL) > 0, 1, 0) AS will_buy_on_return_visit FROM `data-to-insights.ecommerce.web_analytics` GROUP BY fullvisitorid) USING (fullVisitorId) ));
После оценки вашей модели вы получаете roc_auc 0,72,
что показывает, что модель имеет приличную, но не большую предсказательную силу. Поскольку цель состоит в том, чтобы максимально приблизить площадь под кривой к 1,0, есть возможности для улучшения.
Давайте улучшим нашу модель, добавив новые функции, такие как:
- Как далеко посетитель продвинулся в процессе оформления заказа при первом посещении
- Откуда пришел посетитель (источник трафика: обычный поиск, ссылающийся сайт и т. д.)
- Категория устройства (мобильное, планшетное, десктопное)
- Географическая информация (страна)
#standardSQL CREATE OR REPLACE MODEL `ecommerce.classification_model_2` OPTIONS (model_type='logistic_reg', labels = ['will_buy_on_return_visit']) AS WITH all_visitor_stats AS ( SELECT fullvisitorid, IF(COUNTIF(totals.transactions > 0 AND totals.newVisits IS NULL) > 0, 1, 0) AS will_buy_on_return_visit FROM `data-to-insights.ecommerce.web_analytics` GROUP BY fullvisitorid ) # add in new features SELECT * EXCEPT(unique_session_id) FROM ( SELECT CONCAT(fullvisitorid, CAST(visitId AS STRING)) AS unique_session_id, # labels will_buy_on_return_visit, MAX(CAST(h.eCommerceAction.action_type AS INT64)) AS latest_ecommerce_progress, # behavior on the site IFNULL(totals.bounces, 0) AS bounces, IFNULL(totals.timeOnSite, 0) AS time_on_site, IFNULL(totals.pageviews, 0) AS pageviews, # where the visitor came from trafficSource.source, trafficSource.medium, channelGrouping, # mobile or desktop device.deviceCategory, # geographic IFNULL(geoNetwork.country, "") AS country FROM `data-to-insights.ecommerce.web_analytics`, UNNEST(hits) AS h JOIN all_visitor_stats USING(fullvisitorid) WHERE 1=1 # only predict for new visits AND totals.newVisits = 1 AND date BETWEEN '20160801' AND '20170430' # train 9 months GROUP BY unique_session_id, will_buy_on_return_visit, bounces, time_on_site, totals.pageviews, trafficSource.source, trafficSource.medium, channelGrouping, device.deviceCategory, country );
Давайте еще раз оценим нашу модель,
#standardSQL SELECT roc_auc, CASE WHEN roc_auc > .9 THEN 'good' WHEN roc_auc > .8 THEN 'fair' WHEN roc_auc > .7 THEN 'decent' WHEN roc_auc > .6 THEN 'not great' ELSE 'poor' END AS model_quality FROM ML.EVALUATE(MODEL ecommerce.classification_model_2, ( WITH all_visitor_stats AS ( SELECT fullvisitorid, IF(COUNTIF(totals.transactions > 0 AND totals.newVisits IS NULL) > 0, 1, 0) AS will_buy_on_return_visit FROM `data-to-insights.ecommerce.web_analytics` GROUP BY fullvisitorid ) # add in new features SELECT * EXCEPT(unique_session_id) FROM ( SELECT CONCAT(fullvisitorid, CAST(visitId AS STRING)) AS unique_session_id, # labels will_buy_on_return_visit, MAX(CAST(h.eCommerceAction.action_type AS INT64)) AS latest_ecommerce_progress, # behavior on the site IFNULL(totals.bounces, 0) AS bounces, IFNULL(totals.timeOnSite, 0) AS time_on_site, totals.pageviews, # where the visitor came from trafficSource.source, trafficSource.medium, channelGrouping, # mobile or desktop device.deviceCategory, # geographic IFNULL(geoNetwork.country, "") AS country FROM `data-to-insights.ecommerce.web_analytics`, UNNEST(hits) AS h JOIN all_visitor_stats USING(fullvisitorid) WHERE 1=1 # only predict for new visits AND totals.newVisits = 1 AND date BETWEEN '20170501' AND '20170630' # eval 2 months GROUP BY unique_session_id, will_buy_on_return_visit, bounces, time_on_site, totals.pageviews, trafficSource.source, trafficSource.medium, channelGrouping, device.deviceCategory, country ) ));
С этой новой моделью вы получаете значение roc_auc, равное 0,909, что значительно лучше, чем у первой модели.
Теперь мы предскажем, будет ли посетитель покупать в будущем или нет.
#standardSQL SELECT * FROM ml.PREDICT(MODEL `ecommerce.classification_model_2`, ( WITH all_visitor_stats AS ( SELECT fullvisitorid, IF(COUNTIF(totals.transactions > 0 AND totals.newVisits IS NULL) > 0, 1, 0) AS will_buy_on_return_visit FROM `data-to-insights.ecommerce.web_analytics` GROUP BY fullvisitorid ) SELECT CONCAT(fullvisitorid, '-',CAST(visitId AS STRING)) AS unique_session_id, # labels will_buy_on_return_visit, MAX(CAST(h.eCommerceAction.action_type AS INT64)) AS latest_ecommerce_progress, # behavior on the site IFNULL(totals.bounces, 0) AS bounces, IFNULL(totals.timeOnSite, 0) AS time_on_site, totals.pageviews, # where the visitor came from trafficSource.source, trafficSource.medium, channelGrouping, # mobile or desktop device.deviceCategory, # geographic IFNULL(geoNetwork.country, "") AS country FROM `data-to-insights.ecommerce.web_analytics`, UNNEST(hits) AS h JOIN all_visitor_stats USING(fullvisitorid) WHERE # only predict for new visits totals.newVisits = 1 AND date BETWEEN '20170701' AND '20170801' # test 1 month GROUP BY unique_session_id, will_buy_on_return_visit, bounces, time_on_site, totals.pageviews, trafficSource.source, trafficSource.medium, channelGrouping, device.deviceCategory, country ) ) ORDER BY predicted_will_buy_on_return_visit DESC;
Вы можете увидеть три недавно добавленных поля:
- predicted_will_buy_on_return_visit: думает ли модель, что посетитель купит позже (1 = да)
- predicted_will_buy_on_return_visit_probs.label: бинарный классификатор для да/нет
- predicted_will_buy_on_return_visit.prob: уверенность модели в своем прогнозе (1 = 100%).
Результаты:
- Из 6% первых посетителей (отсортированных в порядке убывания прогнозируемой вероятности) более 6% совершают покупку при последующем посещении.
- Эти пользователи составляют почти 50% всех посетителей, впервые зашедших на сайт и совершивших покупку при последующем посещении.
- В целом, только 0,7% посетителей совершают покупку при последующем посещении.
- Ориентация на 6% первых пользователей увеличивает рентабельность инвестиций в маркетинг в 9 раз по сравнению с таргетингом на всех!
Итак, мы успешно предсказываем, будет ли посетитель покупать в будущем или нет.
Юппи!!