1. Antes de comenzar
Quizás pienses que las estadísticas globales no filtran información sobre los individuos a los que pertenecen. Sin embargo, existen muchas maneras en que un atacante puede obtener información sensible sobre las personas a partir de estadísticas agregadas.
En este codelab, aprenderás a calcular estadísticas privadas con agregaciones privadas de manera diferencial de PipelineDP para proteger la privacidad de las personas. PipelineDP es un framework de Python que te permite aplicar privacidad diferencial a grandes conjuntos de datos con sistemas de procesamiento por lotes, como Apache Spark y Apache Beam. Para obtener más información sobre cómo calcular estadísticas con privacidad diferencial en Go, consulta el codelab de Privacy on Beam.
Privado significa que el resultado se calcula de una manera que no filtra información privada sobre las personas físicas en los datos. Puedes lograr este resultado a través de la privacidad diferencial, una noción de privacidad sólida de anonimización, que es el proceso de agregación de datos de varios usuarios para proteger la privacidad. Todos los métodos de anonimización usan la agregación, pero no todos los métodos de agregación logran la anonimización. La privacidad diferencial, por otro lado, ofrece garantías medibles sobre la filtración y privacidad de la información.
Requisitos previos
- Conocimientos de Python
- Conocimiento de la agregación de datos básica
- Experiencia con pandas, Spark y Beam
Qué aprenderás
- Conceptos básicos de la privacidad diferencial
- Cómo calcular estadísticas de resumen con privacidad diferencial con PipelineDP
- Cómo ajustar tus resultados con parámetros adicionales de privacidad y utilidad
Requisitos
- Si deseas ejecutar el codelab en tu propio entorno, debes tener Python 3.7 o una versión posterior instalado en tu computadora.
- Si quieres seguir el codelab sin tu propio entorno, necesitas acceso a Colaboratory.
2. Comprende la privacidad diferencial
Para comprender mejor la privacidad diferencial, veamos este ejemplo simple.
Imagina que trabajas en el departamento de marketing de un minorista de moda en línea y quieres saber cuáles de tus productos tienen más probabilidades de venderse.
En este gráfico, se muestra qué productos miraron primero los clientes cuando visitaron el sitio web de la tienda: camisetas, suéteres, calcetines o jeans. Las camisetas son el artículo más popular, mientras que los calcetines son el menos popular.

Esto parece útil, pero hay una desventaja. Cuando deseas tener en cuenta información adicional, como si los clientes realizaron una compra o qué producto vieron en segundo lugar, corres el riesgo de revelar información sobre personas en tus datos.
En este gráfico, se muestra que solo un cliente miró primero un jersey y, luego, realizó una compra:

Esto no es muy útil desde el punto de vista de la privacidad. Las estadísticas anónimas no deben revelar las contribuciones individuales, entonces, ¿qué haces? Agrega ruido aleatorio a tus gráficos de barras para que sean un poco menos precisos.
Este gráfico de barras no es completamente preciso, pero sigue siendo útil y no revela las contribuciones individuales:

La privacidad diferencial consiste en agregar la cantidad correcta de ruido aleatorio para enmascarar las contribuciones individuales.
Este ejemplo es demasiado simple. La implementación adecuada de la privacidad diferencial es más compleja y tiene una serie de sutilezas de implementación inesperadas. Al igual que la criptografía, crear tu propia implementación de la privacidad diferencial puede no ser la mejor idea. En su lugar, puedes usar PipelineDP.
3. Descarga e instala PipelineDP
No es necesario que instales PipelineDP para seguir este codelab, ya que puedes encontrar todo el código y los gráficos pertinentes en este documento.
Para experimentar con PipelineDP, ejecútalo por tu cuenta o úsalo más adelante:
- Descarga e instala PipelineDP:
pip install pipeline-dp
Si quieres ejecutar el ejemplo con Apache Beam, haz lo siguiente:
- Descarga y, luego, instala Apache Beam:
pip install apache_beam
Puedes encontrar el código de este codelab y el conjunto de datos en el directorio PipelineDP/examples/codelab/.
4. Calcula las métricas de conversiones por el primer producto que se visualizó
Imagina que trabajas en una tienda de moda en línea y quieres comprender cuáles de tus diferentes categorías de productos generan la mayor cantidad y el mayor valor de conversiones cuando se ven por primera vez. Quieres compartir esta información con tu agencia de marketing y otros equipos internos, pero quieres evitar que se filtre información sobre clientes individuales.
Para calcular las métricas de conversiones por el primer producto visto en el sitio web, haz lo siguiente:
- Revisa el conjunto de datos simulado de las visitas a tu sitio web en el directorio
PipelineDP/examples/codelab/.
Esta captura de pantalla es un ejemplo del conjunto de datos. Contiene el ID del usuario, los productos que vio, si realizó una conversión y, si es así, el valor de la conversión.
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 | ninguno | ninguno | falso | 0.0 |
1 | jeans | t_shirt | jeans | Jumper | ninguno | falso | 0.0 |
2 | t_shirt | Jumper | t_shirt | t_shirt | ninguno | verdadero | 105.19 |
3 | t_shirt | t_shirt | jeans | ninguno | ninguno | falso | 0.0 |
4 | t_shirt | calcetines | jeans | jeans | ninguno | falso | 0.0 |
Te interesan las siguientes métricas:
view_counts: Es la cantidad de veces que los visitantes de tu sitio web ven cada producto por primera vez.total_conversion_value: Es la cantidad total de dinero que gastan los visitantes cuando realizan una conversión.conversion_rate: Es el porcentaje de visitantes que generan conversiones.
- Genera las métricas de forma no privada:
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 aprendiste anteriormente, estas estadísticas pueden revelar información sobre las personas incluidas en tu conjunto de datos. Por ejemplo, solo una persona realizó una conversión después de ver primero a un saltador. Para 22 vistas, tu porcentaje de conversiones es de aproximadamente 0.05. Ahora debes transformar cada gráfico de barras en uno privado.
- Define tus parámetros de privacidad con la clase
pipeline_dp.NaiveBudgetAccountanty, luego, especifica los argumentosepsilonydeltaque deseas usar para tu análisis.
La forma en que establezcas estos argumentos dependerá de tu problema en particular. Para obtener más información sobre ellos, consulta la sección Opcional: Modifica los parámetros de privacidad diferencial.
En este fragmento de código, se usan valores de ejemplo:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=1e-5)
- Inicializa la instancia de
LocalBackend:
ops = pipeline_dp.LocalBackend()
Puedes usar la instancia LocalBackend porque ejecutas este programa de forma local sin frameworks adicionales, como Beam o Spark.
- Inicializa la instancia de
DPEngine:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
PipelineDP te permite especificar más parámetros a través de la clase pipeline_dp.AggregateParams, lo que afecta la generación de tus estadísticas privadas.
params = pipeline_dp.AggregateParams(
noise_kind=pipeline_dp.NoiseKind.LAPLACE,
metrics=[pipeline_dp.Metrics.COUNT],
max_partitions_contributed=1,
max_contributions_per_partition=1)
- Especifica que deseas calcular la métrica
county usar la distribución de ruidoLAPLACE. - Establece el argumento
max_partitions_contributeden un valor1.
Este argumento limita la cantidad de visitas diferentes que un usuario puede contribuir. Esperas que los usuarios visiten el sitio web una vez al día y no te importa si lo visitan varias veces durante el día.
- Establece el argumento
max_contributions_per_partitionsen un valor1.
Este argumento especifica cuántas contribuciones puede realizar un solo visitante a una partición individual o a una categoría de producto en este caso.
- Crea una instancia de
data_extractorque especifique dónde encontrar los camposprivacy_id,partitionyvalue.
Tu código debería verse como este fragmento de código:
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
- Agrega este código para transformar tu DataFrame de Pandas en una lista de filas a partir de la cual puedes calcular directamente estadísticas con privacidad diferencial:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)
¡Felicitaciones! Calculaste tu primera estadística privada diferencial.
En este gráfico, se muestra el resultado de tu recuento privado diferencial junto al recuento no privado que calculaste anteriormente:

El gráfico de barras que obtienes cuando ejecutas el código puede ser diferente de este, lo que está bien. Debido al ruido en la privacidad diferencial, obtienes un gráfico de barras diferente cada vez que ejecutas el código, pero puedes ver que son similares al gráfico original de barras no privadas.
Recuerda que es muy importante que las garantías de privacidad no ejecuten la canalización varias veces por el bien de las garantías de privacidad. Para obtener más información, consulta Cómo calcular varias estadísticas.
5. Usa particiones públicas
En la sección anterior, es posible que hayas notado que descartaste todos los datos de visitas de una partición, es decir, los visitantes que vieron calcetines por primera vez en tu sitio web.
Esto se debe a la selección o al umbral de particiones, un paso importante para asegurar las garantías de privacidad diferenciales cuando el resultado de particiones depende solamente de los datos de usuario. Cuando este sea el caso, la existencia de una partición en el resultado puede filtrar la existencia de un usuario individual en los datos. Para obtener más información sobre por qué esto infringe la privacidad, consulta esta entrada de blog. Para evitar este incumplimiento de la privacidad, PipelineDP solo conserva las particiones que tengan una cantidad suficiente de usuarios.
Cuando la lista de particiones de salida no depende de datos privados del usuario, no necesitas este paso de selección de particiones. De hecho, este es el caso de tu ejemplo, ya que conoces todas las categorías de productos posibles que un cliente podría ver primero.
Para usar particiones, haz lo siguiente:
- Crea una lista de las posibles particiones:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
- Pasa la lista a la función
run_pipeline(), que la establece como una entrada adicional para la clasepipeline_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)
Si usas particiones públicas y ruido de LAPLACE, es posible establecer el argumento total_delta en un valor de 0.
Ahora, en el resultado, verás que se informan los datos de todas las particiones o productos.

Las particiones públicas no solo te permiten conservar más particiones, sino que también agregan aproximadamente la mitad del ruido, ya que no inviertes presupuesto de privacidad en la selección de particiones, por lo que la diferencia entre los conteos sin procesar y privados es un poco menor en comparación con la ejecución anterior.
Hay dos aspectos importantes que debes tener en cuenta cuando usas particiones públicas:
- Ten cuidado cuando derives la lista de particiones a partir de datos sin procesar. Si no lo haces de forma diferencial, tu canalización ya no proporcionará garantías de privacidad diferenciales. Para obtener más información, consulta la sección Avanzado: Deriva particiones a partir de los datos.
- Si no hay datos para algunas de las particiones públicas, debes aplicar ruido a esas particiones para preservar la privacidad diferencial. Por ejemplo, si usaste un producto adicional, como pantalones, que no aparece en tu conjunto de datos ni en tu sitio web, seguirá siendo ruido, y los resultados podrían mostrar algunas visitas a productos cuando no hubo ninguna.
Avanzado: Cómo derivar particiones de los datos
Si ejecutas varias agregaciones con la misma lista de particiones de salida no públicas en la misma canalización, puedes derivar la lista de particiones una sola vez con el método dp_engine.select_private_partitions() y proporcionar las particiones a cada agregación como la entrada public_partitions. Esto no solo es seguro desde el punto de vista de la privacidad, sino que también permite agregar menos ruido, ya que solo usas el presupuesto de privacidad en la selección de particiones una vez para toda la canalización.
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. Calcula varias estadísticas
Ahora que sabes cómo funciona PipelineDP, puedes ver cómo usarlo para algunos casos de uso más avanzados. Como se mencionó al principio, te interesan tres estadísticas. PipelineDP te permite calcular varias estadísticas al mismo tiempo, siempre y cuando compartan los mismos parámetros en la instancia de AggregateParams, que verás más adelante. No solo es más limpio y fácil calcular varias métricas de una sola vez, sino que también es mejor en términos de privacidad.
Si recuerdas los parámetros epsilon y delta que proporcionas a la clase NaiveBudgetAccountant, estos representan un elemento que se denomina presupuesto de privacidad, que mide la cantidad de privacidad del usuario que se filtra de los datos.
Recuerda que el presupuesto de privacidad es una suma. Si ejecutas una canalización con un épsilon ε y un delta δ particulares una sola vez, gastas un presupuesto de (ε,δ). Si la ejecutas por segunda vez, habrás usado un presupuesto total de (2ε, 2δ). Del mismo modo, si calculas varias estadísticas con un método NaiveBudgetAccountant y, luego, un presupuesto de privacidad de ε,δ, gastas un presupuesto total de (2ε, 2δ). Esto significa que se degradan las garantías de privacidad.
Para evitar esto, debes usar una sola instancia de NaiveBudgetAccountant con el presupuesto total que deseas usar cuando necesites calcular varias estadísticas sobre los mismos datos. Luego, deberás especificar los valores epsilon y delta que deseas usar para cada agregación. Al final, obtendrás la misma garantía general de privacidad, pero cuanto más altos sean los valores de epsilon y delta de una agregación en particular, mayor será la exactitud que tendrá.
Para ver cómo funciona, puedes calcular las estadísticas de count, mean y sum.
Calculas estadísticas basadas en dos métricas diferentes: una métrica de conversion_value, que usas para inferir la cantidad de ingresos generados en función del producto que se ve primero, y una métrica de has_conversion, que usas para calcular la cantidad de visitantes de tu sitio web y el porcentaje de conversiones promedio.
Para cada métrica, debes especificar por separado los parámetros que guían el cálculo de las estadísticas privadas. Dividirás tu presupuesto de privacidad entre las dos métricas. Calculas dos estadísticas a partir de la métrica has_conversion, por lo que deseas asignarle dos tercios de tu presupuesto inicial y el otro tercio a la métrica conversion_value.
Para calcular varias estadísticas, sigue estos pasos:
- Configura tu contador de presupuesto de privacidad con los valores totales de
epsilonydeltaque deseas usar en las tres estadísticas:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Inicializa
DPEnginepara calcular tus métricas:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
- Especifica los parámetros de esta 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)
El último argumento especifica de forma opcional el peso de tu presupuesto de privacidad. Podrías asignar el mismo peso a todos, pero te recomendamos que establezcas este argumento en un tercio, como se explicó anteriormente.
También puedes establecer un argumento min_value y max_value para especificar el límite inferior y superior que se aplica a un valor aportado por una unidad de privacidad en una partición. Estos parámetros son obligatorios cuando deseas calcular una suma o una media privadas. No esperas valores negativos, por lo que puedes suponer que 0 y 100 son límites razonables.
- Extrae los datos pertinentes y, luego, pásalos a la función de agregación:
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))
- Sigue los mismos pasos para calcular las dos métricas en función de tu variable
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))
El único cambio se encuentra en la instancia de pipeline_dp.AggregateParams, en la que ahora defines mean y count como agregaciones, y asignas dos tercios de tu presupuesto de privacidad a este cálculo. Dado que deseas tener los mismos límites de contribución para ambas estadísticas y calcularlos sobre la misma variable has_conversion, puedes combinarlos en la misma instancia de pipeline_dp.AggregateParams y calcularlos al mismo tiempo.
- Llama al método
budget_accountant.compute_budgets()de la siguiente manera:
budget_accountant.compute_budgets()
Puedes generar un gráfico comparativo de las tres estadísticas privadas y sus estadísticas originales. Según el ruido que se agregue, verás que los resultados pueden quedar fuera de la escala plausible. En este caso, verás un porcentaje de conversiones negativo y un valor de conversión total para los usuarios que abandonan la página porque el ruido agregado es simétrico alrededor de cero. Para realizar análisis y procesamientos adicionales, es mejor no posprocesar manualmente las estadísticas privadas, pero, si quisieras agregar esos gráficos a un informe, podrías simplemente establecer el mínimo en cero después sin incumplir las garantías de privacidad.

7. Ejecuta la canalización con Beam
Hoy en día, el procesamiento de datos requiere que trabajes con enormes cantidades de datos, tantos que no puedes procesarlos de forma local. En cambio, muchas personas usan frameworks para el procesamiento de datos a gran escala, como Beam o Spark, y ejecutan sus canalizaciones en la nube.
PipelineDP admite Beam y Spark con solo pequeños cambios en tu código.
Para ejecutar la canalización con Beam y la API de private_beam, haz lo siguiente:
- Inicializa una variable
runnery, luego, crea una canalización en la que apliques tus operaciones de privacidad a una representación de Beam de turows:
runner = fn_api_runner.FnApiRunner() # local runner
with beam.Pipeline(runner=runner) as pipeline:
beam_data = pipeline | beam.Create(rows)
- Crea una variable
budget_accountantcon los parámetros de privacidad que necesites:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
total_epsilon=1, total_delta=0)
- Crea una variable de
pcol, o colección privada, que garantice que todas las agregaciones cumplan con tus requisitos de privacidad:
pcol = beam_data | pbeam.MakePrivate(
budget_accountant=budget_accountant,
privacy_id_extractor=lambda
row: row.user_id)
- Especifica los parámetros de tu agregación privada en la clase correspondiente.
Aquí, usas la clase pipeline_dp.aggregate_params.SumParams() porque calculas la suma de las vistas de productos.
- Pasa tus parámetros de agregación al método
pbeam.Sumpara calcular tu estadística:
dp_result = pcol | pbeam.Sum(params)
- Al finalizar, tu código debería verse de la siguiente manera:
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: Ajusta los parámetros de privacidad y utilidad
En este codelab, se mencionaron varios parámetros, como epsilon, delta y max_partitions_contributed. Puedes dividirlos en dos categorías: parámetros de privacidad y parámetros de utilidad.
Parámetros de privacidad
Los parámetros epsilon y delta cuantifican la privacidad que proporcionas con la privacidad diferencial. Más precisamente, son una medida de cuánta información puede obtener un atacante potencial sobre los datos a partir del resultado anonimizado. Cuanto mayor sea el valor de los parámetros, más información obtendrá el atacante sobre los datos, lo que representa un riesgo para la privacidad. Por otro lado, cuanto más bajos sean los valores de los parámetros epsilon y delta, más ruido deberás agregar al resultado para que sea anónimo y mayor será la cantidad de usuarios únicos que necesitarás en cada partición para mantenerlos en el resultado anonimizado. En este caso, existe un equilibrio entre utilidad y privacidad.
En PipelineDP, debes especificar las garantías de privacidad deseadas de tu salida anonimizada cuando establezcas el presupuesto de privacidad total en la instancia de NaiveBudgetAccountant. La advertencia es que, si deseas que tus garantías de privacidad se mantengan, debes usar con cuidado una instancia de NaiveBudgetAccountant separada para cada agregación o ejecutar la canalización varias veces para evitar el uso excesivo de tu presupuesto.
Para obtener más información sobre la privacidad diferencial y el significado de los parámetros de privacidad, consulta Una lista de lectura sobre la privacidad diferencial.
Parámetros de utilidad
Los parámetros de utilidad no afectan las garantías de privacidad, pero sí la precisión y, por lo tanto, la utilidad del resultado. Se proporcionan en la instancia AggregateParams y se usan para ajustar el ruido agregado.
Un parámetro de utilidad que se proporciona en la instancia AggregateParams y que se aplica a todas las agregaciones es el parámetro max_partitions_contributed. Una partición corresponde a una clave de los datos que devuelve la operación de agregación de PipelineDP, por lo que el parámetro max_partitions_contributed limita la cantidad de valores clave distintos que un usuario puede aportar al resultado. Si un usuario contribuye a una cantidad de claves que supera el valor del parámetro max_partitions_contributed, se descartarán algunas contribuciones para que coincidan con el valor exacto del parámetro max_partitions_contributed.
Del mismo modo, la mayoría de las agregaciones tienen un parámetro max_contributions_per_partition. También se proporcionan en la instancia AggregateParams y cada agregación podría tener valores distintos. Limitan la contribución de un usuario para cada clave.
El ruido que se agrega al resultado se escala según los parámetros max_partitions_contributed y max_contributions_per_partition, por lo que hay una desventaja aquí: Los valores más grandes asignados a cada parámetro significan que retienes más datos, pero obtienes un resultado con más ruido.
Algunas agregaciones requieren un parámetro min_value y max_value, que especifican los límites para las contribuciones de cada usuario. Si un usuario aporta un valor inferior al asignado al parámetro min_value, el valor se incrementa al valor del parámetro. Del mismo modo, si un usuario aporta un valor mayor que el valor del parámetro max_value, el valor se reducirá al valor del parámetro. Para mantener más valores originales, debes especificar límites más grandes. El ruido se escala según el tamaño de los límites, por lo que los límites más grandes te permiten conservar más datos, pero obtendrás un resultado con más ruido.
Por último, el parámetro noise_kind admite dos mecanismos de ruido diferentes en PipelineDP: ruido de GAUSSIAN y ruido de LAPLACE. La distribución LAPLACE ofrece una mejor utilidad con límites de contribución bajos, por lo que PipelineDP la usa de forma predeterminada. Sin embargo, si deseas usar un ruido de distribución GAUSSIAN, puedes especificarlo en la instancia AggregateParams.
9. Felicitaciones
¡Bien hecho! Completaste el codelab de PipelineDP y aprendiste mucho sobre la privacidad diferencial y PipelineDP.