Вы можете делать прогнозы, используя существующую линейную или логистическую регрессионную модель с известными весами, без использования ML.PREDICT , даже без доступа к самой модели. Для этого вам потребуется использовать обходной путь для использования моделей регрессии с дифференциальной приватностью (DP) внутри запросов активации аудитории в Ads Data Hub.
Этот пошаговый пример научит вас выполнять имитационный вывод для реальных моделей линейной и бинарной логистической регрессии, а затем сравнивать результаты с результатами ML.PREDICT чтобы показать точность имитационных результатов. Он также продемонстрирует практический пример создания списка аудитории с помощью бинарной логистической модели, который будет использоваться при применении модели конверсии для активации аудитории.
Overview of the example:
- Сгенерировать данные
- Обучите модель
- Получите вес и перехватите
- Simulate the prediction
- Сравните результаты
Пошаговый пример
1. Generate data
Создайте таблицу с имитированными данными для обучения модели. Отметьте часть строк для контрольного набора данных.
Линейная регрессия
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
Обратите внимание, что мы добавили достаточно шума к смоделированным данным, чтобы получить модель с коэффициентом детерминации R² = 0,9009.
| Измерение | Ценить |
|---|---|
| Средняя абсолютная ошибка | 0.7359 |
| Среднеквадратичная ошибка | 0.8432 |
| Mean squared log error | 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.
| Измерение | Ценить |
|---|---|
| Positive class | 1 |
| Отрицательный класс | 0 |
| Точность | 0.0810 |
| Отзывать | 0.9315 |
| Точность | 0.9260 |
| F1 score | 0.9328 |
Жирным шрифтом в этой матрице ошибок выделены значения, показывающие, как часто модель правильно классифицировала каждую метку, а значения без жирного шрифта показывают, как часто модель неправильно классифицировала каждую метку.
| True label | Предполагаемая метка 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 |
| функция_5 | 1.7899764387123640 |
| feature_6 | 1.8645246630251291 |
| feature_7 | 1.8698005281925356 |
| feature_8 | 1.7904637080330201 |
| feature_9 | 1.8036887855406274 |
| feature_10 | 1.8117115890624449 |
| ПЕРЕХВАТЫВАТЬ | -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 |
| функция_5 | 3.737386716 |
| feature_6 | 3.567663961 |
| feature_7 | 3.819643052 |
| feature_8 | 3.734673763 |
| feature_9 | 3.839301406 |
| feature_10 | 3.787306994 |
| ПЕРЕХВАТЫВАТЬ | -17.922169920 |
4. Смоделируйте прогноз.
Линейная регрессия
Используйте скалярное произведение значений признаков на веса и добавьте свободный член, чтобы сделать прогноз с помощью стандартного SQL без использования ML.PREDICT . Этот запрос сравнивает прогнозы, полученные с помощью этого метода, с прогнозами, полученными с помощью 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
Бинарная логистическая регрессия
В бинарной логистической регрессии метод моделирования прогнозов очень похож на метод линейной регрессии, с той разницей, что на последнем шаге применяется сигмоидная функция с желаемым пороговым значением.
Используйте скалярное произведение значений признаков на веса и добавьте свободный член, чтобы сделать прогноз с помощью стандартного SQL без использования ML.PREDICT . Затем используйте сигмоидную функцию с порогом 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)
Затем применяется сигмоидная функция Y = 1 / (1+e^-z) к скалярному произведению и свободному члену, используя стандартный SQL:
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Наконец, результат сигмоидной функции сравнивается с пороговым значением 0,5 для получения бинарного прогноза логистической регрессии, равного либо 0, если значение меньше 0,5, либо 1, если оно больше 0,5. Обратите внимание, что можно использовать любое пороговое значение от 0 до 1.
IF((1 / (1 + EXP(-(SUM(element1 * element2) -17.922169920432161)))) < 0.5, 0, 1)
Этот метод также может быть расширен до многоклассовой логистической регрессии. В этом случае веса модели будут представлять собой матрицу nxn, а не вектор, и веса будут вектором, а не скаляром. Вы умножите вектор значений признаков на матрицу весов и добавите вектор свободного члена. Полученный вектор будет содержать оценку для каждой метки, и вы сможете выбрать метку с наивысшей оценкой для прогнозирования. Если вы хотите получить массив вероятностей, вы примените сигмоидную функцию к каждому элементу массива.
5. Сравните результаты.
Линейная регрессия
Результаты выборки практически идентичны, за исключением небольшой погрешности округления.
| фактическая_метка | ml_predicted_label | sql_predicted_label | diff_is_negligible |
|---|---|---|---|
| 6 | 5.2062349420751834 | 5.2062349420751826 | истинный |
| 0 | 0.40318472770048075 | 0.403184727700479 | истинный |
| 3 | 3.0703766078249597 | 3.0703766078249597 | истинный |
| 7 | 7.0588171538562 | 7.0588171538562 | истинный |
| 6 | 6.7802375930646 | 6.7802375930646 | истинный |
| 6 | 5.1088569571339368 | 5.1088569571339377 | истинный |
| 4 | 4.051839078116874 | 4.051839078116874 | истинный |
| 4 | 5.1810254680219243 | 5.1810254680219234 | истинный |
| 6 | 6.1440349466401223 | 6.1440349466401205 | истинный |
| 1 | 2.0842399472783519 | 2.0842399472783519 | истинный |
| 2 | 2.1911209811886847 | 2.1911209811886838 | истинный |
| 3 | 3.0236086790006622 | 3.0236086790006613 | истинный |
| 2 | 2.573083132964213 | 2.5730831329642125 | истинный |
| 7 | 5.68662973136732 | 5.6866297313673186 | истинный |
| 9 | 8.1860026312677938 | 8.1860026312677938 | истинный |
Бинарная логистическая регрессия
Сравнение результатов моделирования с фактическими результатами ML.PREDICT идеально — ни одного противоречия в наборе данных из 10 000 строк. Есть несколько строк, где и ML.PREDICT , и моделирование не совпадают с фактической меткой, что ожидаемо, поскольку точность модели составляет около 93%, а в недиагональных ячейках матрицы ошибок присутствуют небольшие, но ненулевые значения.
| actual_label | ml_predicted_label | sql_predicted_label | simulation_is_accurate |
|---|---|---|---|
| 0 | 1 | 1 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 0 | 0 | истинный |
| 0 | 1 | 1 | истинный |
| 0 | 0 | 0 | истинный |
Create an audience activation list with 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;