Ads Data Hub の回帰モデリング

線形回帰とロジスティック回帰は、広告データから有意な予測を生成できる機械学習モデルです。

  • 線形回帰: 実データのデータポイントとの距離が最小となるような直線の関数を作成します。このモデルを使って、入力データをもとに数値を予測することができます。たとえば、購入データや過去のインタラクションをもとに、ユーザーのライフタイム バリューの予測が可能です。
  • ロジスティック回帰: 予測分類問題に使用されます。指定する変数の数に応じて、次の 2 種類のモデルを使用できます。
    • 二項ロジスティック回帰: Yes / No 型の質問に答えることができます。たとえば、あるコンバージョン イベントが発生する確率を推測することが可能です。
    • 多クラス ロジスティック回帰: 複数の候補が存在する値の予測に使用されます。たとえば、ある顧客が「低価値層」か「中価値層」か「高価値層」かを予測するのに役立ちます。

線形回帰もロジスティック回帰も、トレーニング データ(ここでは広告主様の広告データ)を学習することによって、広告活動の意思決定に役立つ予測モデルを提供する仕組みです。一般に、入力するデータの量が多く、質が高いほど、得られるモデルの精度は向上します。どちらのモデルも、密集度の高いトレーニング データを与えたほうが優れたパフォーマンスを期待できます。

差分プライバシー

線形回帰とロジスティック回帰では、いずれも差分プライバシーが採用されています。これは、Ads Data Hub の他の処理とは異なるシステムによるプライバシー チェックです。差分プライバシーは、トレーニング中にデータにノイズを混ぜることにより、エンドユーザーのプライバシーを確保する仕組みです。ノイズのレベルは、得られた分析結果の有用性が保たれる程度には低く、かつエンドユーザーの識別が不可能になる程度には高くなるよう調整されています。また、ノイズのレベルは非決定性であり、分析結果が受けるノイズの程度は不均一なので、エンドユーザーのプライバシー保護はさらに強化されます。

クエリの制限

デフォルトの EPSILON_PER_MODEL を使用する場合、「データ日」ごとの線形回帰モデリングとロジスティック回帰モデリングのクエリは、100 件までに制限されます。データ日とは、同日に生成されたすべてのイベントを指します。データ日は、クエリ実行の際に指定した開始日、終了日と、クエリが使用するテーブル(トレーニング用の一時テーブルなど)の作成時に使用された開始日、終了日に対応します。つまり、同じ日のデータを使用できるモデルは最大 100 個までです。EPSILON_PER_MODEL の値をデフォルトより大きい値に設定すると、モデルの数を減らせますが、品質は高くなります。EPSILON_PER_MODEL の値を小さくすると、より多くのモデルをトレーニングできますが、モデルの品質は低くなります。

仕組み

ワークフローの概要は次のとおりです。

  1. トレーニング データを準備します。
  2. モデルを作成します。
  3. モデルからインサイトを集めます。

トレーニング データの準備

前述のとおり、一般にデータセットの規模が大きく、質が高いほうが有効な結果を得られます。また、入力データは最小 / 最大スケーリングによってスケール変換されるため、密集度の低いデータや突出した外れ値を含むデータを使用すると、平均値がずれ、モデルに悪影響を与える可能性があります。

デフォルトでは、Ads Data Hub はトレーニング データの 18% をランダムに選択して検証に使用します。検証に使用するデータの割合は、data_split_eval_fraction オプションで制御できます。

モデルの作成

パラメータと入力データを指定して、モデルのトレーニングを行います。

ベスト プラクティス

モデルの品質を高めるうえで最も重要な要素のひとつが、トレーニング セットの規模です。ただし、規模と品質のトレードオフは、解決しようとする問題の種類や下記の要素によって変動します。ぜひご意見、ご感想をお聞かせください。* ユーザー数 100,000 以上のトレーニング セットから構築されたロジスティック回帰モデルで、精度が 0.70 を超える事例が確認されています。* ユーザー数 800,000 以上のトレーニング セットから構築された線形回帰モデルで、決定係数が 0.70 を超える事例が確認されています。

モデルの品質を低下させる要素は他にもあります。* あるクラスが他のクラスよりも著しく強調されているロジスティック モデル。あるラベルのトレーニング セット ユーザー数が少ない場合、他のラベルのトレーニング セット ユーザー数を増やしても、前者に対するモデルの精度向上にはあまり役立ちません。たとえば、2 つのラベルのトレーニング セット ユーザー数がそれぞれ 20,000 人と 1,000 人だった場合、10,000 人と 2,000 人の場合よりも期待できる精度は低くなります。* 各ラベルについて強いシグナルを得られない特徴量データ。* 特徴量エンジニアリングが不足している生データ。たとえば、候補値の数が非常に多いフィールドが含まれる場合などがあります。この種のデータを改善する方法としては、値をカテゴリ(バケット)数の少ない特徴量に変換することが挙げられます。

インサイトの収集

関数を呼び出して検証データでモデルのパフォーマンスを評価するほか、トレーニング イテレーションの特徴量や情報(たとえばモデルが予測の際に使用した比重)を調べたり、未知のデータを予測したりすることができます。

CREATE MODEL ステートメント

CREATE MODEL ステートメントは、指定された名前とデータセットでモデルを作成します。すでに使用されているモデル名が指定された場合、CREATE MODEL は既存のモデルを置換します。

CREATE MODEL の構文

CREATE MODEL
model_name
OPTIONS
(
  // model_option_list:
  // Required parameter.
  MODEL_TYPE = { 'ADH_LINEAR_REGRESSION' | 'ADH_LOGISTIC_REGRESSION'}

  // Optional tuning parameters.
  [, L1_REG = float64_value ]
  [, L2_REG = float64_value ]
  [, DATA_SPLIT_EVAL_FRACTION = float64_value ]
  [, OPTIMIZE_STRATEGY = { 'AUTO_STRATEGY' | 'BATCH_GRADIENT_DESCENT' |
                           'NORMAL_EQUATION' } ]
  [, MAX_ITERATIONS = int64_value ]
  [, LEARN_RATE_STRATEGY = { 'LINE_SEARCH' | 'CONSTANT' } ]
  [, LEARN_RATE = float64_value ]
  [, EARLY_STOP = { TRUE | FALSE } ]
  [, MIN_REL_PROGRESS = float64_value ]
  [, LS_INIT_LEARN_RATE = float64_value ]
  [, EPSILON_PER_MODEL = float64_value ]
  [, AUTOMATIC_IMPUT_SCALING = bool_value ]
  [, MIN_MAX_SCALED_COLS = [string_value, string_value... ] ]
  [, STANDARD_SCALED_COLS = [string_value, string_value... ] ]
  [, QUANTILE_BUCKETIZED_COLS = [
        STRUCT(string_value AS col_name, int64_value AS num_buckets), 
       STRUCT(string_value AS col_name, int64_value AS num_buckets)... ] ]
)
AS query_statement

model_name

モデルの名前を英数字(アンダースコアとハイフンを含む)で指定します。ドットは使用できません。すでに使用されているモデル名を指定した場合、既存のモデルが上書きされます。

query_statement

トレーニング データの生成に使用される標準 SQL クエリを指定します。同じトレーニング データを使って複数のモデルを作成する場合、トレーニング データを格納した一時テーブルを作成しておき、ここで参照します。これにより、ワイプアウトや遅延スパムによって生じることがある差分チェックエラーを避けることができます。

model_option_list

model_type

(必須)唯一の必須オプションです。「adh_linear_regression」または「adh_logistic_regression」を指定できます。

l1_reg

(任意)適用する L1 正則化の量。L1 正則化は、比重の絶対値の和に応じて比重にペナルティーをかけます。任意の負でない数値を指定できます。デフォルト値は 0 です。

l2_reg

(任意)適用する L2 正規化の量。L2 正規化は、比重の平方の和の平方根に応じて比重にペナルティーをかけます。任意の負でない数値を指定できます。デフォルト値は 0 です。

data_split_eval_fraction

(任意)0.01~0.99 の範囲で指定します。デフォルト値は 0.18 です。このパラメータでは、検証用セットに入れるデータの割合を指定します。設定値を引き上げると、モデルに含めるデータ行が減るためモデルの精度に影響がありますが、一方で実行できるモデルの数は増えます。検証用データの割合と許可されるクエリの数の関係は、次の表のとおりです(データセット内のすべてのモデルに同じ割合が設定されている場合の値です)。

検証用データの割合 許可されるクエリの数
0.01 7
0.1 8
0.15 8
0.18 9
0.2 9
0.3 10
0.5 14
0.9 50

optimize_strategy

(任意)線形回帰モデルをトレーニングする際の戦略。

引数

AUTO_STRATEGY」は、トレーニング戦略を次のように決定します。

  • l1_regwarm_start が指定されている場合、batch_gradient_descent 戦略が使用されます。
  • トレーニングの特徴量のカーディナリティが合計 10,000 を超える場合、batch_gradient_descent 戦略が使用されます。
  • 過学習の問題がある(トレーニングのサンプル数が合計カーディナリティの 10 倍を下回る)場合、batch_gradient_descent 戦略が使用されます。
  • 上記以外のケースでは、NORMAL_EQUATION 戦略が使用されます。

BATCH_GRADIENT_DESCENT」(ロジスティックのみ)は、勾配関数を使って損失関数を最適化するバッチ勾配降下法によってモデルをトレーニングします。

NORMAL_EQUATION」(線形のみ)は、線形回帰問題の最小二乗解を分析式で直接計算します。次の場合、正規方程式は使用できません。

  • l1_reg が指定されている。
  • warm_start が指定されている。
  • トレーニングの特徴量のカーディナリティが合計 10,000 を超えている。
  • デフォルト値は「AUTO_STRATEGY」です。

max_iterations

(任意)トレーニングのイテレーション(ステップ)数。このクエリはイテレーションごとに 1 つツリーを構築するため、指定値がツリーの数にもなります。1 より大きい整数を指定してください。デフォルト値は 20 です。

learn_rate_strategy

(任意、ロジスティックのみ)トレーニング中の学習率を指定する際の戦略。

引数

LINE_SEARCH」は、直線探索法を使用して学習率を計算します。直線探索の初期学習率は、LS_INIT_LEARN_RATE に指定された値です。

  • 直線探索はトレーニングを遅くし、処理されるバイト数を増加させますが、一般に、最初に指定した学習率が大きくても収束します。

CONSTANT」は、学習率を LEARN_RATE に指定された値に設定します。

デフォルト値は「LINE_SEARCH」です。

learn_rate

(任意、ロジスティックのみ)LEARN_RATE_STRATEGYCONSTANT に設定されたときの勾配降下の学習率。LEARN_RATE_STRATEGY が「LINE_SEARCH」に設定されていると、エラーが返されます。

引数

float64_value には、任意の 64 ビット浮動小数点数を指定できます。デフォルト値は 0.1(10%)です。

early_stop

(任意)最初のイテレーションで、相対損失改善値が MIN_REL_PROGRESS に指定された値より小さい場合、トレーニングを停止するかどうか。

引数

「yes」の場合は TRUE、「no」の場合は FALSE、デフォルトは TRUE です。

min_rel_progress

(任意)EARLY_STOP が true に設定されている場合に、トレーニングの継続に最低限必要な相対損失改善値。たとえば値を 0.01 に設定した場合、イテレーションごとに損失が 1% 以上減少している場合に限り、トレーニングが継続されます。

引数

float64_value には、任意の 64 ビット浮動小数点数を指定できます。デフォルト値は 0.1(10%)です。

ls_init_learn_rate

(任意)LEARN_RATE_STRATEGY='LINE_SEARCH' が使用する初期学習率を設定します。このオプションは、LINE_SEARCH が指定されている場合にのみ使用できます。

イテレーションごとにモデルの LEARN_RATE が倍増しているように見える場合は、最後に 2 倍になった学習率を LS_INIT_LEARN_RATE に設定してみてください(モデルの状態は ML.TRAINING_INFO で確認できます)。最適な初期学習率はモデルごとに異なります。あるモデルに最適な初期学習率が別のモデルでも最適とは限りません。

引数

float64_value には、任意の 64 ビット浮動小数点数を指定できます。

epsilon_per_model

(省略可)このモデルのトレーニングで使用するプライバシー バジェットの量を指定します。各データ利用者に対して、1 日あたり 10.0 のプライバシー バジェットが付与されます。正常にトレーニングされたモデルでは、クエリの実行時に指定された期間内で、データ日ごとに EPSILON_PER_MODEL のバジェットが消費されます。デフォルト値の ln(3)/10 を使用すると、約 100 個のモデルを作成できます。値を大きくすると、作成できるモデルの数は少なくなりますが、品質は高くなります。値を小さくすると、作成できるモデルの数は多くなりますが、品質は低くなります。

引数

float64_value は、「ln(3)」(約 1.0986)未満の正の 64 ビット浮動小数点数です。デフォルトは ln(3)/10 です。

automatic_input_scaling

(任意)TRUE の場合、数値型の特徴量の列はすべて自動的に min_max_scaling を適用されます。これは min_max_scaled_cols オプションで列名を明示的に指定した場合と同様の動作です。ただし、standard_scaled_cols オプションまたは quantile_bucketized_cols オプションで明示的に指定された列は対象外となります。

引数

bool_valueBOOL で、デフォルト値は TRUE です。

min_max_scaled_cols

(任意)numerical_expression 型の特徴量の各列の全データを、MINMAX を下限 / 上限として 0~1 の範囲になるようスケール変換します。予測においても自動的に同じ MIN および MAX が使用されます。予測データが MIN よりも小さければ 0、MAX よりも大きければ 1 になります。

引数

string_value の配列。各 string_value は変換対象の列名(STRING 値)です。

standard_scaled_cols

(任意)指定された numerical_expression 型の特徴量の列の全データを標準化します。式を標準化するために計算された STDDEVMEAN は、自動的に予測でも使用されます。

引数

string_value の配列。各 string_value は変換対象の列名(STRING 値)です。

quantile_bucketized_cols

指定された連続数値型の特徴量の列を STRING にバケット化します。バケット名は分位数に基づく値になります。予測においても自動的に同じ分位数が使用されます。

引数

STRUCT(string_value AS col_name, int64_value AS num_buckets) の配列。各 string_value は変換対象となる連続数値型の列の名前(STRING 値)、各 int64_value は数値型の値を分ける先のバケットの数です。

検証

  • このクエリで指定された期間内の各データ日には、十分なプライバシー バジェット(EPSILON_PER_MODEL 超)が必要です。十分なプライバシー バジェットがないと、クエリは失敗します。
  • 任意指定のチューニング パラメータが指定されている場合は、上記の範囲で検証されます。
  • 唯一の必須パラメータである model_type だけは、明示的に指定する必要があります。
  • トレーニング セットの列の 1 つを「label」という名前にする必要があります。複数のラベルは現在サポートされていません。
  • ラベル列に null 値を含めることはできません。ラベル列に null 値が含まれていると、クエリが失敗します。
  • 特徴量の列を user_id から導出することはできません。
  • 各データ行は、過不足なく 1 人のユニーク ユーザーに対応している必要があります。1 つの行で複数のユーザーのデータを表すことはできません。ある種の結合(CROSS JOIN など)ではそういったデータ行が発生することがあります。
  • 1 人のユーザーを複数の行に分けることはできません。
  • プライバシー保護のため、使用できるオプションは、構文セクションで説明されているものに限られます。他のオプションは、BQML CREATE MODEL クエリ ドキュメントに記載があっても、現在はサポートされていません。

評価関数

ML.EVALUATE

モデルの指標を評価するには、ML.EVALUATE 関数を使用します。ML.EVALUATE 関数は、線形回帰モデルでもロジスティック回帰モデルでも使用できます。

SELECT
  *
FROM ML.EVALUATE(MODEL `linear_model_test`);

ML.ROC_CURVE

ロジスティック回帰特有の指標を評価するには、ML.ROC_CURVE 関数を使用します。ML.ROC_CURVE で評価できるのはロジスティック回帰モデルのみです。

SELECT
  *
FROM ML.ROC_CURVE(MODEL `logistic_model_test`);

予測関数

ML.PREDICT

モデルを使って得られる結果を予測するには、ML.PREDICT 関数を使用します。ML.PREDICT によって得られた結果は、Ads Data Hub の他の分析結果と同じプライバシー チェックの対象となります。プライバシー チェックの詳細

線形回帰

/* This example outputs the average value for labels that the model predicted */
SELECT
  AVG(predicted_label) AS average_predicted_label
FROM
  ML.PREDICT(MODEL `linear_model_test`, TABLE tmp.linear_training_set);

ロジスティック回帰

/* This example outputs the model's prediction and probabilities for said prediction over individual users. It groups by label and prediction, counting the number of users in each prediction */
SELECT
  label,
  predicted_label, /* one of the two input labels, depending on which label has the higher predicted probability */
  COUNT(*) AS num /* a tally of users */
FROM
  ML.PREDICT(MODEL `logistic_model_test`, TABLE tmp.logistic_training_set)
GROUP BY 1, 2;

モデルと特徴量の検査関数

ML.TRAINING_INFO

モデルのトレーニング イテレーションについての情報を参照するには、ML.TRAINING_INFO 関数を使用します。

SELECT
  *
FROM ML.TRAINING_INFO(MODEL `logistic_model_test`);

ML.FEATURE_INFO

モデルのトレーニングのために入力された特徴量についての情報を参照するには、ML.FEATURE_INFO 関数を使用します。

SELECT
  *
FROM ML.FEATURE_INFO(MODEL `logistic_model_test`);

ML.WEIGHTS

予測の際にモデルが使用する比重を参照するには、ML.WEIGHTS 関数を使用します。

SELECT
  *
FROM ML.WEIGHTS(MODEL `linear_model_test`);

モデルの作成

以下の例はいずれも、natality サンプル テーブルを使ってモデルの作成方法を示したものです。

内部 SELECT でトレーニング データを指定(線形)

次の例では、出生時体重、性別、妊娠週数、母体年齢、母体人種を使って、子供の出生時体重を予測しています。

CREATE MODEL `natality_model`
OPTIONS
  (model_type='adh_linear_regression') AS
SELECT
  weight_pounds as label,
  is_male,
  gestation_weeks,
  mother_age,
  CAST(mother_race AS string) AS mother_race
FROM
  `bigquery-public-data.samples.natality`
WHERE
  weight_pounds IS NOT NULL

内部 SELECT でトレーニング データを指定(ロジスティック)

次の例では、出生時体重、性別、妊娠週数、母体年齢、母体人種を使って、子供の性別を予測しています。

CREATE MODEL `natality_model`
OPTIONS
  (model_type='adh_logistic_regression') AS
SELECT
  weight_pounds,
  is_male as label,
  gestation_weeks,
  mother_age,
  CAST(mother_race AS string) AS mother_race
FROM
  `bigquery-public-data.samples.natality`
WHERE
  weight_pounds IS NOT NULL