tjtjtjのメモ

自分のためのメモです

復習 BQML で分類モデルを使用して訪問者の購入を予測する

復習ための素晴らしいエントリがあった!感謝!感謝!

qiita.com

qiita.com

その1は、どんなデータセットなのか読み取っている。 その2は、データセット分析続きとモデル作成/評価とモデル作成/評価。

1つ目のモデル

2つの特徴(変数)から生成。値の尺度なんかを設定しなくいいものなのかな?

  • fullVisitorId
  • totals.bounces 合計直帰数
  • totals.timeOnSite セッションの合計時間
CREATE OR REPLACE MODEL `ecommerce.classification_model`
OPTIONS
(
model_type='logistic_reg',
labels = ['will_buy_on_return_visit']
)
:
  (SELECT
    fullVisitorId,
    IFNULL(totals.bounces, 0) AS bounces,
    IFNULL(totals.timeOnSite, 0) AS time_on_site
  FROM
:

モデルの評価

期間が20170501から2か月になっている。この2か月をモデルに与えて性能を評価するということなのだろう。結果は 0.72 でまあまあ。

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)

));

2つ目のモデル

totals.bounces, totals.timeOnSite にいろんな変数を加えてモデルを生成している。

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
  ## totals.transactions 取引回数
  ## totals.newVisits 最初の訪問の場合は「1」、そうでない場合は「null」
  ## 帰った来て買ったら1
  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,
      ## 前段selectで生成

      MAX(CAST(h.eCommerceAction.action_type AS INT64)) AS latest_ecommerce_progress, 
      ## アクション タイプ。商品一覧のクリックスルー = 1、商品詳細表示 = 2、カートに商品を追加 = 3、
      ## カートの商品を削除 = 4、決済 = 5、購入の完了 = 6、払い戻し = 7、決算オプション = 8、不明 = 0

      # behavior on the site
      IFNULL(totals.bounces, 0) AS bounces,
      ## セッション開始後にすぐに離脱した場合、値は「1」となります。そうでない場合は「null」
      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,
      ## 端末の種類(モバイル、タブレット、PC)

      # geographic
      IFNULL(geoNetwork.country, "") AS country
      ## IP アドレスに基づいて特定されたセッションの起点となる国

  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
);

モデルの評価結果は 0.91 で good。