Добавление случайных данных

Добавление шума призвано защитить конфиденциальность пользователей при выполнении запросов к базе данных. Суть этой методики состоит в том, что к агрегирующему условию SELECT запроса добавляется некоторое количество случайных данных. При этом обеспечивается достаточно высокая точность результатов, отпадает необходимость в проверке различий и снижается требуемый порог агрегирования для выходных данных. Большинство существующих запросов можно выполнять в режиме добавления шума, хотя есть некоторые ограничения.

Преимущества добавления шума

Не применяется проверка различий. Если добавлять шум в запросы, строки не будут удаляться, поскольку они не отфильтровываются из-за сходства с предыдущими наборами результатов. Это означает, что вы можете проанализировать все доступные данные, не нарушая конфиденциальность пользователей.

Проще устранять неполадки и корректировать запросы, поскольку строки исключаются только из-за требований к агрегированию.

Не нужно изучать новый синтаксис или разбираться в концепциях конфиденциальности, чтобы использовать вместо проверки различий добавление шума.

Проще оценить точность результатов. При успешном выполнении задания вы видите общий процент данных с ожидаемым количеством шума.

Как добавление шума влияет на требования конфиденциальности

Проверка различий. При добавлении случайных данных проверка различий в Ads Data Hub не применяется.

Требования к агрегированию. При добавлении случайных данных сведения о показах предоставляются на основе выборки примерно из 20 или более уникальных пользователей. Для сведений о кликах или конверсиях используется выборка примерно из 10 или более уникальных пользователей.

Статическая проверка. Влияние отсутствует.

Бюджет и ограничение по количеству запросов. Запросы, выполненные с использованием случайных данных, используют тот же бюджет доступа к данным, что и проверка различий. Если вы многократно выполняете один и тот же запрос к одному набору данных или используете в запросах скользящее окно, то можете потерять доступ к такому набору данных.

Режим шума накладывает дополнительные, более строгие ограничения на повторный расчет тех же агрегированных результатов для одного или разных запросов. Как и в случае с бюджетом доступа к данным, вы можете потерять доступ к часто запрашиваемым данным в наборе. Однако ограничения, связанные с повторным расчетом одних и тех же агрегированных результатов, будут относиться только к запросам в режиме шума, а не к проверке различий. Более подробная информация приведена в разделе Повторяющиеся результаты.

Подробнее о проверках конфиденциальности

Как добавление шума влияет на результаты

Ads Data Hub добавляет случайные данные, чтобы снизить вероятность раскрытия информации об отдельном пользователе, сохраняя при этом баланс между эффективностью и защитой конфиденциальности.

При добавлении шума в Ads Data Hub результаты запроса изменяются следующим образом:

  • В агрегированных результатах ограничиваются аномальные данные пользователей. Данные каждого пользователя суммируются, а затем для них устанавливаются минимальные и максимальные границы значений.
  • Ограниченные данные каждого пользователя агрегируются.
  • К каждому агрегированному результату (т. е. к результату, полученному с помощью вызова агрегатной функции в каждой строке) добавляются случайные данные. Их количество пропорционально заданным границам значений.
  • Для каждой строки рассчитывается количество случайных пользователей. Строки, в которых пользователей слишком мало, исключаются. Это похоже на k-анонимность при проверке различий, но в заданиях, где используется один и тот же набор данных, из-за шума могут исключаться разные строки. Кроме того, в режиме шума исключается меньше строк, поскольку требования к агрегации ниже (приблизительно 20, а не ровно 50).

Конечным результатом будет набор данных, в котором в каждой строке есть случайные агрегированные результаты, а небольшие группы исключены. Благодаря этому в полученных результатах нельзя идентифицировать отдельных пользователей.

Ограничение агрегирования

При добавлении случайных данных в Ads Data Hub используется неявное или явное ограничение агрегирования, позволяющее задать количество и диапазон аномальных данных. Вы можете выбрать наиболее подходящий для вас вариант.

Неявное ограничение

В этом случае границы значений определяются автоматически. Чтобы использовать неявное ограничение, не нужен специальный синтаксис SQL. Если в одной строке диапазон значений шире, чем в другой, для них будут определены разные границы. Обычно это снижает погрешность каждого результата. С другой стороны, в каждом агрегированном наборе результатов будут разные границы значений и количество случайных данных, из-за чего их может быть труднее сравнивать.

Неявное ограничение может дать сбой, если агрегируются данные слишком малого числа пользователей, например при вызове функции COUNTIF() с редким условием. В таких случаях возвращается результат NULL. Также обратите внимание, что при вызове функции COUNT(DISTINCT user_id) автоматически устанавливаются минимальные и максимальные границы значений 0 и 1.

Явное ограничение

В этом случае данные каждого пользователя ограничиваются в пределах указанного диапазона. Явные границы всегда задаются литеральными значениями и одинаково применяются ко всем строкам, даже если диапазоны данных каждого пользователя в них отличаются. Благодаря этому результаты для разных строк проще сравнивать, хотя в некоторых строках случайных данных будет больше, чем при неявном ограничении.

Для одинаковых границ значений при явном ограничении используется вдвое меньше случайных данных, чем при неявном. Поэтому, если вы можете рассчитать подходящие границы, лучше задайте их самостоятельно. Так вы получите более точные результаты.

Чтобы использовать явное ограничение, укажите для каждой поддерживаемой агрегатной функции нижнюю и верхнюю границы значений в виде целых чисел. Пример:

SELECT
campaign_name,
-- Set lower and upper bounds to 0 and 1, respectively
ADH.ANON_COUNT(*, contribution_bounds_per_group => (0,1))
FROM data
GROUP BY 1

Как выполнить запрос с добавлением шума

  1. Составьте новый запрос или откройте существующий. Список доступных функций смотрите в разделе Поддерживаемые агрегатные функции.
  2. В редакторе запросов нажмите Выполнить и укажите сведения для нового задания.
  3. Переведите переключатель Настройки конфиденциальности в положение Использовать случайные данные.
  4. Выполните запрос.
  5. Проверьте добавленные случайные данные.
  6. При желании скорректируйте запрос, чтобы уменьшить влияние случайных данных.

Как проверить влияние случайных данных

После успешного выполнения запроса Ads Data Hub указывает надежность результата, основываясь на том, сколько ячеек в выходных данных содержат ожидаемое количество случайных данных. Влияние случайных данных считается значительным, если в ячейке в таблице результатов таких данных более 5 %. Степени влияния описаны в таблице ниже.

Для затронутых результатов на вкладке "Подробная информация" перечислены 10 столбцов с самым большим количеством случайных данных, ранжированные по степени влияния. Это разбивка по ожидаемому количеству шума.

Результаты с ожидаемым количеством шума Цвет индикатора Влияние
>95 % Зеленый Незначительное
85–95 % Желтый Умеренное
75–85 % Оранжевый Значительное
<75 % Красный Очень сильное

Чтобы посмотреть подробную информацию о влиянии случайных данных:

  1. Нажмите Отчеты.
  2. Выберите из списка нужный отчет. В сводке по конфиденциальности указан процент результатов с ожидаемым количеством случайных данных (т. е. результатов, в которых больше 5 % случайных данных).
  3. Чтобы посмотреть дополнительные сведения, нажмите Задания > Подробная информация.
  4. Изучите Сообщения о конфиденциальности. Результаты попадают в одну из указанных категорий.
  5. При необходимости скорректируйте запрос, чтобы улучшить результат.

Как скорректировать запрос

Агрегированные результаты с большей вероятностью будут содержать неожиданное количество случайных данных, если основываются на сведениях о небольшом числе пользователей. Так бывает, когда в строках учитывается мало пользователей или некоторые из них отфильтровываются (например, при использовании функции COUNTIF). Приняв во внимание информацию о случайных данных, вы можете скорректировать запрос, чтобы увеличить процент результатов с ожидаемым количеством шума.

Вот некоторые общие рекомендации:

  • расширьте диапазон дат;
  • перепишите запрос, чтобы снизить уровень детализации данных (например, используйте для их группировки меньше параметров или замените COUNTIF на COUNT);
  • удалите столбцы со случайными данными;
  • используйте явное ограничение.

Поддерживаемые агрегатные функции

Со случайными данными работают следующие агрегатные функции:

  • SUM(...)
  • COUNT(*)
  • COUNT(...)
  • COUNTIF(...)
  • COUNT(DISTINCT user_id)
  • APPROX_COUNT_DISTINCT(user_id)
  • AVG(...)

Ключевое слово DISTINCT работает только с функцией COUNT и только при использовании прямой ссылки на столбец user_id из таблицы Ads Data Hub или выражения, которое возвращает значение user_id или NULL, например COUNT(DISTINCT IF(..., user_id, NULL)).

Указанные ниже функции не поддерживаются напрямую, но для получения статистических результатов их можно заменить другими агрегатными функциями, которые работают со случайными данными. Обратите внимание, что числовые значения приведены в качестве примера.

  • LOGICAL_OR(...). Предлагаемая замена: COUNT(DISTINCT IF(..., user_id, NULL)) > 0.
  • LOGICAL_AND(...). Предлагаемая замена: COUNT(DISTINCT IF(NOT ..., user_id, NULL)) <= 0.

Целочисленные результаты

Хотя Ads Data Hub автоматически добавляет случайные данные для указанных агрегатных функций, их сигнатуры при этом не меняются. Поскольку такие функции, как COUNT или SUM INT64, возвращают значение INT64, десятичная часть результата со случайными данными округляется. Как правило, это округление незначительно по сравнению с объемом результатов и случайных данных.

Если вы хотите получить результат с детализацией до десятичной дроби, не используйте функции, которые возвращают значение INT64. Например, для функции SUM входные данные можно привести к значению FLOAT64.


Поддерживаемые шаблоны запросов

Важно! Большинство стандартных рекомендаций Ads Data Hub также применимы к запросам с добавлением шума. В частности, рекомендуем изучить рекомендации в отношении многократных запросов к одному набору данных.

В этом разделе описаны шаблоны запросов, которые поддерживают добавление шума.

Агрегирование на уровне пользователя

Неограниченное агрегирование на уровне пользователя работает так же, как и в режиме проверки различий. Случайные данные добавляются только в агрегированные результаты, которые объединяют данные нескольких пользователей. При использовании агрегирования, которое явным образом группирует результаты по параметру user_id, и аналитических функций, сегментирующих результаты по параметру user_id, случайные данные не добавляются. Разрешены любые функции. Агрегирование на уровне пользователя, при котором результаты не группируются по параметру user_id явным образом (например, GROUP BY impression_id), считается межпользовательским, поэтому случайные данные добавляются.

Группировки по параметру external_cookie недостаточно. Этот параметр можно использовать для объединения таблиц *_match с таблицами, принадлежащими клиенту, однако любое однопользовательское агрегирование должно группироваться именно по столбцу user_id, а не только по столбцу external_cookie.

Пример агрегатной функции:

WITH user_paths AS (
  # Grouping by user_id, no noise needed, all functions allowed
  SELECT user_id, STRING_AGG(campaign_id, ">" ORDER BY query_id.time_usec) AS path
  FROM adh.google_ads_impressions
  GROUP BY 1
)
# Noise applied here to num_users
SELECT path, COUNT(*) AS num_users
FROM user_paths
GROUP BY 1;

Пример аналитической функции:

WITH events AS (
  # Partitioning by user_id, no noise needed, all functions allowed
  SELECT
    campaign_id,
    ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY query_id.time_usec) AS index
  FROM adh.google_ads_impressions
)
# Noise applied here to first_impressions
SELECT campaign_id, COUNT(*) AS first_impressions
FROM events
WHERE index = 1
GROUP BY 1;

Параллельное агрегирование

При межпользовательском агрегировании случайные данные добавляются отдельно к каждому набору результатов. Вы можете агрегировать сразу несколько типов данных, используя один оператор, и объединить результаты в таблицу с помощью команды JOIN или UNION.

Пример:

WITH result_1 AS (
  # Noise applied here to num_impressions
  SELECT campaign_id, COUNT(*) AS num_impressions
  FROM adh.google_ads_impressions
  GROUP BY 1
), result_2 AS (
  # Noise applied here to num_clicks
  SELECT campaign_id, COUNT(*) AS num_clicks
  FROM adh.google_ads_clicks
  GROUP BY 1
)
SELECT * FROM result_1 JOIN result_2 USING(campaign_id)

Хотя такая возможность доступна, от нее лучше воздержаться в режиме проверки различий. Этот прием можно использовать со случайными данными, поскольку при параллельном агрегировании каждый набор результатов дополняется такими данными и фильтруется независимо.

Объединение агрегированных и неагрегированных данных

Поскольку Ads Data Hub поддерживает только аналитические функции, сегментирующие результаты по параметру user_id, вы можете агрегировать результаты по отдельности и выполнить их самообъединение перед последующим агрегированием. Эти запросы поддерживаются в режиме добавления случайных данных и часто работают эффективнее, чем в режиме проверки различий, поскольку требования конфиденциальности уже соблюдены.

Пример:

WITH campaign_totals AS (
  # Noise applied here to campaign_imps
  SELECT campaign_id, COUNT(*) AS campaign_imps
  FROM adh.google_ads_impressions
  GROUP BY 1
)
# Noise applied here to imps
SELECT campaign_id, demographics, campaign_imps, COUNT(*) AS imps
FROM adh.google_ads_impressions JOIN campaign_totals USING(campaign_id)
GROUP BY 1,2,3

Режим шума не поддерживает повторное агрегирование уже агрегированных результатов, например AVG(campaign_imps).


Неподдерживаемые шаблоны запросов

В этом разделе описаны шаблоны запросов, которые не поддерживают добавление случайных данных.

Запросы данных за текущий день

Запросы в режиме шума не поддерживают данные за текущий день. В режиме проверки различий такая возможность доступна, но от нее лучше воздержаться. Для запросов с добавлением шума нельзя выбрать текущую дату.

Повторяющиеся результаты

В режиме шума Ads Data Hub ограничивает частоту, с которой можно повторять одно и то же агрегирование. Если ограничение будет достигнуто, вы можете потерять доступ к часто запрашиваемым данным в наборе. Ниже приведены примеры того, как это происходит.

Повторением запроса будет его многократное выполнение с одинаковыми или очень похожими параметрами, включая пересекающиеся диапазоны дат. Чтобы этого избежать, используйте данные, уже экспортированные в проект BigQuery.

Когда в двух заданиях запросы выполняются в пересекающихся диапазонах дат, это будет повторением, если обрабатываются сведения об одних и тех же пользователях. В примере ниже запрос, выполняемый в пересекающихся диапазонах дат, приводит к повторению, поскольку он сегментирует данные по дате.

SELECT DATE(TIMESTAMP_MICROS(event.event_time)) AS date,
COUNT(*) AS cnt
FROM adh.cm_dt_clicks
GROUP BY 1

В этом случае запрос нужно выполнить в непересекающихся сегментах дат.

Повторение также происходит, когда данные в некоторой степени не зависят от даты. В примере ниже запрос приводит к повторению, когда выполняется в пересекающихся датах, где оба задания охватывают весь период действия кампании.

SELECT campaign_id, COUNT(*) AS cnt
FROM adh.google_ads_impressions
GROUP BY 1

В этом случае запрос нужно выполнить только один раз, поскольку результат не меняется.

Повторением агрегирования будет его многократное выполнение в рамках одного запроса:

SELECT COUNT(*) AS cnt1, COUNT(*) AS cnt2
FROM table

В этом случае нужно удалить одно из повторений.

Даже если при агрегировании используется различный синтаксис, но вычисляется одно и то же значение, это будет считаться повторением. Другими словами, если значения condition1 и condition2 одинаковы для всех пользователей с некоторым значением key, следующий запрос будет повторяться:

SELECT key, COUNTIF(condition1) AS cnt1, COUNTIF(condition2) AS cnt2
FROM table
GROUP BY key

Если для некоторых групп пользователей есть очень похожие условия, лучше переписать запрос, оставив в нем только одну функцию COUNT.

Дублирование строк происходит, когда при объединении двух таблиц каждой строке в таблице Ads Data Hub соответствуют несколько строк в таблице BigQuery. В примере ниже запрос приводит к повторению, если bq_table содержит несколько строк с одинаковым идентификатором кампании.

SELECT r.campaign_id, COUNT(*) AS cnt
FROM adh_table
INNER JOIN bq_table ON l.campaign_id = r.campaign_id

В этом случае нужно изменить структуру запроса таким образом, чтобы таблица bq_table содержала лишь одну строку для каждого значения ключа соединения (в нашем примере это campaign_id).

Того же эффекта можно добиться, удалив из таблицы Ads Data Hub вложенный массив, если массивы значений для большинства пользователей одинаковы:

SELECT in_market_id, COUNT(*)
FROM adh.dv360_youtube_impressions,
UNNEST(in_market) AS in_market_id
GROUP BY 1

Вы можете посмотреть и другие рекомендации в отношении запросов.

Непосредственное повторное агрегирование

Случайные данные добавляются к первоначальным результатам межпользовательского агрегирования в запросе. Запросы с несколькими уровнями агрегирования блокируются:

WITH layer_1 AS (
  # Noise applied here to partial_result
  SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
  FROM adh.google_ads_impressions
  GROUP BY 1,2,3
  HAVING partial_result > 5
)
# Reaggregation of partial_result with no user-level data, will be rejected
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1

Чтобы обеспечить наилучшие результаты при добавлении случайных данных, выполняйте все операции с межпользовательскими данными на одном уровне агрегирования. Например, подсчитывайте общее количество (SUM) событий, а не количество (SUM) промежуточных значений. Можно переписать запрос для повторного агрегирования зашумленных данных, но тогда в окончательных результатах уровень шума может быть значительно выше.

При крайней необходимости вы можете переписать запрос, чтобы экспортировать результаты непосредственно из первого слоя. Чтобы выполнить агрегирование в рамках одного задания, не изменяя результаты работы скрипта, создайте временную таблицу с синтаксисом OPTIONS(privacy_checked_export=true) или используйте таблицу, экспортированную в проект BigQuery. Пример:

CREATE TEMP TABLE layer_1 OPTIONS(privacy_checked_export=true) AS (
  # Noise applied here to partial_result
  SELECT campaign_id, demographics, location, COUNT(*) AS partial_result
  FROM adh.google_ads_impressions
  GROUP BY 1,2,3
  HAVING partial_result > 5
);
# Reaggregation of privacy checked data, no noise needed
SELECT campaign_id, SUM(partial_result) AS final_result
FROM layer_1
GROUP BY 1

Подробнее о временных таблицах

Если данные первого уровня агрегирования слишком детализированы и не подходят для проверки конфиденциальности, попробуйте переписать запрос, используя агрегирование на уровне пользователя. Если агрегирование нельзя выполнить на уровне пользователя, значит этот запрос не поддерживается в режиме шума.

Необъединенные идентификаторы пользователей

Запросы в режиме добавления случайных данных не должны объединять в одну строку сведения об отдельных пользователях. Это допускается только при агрегировании с использованием случайных данных. В результате выполнения запроса неагрегированные данные Ads Data Hub должны объединяться в столбце user_id.

Указанный ниже запрос не объединяет данные в столбце user_id, поэтому при проверке возникает ошибка.

SELECT …
FROM adh.google_ads_impressions
JOIN adh.google_ads_clicks USING(impression_id)

Эту ошибку можно исправить, изменив условие USING таким образом, чтобы параметр user_id явным образом включался в результаты. Пример: USING(impression_id, user_id).

Обратите внимание, что это ограничение распространяется только на объединение таблиц Ads Data Hub (за исключением таблиц с параметрами). Оно не затрагивает клиентские таблицы. Например, допускается следующее:

SELECT …
FROM adh.google_ads_impressions
JOIN bigquery_project.dataset.table USING(any_column)

Объединение данных Ads Data Hub и BigQuery

Для правильной работы агрегатных функций с использованием случайных данных нужны идентификаторы пользователей. Клиентские сведения в BigQuery не содержат идентификаторы пользователей, поэтому для агрегирования с использованием случайных данных эти сведения нужно объединить с таблицей Ads Data Hub.

При проверке этого запроса возникает ошибка:

SELECT COUNT(*) FROM (
  SELECT 1 FROM adh.google_ads_impressions
  UNION ALL
  SELECT 1 FROM bigquery_project.dataset.table
)

Чтобы исправить ошибку, нужно или присоединить таблицу BigQuery, дополнив таблицу Ads Data Hub, а не объединять их, или разделить данные для агрегирования каждого источника по отдельности.

Учтите, что можно объединить несколько таблиц Ads Data Hub с пользовательскими данными или несколько клиентских таблиц BigQuery, но нельзя смешивать таблицы двух типов.

Объединение данных Ads Data Hub и BigQuery справа

В результате внешнего объединения с клиентскими данными могут появляться строки, в которых отсутствуют идентификаторы пользователей. Это затрудняет добавление случайных данных.

При проверке обоих запросов, указанных ниже, возникают ошибки, поскольку эти запросы допускают наличие в Ads Data Hub несопоставленных строк, в которых отсутствуют идентификаторы пользователей.

SELECT …
FROM adh.google_ads_impressions
RIGHT JOIN bigquery_project.dataset.table USING(column)
SELECT …
FROM bigquery_project.dataset.table
LEFT JOIN adh.google_ads_impressions USING(column)

Обратите внимание, что оба типа объединения будут работать, даже если поменять таблицы местами.

Сводка по отфильтрованным строкам

Сводка по отфильтрованным строкам не поддерживается в режиме добавления случайных данных. При наличии таких данных эта функция чаще всего не нужна из-за более низкого показателя фильтрации и ее отсутствия после проверки различий.

Если значительная часть результатов со случайными данными отфильтровывается, увеличьте количество агрегированных данных. Вы можете выполнить параллельное агрегирование по всему набору данных, чтобы сравнить расчетные итоговые значения. Пример:

SELECT campaign_name, COUNT(*)
FROM data
GROUP BY 1
UNION ALL
SELECT 'Total', COUNT(*)
FROM data
GROUP BY 1

Учтите, что случайные данные добавляются отдельно к каждому итоговому значению, и их сумма может отличаться от ожидаемой. При этом итоговые значения часто оказываются более точными, чем результат сложения строк со случайными данными.

Использование таблиц, созданных в разных режимах

Неэкспортированные таблицы в Ads Data Hub можно использовать только в том режиме конфиденциальности, в котором они были созданы. Нельзя создать таблицу в обычном режиме агрегирования и использовать ее в режиме шума или наоборот. Для этого таблицу сначала нужно экспортировать в BigQuery.