Differential Privacy erweitern

In diesem Dokument wird anhand von Beispielen gezeigt, wie Sie Differential Privacy für den differenziellen Datenschutz in BigQuery erweitern.

Mit BigQuery können Sie differenziellen Datenschutz (Differential Privacy) auf Multi-Cloud-Datenquellen und externe Differential-Privacy-Bibliotheken erweitern. Dieses Dokument enthält Beispiele für die Anwendung von differentiellem Datenschutz für Multi-Cloud-Datenquellen wie AWS S3 mit BigQuery Omni, für den Aufruf einer externen Differential-Privacy-Bibliothek über eine Remote-Funktion und für die Durchführung von Differential-Privacy-Aggregationen mit PipelineDP, einer Python-Bibliothek, die mit Apache Spark und Apache Beam ausgeführt werden kann.

Weitere Informationen zum differenziellen Datenschutz finden Sie unter Differential Privacy verwenden.

Differential Privacy mit BigQuery Omni

BigQuery Differential Privacy unterstützt Aufrufe an Multi-Cloud-Datenquellen wie AWS S3. Im folgenden Beispiel wird eine externe Datenquelle (foo.wikidata) abgefragt und der Differential Privacy-Mechanismus angewendet. Weitere Informationen zur Syntax der differenziellen Datenschutzklausel finden Sie im Abschnitt zur Differenziellen Datenschutzklausel.

SELECT
  WITH
    DIFFERENTIAL_PRIVACY
      OPTIONS (
        epsilon = 1,
        delta = 1e-5,
        privacy_unit_column = foo.wikidata.es_description)
      COUNT(*) AS results
FROM foo.wikidata;

Dieses Beispiel gibt Ergebnisse wie die folgenden zurück:

-- These results will change each time you run the query.
+----------+
| results  |
+----------+
| 3465     |
+----------+

Weitere Informationen zu BigQuery Omni-Limits finden Sie unter Einschränkungen.

Externe Differential-Privacy-Bibliotheken mit Remote-Funktionen aufrufen

Sie können externe Differential-Privacy-Bibliotheken mit Remote-Funktionen aufrufen. Über den folgenden Link wird eine Remote-Funktion verwendet, um eine externe, von Tumult Analytics gehostete Bibliothek aufzurufen, um null-konzentrierten differenziellen Datenschutz für ein Verkaufs-Dataset im Einzelhandel zu nutzen.

Informationen zur Arbeit mit Tumult Analytics finden Sie im Tumult Analytics-Einführungsbeitrag.

Differential-Privacy-Aggregationen mit PipelineDP

PipelineDP ist eine Python-Bibliothek, die differenzielle Datenschutzaggregationen durchführt und mit Apache Spark und Apache Beam ausgeführt werden kann. BigQuery kann gespeicherte Prozeduren von Apache Spark ausführen, die in Python geschrieben sind. Weitere Informationen zum Ausführen von gespeicherten Apache Spark-Prozeduren finden Sie unter Mit gespeicherten Prozeduren für Apache Spark arbeiten.

Im folgenden Beispiel wird eine Differential-Privacy-Aggregation mithilfe der PipelineDP-Bibliothek durchgeführt. Sie verwendet das öffentliche Dataset von Chicago Taxi Trips und berechnet für jedes Taxi die Anzahl der Fahrten sowie die Summe und den Mittelwert der Trinkgelder für diese Fahrten.

Hinweise

Ein Apache Spark-Standard-Image enthält PipelineDP nicht. Sie müssen ein Docker erstellen, das alle erforderlichen Abhängigkeiten enthält, bevor Sie eine gespeicherte PipelineDP-Prozedur ausführen. In diesem Abschnitt wird beschrieben, wie Sie ein Docker-Image erstellen und an Google Cloud übertragen.

Bevor Sie beginnen, müssen Sie Docker auf Ihrem lokalen Computer installiert haben und die Authentifizierung zum Übertragen von Docker-Images an gcr.io einrichten. Weitere Informationen zum Übertragen von Docker-Images finden Sie unter Images hoch- und herunterladen.

Docker-Image erstellen und übertragen

So erstellen und senden Sie ein Docker-Image per Push-Verfahren mit den erforderlichen Abhängigkeiten:

  1. Erstellen Sie einen lokalen Ordner DIR.
  2. Laden Sie das Miniconda-Installationsprogramm mit der Python 3.9-Version in DIR herunter.
  3. Speichern Sie den folgenden Text im Dockerfile.

    
      # Debian 11 is recommended.
      FROM debian:11-slim
    
      # Suppress interactive prompts
      ENV DEBIAN_FRONTEND=noninteractive
    
      # (Required) Install utilities required by Spark scripts.
      RUN apt update && apt install -y procps tini libjemalloc2
    
      # Enable jemalloc2 as default memory allocator
      ENV LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2
    
      # Install and configure Miniconda3.
      ENV CONDA_HOME=/opt/miniconda3
      ENV PYSPARK_PYTHON=${CONDA_HOME}/bin/python
      ENV PATH=${CONDA_HOME}/bin:${PATH}
      COPY Miniconda3-py39_23.1.0-1-Linux-x86_64.sh .
      RUN bash Miniconda3-py39_23.1.0-1-Linux-x86_64.sh -b -p /opt/miniconda3 \
      && ${CONDA_HOME}/bin/conda config --system --set always_yes True \
      && ${CONDA_HOME}/bin/conda config --system --set auto_update_conda False \
      && ${CONDA_HOME}/bin/conda config --system --prepend channels conda-forge \
      && ${CONDA_HOME}/bin/conda config --system --set channel_priority strict
    
      # The following packages are installed in the default image, it is
      # strongly recommended to include all of them.
      RUN apt install -y python3
      RUN apt install -y python3-pip
      RUN apt install -y libopenblas-dev
      RUN pip install \
        cython \
        fastavro \
        fastparquet \
        gcsfs \
        google-cloud-bigquery-storage \
        google-cloud-bigquery[pandas] \
        google-cloud-bigtable \
        google-cloud-container \
        google-cloud-datacatalog \
        google-cloud-dataproc \
        google-cloud-datastore \
        google-cloud-language \
        google-cloud-logging \
        google-cloud-monitoring \
        google-cloud-pubsub \
        google-cloud-redis \
        google-cloud-spanner \
        google-cloud-speech \
        google-cloud-storage \
        google-cloud-texttospeech \
        google-cloud-translate \
        google-cloud-vision \
        koalas \
        matplotlib \
        nltk \
        numba \
        numpy \
        orc \
        pandas \
        pyarrow \
        pysal \
        regex \
        requests \
        rtree \
        scikit-image \
        scikit-learn \
        scipy \
        seaborn \
        sqlalchemy \
        sympy \
        tables \
        virtualenv
      RUN pip install --no-input pipeline-dp==0.2.0
    
      # (Required) Create the 'spark' group/user.
      # The GID and UID must be 1099. Home directory is required.
      RUN groupadd -g 1099 spark
      RUN useradd -u 1099 -g 1099 -d /home/spark -m spark
      USER spark
    
  4. Führen Sie den folgenden Befehl aus:

    
    IMAGE=gcr.io/PROJECT_ID/DOCKER_IMAGE:0.0.1
    # Build and push the image.
    docker build -t "${IMAGE}"
    docker push "${IMAGE}"
    

    Ersetzen Sie Folgendes:

    • PROJECT_ID: das Projekt, in dem Sie das Docker-Image erstellen möchten.
    • DOCKER_IMAGE: der Name des Docker-Images.

    Das Image wird hochgeladen.

Gespeicherte Prozedur für PipelineDP ausführen

  1. Verwenden Sie zum Erstellen einer gespeicherten Prozedur die Anweisung CREATE PROCEDURE.

    CREATE OR REPLACE
    PROCEDURE
      `PROJECT_ID.DATASET_ID.pipeline_dp_example_spark_proc`()
      WITH CONNECTION `PROJECT_ID.REGION.CONNECTION_ID`
    OPTIONS (
      engine = "SPARK",
      container_image= "gcr.io/PROJECT_ID/DOCKER_IMAGE")
    LANGUAGE PYTHON AS R"""
    from pyspark.sql import SparkSession
    import pipeline_dp
    
    def compute_dp_metrics(data, spark_context):
    budget_accountant = pipeline_dp.NaiveBudgetAccountant(total_epsilon=10,
                                                          total_delta=1e-6)
    backend = pipeline_dp.SparkRDDBackend(spark_context)
    
    # Create a DPEngine instance.
    dp_engine = pipeline_dp.DPEngine(budget_accountant, backend)
    
    params = pipeline_dp.AggregateParams(
        noise_kind=pipeline_dp.NoiseKind.LAPLACE,
        metrics=[
            pipeline_dp.Metrics.COUNT, pipeline_dp.Metrics.SUM,
            pipeline_dp.Metrics.MEAN],
        max_partitions_contributed=1,
        max_contributions_per_partition=1,
        min_value=0,
        # Tips that are larger than 100 will be clipped to 100.
        max_value=100)
    # Specify how to extract privacy_id, partition_key and value from an
    # element of the taxi dataset.
    data_extractors = pipeline_dp.DataExtractors(
        partition_extractor=lambda x: x.taxi_id,
        privacy_id_extractor=lambda x: x.unique_key,
        value_extractor=lambda x: 0 if x.tips is None else x.tips)
    
    # Run aggregation.
    dp_result = dp_engine.aggregate(data, params, data_extractors)
    budget_accountant.compute_budgets()
    dp_result = backend.map_tuple(dp_result, lambda pk, result: (pk, result.count, result.sum, result.mean))
    return dp_result
    
    spark = SparkSession.builder.appName("spark-pipeline-dp-demo").getOrCreate()
    spark_context = spark.sparkContext
    
    # Load data from BigQuery.
    taxi_trips = spark.read.format("bigquery") \
    .option("table", "bigquery-public-data:chicago_taxi_trips.taxi_trips") \
    .load().rdd
    dp_result = compute_dp_metrics(taxi_trips, spark_context).toDF(["pk", "count","sum", "mean"])
    # Saving the data to BigQuery
    dp_result.write.format("bigquery") \
    .option("writeMethod", "direct") \
    .save("DATASET_ID.TABLE_NAME")
    """;

    Ersetzen Sie Folgendes:

    • PROJECT_ID: das Projekt, in dem Sie die gespeicherte Prozedur erstellen möchten.
    • DATASET_ID: das Dataset, in dem Sie die gespeicherte Prozedur erstellen möchten.
    • REGION: die Region, in der sich das Projekt befindet.
    • DOCKER_IMAGE: der Name des Docker-Images.
    • CONNECTION_ID: der Name der Verbindung.
    • TABLE_NAME: der Name der Tabelle.
  2. Verwenden Sie die Anweisung CALL, um die Prozedur aufzurufen.

    CALL `PROJECT_ID.DATASET_ID.pipeline_dp_example_spark_proc`()

    Ersetzen Sie Folgendes:

    • PROJECT_ID: das Projekt, in dem Sie die gespeicherte Prozedur erstellen möchten.
    • DATASET_ID: das Dataset, in dem Sie die gespeicherte Prozedur erstellen möchten.

Nächste Schritte