Private Statistiken mit PipelineDP berechnen

1. Hinweis

Sie könnten denken, dass aggregierte Statistiken keine Informationen über die Personen herausgeben, auf die sie sich beziehen. Es gibt jedoch viele Möglichkeiten, wie Angreifer vertrauliche Informationen über Personen aus aggregierten Statistiken gewinnen können.

In diesem Codelab erfahren Sie, wie Sie private Statistiken mit differenziellen privaten Aggregationen aus PipelineDP erstellen, um die Daten von Einzelpersonen zu schützen Datenschutz. PipelineDP ist ein Python-Framework, mit dem Sie mithilfe von Batchverarbeitungssystemen wie Apache Spark und Apache Beam Differential Privacy auf große Datasets anwenden können. Weitere Informationen zum Berechnen von differenziellen privaten Statistiken in Go finden Sie im Codelab zu Privacy on Beam.

Privat bedeutet, dass die Ausgabe so erstellt wird, dass keine privaten Informationen zu den Personen in den Daten offengelegt werden. Dies erreichen Sie mit dem Differential Privacy, einem starken Prinzip der Anonymisierung, bei dem Daten für mehrere Nutzer zusammengefasst werden, um die Privatsphäre der Nutzer zu schützen. Bei allen Anonymisierungsmethoden wird die Aggregation verwendet, aber nicht bei allen Aggregationsmethoden wird eine Anonymisierung erreicht. Differential Privacy hingegen bietet messbare Garantien im Hinblick auf den Verlust von Informationen und den Datenschutz.

Vorbereitung

  • Python-Vorkenntnisse
  • Kenntnisse der grundlegenden Datenaggregation
  • Erfahrung mit pandas, Spark und Beam

Lerninhalte

  • Grundlagen des Differential Privacy
  • So berechnen Sie differenziell private zusammenfassende Statistiken mit PipelineDP
  • Ergebnisse mit zusätzlichen Datenschutz- und Dienstprogrammparametern optimieren

Voraussetzungen

  • Wenn Sie das Codelab in Ihrer eigenen Umgebung ausführen möchten, muss Python 3.7 oder höher auf Ihrem Computer installiert sein.
  • Wenn Sie dem Codelab ohne Ihre eigene Umgebung folgen möchten, benötigen Sie Zugriff auf Colaboratory.

2. Differential Privacy

Sehen Sie sich dieses einfache Beispiel an, um den Differential Privacy besser zu verstehen.

Stellen Sie sich vor, Sie arbeiten in der Marketingabteilung eines Onlinehändlers für Mode und möchten herausfinden, welche Ihrer Produkte am ehesten verkauft werden.

In diesem Diagramm sehen Sie, welche Produkte sich die Kunden beim Besuch der Website des Geschäfts zuerst angesehen haben: T-Shirts, Pullover, Socken oder Jeans. T-Shirts sind das beliebteste Produkt, Socken dagegen am wenigsten.

ea813c698889a4c6.png

Das sieht nützlich aus, aber es gibt einen Haken. Wenn Sie zusätzliche Informationen berücksichtigen möchten, z. B. ob Kunden einen Kauf getätigt haben oder welches Produkt sie sich als Nächstes angesehen haben, riskieren Sie, in Ihren Daten Personen offenzulegen.

Dieses Diagramm zeigt, dass sich nur ein Kunde zuerst eine Steckbrücke angesehen und dann tatsächlich einen Kauf getätigt hat:

b7c6f7f891778366.png

Aus datenschutzrechtlicher Sicht ist das nicht gerade toll. Anonymisierte Statistiken sollten keine individuellen Beiträge preisgeben. Was tun Sie also? Sie fügen zu Ihren Balkendiagrammen zufälliges Rauschen hinzu, um sie etwas ungenauer zu machen!

Dieses Balkendiagramm ist nicht vollständig genau, aber es ist dennoch nützlich und zeigt keine individuellen Beiträge an:

b55e8d7f99f6d574.gif

Differential Privacy ist das Hinzufügen der richtigen Menge an zufälligem Rauschen, um einzelne Beiträge zu maskieren.

Dieses Beispiel ist zu stark vereinfacht. Die ordnungsgemäße Implementierung von Differential Privacy ist aufwendiger und bringt einige unerwartete Feinheiten mit sich. Ähnlich wie bei der Kryptografie ist es möglicherweise keine gute Idee, eine eigene Implementierung von Differential Privacy zu erstellen. Stattdessen können Sie PipelineDP verwenden.

3. PipelineDP herunterladen und installieren

Sie müssen PipelineDP nicht installieren und folgen diesem Codelab, da Sie den relevanten Code und die relevanten Grafiken in diesem Dokument finden.

Wenn Sie PipelineDP ausprobieren möchten, führen Sie es selbst aus oder verwenden Sie es später:

  • Laden Sie PipelineDP herunter und installieren Sie es:
pip install pipeline-dp

Wenn Sie das Beispiel mit Apache Beam ausführen möchten:

  • Laden Sie Apache Beam herunter und installieren Sie es:
pip install apache_beam

Den Code für dieses Codelab und das Dataset finden Sie im Verzeichnis PipelineDP/examples/codelab/.

4. Conversion-Messwerte pro zuerst aufgerufenem Produkt berechnen

Stellen Sie sich vor, Sie arbeiten bei einem Onlinehändler für Mode und möchten herausfinden, welche Ihrer verschiedenen Produktkategorien beim ersten Aufruf die höchste Anzahl und den höchsten Wert von Conversions generieren. Sie möchten diese Informationen mit Ihrer Marketingagentur und anderen internen Teams teilen, aber verhindern, dass Informationen zu einzelnen Kunden offengelegt werden.

So berechnen Sie Conversion-Messwerte pro angesehenem Produkt auf der Website:

  1. Sehen Sie sich das simulierte Dataset zu Besuchen auf Ihrer Website im Verzeichnis PipelineDP/examples/codelab/ an.

Dieser Screenshot ist ein Beispiel für das Dataset. Sie enthält die ID des Nutzers, die vom Nutzer aufgerufenen Produkte, ob der Besucher eine Conversion durchgeführt hat und, falls ja, den Wert der Conversion.

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

keine

keine

falsch

0,0

1

Jeans

t_shirt

Jeans

Jumper

keine

falsch

0,0

2

t_shirt

Jumper

t_shirt

t_shirt

keine

wahr

105,19

3

t_shirt

t_shirt

Jeans

keine

keine

falsch

0,0

4

t_shirt

Socken

Jeans

Jeans

keine

falsch

0,0

Sie interessieren sich für diese Messwerte:

  • view_counts: Gibt an, wie oft Besucher Ihrer Website das jeweilige Produkt zuerst sehen.
  • total_conversion_value: Der Gesamtbetrag, den Besucher bei einer Conversion ausgeben.
  • conversion_rate: Die Conversion-Rate der Besucher.
  1. So generieren Sie Messwerte auf nicht private Weise:
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)

Wie Sie bereits gelernt haben, können diese Statistiken Informationen über Personen in Ihrem Dataset preisgeben. Beispielsweise hat nur eine Person eine Conversion ausgeführt, nachdem sie den Springer zuerst gesehen hat. Bei 22 Aufrufen liegt Ihre Conversion-Rate bei ungefähr 0, 05. Jetzt müssen Sie jedes Balkendiagramm in ein privates Diagramm umwandeln.

  1. Definieren Sie Ihre Datenschutzparameter mit der Klasse pipeline_dp.NaiveBudgetAccountant und geben Sie dann die Argumente epsilon und delta an, die Sie für Ihre Analyse verwenden möchten.

Wie Sie diese Argumente festlegen, hängt von Ihrem spezifischen Problem ab. Weitere Informationen finden Sie unter Optional: Differential Privacy-Parameter optimieren.

In diesem Code-Snippet werden Beispielwerte verwendet:

budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=1e-5)
  1. Initialisieren Sie die Instanz LocalBackend:
ops = pipeline_dp.LocalBackend()

Sie können die Instanz LocalBackend verwenden, da Sie dieses Programm lokal und ohne zusätzliche Frameworks wie Beam oder Spark ausführen.

  1. Initialisieren Sie die Instanz DPEngine:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)

Mit PipelineDP können Sie über die Klasse pipeline_dp.AggregateParams weitere Parameter angeben, die sich auf die Generierung Ihrer privaten Statistiken auswirken.

params = pipeline_dp.AggregateParams(
     noise_kind=pipeline_dp.NoiseKind.LAPLACE,
     metrics=[pipeline_dp.Metrics.COUNT],
     max_partitions_contributed=1,
     max_contributions_per_partition=1)
  1. Geben Sie an, dass Sie den Messwert count berechnen und die Rauschverteilung LAPLACE verwenden möchten.
  2. Legen Sie das Argument max_partitions_contributed auf einen 1-Wert fest.

Dieses Argument begrenzt, wie viele verschiedene Besuche ein Nutzer beitragen kann. Sie erwarten, dass Nutzer die Website einmal am Tag besuchen, und es spielt für Sie keine Rolle, ob sie die Website im Laufe des Tages mehrmals besuchen.

  1. Legen Sie das Argument max_contributions_per_partitions auf einen 1-Wert fest.

Dieses Argument gibt an, wie viele Beiträge ein einzelner Besucher in diesem Fall zu einer einzelnen Partition oder Produktkategorie beitragen kann.

  1. Erstellen Sie eine data_extractor-Instanz, die angibt, wo die Felder privacy_id, partition und value zu finden sind.

Der Code sollte wie dieses Code-Snippet aussehen:

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
  1. Fügen Sie diesen Code hinzu, um den Pandas DataFrame in eine Liste von Zeilen zu transformieren, aus denen sich differenzielle private Statistiken direkt berechnen lassen:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)

Glückwunsch! Sie haben Ihre erste differenzielle Statistik berechnet!

In diesem Diagramm wird das Ergebnis Ihrer differenzierten Zählung neben der zuvor berechneten Anzahl nicht privater Daten angezeigt:

a5a25a00858219ab.png

Das Balkendiagramm, das Sie beim Ausführen des Codes erhalten, kann sich von diesem unterscheiden, was in Ordnung ist. Aufgrund des Rauschens des Differential Privacy wird jedes Mal, wenn Sie den Code ausführen, ein anderes Balkendiagramm angezeigt. Sie können jedoch sehen, dass es dem ursprünglichen nicht privaten Balkendiagramm ähnelt.

Beachten Sie, dass es im Rahmen der Datenschutzgarantien aus Gründen der Datenschutzgarantie sehr wichtig ist, die Pipeline nicht mehrmals auszuführen. Weitere Informationen finden Sie unter „Mehrere Statistiken berechnen“.

5. Öffentliche Partitionen verwenden

Im vorherigen Abschnitt haben Sie vielleicht bemerkt, dass alle Besuchsdaten für eine Partition, d. h. Besucher, die zuerst Socken auf Ihrer Website gesehen haben, nicht berücksichtigt wurden.

Das liegt an der Partitionsauswahl oder an Schwellenwerten. Dies ist ein wichtiger Schritt, um Differential Privacy zu gewährleisten, wenn die Existenz von Ausgabepartitionen von den Nutzerdaten selbst abhängt. In diesem Fall kann das bloße Vorhandensein einer Partition in der Ausgabe die Existenz eines einzelnen Nutzers in den Daten verlieren. Weitere Informationen dazu, warum das den Datenschutz verletzt, finden Sie in diesem Blogpost. Um diese Datenschutzverletzung zu vermeiden, behält PipelineDP nur Partitionen mit einer ausreichenden Anzahl von Nutzern bei.

Wenn die Liste der Ausgabepartitionen nicht von privaten Nutzerdaten abhängt, benötigen Sie diesen Schritt zur Partitionsauswahl nicht. Das ist bei Ihrem Beispiel der Fall, weil Sie alle Produktkategorien kennen, die ein Kunde zuerst sehen könnte.

So verwenden Sie Partitionen:

  1. Erstellen Sie eine Liste der möglichen Partitionen:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
  1. Übergeben Sie die Liste an die Funktion run_pipeline(), die sie als zusätzliche Eingabe für die Klasse pipeline_dp.AggregateParams festlegt:
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)

Wenn Sie öffentliche Partitionen und LAPLACE-Rauschen verwenden, können Sie für das Argument total_delta den Wert 0 festlegen.

Im Ergebnis sehen Sie jetzt, dass Daten für alle Partitionen oder Produkte gemeldet werden.

a4f6302c8efcd5da.png

Mit öffentlichen Partitionen können Sie nicht nur mehr Partitionen behalten, sondern auch etwa halb so viel Rauschen erzeugen, da Sie kein Datenschutzbudget für die Partitionsauswahl ausgeben. Daher ist der Unterschied zwischen RAW- und privaten Zählungen im Vergleich zum vorherigen Durchlauf etwas geringer.

Bei der Verwendung öffentlicher Partitionen müssen zwei wichtige Dinge beachtet werden:

  • Seien Sie vorsichtig, wenn Sie die Liste der Partitionen aus Rohdaten ableiten. Wenn Sie dies nicht auf differenzielle Art und Weise tun, bietet Ihre Pipeline keine Differential Privacy-Garantien mehr. Weitere Informationen finden Sie unter Erweitert: Partitionen aus Daten ableiten.
  • Wenn für einige der öffentlichen Partitionen keine Daten vorhanden sind, müssen Sie diese Partitionen mit Rauschen versehen, um Differential Privacy zu wahren. Wenn Sie beispielsweise ein zusätzliches Produkt wie Hosen verwendet haben, was nicht in Ihrem Datensatz oder auf Ihrer Website vorkommt, ist dies immer noch verunsichert und die Ergebnisse zeigen möglicherweise einige Besuche von Produkten an, wenn keine vorhanden sind.

Erweitert: Partitionen aus Daten ableiten

Wenn Sie mehrere Aggregationen mit derselben Liste nicht öffentlicher Ausgabepartitionen in derselben Pipeline ausführen, können Sie die Liste der Partitionen einmal mit der Methode dp_engine.select_private_partitions() ableiten und die Partitionen jeder Aggregation als public_partitions-Eingabe bereitstellen. Das ist nicht nur aus datenschutzrechtlicher Sicht sicher, sondern es wird auch weniger störend erzeugt, da Sie das Datenschutzbudget für die Partitionsauswahl nur einmalig für die gesamte Pipeline verwenden.

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. Mehrere Statistiken berechnen

Jetzt, da Sie wissen, wie PipelineDP funktioniert, können Sie sehen, wie Sie es für einige komplexere Anwendungsfälle verwenden können. Wie anfangs erwähnt, sind Sie an drei Statistiken interessiert. Mit PipelineDP können Sie mehrere Statistiken gleichzeitig berechnen, sofern diese dieselben Parameter in der Instanz AggregateParams haben, die Sie später sehen. Die Berechnung mehrerer Messwerte auf einmal ist nicht nur übersichtlicher und einfacher, sondern auch im Hinblick auf den Datenschutz.

Wenn Sie sich an die Parameter epsilon und delta erinnern, die Sie an die NaiveBudgetAccountant-Klasse übergeben, stellen diese ein sogenanntes Datenschutzbudget dar. Damit wird gemessen, wie viel Datenschutz für Nutzer aus den Daten gestohlen wird.

Ein wichtiger Punkt beim Datenschutzbudget ist, dass es additiv ist. Wenn Sie eine Pipeline mit einem bestimmten Epsilon-{4/} und Delta Delta in einem einzigen Zeitraum ausführen, geben Sie ein (Seiten-, Delta)-Budget aus. Wenn Sie sie ein zweites Mal ausführen, investieren Sie ein Gesamtbudget in Höhe von (2\}}"></, 2∫). Wenn Sie also mehrere Statistiken mit einer NaiveBudgetAccountant-Methode und nacheinander ein Datenschutzbudget in Höhe von {4/},variance Das bedeutet, dass Sie die Datenschutzgarantien herabsetzen.

Um dies zu umgehen, müssen Sie eine einzelne NaiveBudgetAccountant-Instanz mit dem Gesamtbudget verwenden, das Sie verwenden möchten, wenn Sie mehrere Statistiken für dieselben Daten berechnen müssen. Anschließend müssen Sie die Werte epsilon und delta angeben, die Sie für jede Aggregation verwenden möchten. Letztendlich haben Sie dieselbe allgemeine Datenschutzgarantie, aber je höher die Werte für epsilon und delta, die eine bestimmte Aggregation hat, desto höher ist die Genauigkeit.

Um dies in Aktion zu sehen, können Sie die Statistiken count, mean und sum berechnen.

Sie berechnen Statistiken anhand von zwei verschiedenen Messwerten: dem Messwert conversion_value, mit dem Sie den erzielten Umsatz basierend darauf ableiten, welches Produkt zuerst angesehen wird, und dem Messwert has_conversion, mit dem Sie die Anzahl der Besucher Ihrer Website und die durchschnittliche Conversion-Rate berechnen.

Die Parameter für die Berechnung der privaten Statistiken müssen für jeden Messwert separat angegeben werden. Sie teilen Ihr Datenschutzbudget auf die beiden Messwerte auf. Sie berechnen zwei Statistiken aus dem Messwert has_conversion. Sie möchten also zwei Drittel Ihres anfänglichen Budgets und das andere Drittel dem Messwert conversion_value zuweisen.

So berechnen Sie mehrere Statistiken:

  1. Richten Sie Ihren Budgetbuchhalter ein und legen Sie die Gesamtwerte für epsilon und delta fest, die Sie für die drei Statistiken verwenden möchten:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=0)
  1. Initialisieren Sie DPEngine, um Ihre Messwerte zu berechnen:
 dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
  1. Geben Sie die Parameter für diesen Messwert an.
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)

Das letzte Argument gibt optional die Gewichtung Ihres Datenschutzbudgets an. Sie könnten allen die gleiche Gewichtung geben, aber Sie möchten dieses Argument, wie oben erläutert, auf ein Drittel festlegen.

Außerdem legen Sie die Argumente min_value und max_value fest, um die Unter- und Obergrenze anzugeben, die auf einen Wert angewendet wird, der von einer Datenschutzeinheit in einer Partition beigesteuert wird. Diese Parameter sind erforderlich, wenn Sie eine private Summe oder einen Mittelwert berechnen möchten. Sie erwarten keine negativen Werte, daher können Sie 0 und 100 als sinnvolle Grenzen annehmen.

  1. Extrahieren Sie die relevanten Daten und übergeben Sie sie dann an die Aggregationsfunktion:
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))
  1. Führen Sie dieselben Schritte aus, um die beiden Messwerte basierend auf der Variablen has_conversion zu berechnen:
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))

Die einzige Änderung betrifft die Instanz pipeline_dp.AggregateParams, in der Sie jetzt mean und count als Zusammenfassungen definieren und dieser Berechnung zwei Drittel Ihres Datenschutzbudgets zuweisen. Da Sie dieselben Beitragsgrenzen für beide Statistiken haben und sie auf Basis derselben has_conversion-Variable berechnen möchten, können Sie sie in derselben pipeline_dp.AggregateParams-Instanz kombinieren und gleichzeitig berechnen.

  1. Rufen Sie die Methode budget_accountant.compute_budgets() auf:
budget_accountant.compute_budgets()

Sie können alle drei privaten Statistiken im Vergleich zu ihren ursprünglichen Statistiken grafisch darstellen. Je nachdem, welches Rauschen hinzugefügt wurde, sehen Sie, dass die Ergebnisse tatsächlich außerhalb der plausiblen Skala liegen. In diesem Fall sehen Sie eine negative Conversion-Rate und einen negativen Gesamt-Conversion-Wert für Jumper, da das hinzugefügte Rauschen symmetrisch um null herum ist. Für die weitere Analyse und Verarbeitung empfiehlt es sich, die privaten Statistiken nicht manuell nachzuverarbeiten. Wenn Sie diese Diagramme jedoch zu einem Bericht hinzufügen möchten, können Sie den Mindestwert anschließend einfach auf null setzen, ohne die Datenschutzgarantien zu verletzen.

cb1fc563f817eaf.png

7. Pipeline mit Beam ausführen

Bei der Datenverarbeitung sind heute so große Datenmengen zu bewältigen, dass sie nicht lokal verarbeitet werden können. Stattdessen verwenden viele Nutzer für die Verarbeitung großer Datenmengen Frameworks wie Beam oder Spark und führen ihre Pipelines in der Cloud aus.

PipelineDP unterstützt Beam und Spark mit nur geringfügigen Änderungen am Code.

So führen Sie die Pipeline mit Beam mit der private_beam API aus:

  1. Initialisieren Sie eine runner-Variable und erstellen Sie dann eine Pipeline, in der Sie Ihre Datenschutzvorgänge auf eine Beam-Darstellung Ihrer rows anwenden:
runner = fn_api_runner.FnApiRunner()  # local runner

with beam.Pipeline(runner=runner) as pipeline:
   beam_data = pipeline | beam.Create(rows)
  1. Erstellen Sie eine budget_accountant-Variable mit den erforderlichen Datenschutzparametern:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
               total_epsilon=1, total_delta=0)
  1. Erstellen Sie die Variable pcol oder private Sammlung, die garantiert, dass Aggregationen Ihren Datenschutzanforderungen entsprechen:
pcol = beam_data | pbeam.MakePrivate(
                                 budget_accountant=budget_accountant,
                                 privacy_id_extractor=lambda 
                                                    row: row.user_id)
  1. Geben Sie die Parameter der privaten Aggregation in der entsprechenden Klasse an.

Hier verwenden Sie die Klasse pipeline_dp.aggregate_params.SumParams(), weil Sie die Summe der Produktaufrufe berechnen.

  1. Übergeben Sie die Aggregationsparameter an die Methode pbeam.Sum, um die Statistik zu berechnen:
dp_result = pcol | pbeam.Sum(params)
  1. Ihr Code sollte schließlich wie dieses Code-Snippet aussehen:
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. Optional: Parameter für Datenschutz und Dienstprogramm optimieren

Sie haben schon einige in diesem Codelab erwähnte Parameter gesehen, z. B. die Parameter epsilon, delta und max_partitions_contributed. Sie lassen sich grob in zwei Kategorien unterteilen: Datenschutzparameter und Dienstprogrammparameter.

Datenschutzparameter

Die Parameter epsilon und delta beziffern den Datenschutz, den du mit Differential Privacy bietest. Genauer gesagt geben sie ein Maß dafür, wie viele Informationen ein potenzieller Angreifer aus den anonymisierten Daten zu den Daten gewinnen kann. Je höher der Wert der Parameter ist, desto mehr Informationen erhält der Angreifer über die Daten, was ein Datenschutzrisiko darstellt. Andererseits gilt: Je niedriger der Wert der Parameter epsilon und delta ist, desto mehr Rauschen müssen Sie in die Ausgabe einfügen, damit sie anonym wird, und desto mehr einzelne Nutzer benötigen Sie in jeder Partition, um sie in der anonymisierten Ausgabe beizubehalten. In diesem Fall gibt es einen Kompromiss zwischen Nutzen und Datenschutz.

In PipelineDP müssen Sie die gewünschten Datenschutzgarantien für Ihre anonymisierte Ausgabe angeben, wenn Sie das Gesamtbudget für den Datenschutz in der Instanz NaiveBudgetAccountant festlegen. Wenn Ihre Datenschutzgarantien jedoch gelten sollen, müssen Sie für jede Aggregation sorgfältig eine separate NaiveBudgetAccountant-Instanz verwenden oder die Pipeline mehrmals ausführen, um eine übermäßige Nutzung Ihres Budgets zu vermeiden.

Weitere Informationen zum Differential Privacy und zur Bedeutung der Parameter finden Sie in der Leseliste zum Differential Privacy.

Dienstprogrammparameter

Dienstprogrammparameter wirken sich nicht auf die Datenschutzgarantien aus, beeinflussen aber die Genauigkeit und folglich den Nutzen der Ausgabe. Sie werden in der AggregateParams-Instanz bereitgestellt und zum Skalieren des hinzugefügten Rauschens verwendet.

Ein Dienstprogrammparameter, der in der Instanz AggregateParams bereitgestellt und für alle Aggregationen anwendbar ist, ist der Parameter max_partitions_contributed. Eine Partition entspricht einem Schlüssel der Daten, die vom PipelineDP-Aggregationsvorgang zurückgegeben werden. Daher beschränkt der Parameter max_partitions_contributed die Anzahl der unterschiedlichen Schlüssel/Wert-Paare, die ein Nutzer zur Ausgabe beitragen kann. Wenn ein Nutzer zu einer Anzahl von Schlüsseln beitragen, die den Wert des Parameters max_partitions_contributed überschreitet, werden einige Beiträge verworfen, sodass sie zum genauen Wert des Parameters max_partitions_contributed beitragen.

Ebenso haben die meisten Aggregationen einen max_contributions_per_partition-Parameter. Sie werden auch in der AggregateParams-Instanz bereitgestellt und jede Aggregation kann eigene Werte haben. Sie haben den Beitrag eines Nutzers für jeden Schlüssel gebunden.

Das der Ausgabe hinzugefügte Rauschen wird durch die Parameter max_partitions_contributed und max_contributions_per_partition skaliert, daher gibt es hier einen Nachteil: Je höher die Werte für jeden Parameter zugewiesen sind, desto mehr Daten bleiben erhalten, das Ergebnis ist jedoch ungenauer.

Einige Aggregationen erfordern die Parameter min_value und max_value, die die Grenzen für Beiträge der einzelnen Nutzer festlegen. Wenn ein Nutzer einen Wert beiträgt, der niedriger ist als der Wert, der dem Parameter min_value zugewiesen ist, wird der Wert auf den Wert des Parameters erhöht. Wenn ein Nutzer einen Wert beiträgt, der größer als der Wert des Parameters max_value ist, wird der Wert auf den Wert des Parameters verringert. Wenn Sie mehr der ursprünglichen Werte beibehalten möchten, müssen Sie größere Grenzen angeben. Rauschen wird anhand der Größe der Grenzen skaliert, sodass Sie mit größeren Grenzen mehr Daten behalten können, aber ein verrauschteres Ergebnis erhalten.

Schließlich unterstützt der Parameter noise_kind zwei verschiedene Rauschmechanismen in PipelineDP: GAUSSIAN- und LAPLACE-Rauschen. Die LAPLACE-Verteilung bietet einen besseren Nutzen mit niedrigen Beitragsgrenzen, weshalb PipelineDP sie standardmäßig verwendet. Wenn Sie jedoch ein GAUSSIAN-Verteilungsrauschen verwenden möchten, können Sie es in der AggregateParams-Instanz angeben.

9. Glückwunsch

Gut gemacht! Sie haben das PipelineDP-Codelab abgeschlossen und viel über Differential Privacy und PipelineDP gelernt.

Weitere Informationen