Codelab: ロジスティック回帰

Codelab:
ロジスティック回帰

この Codelab について

subject最終更新: 11月 21, 2023
account_circleGoogle 社員により作成

1. はじめに

この Codelab では、性別、年齢層、インプレッション時刻、ブラウザの種類といった要素と、ユーザーが広告をクリックする確率との相関性の度合いを、ロジスティック回帰によって理解する方法を解説します。

前提条件

この Codelab を完了するには、モデルを作成するのに十分な量の高品質なキャンペーン データが必要になります。

2. キャンペーンを選択

まず、十分な量の高品質なデータを含む古いキャンペーンを選びます。最良のデータを含むキャンペーンがわからない場合は、アクセス可能なデータの中で最も古い月(月の最初から最後までデータが揃っているもの)に対して、次のクエリを実行します。

SELECT
  campaign_id
,
  COUNT
(DISTINCT user_id) AS user_count,
  COUNT
(*) AS impression_count
FROM adh.google_ads_impressions

ORDER BY user_count DESC;

12~13 か月前のデータを選択すれば、Ads Data Hub からまもなく削除されるデータを使ってモデルのトレーニングとテストを行うことができます。このデータでモデル トレーニングの制限に達しても、データの削除とともに制限も終了します。

特にアクティブなキャンペーンなら、1 週間分のデータで十分なこともあります。最後に、ユーザーの正味人数が 100,000 人以上になるようにしましょう。このことは、多数の機能を使ってトレーニングを行う場合に特に重要です。

3. 一時テーブルを作成

モデルのトレーニングに使うキャンペーンを決めたら、以下のクエリを実行します。

CREATE TABLE
 binary_logistic_regression_example_data
AS(
 
WITH all_data AS (
   
SELECT
     imp
.user_id as user_id,
     ROW_NUMBER
() OVER(PARTITION BY imp.user_id) AS rowIdx,
     imp
.browser as browser_name,
     gender_name
as gender_name,
     age_group_name
as age_group_name,
     DATETIME
(TIMESTAMP_MICROS(
       imp
.query_id.time_usec), "America/Los_Angeles") as impression_time,
     
CASE # Binary classification of clicks simplifies model weight interpretation
       
WHEN clk.click_id.time_usec IS NULL THEN 0
       
ELSE 1
     
END AS label
   
FROM adh.google_ads_impressions imp
     
LEFT JOIN adh.google_ads_clicks clk USING (impression_id)
     
LEFT JOIN adh.gender ON demographics.gender = gender_id
     
LEFT JOIN adh.age_group ON demographics.age_group = age_group_id
   
WHERE
     campaign_id
IN (YOUR_CID_HERE)
 
)
 
SELECT
   label
,
   browser_name
,
   gender_name
,
   age_group_name
,
   
# Although BQML could divide impression_time into several useful variables on
   
# its own, it may attempt to divide it into too many features. As a best
   
# practice extract the variables that you think will be most helpful.
   
# The output of impression_time is a number, but we care about it as a
   
# category, so we cast it to a string.
   CAST
(EXTRACT(DAYOFWEEK FROM impression_time) AS STRING) AS day_of_week,
   
# Comment out the previous line if training on a single week of data
   CAST
(EXTRACT(HOUR FROM impression_time) AS STRING) AS hour,
 
FROM
   all_data
 
WHERE
   rowIdx
= 1 # This ensures that there's only 1 row per user.
   
AND
   gender_name
IS NOT NULL
   
AND
   age_group_name
IS NOT NULL
);

4. モデルを作成してトレーニング

テーブル作成のステップとモデル作成のステップは分けておくことをおすすめします。

前のステップで作成した一時テーブルに対して、次のクエリを実行します。開始日と終了日は一時テーブル内のデータから自動的に推測されるため、指定しなくても問題ありません。

CREATE OR REPLACE
MODEL
`binary_logistic_example`
OPTIONS
(
   model_type
= 'adh_logistic_regression'
)
AS (
   
SELECT *
   
FROM
       tmp
.binary_logistic_regression_example_data
);

SELECT * FROM ML.EVALUATE(MODEL `binary_logistic_example`)

5. 結果の解釈

クエリの実行が完了すると、以下のようなテーブルが得られます(内容はキャンペーンに応じて異なります)。

precision

recall

accuracy

f1_score

log_loss

roc_auc

1

0.53083894341399718

0.28427804486705865

0.54530547622568992

0.370267971696336

0.68728232223722974

0.55236263736263735

比重を検証

以下のクエリを実行して比重を確認し、モデルのクリック発生予測において考慮されている要素を調べましょう。

SELECT * FROM ML.WEIGHTS(MODEL `binary_logistic_example`)

クエリの結果は以下のようになります。各ラベルはソートされ、最も小さいものが 0、最も大きいものが 1 に設定されていることに注意しましょう。この例では、clicked が 0、not_clicked が 1 になっています。このため、比重が大きいものはクリック発生の確率を下げる要素と解釈することができます。また、day_of_week については 1 が日曜日に対応します。

processed_input

weight

category_weights.category

category_weights.weight

1

INTERCEPT

-0.0067900886484743364

2

browser_name

null

unknown 0.78205563068099249

Opera 0.097073700069504443

Dalvik -0.75233190448454246

Edge 0.026672464688442348

Silk -0.72539916969348706

Other -0.10317444840919325

Samsung Browser 0.49861066525009368

Yandex 1.3322608977581121

IE -0.44170947381475295

Firefox -0.10372609461557714

Chrome 0.069115931084794066

Safari 0.10931362123676475

3

day_of_week

null

7 0.051780350639992277

6 -0.098905011477176716

4 -0.092395178188358462

5 -0.010693625983554155

3 -0.047629987110766638

1 -0.0067030673140933122

2 0.061739400111810727

4

hour

null

15 -0.12081420778273

16 -0.14670467657779182

1 0.036118460001355934

10 -0.022111985303061014

3 0.10146297241339688

8 0.00032334907570882464

12 -0.092819888101463813

19 -0.12158349523248162

2 0.27252001951689164

4 0.1389215333278028

18 -0.13202189122418825

5 0.030387010564142392

22 0.0085803647602565782

13 -0.070696534712732753

14 -0.0912853928925844

9 -0.017888651719350213

23 0.10216569641652029

11 -0.053494611827240059

20 -0.10800180853273429

21 -0.070702105471528345

0 0.011735200996326559

6 0.016581239381563598

17 -0.15602138949559918

7 0.024077394387953525

5

age_group_name

null

45-54 -0.013192901125032637

65+ 0.035681341407469279

25-34 -0.044038102549733116

18-24 -0.041488170110836373

unknown 0.025466344709472313

35-44 0.01582412778809188

55-64 -0.004832373590628946

6

gender_name

null

male 0.061475274448403977

unknown 0.46660611583398443

female -0.13635601771194916