1. Prima di iniziare
Potresti pensare che le statistiche aggregate non rivelino informazioni sulle persone a cui si riferiscono. Tuttavia, esistono molti modi in cui un malintenzionato può apprendere informazioni sensibili sulle persone dalle statistiche aggregate.
In questo codelab imparerai a produrre statistiche private con aggregazioni con privacy differenziale da PipelineDP per proteggere la privacy delle persone. PipelineDP è un framework Python che consente di applicare la privacy differenziale a set di dati di grandi dimensioni con sistemi di elaborazione batch, come Apache Spark e Apache Beam. Per saperne di più su come calcolare le statistiche di privacy differenziale in Go, consulta il codelab Privacy on Beam.
Privato significa che l'output viene prodotto in modo da non divulgare informazioni private sulle persone nei dati. Puoi ottenere questo risultato tramite la privacy differenziale, un concetto di anonimizzazione che consiste nell'aggregazione dei dati di più utenti per proteggere la loro privacy. Tutti i metodi di anonimizzazione utilizzano l'aggregazione, ma non tutti i metodi di aggregazione consentono di ottenere l'anonimizzazione. La privacy differenziale, invece, fornisce garanzie misurabili in merito alla divulgazione di informazioni e alla privacy.
Prerequisiti
- Familiarità con Python
- Familiarità con l'aggregazione di base dei dati
- Esperienza con pandas, Spark e Beam
Obiettivi didattici
- Nozioni di base sulla privacy differenziale
- Come calcolare statistiche riepilogative con privacy differenziale con PipelineDP
- Come modificare i risultati con parametri aggiuntivi di privacy e utilità
Che cosa ti serve
- Se vuoi eseguire il codelab nel tuo ambiente, sul computer deve essere installato Python 3.7 o versioni successive.
- Se vuoi seguire il codelab senza un tuo ambiente, devi accedere a Colaboratory.
2. Informazioni sulla privacy differenziale
Per comprendere meglio la privacy differenziale, esaminiamo questo semplice esempio.
Immagina di lavorare nel reparto marketing di un rivenditore di moda online e di voler capire quali dei tuoi prodotti hanno maggiori probabilità di essere venduti.
Questo grafico mostra quali prodotti i clienti hanno guardato per primi quando hanno visitato il sito web del negozio: t-shirt, maglioni, calzini o jeans. Le t-shirt sono l'articolo più popolare, mentre i calzini sono il meno popolare.

Sembra utile, ma c'è un problema. Se vuoi prendere in considerazione informazioni aggiuntive, ad esempio se i clienti hanno effettuato un acquisto o quale prodotto hanno visualizzato per secondo, rischi di rivelare l'identità delle persone nei tuoi dati.
Questo grafico mostra che solo un cliente ha guardato prima un maglione e poi ha effettuato un acquisto:

Dal punto di vista della privacy, non è il massimo. Le statistiche anonimizzate non devono rivelare i contributi individuali, quindi cosa fai? Aggiungi rumore casuale ai grafici a barre per renderli un po' meno precisi.
Questo grafico a barre non è completamente preciso, ma è comunque utile e non rivela i singoli contributi:

La privacy differenziale consiste nell'aggiunta della giusta quantità di rumore casuale per mascherare i contributi individuali.
Questo esempio è eccessivamente semplificato. La corretta implementazione della privacy differenziale è più complessa e presenta una serie di sottigliezze di implementazione inattese. Analogamente alla crittografia, potrebbe non essere una buona idea creare una tua implementazione della privacy differenziale. In alternativa, puoi utilizzare PipelineDP.
3. Scaricare e installare PipelineDP
Non è necessario installare PipelineDP per seguire questo codelab, perché puoi trovare tutto il codice e i grafici pertinenti in questo documento.
Per giocare con PipelineDP, eseguilo tu stesso o utilizzalo in un secondo momento:
- Scarica e installa PipelineDP:
pip install pipeline-dp
Se vuoi eseguire l'esempio utilizzando Apache Beam:
- Scarica e installa Apache Beam:
pip install apache_beam
Puoi trovare il codice per questo codelab e il set di dati nella directory PipelineDP/examples/codelab/.
4. Calcolare le metriche di conversione per il primo prodotto visualizzato
Immagina di lavorare presso un rivenditore di moda online e di voler capire quali delle tue diverse categorie di prodotti generano il maggior numero e valore di conversioni quando vengono visualizzate per la prima volta. Vuoi condividere queste informazioni con la tua agenzia di marketing e con altri team interni, ma vuoi evitare la divulgazione di informazioni su singoli clienti.
Per calcolare le metriche di conversione per il primo prodotto visualizzato per il sito web:
- Esamina il set di dati simulato delle visite al tuo sito web nella directory
PipelineDP/examples/codelab/.
Questo screenshot è un esempio del set di dati. Contiene l'ID utente, i prodotti visualizzati da un utente, se il visitatore ha eseguito una conversione e, in caso affermativo, il valore della conversione.
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 | nessuno | nessuno | falso | 0.0 |
1 | jeans | t_shirt | jeans | jumper | nessuno | falso | 0.0 |
2 | t_shirt | jumper | t_shirt | t_shirt | nessuno | true | 105,19 |
3 | t_shirt | t_shirt | jeans | nessuno | nessuno | falso | 0.0 |
4 | t_shirt | calzini | jeans | jeans | nessuno | falso | 0.0 |
Ti interessano queste metriche:
view_counts: il numero di volte in cui i visitatori del tuo sito web vedono per la prima volta ogni prodotto.total_conversion_value: l'importo totale speso dai visitatori quando effettuano una conversione.conversion_rate: il tasso con cui i visitatori effettuano una conversione.
- Genera le metriche in modo non privato:
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)
Come hai appreso in precedenza, queste statistiche possono rivelare informazioni sulle persone nel tuo set di dati. Ad esempio, solo una persona ha effettuato una conversione dopo aver visto per prima una felpa. Per 22 visualizzazioni, il tasso di conversione è circa 0,05. Ora devi trasformare ogni grafico a barre in uno privato.
- Definisci i parametri di privacy con la classe
pipeline_dp.NaiveBudgetAccountant, quindi specifica gli argomentiepsilonedeltache vuoi utilizzare per l'analisi.
La modalità di impostazione di questi argomenti dipende dal problema specifico. Per saperne di più, consulta Facoltativo: modifica i parametri di privacy differenziale.
Questo snippet di codice utilizza valori di esempio:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=1e-5)
- Inizializza l'istanza
LocalBackend:
ops = pipeline_dp.LocalBackend()
Puoi utilizzare l'istanza LocalBackend perché esegui questo programma localmente senza framework aggiuntivi, come Beam o Spark.
- Inizializza l'istanza
DPEngine:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
PipelineDP consente di specificare ulteriori parametri tramite la classe pipeline_dp.AggregateParams, che influisce sulla generazione delle statistiche private.
params = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT],
max_partitions_contributed=1,
max_contributions_per_partition=1)
- Specifica che vuoi calcolare la metrica
counte utilizzare la distribuzione del rumoreLAPLACE. - Imposta l'argomento
max_partitions_contributedsu un valore1.
Questo argomento limita il numero di visite diverse che un utente può contribuire. Prevedi che gli utenti visitino il sito web una volta al giorno e non ti interessa se lo visitano più volte nel corso della giornata.
- Imposta l'argomento
max_contributions_per_partitionssu un valore1.
Questo argomento specifica il numero di contributi che un singolo visitatore può apportare a una singola partizione o a una categoria di prodotto in questo caso.
- Crea un'istanza
data_extractorche specifica dove trovare i campiprivacy_id,partitionevalue.
Il tuo codice dovrebbe essere simile a questo snippet di codice:
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
- Aggiungi questo codice per trasformare il DataFrame Pandas in un elenco di righe da cui puoi calcolare direttamente le statistiche di privacy differenziale:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)
Complimenti! Hai calcolato la tua prima statistica con privacy differenziale.
Questo grafico mostra il risultato del conteggio con privacy differenziale accanto al conteggio non privato che hai calcolato in precedenza:

Il grafico a barre che ottieni quando esegui il codice potrebbe essere diverso da questo, il che va bene. A causa del rumore nella privacy differenziale, ottieni un grafico a barre diverso ogni volta che esegui il codice, ma puoi notare che sono simili al grafico a barre originale non privato.
Tieni presente che è molto importante che le garanzie di privacy non eseguano la pipeline più volte per il bene delle garanzie di privacy. Per ulteriori informazioni, consulta Calcolare più statistiche.
5. Utilizzare le partizioni pubbliche
Nella sezione precedente, potresti aver notato che hai eliminato tutti i dati sulle visite per una partizione, ovvero i visitatori che hanno visto per la prima volta i calzini sul tuo sito web.
Ciò è dovuto alla selezione delle partizioni o all'applicazione di soglie, un passaggio importante per garantire la privacy differenziale quando l'esistenza delle partizioni di output dipende dai dati utente stessi. In questo caso, la semplice esistenza di una partizione nell'output può rivelare l'esistenza di un singolo utente nei dati. Per scoprire di più sul motivo per cui questa azione viola la privacy, consulta questo post del blog. Per evitare questa violazione della privacy, PipelineDP conserva solo le partizioni con un numero sufficiente di utenti.
Quando l'elenco delle partizioni di output non dipende dai dati utente privati, non è necessario questo passaggio di selezione delle partizioni. Questo è effettivamente il caso del tuo esempio, perché conosci tutte le possibili categorie di prodotti che un cliente potrebbe vedere per prime.
Per utilizzare le partizioni:
- Crea un elenco delle possibili partizioni:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
- Passa l'elenco alla funzione
run_pipeline(), che lo imposta come input aggiuntivo per la 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 utilizzi partizioni pubbliche e rumore LAPLACE, è possibile impostare l'argomento total_delta su un valore 0.
Ora nel risultato vedi che vengono riportati i dati di tutte le partizioni o di tutti i prodotti.

Le partizioni pubbliche non solo ti consentono di conservare più partizioni, ma aggiungono anche circa la metà del rumore perché non spendi budget per la privacy per la selezione delle partizioni, quindi la differenza tra i conteggi non elaborati e privati è leggermente inferiore rispetto all'esecuzione precedente.
Quando utilizzi le partizioni pubbliche, ci sono due aspetti importanti da tenere presenti:
- Fai attenzione quando derivi l'elenco delle partizioni dai dati non elaborati. Se non lo fai in modo differenzialmente privato, la tua pipeline non fornisce più garanzie di privacy differenziale. Per saperne di più, consulta la sezione Avanzate: deriva le partizioni dai dati.
- Se non sono presenti dati per alcune delle partizioni pubbliche, devi applicare il rumore a queste partizioni per preservare la privacy differenziale. Ad esempio, se hai utilizzato un prodotto aggiuntivo come i pantaloni, che non è presente nel tuo set di dati o sul tuo sito web, si tratta comunque di rumore e i risultati potrebbero mostrare alcune visite ai prodotti quando non ce ne sono state.
Avanzato: derivare le partizioni dai dati
Se esegui più aggregazioni con lo stesso elenco di partizioni di output non pubbliche nella stessa pipeline, puoi derivare l'elenco delle partizioni una sola volta con il metodo dp_engine.select_private_partitions() e fornire le partizioni a ogni aggregazione come input public_partitions. Non solo è sicuro dal punto di vista della privacy, ma ti consente anche di aggiungere meno rumore perché utilizzi il budget per la privacy sulla selezione delle partizioni una sola volta per l'intera 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. Calcola più statistiche
Ora che sai come funziona PipelineDP, puoi vedere come utilizzarlo per alcuni casi d'uso più avanzati. Come accennato all'inizio, ti interessano tre statistiche. PipelineDP consente di calcolare più statistiche contemporaneamente, a condizione che condividano gli stessi parametri nell'istanza AggregateParams, che vedrai in seguito. Non solo è più pulito e più facile calcolare più metriche contemporaneamente, ma è anche migliore in termini di privacy.
Se ricordi i parametri epsilon e delta che fornisci alla classe NaiveBudgetAccountant, questi rappresentano un budget per la privacy, ovvero una misura della quantità di privacy dell'utente che viene divulgata dai dati.
Un aspetto importante da ricordare del budget per la privacy è che è cumulativo. Se esegui una pipeline con un determinato epsilon ε e delta δ una sola volta, spendi un budget (ε,δ). Se lo esegui una seconda volta, spendi un budget totale di (2ε, 2δ). Analogamente, se calcoli più statistiche con un metodo NaiveBudgetAccountant e consecutivamente un budget di privacy di ε,δ, spendi un budget totale di (2ε, 2δ). Ciò significa che riduci le garanzie di privacy.
Per aggirare questo problema, devi utilizzare una singola istanza di NaiveBudgetAccountant con il budget totale che vuoi utilizzare quando devi calcolare più statistiche sugli stessi dati. Dopodiché, devi specificare i valori epsilon e delta che vuoi utilizzare per ogni aggregazione. Alla fine, la garanzia della privacy complessiva rimane la stessa, ma maggiore è il valore di epsilon e delta di una determinata aggregazione, maggiore è la sua precisione.
Per vedere questo in azione, puoi calcolare le statistiche count, mean e sum.
Calcoli le statistiche in base a due metriche diverse: una metrica conversion_value, che utilizzi per dedurre l'importo delle entrate generate in base al prodotto visualizzato per primo, e una metrica has_conversion, che utilizzi per calcolare il numero di visitatori del tuo sito web e il tasso di conversione medio.
Per ogni metrica, devi specificare separatamente i parametri che guidano il calcolo delle statistiche private. Dividi il budget per la privacy tra le due metriche. Calcoli due statistiche dalla metrica has_conversion, quindi vuoi assegnarle i due terzi del budget iniziale e assegnare l'altro terzo alla metrica conversion_value.
Per calcolare più statistiche:
- Configura il tuo contabile del budget per la privacy con i valori totali di
epsilonedeltache vuoi utilizzare per le tre statistiche:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Inizializza
DPEngineper calcolare le metriche:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
- Specifica i parametri per questa metrica.
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)
L'ultimo argomento specifica facoltativamente il peso del budget per la privacy. Potresti assegnare lo stesso peso a tutti, ma vuoi impostare questo argomento su un terzo come spiegato in precedenza.
Imposti anche un argomento min_value e max_value per specificare il limite inferiore e superiore applicato a un valore fornito da un'unità di privacy in una partizione. Questi parametri sono obbligatori quando vuoi calcolare una somma o una media privata. Non ti aspetti valori negativi, quindi puoi considerare 0 e 100 come limiti ragionevoli.
- Estrai i dati pertinenti e passali alla funzione di aggregazione:
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))
- Segui gli stessi passaggi per calcolare le due metriche in base alla variabile
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))
L'unica modifica riguarda l'istanza pipeline_dp.AggregateParams, in cui ora definisci mean e count come aggregazioni e assegni a questo calcolo i due terzi del budget per la privacy. Poiché vuoi avere gli stessi limiti di contribuzione per entrambe le statistiche e calcolarli in base alla stessa variabile has_conversion, puoi combinarli nella stessa istanza pipeline_dp.AggregateParams e calcolarli contemporaneamente.
- Chiama il metodo
budget_accountant.compute_budgets():
budget_accountant.compute_budgets()
Puoi tracciare tutte e tre le statistiche private rispetto a quelle originali. A seconda del rumore aggiunto, vedrai che i risultati possono effettivamente rientrare al di fuori della scala plausibile. In questo caso, vedrai un tasso di conversione e un valore di conversione totale negativi per i saltatori perché il rumore aggiunto è simmetrico rispetto allo zero. Per ulteriori analisi ed elaborazioni, è meglio non post-elaborare manualmente le statistiche private, ma se vuoi aggiungere questi grafici a un report, puoi semplicemente impostare il valore minimo su zero in un secondo momento senza violare le garanzie della privacy.

7. Esegui la pipeline con Beam
Al giorno d'oggi, l'elaborazione dei dati richiede di gestire enormi quantità di dati, così tante che non è possibile elaborarli localmente. Molte persone utilizzano invece framework per l'elaborazione di dati su larga scala, come Beam o Spark, ed eseguono le pipeline nel cloud.
PipelineDP supporta Beam e Spark con solo piccole modifiche al codice.
Per eseguire la pipeline con Beam con l'API private_beam:
- Inizializza una variabile
runnere poi crea una pipeline in cui applichi le operazioni di privacy a una rappresentazione Beam dirows:
runner = fn_api_runner.FnApiRunner() # local runner
with beam.Pipeline(runner=runner) as pipeline:
beam_data = pipeline | beam.Create(rows)
- Crea una variabile
budget_accountantcon i parametri della privacy richiesti:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Crea una variabile
pcolo raccolta privata, che garantisce che qualsiasi aggregazione sia conforme ai tuoi requisiti di privacy:
pcol = beam_data | pbeam.MakePrivate(
budget_accountant=budget_accountant,
privacy_id_extractor=lambda
row: row.user_id)
- Specifica i parametri dell'aggregazione privata nella classe appropriata.
Qui utilizzi la classe pipeline_dp.aggregate_params.SumParams() perché calcoli la somma delle visualizzazioni di prodotto.
- Trasmetti i parametri di aggregazione al metodo
pbeam.Sumper calcolare la statistica:
dp_result = pcol | pbeam.Sum(params)
- Alla fine, il codice dovrebbe essere simile a questo snippet:
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. (Facoltativo) Modifica i parametri di privacy e utilità
In questo codelab sono stati menzionati diversi parametri, ad esempio epsilon, delta e max_partitions_contributed. Puoi suddividerli in due categorie: parametri di privacy e parametri di utilità.
Parametri della privacy
I parametri epsilon e delta quantificano la privacy che fornisci con la privacy differenziale. Più precisamente, sono una misura della quantità di informazioni che un potenziale malintenzionato può ottenere sui dati dall'output anonimizzato. Maggiore è il valore dei parametri, più informazioni l'aggressore ottiene sui dati, il che rappresenta un rischio per la privacy. D'altra parte, più basso è il valore dei parametri epsilon e delta, più rumore devi aggiungere all'output per renderlo anonimo e maggiore è il numero di utenti unici necessari in ogni partizione per mantenerli nell'output anonimizzato. In questo caso, esiste un compromesso tra utilità e privacy.
In PipelineDP, devi specificare le garanzie di privacy desiderate per l'output anonimizzato quando imposti il budget di privacy totale nell'istanza NaiveBudgetAccountant. L'avvertenza è che, se vuoi che le garanzie di privacy siano valide, devi utilizzare con attenzione un'istanza NaiveBudgetAccountant separata per ogni aggregazione o eseguire la pipeline più volte per evitare un utilizzo eccessivo del budget.
Per ulteriori informazioni sulla privacy differenziale e sul significato dei parametri di privacy, consulta l'elenco di letture sulla privacy differenziale.
Parametri di utilità
I parametri di utilità non influiscono sulle garanzie di privacy, ma influiscono sull'accuratezza e, di conseguenza, sull'utilità dell'output. Vengono forniti nell'istanza AggregateParams e utilizzati per scalare il rumore aggiunto.
Un parametro di utilità fornito nell'istanza AggregateParams e applicabile a tutte le aggregazioni è il parametro max_partitions_contributed. Una partizione corrisponde a una chiave dei dati restituiti dall'operazione di aggregazione PipelineDP, pertanto il parametro max_partitions_contributed limita il numero di valori chiave distinti che un utente può contribuire all'output. Se un utente contribuisce a un numero di chiavi superiore al valore del parametro max_partitions_contributed, alcune contribuzioni vengono eliminate in modo che contribuiscano al valore esatto del parametro max_partitions_contributed.
Allo stesso modo, la maggior parte delle aggregazioni ha un parametro max_contributions_per_partition. Vengono forniti anche nell'istanza AggregateParams e ogni aggregazione potrebbe avere valori separati. Hanno vincolato il contributo di un utente per ogni chiave.
Il rumore aggiunto all'output viene scalato in base ai parametri max_partitions_contributed e max_contributions_per_partition, quindi esiste un compromesso: valori più grandi assegnati a ciascun parametro significano che conservi più dati, ma ottieni un risultato più rumoroso.
Alcune aggregazioni richiedono un parametro min_value e max_value, che specificano i limiti per i contributi di ciascun utente. Se un utente inserisce un valore inferiore a quello assegnato al parametro min_value, il valore viene aumentato fino a raggiungere il valore del parametro. Allo stesso modo, se un utente contribuisce con un valore superiore a quello del parametro max_value, il valore viene ridotto a quello del parametro. Per conservare più valori originali, devi specificare limiti più ampi. Il rumore viene scalato in base alle dimensioni dei limiti, quindi limiti più grandi ti consentono di conservare più dati, ma il risultato è più rumoroso.
Infine, il parametro noise_kind supporta due diversi meccanismi di rumore in PipelineDP: rumore GAUSSIAN e LAPLACE. La distribuzione LAPLACE offre una migliore utilità con limiti di contributo bassi, motivo per cui PipelineDP la utilizza per impostazione predefinita. Tuttavia, se vuoi utilizzare un rumore di distribuzione GAUSSIAN, puoi specificarlo nell'istanza AggregateParams.
9. Complimenti
Ottimo lavoro. Hai completato il codelab PipelineDP e hai imparato molto sulla privacy differenziale e su PipelineDP.