잠재고객 목록의 회귀 모델링

모델 자체에 대한 액세스 권한이 없어도, ML.PREDICT를 사용하지 않고 알려진 가중치를 가진 기존 선형 혹은 로지스틱 회귀 모델을 사용하여 예측할 수 있습니다. 이렇게 하려면 Ads Data Hub의 잠재고객 활성화 쿼리 내에서 개인 정보 차등 보호(DP) 회귀 모델을 사용하는 해결 방법을 활용해야 합니다.

이 단계별 예에서는 실제 선형 및 바이너리 로지스틱 회귀 모델에 시뮬레이션된 추론을 실행한 다음 결과를 ML.PREDICT의 결과와 비교하여 시뮬레이션된 결과의 정확성을 확인하는 방법을 설명합니다. 또한 바이너리 로지스틱 모델로 잠재고객 활성화에 전환 모델을 적용하는 데 사용할 잠재고객 목록을 만드는 방법에 대한 실제 예를 보여줍니다.

예 개요:

  1. 데이터 생성
  2. 모델 학습
  3. 가중치 및 절편 가져오기
  4. 예측 시뮬레이션
  5. 결과 비교

단계별 예

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;