Injeção de ruído

Injeção de ruído é uma técnica usada para proteger a privacidade do usuário ao consultar um banco de dados. Ela adiciona um ruído aleatório à cláusula SELECT de agregação de uma consulta. Esse ruído protege a privacidade do usuário e fornece resultados razoavelmente precisos, eliminando a necessidade de realizar verificações de diferenças e reduzindo o limite de agregação necessário para a saída. A maioria das consultas atuais pode ser executada em modo de ruído, com algumas limitações.

Benefícios de usar a injeção de ruído

Não é necessário realizar verificações de diferenças: ao executar consultas com a injeção de ruído, o Ads Data Hub não filtra as linhas devido às semelhanças com os conjuntos de resultados anteriores. Isso significa que você pode ter uma visão completa dos dados e proteger a privacidade do usuário.

A solução de problemas ficou mais simples: as linhas só são omitidas devido aos requisitos de agregação, facilitando a solução de problemas e a adaptação das consultas.

Não é necessário aprender uma nova sintaxe: você não precisa fazer isso nem conhecer os conceitos de privacidade para usar o ruído em vez das verificações de diferenças.

A precisão dos resultados é clara: um job concluído mostra a porcentagem total dos dados com a quantidade esperada de ruído.

Como o ruído afeta as normas de privacidade

Verificações de diferenças: a injeção de ruído não usa as verificações de diferenças atuais do Ads Data Hub. Quando você usa a injeção de ruído, as verificações de diferenças são desativadas.

Requisito de agregação: a injeção de ruído gera dados de impressão representados por aproximadamente 20 ou mais usuário únicos, além de dados de conversão ou cliques representados por aproximadamente 10 ou mais usuários únicos.

Verificações estáticas: não há impacto.

Orçamentos e limites de consulta: consultas executadas com o ruído têm o mesmo orçamento de acesso aos dados com verificações de diferenças. Como acontece com as verificações de diferenças, se você executar a mesma consulta no mesmo conjunto de dados várias vezes, talvez não possa fazer outras consultas nele. Isso poderá acontecer se você executar consultas em janelas deslizantes ou fizer a mesma solicitação diversas vezes.

O modo de ruído impõe limites extras mais restritos ao recalcular os mesmos resultados agregados de diferentes queries ou delas mesmo. Assim como no orçamento de acesso aos dados, você pode perder o acesso às datas consultadas com frequência no conjunto de dados. No entanto, as limitações para recalcular os mesmos resultados agregados vai restringir só consultas no modo de ruído, não consultas no modo de verificação de diferenças. Para saber mais, consulte Resultados repetidos.

Saiba mais sobre as verificações de privacidade.

Como a injeção de ruído afeta os resultados

O Ads Data Hub injeta ruído para reduzir o risco de divulgação, ou seja, o risco de alguém ter acesso a informações sobre um usuário individual. Ele busca o equilíbrio entre a privacidade e a utilidade.

A injeção de ruído no Ads Data Hub transforma a consulta da seguinte maneira:

  • Ela restringe as contribuições de usuários outliers nos resultados agregados. Ela soma a contribuição dos usuários em cada agregação e depois impõe limites de restrição mínimos e máximos às contribuições.
  • Ela agrega as contribuições restringidas de cada usuário.
  • Ela adiciona ruído a cada resultado agregado, ou seja, o resultado das chamadas de função de agregação em cada linha. A escala desse ruído aleatório é proporcional aos limites de restrição.
  • Ela calcula uma quantidade de usuários com ruído para cada linha e elimina aquelas com poucas pessoas. Isso é parecido com a medida de k-anonimato no modo de verificação de diferenças, mas, devido ao ruído, os jobs sendo executados no mesmo conjunto de dados podem gerar linhas diferentes. Além disso, o modo de ruído produz menos linhas porque o requisito de agregação é mais baixo (cerca de 20 em comparação com 50 linhas exatas).

O resultado final é um conjunto de dados em que cada linha tem resultados agregados com ruído e pequenos grupos foram eliminados. Isso mascara o efeito de um usuário individual sobre os resultados retornados.

Sobre a restrição de agregação

A injeção de ruído no Ads Data Hub usa restrição de agregação implícita ou explícita para limitar a contribuição de outliers. Você pode escolher que tipo de restrição usar, dependendo do seu caso de uso.

Restrição implícita

Na restrição implícita, os limites são determinados automaticamente. Você não precisa de nenhuma sintaxe de SQL especial para usá-la. Se uma linha tiver um conjunto maior de valores do que outra, a restrição implícita encontra limites diferentes para essas linhas. Geralmente, isso gera uma margem de erro menor para cada resultado. Por outro lado, cada agregação recebe limites de restrição e níveis de ruído diferentes, o que pode dificultar a comparação delas.

A restrição implícita pode falhar quando uma agregação recebe dados de um número muito pequeno de usuários. Por exemplo, uma chamada COUNTIF() com uma condição rara. Esses casos podem retornar resultados NULL. É importante lembrar que COUNT(DISTINCT user_id)automaticamente usa a restrição explícita com limites de 0 e 1.

Restrição explícita

A restrição explícita limita a contribuição total de cada usuário para um conjunto específico. As restrições explícitas são aplicadas de maneira uniforme a todas as linhas e devem ser valores literais. Mesmo que algumas linhas tenham um conjunto maior de contribuições por usuário do que outras, os mesmos limites são aplicados a todas elas. Isso facilita a comparação de resultados de linhas diferentes, ainda que algumas recebam mais ruído do que receberiam com a restrição implícita.

A restrição explícita usa metade do ruído usado na restrição implícita para um determinado conjunto de limites de restrição. Portanto, se você estimar os limites razoáveis, poderá melhorar os resultados definindo os limites explicitamente.

Para usar a restrição explícita, defina os limites para cada função agregada compatível adicionando números inteiros que representem o limite menor e o limite maior. Por exemplo:

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

Como executar uma consulta usando a injeção de ruído

  1. Escreva uma consulta ou abra uma. Para saber quais funções de agregação podem ser usadas, consulte Funções compatíveis.
  2. No editor de consultas, clique em Executar e insira os detalhes para um novo job.
  3. Clique no botão das configurações de privacidade e alterne para a posição Usar ruído.
  4. Execute a consulta.
  5. Revise o ruído adicionado.
  6. Opcional: adapte a consulta para reduzir o impacto do ruído.

Como analisar o impacto do ruído

Quando a consulta é concluída, o Ads Data Hub mostra a confiabilidade do resultado, com base em quantas células resultantes têm a quantidade esperada de ruído. Um valor na tabela do resultado é considerado altamente afetado quando o ruído adicionado é maior do que 5% do resultado na célula. Confira se o impacto varia na seguinte tabela.

Para os conjuntos de dados de saída afetados, a guia de detalhes lista as 10 colunas com mais ruído, do maior impacto para o menor, e sua respectiva contribuição para o ruído. Este é o detalhamento da quantidade de ruído esperada.

Dados com a quantidade de ruído esperada Cor indicadora Impacto
>95% Verde Baixo impacto
85%-95% Amarelo Médio impacto
75%-85% Laranja Alto impacto
<75% Vermelho Altíssimo impacto

Para conferir informações detalhadas sobre o impacto do ruído:

  1. Clique em Relatórios.
  2. Selecione um relatório na lista. A dica do resumo de privacidade indica a porcentagem de resultados que têm a quantidade esperada de ruído, correspondente à quantidade de ruído adicionada que é maior do que 5% do resultado.
  3. Para conferir mais informações, clique em Jobs > Detalhes.
  4. Consulte as mensagens sobre privacidade nos detalhes do job. Os resultados se enquadram em uma das categorias listadas.
  5. Se necessário, ajuste a consulta para melhorar o resultado.

Adaptação das consultas

Os resultados agregados têm mais probabilidade de receber uma quantidade inesperada de ruído quando poucos usuários contribuem para esses resultados. Isso pode acontecer quando as linhas têm poucos usuários ou quando alguns deles não afetam os resultados (por exemplo, ao usar a função COUNTIF). Com base nos detalhes do ruído, você pode ajustar a consulta para aumentar a porcentagem de dados com a quantidade esperada de ruído.

Estas são as orientações gerais:

  • Aumente o período.
  • Reescreva a consulta para reduzir a granularidade dos dados (por exemplo, usando menos parâmetros para agrupar ou substituindo COUNTIF por COUNT).
  • Remova as colunas com ruído.
  • Use a restrição explícita.

Funções agregadas com suporte

As funções de agregação a seguir são compatíveis com ruído:

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

A palavra-chave DISTINCT só é compatível com a função COUNT e usada com referência direta à coluna user_id de uma tabela do Ads Data Hub ou uma expressão que retorna user_id ou NULL, como COUNT(DISTINCT IF(..., user_id, NULL)).

As funções a seguir não são compatíveis diretamente, mas podem ser substituídas por outros agregadores com ruído para receber resultados estatísticos. Os valores numéricos são apenas exemplos:

  • LOGICAL_OR(...). Substituição sugerida: COUNT(DISTINCT IF(..., user_id, NULL)) > 0
  • LOGICAL_AND(...). Substituição sugerida: COUNT(DISTINCT IF(NOT ..., user_id, NULL)) <= 0

Sobre resultados com números inteiros

Embora o Ads Data Hub injete ruído para as funções de agregação de maneira automática, as assinaturas das funções não mudam. Como funções do tipo COUNT ou SUM de INT64 retornam INT64, qualquer parte decimal do resultado com ruído é arredondada. Isso geralmente é ignorado devido ao tamanho do resultado e do ruído.

Se você precisar da granularidade da casa decimal no seu resultado, evite escrever funções que retornem INT64 (por exemplo, usando SUM com entrada convertida para FLOAT64).


Padrões de consulta compatíveis

Importante: a maioria das práticas recomendadas padrão do Ads Data Hub ainda se aplica a consultas que usam injeção de ruído. Especificamente, é recomendado revisar as diretrizes sobre consultas repetidas dos mesmos dados.

Esta seção descreve os padrões compatíveis ao executar consultas usando a injeção de ruído.

Dados agregados no nível do usuário

Dados agregados não restritos no nível do usuário funcionam da mesma maneira que no modo de verificação de diferenças. O ruído só é injetado em agregações que combinam dados de vários usuários. Agregações que fazem agrupamentos explícitos por user_id ou funções analíticas que fazem particionamento por user_id não recebem nenhum ruído e nenhuma função é permitida. Agregações no nível do usuário que não fazem agrupamentos explícitos por user_id, como GROUP BY impression_id, são tratadas como agregações de usuários diferentes. Por isso, o ruído é adicionado.

Agrupar usando external_cookie não é suficiente. Embora o external_cookie possa ser usado para juntar *_tabelas de correspondência com tabelas do cliente, todas as agregações devem agrupar os dados explicitamente com base nas colunas user_id e coluna external_cookie.

Exemplo de função agregada:

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;

Exemplo de função analítica:

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;

Dados agregados paralelos

Cada agregação de usuários diferentes recebe ruído de maneira independente. Você pode executar várias dessas agregações em uma única instrução, combinando resultados em uma tabela usando JOIN ou UNION.

Exemplos:

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)

Isso funcionaria, mas deve ser evitado no modo de verificação de diferenças. Essa prática não causa problemas com o ruído, uma vez que cada dado agregado paralelo recebe ruído e é filtrado de maneira independente.

Dados agregados mesclados com dados não agregados

Como o Ads Data Hub só é compatível com janelas analíticas que fazem particionamento por user_id, uma solução comum é agregar esses resultados de modo separado e fazer a mesclagem automática deles antes de agregá-los de novo. Essas consultas são compatíveis com o modo de ruído e geralmente têm performance melhor do que teriam no modo de verificação de diferenças, porque as normas de privacidade são resolvidas antes.

Exemplos:

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

No modo de ruído, é proibido reagregar os resultados agregados, como AVG(campaign_imps).


Padrões de consulta não compatíveis

Esta seção descreve padrões não compatíveis ao executar consultas usando injeção de ruído.

Consultas que incluem a data atual

As consultas do modo de ruído não oferecem suporte a consultas da data de hoje. Isso deve ser evitado no modo de verificação de diferenças. A data atual não pode ser selecionada para consultas que usam injeção de ruído.

Resultados repetidos

No modo de ruído, o Ads Data Hub limita a frequência com que você pode repetir a mesma agregação. Se você atingir os limites, suas consultas do modo de ruído vão perder acesso às datas das consultas frequentes no conjunto de dados. Confira a seguir exemplos de como isso pode ocorrer.

A repetição de consulta acontece quando a mesma consulta é executada várias vezes com os mesmos parâmetros, incluindo períodos que se sobrepõem. Você pode evitar isso usando os dados que já foram exportados para seu projeto do BigQuery.

Se dois jobs consultarem períodos sobrepostos, eles podem produzir repetições se realizarem o mesmo cálculo nos mesmos usuários. Por exemplo, a consulta a seguir, executada em períodos sobrepostos, cria repetições porque está particionando por data:

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

Nesse caso, você precisa executar a consulta em segmentos de data separados.

Outro exemplo de repetição acontece quando os dados de alguma maneira independem de data. A consulta a seguir produz repetições quando executada em datas sobrepostas, em que os dois jobs abrangem todo o ciclo de vida de uma campanha:

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

Nesse caso, você precisa executar a consulta apenas uma vez, porque o resultado não muda.

A repetição de agregação acontece quando a mesma agregação é repetida várias vezes em uma consulta:

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

Nesse caso, você precisa remover uma das repetições.

Mesmo que as agregações sejam sintaticamente diferentes, mas calculem o mesmo valor, ele seria contado como uma repetição. Em outras palavras, se os valores de condition1 e condition2 forem os mesmos para todos os usuários com algum valor de key, a consulta a seguir teria uma repetição:

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

Se você tiver condições que sejam bastante semelhantes para alguns grupos de usuários, reescreva a consulta para ter apenas um COUNT.

A duplicação de linhas acontece quando uma tabela do Ads Data Hub é mesclada com uma tabela do BigQuery de uma maneira que cada linha da tabela do Ads Data Hub corresponde a várias linhas da tabela do BigQuery. Por exemplo, a consulta a seguir produz uma repetição se houver várias linhas com o mesmo ID de campanha em bq_table:

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

Nesse caso, você precisa reestruturar a consulta para que bq_table tenha apenas uma linha por chave-valor de junção (campaign_id, nesse caso).

Desaninhar uma matriz da tabela do Ads Data Hub pode produzir o mesmo efeito se a maioria dos usuários tiver as mesmas matrizes de valores:

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

Conheça outras práticas recomendadas para consultas.

Reagregação direta

O ruído é aplicado à primeira camada da agregação de usuários diferentes na consulta. Consultas com várias camadas de agregação são bloqueadas:

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

Para receber os melhores resultados do ruído, calcule todas as operações de usuários diferentes em uma única agregação. Por exemplo, considere SUM de eventos em vez de SUM de contagens intermediárias. É possível reescrever uma consulta para reagregar ruídos, mas o final agrega muito mais ruídos.

Se isso for inevitável, você pode reescrever sua consulta para exportar resultados diretamente da primeira camada. Para fazer isso em um único job sem mudar os resultados de script, crie uma tabela temporária (ou uma tabela exportada para seu projeto do BigQue) com a sintaxe OPTIONS(privacy_checked_export=true). Por exemplo:

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

Saiba mais sobre tabelas temporárias.

Se a primeira camada de agregação for muito granular para verificações de privacidade, considere reescrever a consulta com agregações no nível do usuário. Se isso não for possível, não haverá suporte para essa consulta no modo de ruído.

IDs de usuários não mesclados

Consultas no modo de ruído não devem combinar dados de usuários separados em uma única linha, exceto ao realizar uma agregação com ruído. Como consequência, as mesclagens de dados do Ads Data Hub não agregados devem ser explicitamente mescladas na coluna user_id.

Esta consulta não é mesclada de maneira explícita na coluna user_id, o que resulta em um erro de validação:

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

Isso pode ser corrigido ajudando a cláusula USING para incluir explicitamente user_id. Por exemplo, USING(impression_id, user_id).

Essa limitação se aplica somente a mesclagens entre tabelas do Ads Data Hub (com exceção das tabelas de dimensões). Isso não se aplica às tabelas do cliente. Por exemplo, o seguinte é permitido:

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

Junções do Ads Data Hub com o BigQuery

As agregações com ruído requerem que os identificadores de usuários tenham uma ótima performance. Os dados de propriedade do cliente no BigQuery não têm identificadores de usuários. Por isso, eles não podem ser juntados em uma única agregação de ruído sem serem mesclados em uma tabela do Ads Data Hub.

Esta consulta resulta em um erro de validação:

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

Para corrigir isso, mescle a tabela do BigQuery para aumentar os dados do Ads Data Hub em vez de juntar ou separe os dados para agregar cada fonte de maneira independente.

Não há problema em juntar várias tabelas do Ads Data Hub com dados de usuários ou várias tabelas de clientes do BigQuery, mas não é possível misturar as duas.

Mesclagens direitas do Ads Data Hub com o BigQuery

Mesclagens externas com dados de propriedade do cliente podem resultar em linhas sem identificadores de usuários, o que impede o ruído de funcionar bem.

Estas duas consultas resultam em erros de validação porque permitem linhas não correspondentes sem identificadores de usuários no 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)

Qualquer mesclagem funcionaria se a ordem das tabelas fosse invertida.

Resumo das linhas filtradas

As especificações do resumo das linhas filtradas não são compatíveis com o modo de ruído. Esse recurso costuma ser desnecessário com o ruído devido às baixas taxas de filtragem e à falta de filtragem das verificações de diferenças.

Se você notar uma filtragem significativa de dados em um resultado de ruído, aumente os dados agregados. É possível realizar uma agregação paralela no conjunto completo de dados para comparar uma estimativa do total. Por exemplo:

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

A contagem total recebe ruído de maneira independente e os valores totais podem não ser relevantes, mas a contagem total geralmente é mais precisa do que somar as linhas com ruído.

Tabelas criadas com vários modos

Tabelas não exportadas no Ads Data Hub só podem ser usadas com o mesmo modo de privacidade em que foram criadas. Não é possível criar uma tabela no modo de agregação normal e usá-la no modo de ruído ou vice-versa (a menos que a tabela seja exportada para o BigQuery primeiro).