1. Antes de começar
Talvez você pense que as estatísticas agregadas não vazam informações sobre os indivíduos a quem pertencem. No entanto, há muitas maneiras pelas quais um invasor pode obter informações sensíveis sobre indivíduos a partir de estatísticas agregadas.
Neste codelab, você vai aprender a produzir estatísticas particulares com agregações particulares diferenciadas do PipelineDP para proteger dados privacidade. O PipelineDP é um framework do Python usado para aplicar privacidade diferencial a grandes conjuntos de dados com sistemas de processamento em lote, como o Apache Spark e o Apache Beam (links em inglês). Para mais informações sobre como calcular estatísticas particulares diferenciadas no Go, consulte o codelab Privacidade no Beam.
Particular significa que a saída é produzida de uma maneira que não vaza informações particulares sobre os indivíduos nos dados. Você pode alcançar esse resultado usando a privacidade diferencial, uma forte noção de privacidade de anonimização, que é o processo de agregação de dados entre vários usuários para proteger a privacidade do usuário. Todos os métodos de anonimização usam agregação, mas nem todos os métodos de agregação alcançam a anonimização. A privacidade diferencial, por outro lado, oferece garantias mensuráveis sobre o vazamento e a privacidade de informações.
Pré-requisitos
- Familiaridade com Python
- Conhecer os conceitos básicos de agregação de dados.
- Experiência com pandas, Spark e Beam
O que você vai aprender
- Noções básicas da privacidade diferencial
- Como calcular estatísticas de resumo particular diferenciada com o PipelineDP
- Como ajustar os resultados com parâmetros adicionais de privacidade e utilidade.
O que é necessário
- Se você quiser executar o codelab no seu ambiente, vai precisar do Python 3.7 ou mais recente instalado no computador.
- Se quiser seguir o codelab sem um ambiente próprio, você vai precisar acessar o Colaboratory.
2. Entender a privacidade diferencial
Para entender melhor a privacidade diferencial, confira este exemplo simples.
Imagine que você trabalha no departamento de marketing de uma loja de moda on-line e quer entender quais produtos têm mais chances de vender.
Este gráfico mostra quais produtos os clientes viram primeiro ao visitar o site da loja: camisetas, blusas, meias ou jeans. Camisetas são o item mais popular, enquanto meias são o item menos popular.
Isso parece útil, mas há um problema. Ao considerar informações adicionais, por exemplo, se os clientes fizeram uma compra ou qual produto eles visualizaram depois, você corre o risco de revelar indivíduos nos seus dados.
Este gráfico mostra que, primeiro, apenas um cliente olhou para uma jaqueta e depois fez a compra:
Isso não é muito bom do ponto de vista da privacidade. As estatísticas anonimizadas não devem revelar contribuições individuais. Então, o que você faz? Você adiciona ruído aleatório aos seus gráficos de barras para torná-los um pouco menos precisos!
Esse gráfico de barras não é totalmente preciso, mas ainda é útil e não revela contribuições individuais:
A privacidade diferencial é a adição da quantidade certa de ruído aleatório para mascarar contribuições individuais.
Este exemplo é muito simplificado. A implementação correta da privacidade diferencial é mais complexa e vem com várias sutilezas inesperadas. Assim como na criptografia, pode não ser uma boa ideia criar sua própria implementação de privacidade diferencial. Em vez disso, é possível usar o PipelineDP.
3. Fazer o download e instalar o PipelineDP
Não é necessário instalar o PipelineDP seguindo este codelab, porque este documento contém todos os códigos e gráficos relevantes.
Para testar o PipelineDP, execute-o por conta própria ou use-o mais tarde:
- Faça o download e instale o PipelineDP:
pip install pipeline-dp
Se você quiser executar o exemplo usando o Apache Beam:
- Faça o download e instale o Apache Beam:
pip install apache_beam
O código deste codelab e o conjunto de dados estão disponíveis no diretório PipelineDP/examples/codelab/
.
4. Calcule as métricas de conversão por primeiro produto visualizado
Imagine que você trabalha em uma loja de moda on-line e quer saber quais das suas diferentes categorias de produtos geram o maior número e valor de conversões na primeira visualização. Você quer compartilhar essas informações com a agência de marketing e outras equipes internas, mas quer evitar o vazamento de informações sobre um cliente específico.
Para calcular as métricas de conversão por primeiro produto visualizado no site:
- Revise o conjunto de dados simulado de visitas ao seu site no diretório
PipelineDP/examples/codelab/
.
A captura de tela é um exemplo do conjunto de dados. Ele contém o ID do usuário, os produtos que ele visualizou, se o visitante fez uma conversão e, em caso afirmativo, o valor da conversão.
user_id | product_view_0 | product_view_1 | product_view_2 | product_view_3 | product_view_4 | has_conversion | conversion_value |
0 | Jeans | t_shirt | t_shirt | nenhum | nenhum | falso | 0,0 |
1 | Jeans | t_shirt | Jeans | pula-pula | nenhum | falso | 0,0 |
2 | t_shirt | pula-pula | t_shirt | t_shirt | nenhum | verdadeiro | 105,19 |
3 | t_shirt | t_shirt | Jeans | nenhum | nenhum | falso | 0,0 |
4 | t_shirt | meias | Jeans | Jeans | nenhum | falso | 0,0 |
Você tem interesse nestas métricas:
view_counts
: o número de vezes que os visitantes do seu site veem cada produto primeiro.total_conversion_value
: o valor total que os visitantes gastam quando fazem uma conversão.conversion_rate
: a taxa de conversão dos visitantes.
- Gere as métricas de maneira não particular:
conversion_metrics = df.groupby(['product_view_0'
])[['conversion_value', 'has_conversion']].agg({
'conversion_value': [len, np.sum],
'has_conversion': np.mean
})
conversion_metrics = conversion_metrics.rename(
columns={
'len': 'view_counts',
'sum': 'total_conversion_value',
'mean': 'conversion_rate'
}).droplevel(
0, axis=1)
Como você aprendeu anteriormente, essas estatísticas podem revelar informações sobre indivíduos em seu conjunto de dados. Por exemplo, apenas uma pessoa converteu depois que ela viu um salto pela primeira vez. Para 22 visualizações, sua taxa de conversão é de aproximadamente 0,05. Agora você precisa transformar cada gráfico de barras em um gráfico particular.
- Defina os parâmetros de privacidade com a classe
pipeline_dp.NaiveBudgetAccountant
e especifique os argumentosepsilon
edelta
que você quer usar na análise.
A forma como esses argumentos são definidos depende do problema específico. Para saber mais sobre eles, consulte "Opcional: ajustar os parâmetros de privacidade diferencial".
Este snippet de código usa valores de exemplo:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=1e-5)
- Inicialize a instância
LocalBackend
:
ops = pipeline_dp.LocalBackend()
É possível usar a instância LocalBackend
porque você executa esse programa localmente sem frameworks adicionais, como o Beam ou o Spark.
- Inicialize a instância
DPEngine
:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
O PipelineDP permite especificar outros parâmetros com a classe pipeline_dp.AggregateParams
, que afeta a geração das estatísticas particulares.
params = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT],
max_partitions_contributed=1,
max_contributions_per_partition=1)
- Especifique que você quer calcular a métrica
count
e use a distribuição de ruídoLAPLACE
. - Defina o argumento
max_partitions_contributed
como um valor1
.
Esse argumento limita com quantas visitas diferentes um usuário pode contribuir. Você espera que os usuários visitem o site uma vez por dia e não se importa se eles o acessam várias vezes ao longo do dia.
- Defina o argumento
max_contributions_per_partitions
como um valor1
.
Esse argumento especifica quantas contribuições um único visitante pode fazer a uma partição individual ou uma categoria de produto nesse caso.
- Crie uma instância
data_extractor
que especifique onde encontrar os camposprivacy_id
,partition
evalue
.
O código vai ficar parecido com este:
def run_pipeline(data, ops):
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=1e-5)
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
params = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT],
max_partitions_contributed=1, # A single user can only contribute to one partition.
max_contributions_per_partition=1, # For a single partition, only one contribution per user is used.
)
data_extractors = pipeline_dp.DataExtractors(
privacy_id_extractor=lambda row: row.user_id,
partition_extractor=lambda row: row.product_view_0
value_extractor=lambda row: row.has_conversion)
dp_result = dp_engine.aggregate(data, params, data_extractors)
budget_accountant.compute_budgets()
return dp_result
- Adicione este código para transformar seu DataFrame do Pandas em uma lista de linhas para calcular diretamente estatísticas particulares diferenciadas:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)
Parabéns! Você calculou sua primeira estatística particular diferenciada!
Este gráfico mostra o resultado da sua contagem particular diferenciada ao lado da contagem não particular calculada anteriormente:
O gráfico de barras que você vê ao executar o código pode ser diferente deste, o que não é um problema. Devido ao ruído na privacidade diferencial, você recebe um gráfico de barras diferente toda vez que executa o código, mas pode notar que eles são semelhantes ao gráfico de barras não particular original.
É muito importante que as garantias de privacidade não executem o pipeline várias vezes para garantir a privacidade. Para mais informações, consulte "Calcular várias estatísticas".
5. Usar partições públicas
Na seção anterior, você pode ter notado que descartou todos os dados de visitas de uma partição, ou seja, os visitantes que viram meias no seu site primeiro.
Isso ocorre devido à seleção ou ao limite de partição, uma etapa importante para garantir as garantias de privacidade diferencial quando a existência de partições de saída depende dos próprios dados do usuário. Nesse caso, a simples existência de uma partição na saída pode causar o vazamento da existência de um usuário individual nos dados. Para saber mais sobre por que isso viola a privacidade, leia esta postagem do blog. Para evitar essa violação de privacidade, o PipelineDP mantém apenas partições com um número suficiente de usuários.
Quando a lista de partições de saída não depende de dados particulares do usuário, essa etapa de seleção de partição não é necessária. Esse é o caso do seu exemplo, porque você conhece todas as categorias de produtos possíveis que um cliente poderia ver primeiro.
Para usar partições:
- Crie uma lista das partições possíveis:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
- Transmita a lista para a função
run_pipeline()
, que a define como uma entrada extra para a classepipeline_dp.AggregateParams
:
run_pipeline(
rows, ops, total_delta=0, public_partitions=public_partitions_products)
# Returns generator
params = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT],
max_partitions_contributed=1,
max_contributions_per_partition=1,
public_partitions=public_partitions_products)
Se você usa partições públicas e ruído LAPLACE
, é possível definir o argumento total_delta
como um valor 0
.
O resultado mostra que os dados de todas as partições ou produtos foram informados.
As partições públicas não apenas permitem manter mais partições, mas também adicionam cerca de metade do ruído porque você não gasta nenhum orçamento de privacidade na seleção de partições. Assim, a diferença entre as contagens bruta e privada é um pouco menor em comparação com a execução anterior.
Há dois pontos importantes a serem considerados ao usar partições públicas:
- Tenha cuidado ao derivar a lista de partições de dados brutos. Se você não fizer isso de maneira particular diferencial, o pipeline não vai mais oferecer garantias de privacidade diferencial. Para mais informações, consulte "Avançado: derivar partições de dados".
- Se não houver dados para algumas das partições públicas, será necessário aplicar ruído a elas para preservar a privacidade diferencial. Por exemplo, se você usou um produto adicional, como calças, que não ocorre no seu conjunto de dados ou site, ainda será ruído, e os resultados poderão mostrar algumas visitas a produtos quando não houver nenhuma.
Avançado: derivar partições de dados
Se você executar várias agregações com a mesma lista de partições de saída não públicas no mesmo pipeline, poderá derivar a lista de partições uma vez com o método dp_engine.select_private_partitions()
e fornecer as partições a cada agregação como a entrada public_partitions
. Isso não é apenas seguro do ponto de vista da privacidade, mas também permite que você adicione menos ruído, porque o orçamento de privacidade na seleção de partições só é usado uma vez para todo o pipeline.
def get_private_product_views(data, ops):
"""Obtains the list of product_views in a private manner.
This does not calculate any private metrics; it merely obtains the list of
product_views but does so while making sure the result is differentially private.
"""
# Set the total privacy budget.
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=1e-5)
# Create a DPEngine instance.
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
# Specify how to extract privacy_id, partition_key, and value from a
# single element.
data_extractors = pipeline_dp.DataExtractors(
partition_extractor=lambda row: row.product_view_0,
privacy_id_extractor=lambda row: row.user_id)
# Run aggregation.
dp_result = dp_engine.select_partitions(
data, pipeline_dp.SelectPrivatePartitionsParams(
max_partitions_contributed=1),
data_extractors=data_extractors)
budget_accountant.compute_budgets()
return dp_result
6. Calcular várias estatísticas
Agora que você sabe como o PipelineDP funciona, pode usá-lo em alguns casos de uso mais avançados. Como mencionado no início, você está interessado em três estatísticas. O PipelineDP permite calcular várias estatísticas ao mesmo tempo, desde que elas compartilhem os mesmos parâmetros na instância de AggregateParams
, que será mostrada mais tarde. Além de ser mais limpo e fácil de calcular várias métricas de uma vez, ele também é melhor em termos de privacidade.
Se você se lembrar dos parâmetros epsilon
e delta
fornecidos à classe NaiveBudgetAccountant
, eles representam algo chamado orçamento de privacidade, que é uma medida da quantidade de privacidade do usuário que você vaza dos dados.
É importante lembrar que o orçamento de privacidade é cumulativo. Se você executar um pipeline com um determinado épsilon ε e delta ε uma única vez, você gastará um orçamento de (ε,ε). Ao executá-lo pela segunda vez, você gasta um orçamento total de (2ε, 2Você). Da mesma forma, se você computar várias estatísticas com um método NaiveBudgetAccountant
e consecutivamente um orçamento de privacidade de ε,ε, você gasta um orçamento total de (2ε, 2π). Isso significa que você degrada as garantias de privacidade.
Para contornar isso, você precisa usar uma única instância de NaiveBudgetAccountant
com o orçamento total que pretende usar quando precisar calcular várias estatísticas sobre os mesmos dados. Em seguida, especifique os valores de epsilon
e delta
que você quer usar para cada agregação. No final, você terá a mesma garantia geral de privacidade, mas quanto mais altos forem os valores de epsilon
e delta
de uma agregação específica, maior será a precisão dela.
Para ver isso em ação, calcule as estatísticas count
, mean
e sum
.
Você calcula as estatísticas com base em duas métricas diferentes: uma conversion_value
, que você usa para inferir o valor da receita gerada com base em qual produto foi visualizado primeiro, e uma has_conversion
, que você usa para calcular o número de visitantes do seu site e a taxa média de conversão.
Para cada métrica, você precisa especificar separadamente os parâmetros que orientam o cálculo das estatísticas particulares. Você divide seu orçamento de privacidade entre as duas métricas. Como você calcula duas estatísticas com base na métrica has_conversion
, convém atribuir dois terços do orçamento inicial a ela e os outros 1 terço à métrica conversion_value
.
Para computar várias estatísticas:
- Configure seu contador de orçamento de privacidade com os valores totais de
epsilon
edelta
que você quer usar nas três estatísticas:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Inicialize o
DPEngine
para calcular suas métricas:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
- Especifique os parâmetros dessa métrica.
params_conversion_value_metrics = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.SUM],
max_partitions_contributed=1,
max_contributions_per_partition=1,
min_value=0,
max_value=100,
public_partitions=public_partitions,
budget_weight=1/3)
O último argumento pode especificar o peso do seu orçamento de privacidade. Você pode dar o mesmo peso a todos, mas precisa definir esse argumento como um terço, conforme explicado anteriormente.
Você também define os argumentos min_value
e max_value
para especificar os limites inferior e superior aplicados a um valor contribuído por uma unidade de privacidade em uma partição. Esses parâmetros são necessários quando você quer calcular uma soma ou média particular. Como não esperam valores negativos, você pode presumir 0
e 100
como limites razoáveis.
- Extraia os dados relevantes e transmita-os para a função de agregação:
data_extractors_conversion_value_metrics = pipeline_dp.DataExtractors(
privacy_id_extractor=lambda row: row.user_id,
partition_extractor=lambda row: row.product_view_0,
value_extractor=lambda row: row.conversion_value)
dp_result_conversion_value_metrics = (
dp_engine.aggregate(data, params_conversion_value_metrics,
data_extractors_conversion_value_metrics))
- Siga as mesmas etapas para calcular as duas métricas com base na variável
has_conversion
:
params_conversion_rate_metrics = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT, pipeline_dp.Metrics.MEAN],
max_partitions_contributed=1,
max_contributions_per_partition=1,
min_value=0,
max_value=1,
public_partitions=public_partitions,
budget_weight=2/3)
data_extractors_conversion_rate_metrics = pipeline_dp.DataExtractors(
privacy_id_extractor=lambda row: row.user_id,
partition_extractor=lambda row: row.product_view_0,
value_extractor=lambda row: row.has_conversion)
dp_result_conversion_rate_metrics = (
dp_engine.aggregate(data, params_conversion_rate_metrics,
data_extractors_conversion_rate_metrics))
A única mudança está na instância pipeline_dp.AggregateParams
, em que agora você define mean
e count
como agregações e atribui dois terços do seu orçamento de privacidade a esse cálculo. Como você quer ter os mesmos limites de contribuição para as duas estatísticas e calculá-los na mesma variável has_conversion
, é possível combiná-los na mesma instância de pipeline_dp.AggregateParams
e calculá-los ao mesmo tempo.
- Chame o método
budget_accountant.compute_budgets()
:
budget_accountant.compute_budgets()
Você pode plotar todas as três estatísticas particulares em comparação com suas estatísticas originais. Dependendo do ruído adicionado, você vê que os resultados podem realmente ficar fora da escala plausível. Nesse caso, você vê uma taxa de conversão negativa e um valor total de conversão para jumpers porque o ruído adicionado é simétrico em torno de zero. Para análises e processamentos adicionais, é melhor não pós-processar manualmente as estatísticas particulares, mas se você quisesse adicionar esses gráficos a um relatório, poderia simplesmente definir o mínimo como zero posteriormente sem violar as garantias de privacidade.
7. Executar o pipeline com o Beam
Hoje em dia, o processamento de dados exige tanto que você lide com grandes quantidades de dados que não é possível processá-los localmente. Em vez disso, muitas pessoas usam frameworks para processamento de dados em grande escala, como Beam ou Spark, e executam seus pipelines na nuvem.
O PipelineDP dá suporte ao Beam e ao Spark com apenas pequenas mudanças no código.
Para executar o pipeline com o Beam com a API private_beam
:
- Inicialize uma variável
runner
e crie um pipeline para aplicar as operações de privacidade a uma representação darows
no Beam:
runner = fn_api_runner.FnApiRunner() # local runner
with beam.Pipeline(runner=runner) as pipeline:
beam_data = pipeline | beam.Create(rows)
- Crie uma variável
budget_accountant
com os parâmetros de privacidade necessários:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Crie uma variável
pcol
(coleção particular) para garantir que todas as agregações estejam em conformidade com seus requisitos de privacidade:
pcol = beam_data | pbeam.MakePrivate(
budget_accountant=budget_accountant,
privacy_id_extractor=lambda
row: row.user_id)
- Especifique os parâmetros da agregação privada na classe apropriada.
Aqui, você usa a classe pipeline_dp.aggregate_params.SumParams()
porque calcula a soma das visualizações do produto.
- Transmita os parâmetros de agregação ao método
pbeam.Sum
para calcular a estatística:
dp_result = pcol | pbeam.Sum(params)
- No final, seu código ficará parecido com este snippet de código:
import pipeline_dp.private_beam as pbeam
runner = fn_api_runner.FnApiRunner() # local runner
with beam.Pipeline(runner=runner) as pipeline:
beam_data = pipeline | beam.Create(rows)
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
# Create private collection.
pcol = beam_data | pbeam.MakePrivate(
budget_accountant=budget_accountant,
privacy_id_extractor=lambda row:
row.user_id)
# Specify parameters.
params = pipeline_dp.aggregate_params.SumParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
max_partitions_contributed=1,
max_contributions_per_partition=1,
min_value=0,
max_value=100,
public_partitions=public_partitions_product_views,
partition_extractor=lambda row: row.product_view_0,
value_extractor=lambda row:row.conversion_value)
dp_result = pcol | pbeam.Sum(params)
budget_accountant.compute_budgets()
dp_result | beam.Map(print)
8. Opcional: ajustar os parâmetros de privacidade e utilitários
Você já conheceu alguns parâmetros mencionados neste codelab, como epsilon
, delta
e max_partitions_contributed
. Em linhas gerais, é possível dividi-los em duas categorias: parâmetros de privacidade e parâmetros de utilitários.
Parâmetros de privacidade
Os parâmetros epsilon
e delta
quantificam a privacidade que você oferece com a privacidade diferencial. Mais precisamente, eles são uma medida de quanta informação um possível invasor pode conseguir sobre os dados a partir da saída anonimizada. Quanto maior o valor dos parâmetros, mais informações o invasor consegue sobre os dados, o que é um risco à privacidade. Por outro lado, quanto menor o valor dos parâmetros epsilon
e delta
, mais ruído você precisa adicionar à saída para torná-la anônima e maior o número de usuários únicos necessários em cada partição para mantê-los na saída anônima. Nesse caso, há uma compensação entre utilidade e privacidade.
No PipelineDP, é necessário especificar as garantias de privacidade desejadas da saída anonimizada ao definir o orçamento total de privacidade na instância NaiveBudgetAccountant
. A ressalva é que, se você quiser que as garantias de privacidade sejam mantidas, será necessário usar cuidadosamente uma instância de NaiveBudgetAccountant
separada para cada agregação ou executar o pipeline várias vezes para evitar o uso excessivo do orçamento.
Para mais informações sobre a privacidade diferencial e o significado dos parâmetros de privacidade, consulte Lista de leitura sobre privacidade diferencial.
Parâmetros de utilitários
Os parâmetros de utilidade não afetam as garantias de privacidade, mas afetam a precisão e, consequentemente, a utilidade da saída. Eles são fornecidos na instância do AggregateParams
e usados para dimensionar o ruído adicionado.
Um parâmetro utilitário fornecido na instância do AggregateParams
e aplicável a todas as agregações é o parâmetro max_partitions_contributed
. Uma partição corresponde a uma chave de dados retornada pela operação de agregação do PipelineDP. Portanto, o parâmetro max_partitions_contributed
limita o número de chaves-valor distintas com as quais um usuário pode contribuir para a saída. Se um usuário contribuir com um número de chaves que excede o valor do parâmetro max_partitions_contributed
, algumas contribuições serão descartadas para que contribuam com o valor exato do parâmetro max_partitions_contributed
.
Da mesma forma, a maioria das agregações tem um parâmetro max_contributions_per_partition
. Elas também são fornecidas na instância do AggregateParams
, e cada agregação pode ter valores separados para elas. Eles vincularam a contribuição de um usuário para cada chave.
O ruído adicionado à saída é dimensionado pelos parâmetros max_partitions_contributed
e max_contributions_per_partition
. Portanto, há uma compensação aqui: valores maiores atribuídos a cada parâmetro significam que você mantém mais dados, mas recebe um resultado com mais ruído.
Algumas agregações exigem os parâmetros min_value
e max_value
, que especificam os limites das contribuições de cada usuário. Se um usuário contribuir com um valor menor que o atribuído ao parâmetro min_value
, esse valor vai aumentar para o do parâmetro. Da mesma forma, se um usuário contribuir com um valor maior que o do parâmetro max_value
, esse valor é reduzido para o parâmetro. Para manter mais valores originais, é necessário especificar limites maiores. O ruído é dimensionado pelo tamanho dos limites. Limites maiores permitem manter mais dados, mas você acaba com um resultado com mais ruído.
Por fim, o parâmetro noise_kind
aceita dois mecanismos de ruído diferentes no PipelineDP: GAUSSIAN
e LAPLACE
. A distribuição LAPLACE
oferece uma utilidade melhor com limites de contribuição baixos. É por isso que o PipelineDP a usa por padrão. No entanto, se você quiser usar um ruído de distribuição de GAUSSIAN
, especifique-o na instância de AggregateParams
.
9. Parabéns
Muito bem! Você concluiu o codelab PipelineDP e aprendeu muito sobre privacidade diferencial e PipelineDP.