모델 자체에 대한 액세스 권한이 없어도, 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
시뮬레이션 데이터에 R2 = 0.9009인 모델을 가져오는 데 충분한 노이즈를 추가했습니다.
측정 | 값 |
---|---|
평균 절대 오차 | 0.7359 |
평균 제곱 오차 | 0.8432 |
평균 제곱 로그 오차 | 0.0810 |
절대 오차 중앙값 | 0.6239 |
R 제곱 | 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 |
이 혼동 행렬의 굵게 표시된 값은 모델이 각 라벨을 정확히 분류한 빈도를 보여주며 굵게 표시되지 않은 값은 모델이 각 라벨을 잘못 분류한 빈도를 보여줍니다.
실제 라벨 | 예측된 라벨 1 | 예측된 라벨 2 |
---|---|---|
1 | 93% | 7% |
0 | 8% | 92% |
3. 가중치 및 절편 가져오기
모델의 가중치와 절편을 가져옵니다.
선형 회귀
SELECT
*
FROM
ML.WEIGHTS(MODEL `DATASET_NAME.LIN_REG_MODEL`)
weight | 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`)
weight | 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, 0.5 이상인 경우 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개의 행 홀드백 세트에서 하나도 상충하지 않습니다. ML.PREDICT
와 시뮬레이션된 추론이 모두 실제 라벨과 일치하지 않는 행이 몇 개 있습니다. 이는 모델 정확성이 약 93%이고 혼동 행렬의 대각선 셀에 작지만 0이 아닌 값이 있기 때문에 예상되는 결과입니다.
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;