既存の線形回帰モデルまたはロジスティック回帰モデルを使用することで、ML.PREDICT
を使用せずに、既知の重み付けによる予測を行うことができます。モデル自体へのアクセスも不要です。これを行うためには、Ads Data Hub でのオーディエンスの有効化クエリ内で、差分プライベート化(DP)の回帰モデルを使用するための対処法を講じる必要があります。
手順の例を参照しながら、実際の線形回帰モデルやバイナリ ロジスティック回帰モデルのシミュレーション予測を実行する方法を説明します。また、その結果を ML.PREDICT
の結果と比較して、シミュレーション結果の精度を把握する方法も説明します。実践的な例として、コンバージョン モデルをオーディエンスの有効化に適用する際に使用されるバイナリ ロジスティック モデルによって、オーディエンス リストを作成する方法も紹介します。
例の概要:
- データの生成
- モデルのトレーニング
- 重み付けと切片の取得
- 予測のシミュレーション
- 結果の比較
手順の例
1. データの生成
モデルをトレーニングするためのシミュレーション データを含むテーブルを作成します。ホールドバック セット用に一部の行をマークします。
線形回帰
CREATE OR REPLACE TABLE DATASET_NAME.LIN_REG_TRAINING_SET AS
WITH
A AS (
SELECT
*
FROM
UNNEST(GENERATE_ARRAY(1, 100000)) AS row_number),
B AS (
SELECT
row_number,
RAND() AS rand_label,
RAND() AS rand_feature_1,
RAND() AS rand_feature_2,
RAND() AS rand_feature_3,
RAND() AS rand_feature_4,
RAND() AS rand_feature_5,
RAND() AS rand_feature_6,
RAND() AS rand_feature_7,
RAND() AS rand_feature_8,
RAND() AS rand_feature_9,
RAND() AS rand_feature_10
FROM
A),
C AS (
SELECT
rand_label AS label,
*
FROM
B),
D AS (
SELECT
row_number,
CAST(round(10 * label) AS INT64) AS label,
(rand_label + rand_feature_1) / 2 AS feature_1,
(rand_label + rand_feature_2) / 2 AS feature_2,
(rand_label + rand_feature_3) / 2 AS feature_3,
(rand_label + rand_feature_4) / 2 AS feature_4,
(rand_label + rand_feature_5) / 2 AS feature_5,
(rand_label + rand_feature_6) / 2 AS feature_6,
(rand_label + rand_feature_7) / 2 AS feature_7,
(rand_label + rand_feature_8) / 2 AS feature_8,
(rand_label + rand_feature_9) / 2 AS feature_9,
(rand_label + rand_feature_10) / 2 AS feature_10
FROM
C)
SELECT
label,
feature_1,
feature_2,
feature_3,
feature_4,
feature_5,
feature_6,
feature_7,
feature_8,
feature_9,
feature_10,
RAND() < 0.1 AS holdback -- Ten percent will be true.
FROM
D
バイナリ ロジスティック回帰
SELECT
CASE
WHEN label < 5 THEN 0
WHEN label >= 5 THEN 1
END
AS label,
* EXCEPT (label)
FROM
`DATASET_NAME.BIN_LOG_REG_TRAINING_SET`
2. モデルのトレーニング
トレーニング セットを基に回帰モデルをトレーニングします。
線形回帰
CREATE OR REPLACE MODEL `DATASET_NAME.LIN_REG_MODEL` OPTIONS (model_type="linear_reg") AS
SELECT
* except (holdback)
FROM
`DATASET_NAME.LIN_REG_TRAINING_SET`
WHERE
NOT holdback
なお、決定係数 = 0.9009 として、十分なノイズをシミュレーション データに追加してモデルを取得できるようにしています。
測定対象 | 値 |
---|---|
平均絶対誤差 | 0.7359 |
平均二乗誤差 | 0.8432 |
平均二乗対数誤差 | 0.0810 |
絶対誤差の中央値 | 0.6239 |
決定係数 | 0.9009 |
バイナリ ロジスティック回帰
CREATE OR REPLACE MODEL `DATASET_NAME.BIN_LOG_REG_MODEL` OPTIONS (model_type="logistic_reg") AS
SELECT
* EXCEPT (holdback)
FROM
`DATASET_NAME.BIN_LOG_REG_TRAINING_SET`
WHERE
NOT holdback
結果の例です。精度は 0.9260 です。
測定対象 | 値 |
---|---|
陽性クラス | 1 |
陰性クラス | 0 |
適合率 | 0.0810 |
再現率 | 0.9315 |
精度 | 0.9260 |
F1 スコア | 0.9328 |
以下の混同行列内の太字の値は、モデルによって各ラベルが正しく分類された頻度を表し、太字以外の値は、モデルによって各ラベルが誤って分類された頻度を表しています。
True ラベル | 予測ラベル 1 | 予測ラベル 2 |
---|---|---|
1 | 93% | 7% |
0 | 8% | 92% |
3.重み付けと切片の取得
モデルの重み付けと切片を取得します。
線形回帰
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
重み付け | category_weights.category |
---|---|
feature_1 | 1.8263055528635743 |
feature_2 | 1.8143804404490813 |
feature_3 | 1.8601204874033492 |
feature_4 | 1.8507603439031859 |
feature_5 | 1.7899764387123640 |
feature_6 | 1.8645246630251291 |
feature_7 | 1.8698005281925356 |
feature_8 | 1.7904637080330201 |
feature_9 | 1.8036887855406274 |
feature_10 | 1.8117115890624449 |
INTERCEPT | -4.1428754911504306 |
バイナリ ロジスティック回帰
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`)
重み付け | category_weights.category |
---|---|
feature_1 | 3.823533928 |
feature_2 | 3.734812819 |
feature_3 | 3.842239823 |
feature_4 | 3.785488823 |
feature_5 | 3.737386716 |
feature_6 | 3.567663961 |
feature_7 | 3.819643052 |
feature_8 | 3.734673763 |
feature_9 | 3.839301406 |
feature_10 | 3.787306994 |
INTERCEPT | -17.922169920 |
4. 予測のシミュレーション
線形回帰
特徴値と重み付けのドット積を使用し、切片を追加して、ML.PREDICT
を使用せずに標準 SQL で予測を行います。このクエリは、この手法による予測と ML.PREDICT
による予測を比較します。SQL 行の太字部分によって、行の特徴値とモデルの重み付けのドット積が求められ、切片が追加されます。
WITH
T AS (
SELECT
label AS actual_label,
predicted_label AS ml_predicted_label,
[feature_1,
feature_2,
feature_3,
feature_4,
feature_5,
feature_6,
feature_7,
feature_8,
feature_9,
feature_10] AS features,
[1.8263055528635743,
1.8143804404490813,
1.8601204874033492,
1.8507603439031859,
1.789976438712364,
1.8645246630251291,
1.8698005281925356,
1.7904637080330201,
1.8036887855406274,
1.8117115890624449] AS weights
FROM
ML.PREDICT(MODEL `DATASET_NAME.LIN_REG_MODEL`,
(
SELECT
*
FROM
`PROJECT_NAME.DATASET_NAME.LIN_REG_TRAINING_SET`))
WHERE
holdback),
P AS (
SELECT
actual_label,
ml_predicted_label,
(
SELECT
SUM(element1 * element2) - 4.1428754911504306
FROM
T.features element1
WITH
OFFSET
pos
JOIN
T.weights element2
WITH
OFFSET
pos
USING
(pos) ) sql_predicted_label,
features,
weights
FROM
T)
SELECT
actual_label,
ml_predicted_label,
sql_predicted_label,
ABS(ml_predicted_label - sql_predicted_label) < 0.00000000001 AS diff_is_negligible
FROM
P
バイナリ ロジスティック回帰
バイナリ ロジスティック回帰の場合、予測のシミュレーション手法は線形回帰とよく似ていますが、最終ステップに、所定のしきい値でシグモイド関数が追加で適用されます。
特徴値と重み付けのドット積を使用し、切片を追加して、ML.PREDICT
を使用せずに標準 SQL で予測を行います。次に、結果に対してしきい値 0.5 のシグモイド関数を使用して、0 または 1 を予測します。このクエリは、この手法による予測と ML.PREDICT
による予測を比較します。
WITH
T AS (
SELECT
label AS actual_label,
predicted_label AS ml_predicted_label,
[feature_1,
feature_2,
feature_3,
feature_4,
feature_5,
feature_6,
feature_7,
feature_8,
feature_9,
feature_10] AS features,
[3.8235339279050287,
3.7348128191185244,
3.8422398227859471,
3.7854888232502479,
3.7373867156553713,
3.5676639605351026,
3.8196430517007811,
3.7346737628343032,
3.8393014063170749,
3.7873069939244743] AS weights
FROM
ML.PREDICT(MODEL `DATASET_NAME.BIN_LOG_REG_MODEL`,
(
SELECT
*
FROM
`PROJECT_NAME.DATASET_NAME.BIN_LOG_REG_TRAINING_SET`))
WHERE
holdback),
P AS (
SELECT
actual_label,
ml_predicted_label,
(
SELECT
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
FROM
T.features element1
WITH
OFFSET
pos
JOIN
T.weights element2
WITH
OFFSET
pos
USING
(pos) ) sql_predicted_label,
features,
weights
FROM
T)
SELECT
actual_label,
ml_predicted_label,
sql_predicted_label,
ml_predicted_label = sql_predicted_label AS simulation_is_accurate
FROM
P
上のクエリでは、SQL コードの太字部分のブロックで、各行の特徴値とモデルの重み付けのドット積を求め、インターセプトを追加して線形回帰の予測を行っています。
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
次に、標準 SQL を使用して、シグモイド関数 Y = 1 / (1+e^-z)
をドット積と切片に適用します。
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
最後に、シグモイド関数の結果がしきい値 0.5 と比較され、0.5 未満の場合は 0、そうでない場合は 1 というバイナリ ロジスティック回帰予測に到達します。しきい値には、0~1 の任意の値を使用できます。
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
この手法は、マルチクラス ロジスティック回帰にも応用できます。その場合、モデルの重み付けはベクトルではなく nxn 行列になり、重み付けはスカラーではなくベクトルになります。特徴値のベクトルに重み付けの行列を掛けて、切片のベクトルを追加します。結果として導出されるベクトルには各ラベルのスコアが含まれ、予測には最もスコアが高いラベルを選択できます。確率配列を返す場合は、配列の各要素にシグモイド関数を適用します。
5. 結果の比較
線形回帰
小さな丸め誤差を除き、サンプルの結果はほぼ同じです。
actual_label | ml_predicted_label | sql_predicted_label | diff_is_negligible |
---|---|---|---|
6 | 5.2062349420751834 | 5.2062349420751826 | true |
0 | 0.40318472770048075 | 0.403184727700479 | true |
3 | 3.0703766078249597 | 3.0703766078249597 | true |
7 | 7.0588171538562 | 7.0588171538562 | true |
6 | 6.7802375930646 | 6.7802375930646 | true |
6 | 5.1088569571339368 | 5.1088569571339377 | true |
4 | 4.051839078116874 | 4.051839078116874 | true |
4 | 5.1810254680219243 | 5.1810254680219234 | true |
6 | 6.1440349466401223 | 6.1440349466401205 | true |
1 | 2.0842399472783519 | 2.0842399472783519 | true |
2 | 2.1911209811886847 | 2.1911209811886838 | true |
3 | 3.0236086790006622 | 3.0236086790006613 | true |
2 | 2.573083132964213 | 2.5730831329642125 | true |
7 | 5.68662973136732 | 5.6866297313673186 | true |
9 | 8.1860026312677938 | 8.1860026312677938 | true |
バイナリ ロジスティック回帰
シミュレーション予測と ML.PREDICT
の実際の結果を比較すると、完全に一致しており、10,000 行のホールドバック セット内に不一致が 1 つもありません。ML.PREDICT
とシミュレーション予測の両方が実際のラベルと一致していない行がいくつかありますが、これはモデルの精度が約 93% であるため予想されたことです。また、混同行列の非対角セルに、ゼロではない小さい値があります。
actual_label | ml_predicted_label | sql_predicted_label | simulation_is_accurate |
---|---|---|---|
0 | 1 | 1 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 0 | 0 | true |
0 | 1 | 1 | true |
0 | 0 | 0 | true |
ML によるオーディエンスの有効化リストの作成
ユースケースとしては、コンバージョンを予測するための差分プライベート バイナリ ロジスティック回帰モデルを作成してから、オーディエンス リストを作成する際にこのモデルで予測を適用する方法が一般的です。前提として、上記の例で作成したバイナリ ロジスティック モデルはコンバージョンのモデリングを行い、トレーニング セットと評価セットの各行は個々のユーザーを表すものとします。
次のクエリは、モデルによって、コンバージョンに至ると予測されたユーザーで構成されるオーディエンス リストを作成する方法を示しています。
WITH
T AS (
SELECT
*,
label AS actual_label,
[feature_1,
feature_2,
feature_3,
feature_4,
feature_5,
feature_6,
feature_7,
feature_8,
feature_9,
feature_10] AS features,
[3.8235339279050287,
3.7348128191185244,
3.8422398227859471,
3.7854888232502479,
3.7373867156553713,
3.5676639605351026,
3.8196430517007811,
3.7346737628343032,
3.8393014063170749,
3.7873069939244743] AS weights
FROM
`PROJECT_NAME.DATASET_NAME.BIN_LOG_REG_TRAINING_SET`
WHERE
holdback),
P AS (
SELECT
*,
(
SELECT
IF
((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
FROM
T.features element1
WITH
OFFSET
pos
JOIN
T.weights element2
WITH
OFFSET
pos
USING
(pos) ) predicted_label,
features,
weights
FROM
T),
SELECT
user_id
FROM
P
WHERE
predicted_label = 1;