Tính toán số liệu thống kê riêng tư bằng PipelineDP

1. Trước khi bắt đầu

Bạn có thể cho rằng số liệu thống kê tổng hợp không làm lộ bất kỳ thông tin nào về cá nhân mà họ có liên quan. Tuy nhiên, có nhiều cách để kẻ tấn công có thể biết được thông tin nhạy cảm về các cá nhân từ số liệu thống kê tổng hợp.

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo số liệu thống kê riêng tư bằng các dữ liệu tổng hợp riêng tư khác biệt từ PipelineDP để bảo vệ dữ liệu cá nhân quyền riêng tư. PipelineDP là một khung Python cho phép bạn áp dụng sự riêng tư biệt lập cho các tập dữ liệu lớn bằng các hệ thống xử lý hàng loạt, chẳng hạn như Apache SparkApache Beam. Để biết thêm thông tin về cách tính toán các số liệu thống kê riêng tư khác biệt trong Go (Tiếp tục), hãy xem lớp học lập trình Quyền riêng tư trên truyền.

Riêng tư có nghĩa là dữ liệu đầu ra được tạo sao cho không làm rò rỉ thông tin riêng tư nào về các cá nhân trong dữ liệu. Bạn có thể đạt được kết quả này thông qua sự riêng tư biệt lập, một khái niệm mạnh mẽ về quyền riêng tư là ẩn danh, đây là quá trình tổng hợp dữ liệu giữa nhiều người dùng để bảo vệ quyền riêng tư của người dùng. Mọi phương thức ẩn danh đều sử dụng phương thức tổng hợp, nhưng không phải phương thức tổng hợp nào cũng làm được việc ẩn danh. Mặt khác, sự riêng tư biệt lập cung cấp các đảm bảo có thể đo lường được về việc rò rỉ thông tin và quyền riêng tư.

Điều kiện tiên quyết

  • Quen thuộc với Python
  • Quen thuộc với tổng hợp dữ liệu cơ bản
  • Trải nghiệm với gấu trúc, tia sáng và tia lửa

Kiến thức bạn sẽ học được

  • Kiến thức cơ bản về sự riêng tư biệt lập
  • Cách tính số liệu thống kê tóm tắt riêng tư khác biệt bằng PipelineDP
  • Cách tinh chỉnh kết quả bằng các thông số bổ sung về quyền riêng tư và tiện ích

Bạn cần có

  • Nếu muốn chạy lớp học lập trình này trong môi trường của riêng mình, bạn cần cài đặt Python 3.7 trở lên trên máy tính.
  • Nếu muốn tham gia lớp học lập trình mà không cần môi trường riêng, bạn cần có quyền truy cập vào Colaboratory.

2. Tìm hiểu về sự riêng tư biệt lập

Để hiểu rõ hơn về sự riêng tư biệt lập, hãy xem ví dụ đơn giản này.

Hãy tưởng tượng rằng bạn làm việc trong bộ phận tiếp thị của một cửa hàng bán lẻ thời trang trực tuyến và bạn muốn biết sản phẩm nào có nhiều khả năng bán được nhất.

Biểu đồ này cho biết những sản phẩm mà khách hàng đã xem trước tiên khi truy cập vào trang web của cửa hàng: áo thun, áo thun, tất hoặc quần jean. Áo phông là mặt hàng phổ biến nhất, còn tất là mặt hàng ít phổ biến nhất.

ea813c698889a4c6.png

Việc này có vẻ hữu ích, nhưng có một điểm bất lợi. Khi bạn muốn xem xét thêm thông tin, chẳng hạn như liệu khách hàng có mua hàng hay không hoặc sản phẩm nào họ đã xem thứ hai, bạn có nguy cơ tiết lộ các cá nhân trong dữ liệu của mình.

Biểu đồ này cho bạn thấy rằng chỉ có một khách hàng xem một người nhảy trước tiên rồi sau đó thực sự mua hàng:

b7c6f7f891778366.png

Điều này không tốt từ góc độ quyền riêng tư. Số liệu thống kê ẩn danh không được tiết lộ nội dung đóng góp của từng cá nhân, vậy bạn sẽ làm gì? Bạn thêm tạp âm ngẫu nhiên vào biểu đồ thanh để giảm độ chính xác của biểu đồ một chút!

Biểu đồ thanh này không hoàn toàn chính xác nhưng vẫn hữu ích và không thể hiện các đóng góp riêng lẻ:

b55e8d7f99f6d574.gif

Sự riêng tư biệt lập là việc bổ sung độ nhiễu ngẫu nhiên phù hợp để che giấu những nội dung đóng góp riêng lẻ.

Ví dụ này được đơn giản hoá quá mức. Việc triển khai đúng cách cơ chế sự riêng tư biệt lập sẽ phức tạp hơn và đi kèm với một số chi tiết triển khai ngoài dự kiến. Tương tự như mật mã học, việc tạo phương thức triển khai sự riêng tư biệt lập của riêng bạn có thể không phải là ý tưởng hay. Thay vào đó, bạn có thể sử dụng PipelineDP.

3. Tải xuống và cài đặt PipelineDP

Bạn không cần cài đặt PipelineDP theo lớp học lập trình này vì bạn có thể tìm thấy mọi mã và biểu đồ có liên quan trong tài liệu này.

Để chơi bằng PipelineDP, hãy tự chạy hoặc sử dụng vào lúc khác:

  • Tải xuống và cài đặt PipelineDP:
pip install pipeline-dp

Nếu bạn muốn chạy ví dụ bằng cách sử dụng Apache Beam:

  • Tải xuống và cài đặt Apache Beam:
pip install apache_beam

Bạn có thể tìm thấy mã cho lớp học lập trình này và tập dữ liệu trong thư mục PipelineDP/examples/codelab/.

4. Tính toán chỉ số lượt chuyển đổi cho mỗi sản phẩm đầu tiên được xem

Hãy tưởng tượng rằng bạn làm việc tại một nhà bán lẻ thời trang trực tuyến và bạn muốn biết danh mục sản phẩm nào của mình tạo ra số lượng và giá trị lượt chuyển đổi cao nhất khi được xem đầu tiên. Bạn muốn chia sẻ thông tin này với công ty tiếp thị của mình cũng như các nhóm nội bộ khác, nhưng muốn ngăn chặn việc rò rỉ thông tin về bất kỳ khách hàng cá nhân nào.

Cách tính chỉ số lượt chuyển đổi cho mỗi sản phẩm đầu tiên được xem đối với trang web:

  1. Xem tập dữ liệu mô phỏng về lượt truy cập vào trang web của bạn trong thư mục PipelineDP/examples/codelab/.

Ảnh chụp màn hình này là một ví dụ về tập dữ liệu. Trường này chứa mã nhận dạng người dùng, các sản phẩm mà người dùng đã xem, liệu khách truy cập có chuyển đổi hay không và giá trị của lượt chuyển đổi (nếu có).

user_id

product_view_0

product_view_1

product_view_2

product_view_3

product_view_4

has_conversion

conversion_value

0

quần jean

t_shirt

t_shirt

không có

không có

false

0,0

1

quần jean

t_shirt

quần jean

áo liền quần

không có

false

0,0

2

t_shirt

áo liền quần

t_shirt

t_shirt

không có

đúng

105,19

3

t_shirt

t_shirt

quần jean

không có

không có

false

0,0

4

t_shirt

bít tất

quần jean

quần jean

không có

false

0,0

Bạn quan tâm đến các chỉ số sau:

  • view_counts: Số lần khách truy cập trang web của bạn nhìn thấy từng sản phẩm đầu tiên.
  • total_conversion_value: Tổng số tiền mà khách truy cập chi tiêu khi họ chuyển đổi.
  • conversion_rate: Tỷ lệ khách truy cập chuyển đổi.
  1. Tạo chỉ số theo cách không riêng tư:
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)

Như bạn đã tìm hiểu trước đó, các số liệu thống kê này có thể tiết lộ thông tin về các cá nhân trong tập dữ liệu của bạn. Ví dụ: chỉ có một người chuyển đổi sau khi người đó nhìn thấy người nhảy trước tiên. Đối với 22 lượt xem, tỷ lệ chuyển đổi của bạn là khoảng 0,05. Bây giờ, bạn cần chuyển đổi từng biểu đồ thanh thành một biểu đồ riêng tư.

  1. Xác định các tham số về quyền riêng tư bằng lớp pipeline_dp.NaiveBudgetAccountant, sau đó chỉ định các đối số epsilondelta mà bạn muốn sử dụng cho bản phân tích của mình.

Cách bạn đặt các đối số này tuỳ thuộc vào vấn đề cụ thể của bạn. Để tìm hiểu thêm về các thông số này, hãy xem phần Không bắt buộc: Chỉnh sửa tham số vi phân về sự riêng tư.

Đoạn mã này sử dụng các giá trị mẫu:

budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=1e-5)
  1. Khởi động thực thể LocalBackend:
ops = pipeline_dp.LocalBackend()

Bạn có thể dùng thực thể LocalBackend vì bạn chạy chương trình này cục bộ mà không cần khung bổ sung, chẳng hạn như Beam hoặc Spark.

  1. Khởi động thực thể DPEngine:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)

PipelineDP cho phép bạn chỉ định thêm tham số thông qua lớp pipeline_dp.AggregateParams, điều này ảnh hưởng đến việc tạo số liệu thống kê riêng tư của bạn.

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. Chỉ định rằng bạn muốn tính toán chỉ số count và sử dụng hệ số phân phối độ nhiễu LAPLACE.
  2. Đặt đối số max_partitions_contributed thành giá trị 1.

Đối số này giới hạn số lượt truy cập khác nhau mà một người dùng có thể đóng góp. Bạn muốn người dùng truy cập vào trang web một lần mỗi ngày và bạn không quan tâm liệu họ có truy cập vào trang web đó nhiều lần trong ngày hay không.

  1. Đặt đối số max_contributions_per_partitions thành giá trị 1.

Đối số này xác định số lượng đóng góp mà một khách truy cập có thể thực hiện cho một phân vùng riêng lẻ hoặc danh mục sản phẩm trong trường hợp này.

  1. Tạo một thực thể data_extractor chỉ định nơi cần tìm các trường privacy_id, partitionvalue.

Mã của bạn sẽ trông giống như đoạn mã sau:

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. Thêm mã này để chuyển đổi Pandas DataFrame của bạn thành danh sách các hàng mà từ đó bạn có thể trực tiếp tính toán số liệu thống kê riêng tư khác biệt:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)

Xin chúc mừng! Bạn đã tính toán số liệu thống kê riêng tư khác biệt đầu tiên của mình!

Biểu đồ này hiển thị kết quả của số lượt xem video riêng tư khác biệt bên cạnh số lượt xem video không riêng tư mà bạn đã tính trước đó:

a5a25a00858219ab.png

Biểu đồ thanh mà bạn nhận được khi chạy mã có thể khác với biểu đồ thanh này. Điều này là bình thường. Do nhiễu trong sự riêng tư biệt lập, bạn sẽ nhận được một biểu đồ thanh khác mỗi lần chạy mã này. Tuy nhiên, bạn có thể thấy rằng các biểu đồ này giống với biểu đồ thanh ban đầu không phải là biểu đồ riêng tư.

Xin lưu ý rằng để đảm bảo quyền riêng tư, điều quan trọng là bạn không được chạy quy trình nhiều lần. Để biết thêm thông tin, hãy xem phần Tính toán nhiều số liệu thống kê.

5. Sử dụng phân vùng công khai

Trong phần trước, bạn có thể nhận thấy rằng bạn đã bỏ tất cả dữ liệu về lượt truy cập cho một phân vùng, cụ thể là những khách truy cập đã nhìn thấy tất trên trang web của bạn lần đầu tiên.

Điều này là do việc chọn phân vùng hoặc đặt ngưỡng. Đây là một bước quan trọng để đảm bảo sự đảm bảo sự riêng tư biệt lập khi sự tồn tại của các phân vùng đầu ra phụ thuộc vào chính dữ liệu người dùng. Trong trường hợp này, việc chỉ tồn tại một phân vùng trong dữ liệu đầu ra có thể làm rò rỉ sự tồn tại của một người dùng riêng lẻ trong dữ liệu. Để tìm hiểu thêm về lý do khiến nội dung này vi phạm quyền riêng tư, hãy xem bài đăng này trên blog. Để ngăn chặn lỗi vi phạm về quyền riêng tư này, PipelineDP chỉ giữ lại những phân vùng có đủ số lượng người dùng.

Khi danh sách các phân vùng đầu ra không phụ thuộc vào dữ liệu riêng tư của người dùng, thì bạn không cần bước lựa chọn phân vùng này. Đây thực sự là trường hợp cho ví dụ của bạn vì bạn biết tất cả các danh mục sản phẩm có thể có mà khách hàng có thể nhìn thấy đầu tiên.

Cách sử dụng phân vùng:

  1. Tạo danh sách các phân vùng có thể có:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
  1. Truyền danh sách này vào hàm run_pipeline() để đặt hàm này làm dữ liệu đầu vào bổ sung cho lớp pipeline_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)

Nếu sử dụng phân vùng công khai và nhiễu LAPLACE, thì bạn có thể đặt đối số total_delta thành giá trị 0.

Bây giờ, bạn sẽ thấy kết quả báo cáo dữ liệu cho tất cả các phân vùng hoặc sản phẩm.

a4f6302c8efcd5da.png

Phân vùng công khai không chỉ cho phép bạn giữ lại nhiều phân vùng hơn mà còn gây nhiễu gần bằng một nửa vì bạn không chi tiêu ngân sách quyền riêng tư cho việc lựa chọn phân vùng, do đó, sự khác biệt giữa số lượng phân vùng thô và riêng tư là ít hơn một chút so với lần chạy trước đó.

Có hai điều quan trọng cần lưu ý khi bạn sử dụng phân vùng công khai:

  • Hãy cẩn thận khi bạn lấy danh sách phân vùng từ dữ liệu thô. Nếu bạn không thực hiện việc này theo cách khác biệt về sự riêng tư, thì quy trình của bạn sẽ không còn cung cấp cơ chế đảm bảo sự riêng tư biệt lập nữa. Để biết thêm thông tin, hãy xem phần Nâng cao: Lấy phân vùng từ dữ liệu.
  • Nếu không có dữ liệu cho một số phân vùng công khai, bạn cần áp dụng nhiễu cho những phân vùng đó để bảo toàn sự riêng tư biệt lập. Ví dụ: Nếu bạn đã sử dụng một sản phẩm bổ sung như quần, dù sản phẩm đó không xuất hiện trong tập dữ liệu hoặc trên trang web của bạn, thì sản phẩm đó vẫn bị nhiễu và kết quả có thể cho thấy một số lượt truy cập vào các sản phẩm khi không có sản phẩm đó.

Nâng cao: Lấy phân vùng từ dữ liệu

Nếu chạy nhiều quá trình tổng hợp có cùng một danh sách phân vùng đầu ra không công khai trong cùng một quy trình, bạn có thể lấy danh sách các phân vùng một lần bằng phương thức dp_engine.select_private_partitions() và cung cấp các phân vùng cho mỗi quá trình tổng hợp dưới dạng đầu vào public_partitions. Việc này không chỉ an toàn về quyền riêng tư mà còn giúp bạn giảm bớt tạp âm vì bạn chỉ sử dụng ngân sách quyền riêng tư khi chọn phân vùng một lần cho toàn bộ quy trình.

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. Tính toán nhiều số liệu thống kê

Giờ thì bạn đã biết cách hoạt động của PipelineDP, bạn có thể xem cách sử dụng PipelineDP cho một số trường hợp sử dụng nâng cao hơn. Như đã đề cập ở phần đầu, bạn quan tâm đến 3 số liệu thống kê. PipelineDP cho phép bạn tính toán nhiều số liệu thống kê cùng lúc, miễn là các số liệu thống kê đó có cùng tham số trong thực thể AggregateParams mà bạn sẽ thấy sau này. Tính năng này không chỉ rõ ràng và dễ dàng hơn khi tính nhiều chỉ số một lần, mà còn tốt hơn về quyền riêng tư.

Nếu bạn còn nhớ các tham số epsilondelta mà bạn cung cấp cho lớp NaiveBudgetAccountant, thì các tham số này sẽ đại diện cho ngân sách quyền riêng tư. Đây là thước đo lượng thông tin về quyền riêng tư của người dùng mà bạn bị rò rỉ từ dữ liệu.

Một điều quan trọng cần nhớ về ngân sách quyền riêng tư là ngân sách bổ sung. Nếu bạn chạy quy trình với một epsilon "> và delta Indi cụ thể một lần, thì bạn sẽ chi tiêu một ngân sách là ( , ) . Nếu chạy lần thứ hai, bạn sẽ chi tiêu tổng ngân sách là (2, 23). Tương tự, nếu bạn tính toán nhiều số liệu thống kê bằng phương thức NaiveBudgetAccountant và liên tiếp nhau sử dụng ngân sách quyền riêng tư là ">,D", bạn sẽ chi tiêu tổng ngân sách là (2, 2 ). Điều này có nghĩa là bạn sẽ làm giảm mức độ đảm bảo về quyền riêng tư.

Để tránh né tránh tình trạng này, bạn cần sử dụng một phiên bản NaiveBudgetAccountant duy nhất có tổng ngân sách mà bạn muốn sử dụng khi cần tính toán nhiều số liệu thống kê trên cùng một dữ liệu. Sau đó, bạn cần chỉ định các giá trị epsilondelta mà bạn muốn dùng cho từng dữ liệu tổng hợp. Cuối cùng, bạn cuối cùng vẫn nhận được cùng một sự đảm bảo về quyền riêng tư tổng thể, nhưng giá trị epsilondelta càng cao mà một giá trị tổng hợp cụ thể có thì độ chính xác càng cao.

Để xem điều này trong thực tế, bạn có thể tính toán số liệu thống kê count, meansum.

Bạn tính toán thống kê dựa trên hai chỉ số khác nhau: chỉ số conversion_value mà bạn sử dụng để dự đoán doanh thu được tạo ra dựa trên sản phẩm được xem đầu tiên và chỉ số has_conversion dùng để tính số lượng khách truy cập vào trang web của bạn và tỷ lệ chuyển đổi trung bình.

Đối với mỗi chỉ số, bạn cần chỉ định riêng các thông số hướng dẫn cách tính toán số liệu thống kê riêng tư. Bạn chia ngân sách quyền riêng tư thành hai chỉ số. Bạn tính toán hai số liệu thống kê từ chỉ số has_conversion, do đó, bạn muốn chỉ định 2/3 ngân sách ban đầu và chỉ định 1/3 còn lại cho chỉ số conversion_value.

Để tính toán nhiều số liệu thống kê:

  1. Thiết lập kế toán ngân sách về quyền riêng tư với tổng giá trị epsilondelta mà bạn muốn sử dụng trên 3 số liệu thống kê:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=0)
  1. Khởi động DPEngine để tính toán chỉ số:
 dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
  1. Chỉ định các thông số cho chỉ số này.
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)

Đối số cuối cùng chỉ định trọng số của ngân sách quyền riêng tư (không bắt buộc). Bạn có thể gán cùng một trọng số cho tất cả, nhưng muốn thiết lập đối số này là 1/3 như đã giải thích trước đó.

Bạn cũng thiết lập đối số min_valuemax_value để chỉ định giới hạn dưới và giới hạn trên áp dụng cho một giá trị do một đơn vị quyền riêng tư đóng góp trong một phân vùng. Đây là các tham số bắt buộc khi bạn muốn tính tổng hoặc giá trị trung bình riêng. Bạn sẽ không muốn có giá trị âm, vì vậy, bạn có thể giả định 0100 là giới hạn hợp lý.

  1. Trích xuất dữ liệu liên quan rồi truyền dữ liệu đó vào hàm tổng hợp:
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. Hãy làm theo các bước tương tự để tính hai chỉ số này dựa trên biến 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))

Thay đổi duy nhất là trong thực thể pipeline_dp.AggregateParams, trong đó bạn hiện xác định meancount làm dữ liệu tổng hợp và chỉ định 2/3 ngân sách quyền riêng tư cho phép tính này. Vì bạn muốn có cùng giới hạn đóng góp cho cả hai số liệu thống kê, đồng thời tính toán các giới hạn này trên cùng một biến has_conversion, nên bạn có thể kết hợp các giới hạn này trong cùng một phiên bản pipeline_dp.AggregateParams và tính toán các số liệu này cùng một lúc.

  1. Gọi phương thức budget_accountant.compute_budgets():
budget_accountant.compute_budgets()

Bạn có thể vẽ biểu đồ của cả ba số liệu thống kê riêng tư này so với số liệu thống kê ban đầu. Tuỳ thuộc vào độ nhiễu được thêm vào, bạn sẽ thấy kết quả có thể thực sự nằm ngoài thang đo hợp lý. Trong trường hợp này, bạn sẽ thấy tỷ lệ chuyển đổi âm và tổng giá trị chuyển đổi cho người nhảy vì độ nhiễu được thêm vào là đối xứng quanh 0. Để phân tích và xử lý thêm, tốt nhất bạn không nên xử lý số liệu thống kê riêng tư theo cách thủ công, nhưng nếu muốn thêm biểu đồ đó vào báo cáo, bạn có thể chỉ cần đặt giá trị tối thiểu là 0 sau đó mà không vi phạm chính sách đảm bảo quyền riêng tư.

cb1fc563f817eaf.png

7. Chạy đường ống bằng Tia

Ngày nay, việc xử lý dữ liệu đòi hỏi bạn phải xử lý một lượng dữ liệu khổng lồ, nhiều đến mức bạn không thể xử lý cục bộ. Thay vào đó, nhiều người sử dụng các khung để xử lý dữ liệu trên quy mô lớn, chẳng hạn như Beam hoặc Spark và chạy quy trình của họ trên đám mây.

PipelineDP hỗ trợ Beam và Spark chỉ với những thay đổi nhỏ đối với mã của bạn.

Cách chạy quy trình bằng Beam với API private_beam:

  1. Khởi chạy biến runner, rồi tạo quy trình, trong đó bạn áp dụng các hoạt động về quyền riêng tư cho bản trình bày Tia của rows:
runner = fn_api_runner.FnApiRunner()  # local runner

with beam.Pipeline(runner=runner) as pipeline:
   beam_data = pipeline | beam.Create(rows)
  1. Tạo biến budget_accountant bằng các tham số bắt buộc về quyền riêng tư:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
               total_epsilon=1, total_delta=0)
  1. Tạo biến pcol, hay còn gọi là bộ sưu tập riêng tư, giúp đảm bảo rằng mọi dữ liệu tổng hợp đều tuân thủ các yêu cầu về quyền riêng tư của bạn:
pcol = beam_data | pbeam.MakePrivate(
                                 budget_accountant=budget_accountant,
                                 privacy_id_extractor=lambda 
                                                    row: row.user_id)
  1. Chỉ định các tham số của dữ liệu tổng hợp riêng tư trong lớp thích hợp.

Ở đây, bạn sử dụng lớp pipeline_dp.aggregate_params.SumParams() để tính tổng số lượt xem sản phẩm.

  1. Truyền các tham số tổng hợp đến phương thức pbeam.Sum để tính toán số liệu thống kê của bạn:
dp_result = pcol | pbeam.Sum(params)
  1. Cuối cùng, mã của bạn sẽ trông giống như đoạn mã sau:
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. Không bắt buộc: Chỉnh sửa các tham số về quyền riêng tư và phần mềm tiện ích

Bạn đã thấy khá nhiều tham số được đề cập trong lớp học lập trình này, chẳng hạn như các tham số epsilon, deltamax_partitions_contributed. Bạn có thể chia gần đúng chúng thành 2 loại: thông số về quyền riêng tưthông số tiện ích.

Tham số về quyền riêng tư

Các tham số epsilondelta định lượng sự riêng tư mà bạn cung cấp thông qua cơ chế sự riêng tư biệt lập. Chính xác hơn, đây là chỉ số đo lường lượng thông tin mà kẻ tấn công tiềm ẩn có thể thu được về dữ liệu từ dữ liệu đầu ra ẩn danh. Giá trị tham số càng cao thì kẻ tấn công càng thu thập được nhiều thông tin về dữ liệu và đây là một rủi ro về quyền riêng tư. Mặt khác, giá trị của các tham số epsilondelta càng thấp thì bạn càng cần thêm nhiều tạp âm vào kết quả để ẩn danh, đồng thời bạn cần càng nhiều người dùng riêng biệt trong mỗi phân vùng để giữ cho họ trong kết quả ẩn danh. Trong trường hợp này, sẽ có sự đánh đổi giữa tiện ích và quyền riêng tư.

Trong PipelineDP, bạn cần chỉ định cam kết đảm bảo quyền riêng tư mong muốn của mình đối với đầu ra ẩn danh khi đặt tổng ngân sách quyền riêng tư trong thực thể NaiveBudgetAccountant. Xin lưu ý rằng nếu muốn giữ nguyên cam kết về quyền riêng tư, bạn cần cẩn thận sử dụng một thực thể NaiveBudgetAccountant riêng biệt cho mỗi dữ liệu tổng hợp hoặc chạy quy trình nhiều lần để tránh việc sử dụng quá mức ngân sách.

Để biết thêm thông tin về sự riêng tư biệt lập và ý nghĩa của các tham số về quyền riêng tư, hãy xem Danh sách đọc về sự riêng tư biệt lập.

Tham số về phần mềm tiện ích

Tham số tiện ích không ảnh hưởng đến đảm bảo về quyền riêng tư nhưng ảnh hưởng đến độ chính xác và do đó, làm giảm tính hữu ích của kết quả. Các thành phần này được cung cấp trong thực thể AggregateParams và dùng để tăng độ nhiễu.

Một tham số hiệu dụng được cung cấp trong thực thể AggregateParams và áp dụng cho tất cả các dữ liệu tổng hợp là tham số max_partitions_contributed. Một phân vùng tương ứng với một khoá của dữ liệu mà thao tác tổng hợp PipelineDP trả về, do đó, tham số max_partitions_contributed sẽ giới hạn số lượng giá trị khoá riêng biệt mà người dùng có thể đóng góp cho kết quả. Nếu người dùng đóng góp số lượng khoá vượt quá giá trị của tham số max_partitions_contributed, thì một số giá trị đóng góp sẽ bị loại bỏ để đóng góp vào giá trị chính xác của tham số max_partitions_contributed.

Tương tự, hầu hết các hàm tổng hợp đều có tham số max_contributions_per_partition. Các tham số này cũng được cung cấp trong thực thể AggregateParams và mỗi hàm tổng hợp có thể có các giá trị riêng. Các khoá này ràng buộc mức đóng góp của người dùng cho mỗi khoá.

Độ nhiễu được thêm vào đầu ra được điều chỉnh theo các tham số max_partitions_contributedmax_contributions_per_partition, vì vậy, sẽ có một sự đánh đổi: Giá trị lớn hơn được gán cho mỗi tham số có nghĩa là bạn giữ được nhiều dữ liệu hơn, nhưng bạn sẽ nhận được kết quả nhiễu hơn.

Một số dữ liệu tổng hợp yêu cầu tham số min_valuemax_value. Các tham số này chỉ định giới hạn đối với sự đóng góp của từng người dùng. Nếu người dùng đóng góp một giá trị thấp hơn giá trị được gán cho thông số min_value, thì giá trị đó sẽ được tăng lên thành giá trị của thông số. Tương tự, nếu người dùng đóng góp một giá trị lớn hơn giá trị của thông số max_value, thì giá trị đó sẽ giảm xuống giá trị của thông số. Để giữ lại nhiều giá trị ban đầu hơn, bạn phải chỉ định giới hạn lớn hơn. Độ nhiễu được điều chỉnh theo kích thước của giới hạn, vì vậy, giới hạn lớn hơn cho phép bạn giữ lại nhiều dữ liệu hơn, nhưng cuối cùng bạn sẽ nhận được kết quả nhiễu hơn.

Cuối cùng, tham số noise_kind hỗ trợ 2 cơ chế nhiễu trong PipelineDP: nhiễu GAUSSIANLAPLACE. Việc phân phối LAPLACE mang lại lợi ích tốt hơn với giới hạn đóng góp thấp. Đó là lý do PipelineDP sử dụng theo mặc định. Tuy nhiên, nếu muốn sử dụng độ nhiễu phân phối GAUSSIAN, bạn có thể chỉ định độ nhiễu này trong thực thể AggregateParams.

9. Xin chúc mừng

Tuyệt vời! Bạn đã hoàn thành lớp học lập trình PipelineDP và tìm hiểu nhiều về sự riêng tư biệt lập và PipelineDP.

Tìm hiểu thêm