محاسبه آمار خصوصی با PipelineDP

1. قبل از شروع

ممکن است فکر کنید که آمارهای انبوه هیچ اطلاعاتی را در مورد افرادی که به آنها مربوط می شود درز نمی دهد. با این حال، راه‌های زیادی وجود دارد که مهاجم می‌تواند اطلاعات حساس افراد را از آمارهای جمع‌آوری کند.

در این کد لبه، یاد می گیرید که چگونه آمار خصوصی را با تجمیع خصوصی متفاوت از PipelineDP برای محافظت از حریم خصوصی افراد تولید کنید. PipelineDP یک چارچوب پایتون است که به شما امکان می دهد حریم خصوصی دیفرانسیل را برای مجموعه داده های بزرگ با سیستم های پردازش دسته ای، مانند Apache Spark و Apache Beam اعمال کنید. برای اطلاعات بیشتر در مورد نحوه محاسبه آمار خصوصی متفاوت در Go ، به بخش Privacy on Beam codelab مراجعه کنید.

خصوصی به این معنی است که خروجی به گونه ای تولید می شود که هیچ اطلاعات خصوصی در مورد افراد موجود در داده ها درز نمی کند. شما می توانید این نتیجه را از طریق حریم خصوصی متمایز ، یک مفهوم قوی حریم خصوصی از ناشناس سازی ، که فرآیند جمع آوری داده ها در چندین کاربر برای محافظت از حریم خصوصی کاربر است، به دست آورید. همه روش‌های ناشناس‌سازی از تجمیع استفاده می‌کنند، اما همه روش‌های تجمع به بی‌نام‌سازی نمی‌رسند. از سوی دیگر، حریم خصوصی متفاوت، تضمین های قابل اندازه گیری در مورد نشت اطلاعات و حریم خصوصی ارائه می دهد.

پیش نیازها

  • آشنایی با پایتون
  • آشنایی با تجمیع داده های اولیه
  • تجربه با پانداها، اسپارک و بیم

چیزی که یاد خواهید گرفت

  • اصول اولیه حریم خصوصی دیفرانسیل
  • نحوه محاسبه آمار خلاصه خصوصی متفاوت با PipelineDP
  • چگونه نتایج خود را با پارامترهای بیشتر حریم خصوصی و ابزار تغییر دهید

آنچه شما نیاز دارید

  • اگر می‌خواهید کد لبه را در محیط شخصی خود اجرا کنید، باید پایتون 3.7 یا بالاتر را روی رایانه‌تان نصب کنید.
  • اگر می‌خواهید بدون محیط شخصی خود، کد لبه را دنبال کنید، باید به Colaboratory دسترسی داشته باشید.

2. حریم خصوصی دیفرانسیل را درک کنید

برای درک بهتر حریم خصوصی دیفرانسیل، به این مثال ساده نگاه کنید.

تصور کنید که در بخش بازاریابی یک خرده فروش مد آنلاین کار می کنید و می خواهید بفهمید کدام یک از محصولات شما بیشتر به فروش می رسد.

این نمودار نشان می دهد که مشتریان هنگام بازدید از وب سایت فروشگاه ابتدا به کدام محصولات نگاه می کردند: تی شرت، جامپر، جوراب یا شلوار جین. تی شرت ها محبوب ترین اجناس هستند در حالی که جوراب ها کمترین محبوبیت را دارند.

ea813c698889a4c6.png

این به نظر مفید است، اما یک نکته وجود دارد. وقتی می‌خواهید اطلاعات بیشتری را در نظر بگیرید، مانند اینکه آیا مشتریان خریدی انجام داده‌اند یا محصولی را که در مرحله دوم مشاهده کرده‌اند، در معرض خطر افشای افراد در داده‌های خود هستید.

این نمودار به شما نشان می دهد که فقط یک مشتری ابتدا به یک جامپر نگاه کرده و سپس در واقع خرید کرده است:

b7c6f7f891778366.png

این از منظر حریم خصوصی عالی نیست. آمارهای ناشناس نباید مشارکت های فردی را نشان دهد، پس چه می کنید؟ شما نویز تصادفی را به نمودارهای میله ای خود اضافه می کنید تا کمی دقت آنها را کاهش دهید!

این نمودار میله‌ای کاملاً دقیق نیست، اما همچنان مفید است و مشارکت‌های فردی را نشان نمی‌دهد:

b55e8d7f99f6d574.gif

حریم خصوصی دیفرانسیل اضافه کردن مقدار مناسبی از نویز تصادفی برای پنهان کردن مشارکت های فردی است.

این مثال بیش از حد ساده شده است. اجرای صحیح حریم خصوصی دیفرانسیل بیشتر دخیل است و با تعدادی از ظرافت های اجرایی غیرمنتظره همراه است. مشابه رمزنگاری، ممکن است ایده خوبی نباشد که پیاده‌سازی حریم خصوصی متفاوت را ایجاد کنید. در عوض، می توانید از PipelineDP استفاده کنید.

3. PipelineDP را دانلود و نصب کنید

شما نیازی به نصب PipelineDP از این کد لبه ندارید زیرا می توانید تمام کدها و نمودارهای مربوطه را در این سند پیدا کنید.

برای بازی با PipelineDP، خودتان آن را اجرا کنید یا بعداً از آن استفاده کنید:

  • PipelineDP را دانلود و نصب کنید:
pip install pipeline-dp

اگر می خواهید مثال را با استفاده از Apache Beam اجرا کنید:

  • Apache Beam را دانلود و نصب کنید:
pip install apache_beam

می‌توانید کد این codelab و مجموعه داده را در فهرست PipelineDP/examples/codelab/ پیدا کنید.

4. معیارهای تبدیل را برای اولین محصول مشاهده شده محاسبه کنید

تصور کنید که در یک خرده‌فروش مد آنلاین کار می‌کنید و می‌خواهید بفهمید که کدام یک از دسته‌های مختلف محصولات شما، بیشترین تعداد و ارزش تبدیل‌ها را در ابتدا ایجاد می‌کنند. شما می خواهید این اطلاعات را با آژانس بازاریابی خود و همچنین سایر تیم های داخلی به اشتراک بگذارید، اما می خواهید از درز اطلاعات در مورد هر مشتری فردی جلوگیری کنید.

برای محاسبه معیارهای تبدیل به ازای اولین محصول مشاهده شده برای وب سایت:

  1. مجموعه داده ساختگی بازدیدهای وب سایت خود را در فهرست PipelineDP/examples/codelab/ مرور کنید.

این اسکرین شات نمونه ای از مجموعه داده است. این شامل شناسه کاربر، محصولاتی است که کاربر مشاهده کرده است، آیا بازدیدکننده تبدیل کرده است یا خیر، و اگر چنین است، ارزش تبدیل.

user_id

product_view_0

product_view_1

product_view_2

product_view_3

product_view_4

دارای_تبدیل

conversion_value

0

شلوار جین

تی شرت

تی شرت

هیچ کدام

هیچ کدام

نادرست

0.0

1

شلوار جین

تی شرت

شلوار جین

جامپر

هیچ کدام

نادرست

0.0

2

تی شرت

جامپر

تی شرت

تی شرت

هیچ کدام

درست است

105.19

3

تی شرت

تی شرت

شلوار جین

هیچ کدام

هیچ کدام

نادرست

0.0

4

تی شرت

جوراب

شلوار جین

شلوار جین

هیچ کدام

نادرست

0.0

شما به این معیارها علاقه دارید:

  • view_counts : تعداد دفعاتی که بازدیدکنندگان وب سایت شما ابتدا هر محصول را می بینند.
  • total_conversion_value : کل مبلغی که بازدیدکنندگان هنگام تبدیل خرج می کنند.
  • conversion_rate : نرخی که بازدیدکنندگان با آن تبدیل می کنند.
  1. معیارها را به روشی غیر خصوصی ایجاد کنید:
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)

همانطور که قبلاً یاد گرفتید، این آمار می تواند اطلاعاتی را درباره افراد موجود در مجموعه داده شما نشان دهد. به عنوان مثال، تنها یک نفر بعد از اینکه شخص ابتدا یک جامپر را دید، تبدیل شد. برای 22 بازدید، نرخ تبدیل شما تقریبا 0.05 است. اکنون باید هر نمودار میله ای را به یک نمودار خصوصی تبدیل کنید.

  1. پارامترهای حریم خصوصی خود را با کلاس pipeline_dp.NaiveBudgetAccountant تعریف کنید و سپس آرگومان های epsilon و delta را که می خواهید برای تجزیه و تحلیل خود استفاده کنید، مشخص کنید.

نحوه تنظیم این استدلال ها به مشکل خاص شما بستگی دارد. برای کسب اطلاعات بیشتر در مورد آنها، به اختیاری مراجعه کنید: پارامترهای دیفرانسیل-حریم خصوصی را تغییر دهید.

این قطعه کد از مقادیر نمونه استفاده می کند:

budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=1e-5)
  1. نمونه LocalBackend را راه اندازی کنید:
ops = pipeline_dp.LocalBackend()

می توانید از نمونه LocalBackend استفاده کنید زیرا این برنامه را به صورت محلی و بدون فریمورک های اضافی مانند Beam یا Spark اجرا می کنید.

  1. نمونه DPEngine راه اندازی کنید:
dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)

PipelineDP به شما امکان می دهد پارامترهای بیشتری را از طریق کلاس pipeline_dp.AggregateParams تعیین کنید، که بر تولید آمار خصوصی شما تأثیر می گذارد.

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. مشخص کنید که می خواهید متریک count را محاسبه کنید و از توزیع نویز LAPLACE استفاده کنید.
  2. آرگومان max_partitions_contributed را روی 1 مقدار تنظیم کنید.

این آرگومان تعداد بازدیدهای مختلف را که یک کاربر می تواند مشارکت داشته باشد محدود می کند. شما انتظار دارید کاربران یک بار در روز از وب سایت بازدید کنند و برای شما مهم نیست که چندین بار در طول روز از آن بازدید کنند.

  1. آرگومان max_contributions_per_partitions را روی 1 مقدار تنظیم کنید.

این آرگومان مشخص می‌کند که یک بازدیدکننده می‌تواند در این مورد چند مشارکت در یک پارتیشن یا یک دسته محصول داشته باشد.

  1. یک نمونه data_extractor ایجاد کنید که محل پیدا کردن فیلدهای privacy_id ، partition و value مشخص کند.

کد شما باید شبیه این قطعه کد باشد:

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. این کد را اضافه کنید تا Pandas DataFrame خود را به لیستی از ردیف‌هایی تبدیل کنید که می‌توانید مستقیماً آمار خصوصی متفاوت را محاسبه کنید:
rows = [index_row[1] for index_row in df.iterrows()]
dp_result_local = run_pipeline(rows, ops) # Returns generator
list(dp_result_local)

تبریک می گویم! شما اولین آمار خصوصی متفاوت خود را محاسبه کردید!

این نمودار نتیجه تعداد متفاوت خصوصی شما را در کنار تعداد غیرخصوصی که قبلاً محاسبه کرده اید نشان می دهد:

a5a25a00858219ab.png

نمودار میله‌ای که هنگام اجرای کد دریافت می‌کنید ممکن است با این نمودار متفاوت باشد، که اشکالی ندارد. به دلیل نویز در حریم خصوصی دیفرانسیل، هر بار که کد را اجرا می‌کنید، نمودار میله‌ای متفاوتی دریافت می‌کنید، اما می‌توانید ببینید که آنها شبیه نمودار میله‌ای غیرخصوصی اصلی هستند.

لطفاً توجه داشته باشید که برای تضمین حریم خصوصی بسیار مهم است که به خاطر تضمین حفظ حریم خصوصی، خط لوله را چندین بار اجرا نکنید. برای اطلاعات بیشتر، به محاسبه آمار چندگانه مراجعه کنید.

5. از پارتیشن های عمومی استفاده کنید

در بخش قبل، ممکن است متوجه شده باشید که تمام اطلاعات بازدیدهای یک پارتیشن را حذف کرده اید، یعنی بازدیدکنندگانی که برای اولین بار جوراب را در وب سایت شما دیدند.

این به دلیل انتخاب پارتیشن یا آستانه گذاری است، که گام مهمی برای اطمینان از تضمین حریم خصوصی متفاوت است، زمانی که وجود پارتیشن های خروجی به خود داده های کاربر بستگی دارد. در این حالت، صرف وجود یک پارتیشن در خروجی می‌تواند وجود یک کاربر را در داده‌ها لو دهد. برای اطلاعات بیشتر در مورد اینکه چرا این امر حریم خصوصی را نقض می کند، به این پست وبلاگ مراجعه کنید. برای جلوگیری از این نقض حریم خصوصی، PipelineDP فقط پارتیشن هایی را با تعداد کافی کاربر در آنها نگه می دارد.

هنگامی که لیست پارتیشن های خروجی به داده های کاربر خصوصی بستگی ندارد، به این مرحله انتخاب پارتیشن نیازی ندارید. این در واقع در مورد مثال شما صدق می کند زیرا شما همه دسته بندی های محصول ممکن را می دانید که یک مشتری می تواند ابتدا ببیند.

برای استفاده از پارتیشن:

  1. لیستی از پارتیشن های احتمالی خود ایجاد کنید:
public_partitions_products = ['jeans', 'jumper', 'socks', 't-shirt']
  1. لیست را به تابع run_pipeline() ارسال کنید، که آن را به عنوان ورودی اضافی برای کلاس 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)

اگر از پارتیشن‌های عمومی و نویز LAPLACE استفاده می‌کنید، می‌توانید آرگومان total_delta را روی مقدار 0 تنظیم کنید.

اکنون در نتیجه مشاهده می کنید که داده های همه پارتیشن ها یا محصولات گزارش می شود.

a4f6302c8efcd5da.png

پارتیشن‌های عمومی نه تنها به شما امکان می‌دهند پارتیشن‌های بیشتری را نگه دارید، بلکه تقریباً نیمی از نویز را نیز اضافه می‌کنند، زیرا هیچ بودجه حفظ حریم خصوصی را برای انتخاب پارتیشن صرف نمی‌کنید، بنابراین تفاوت بین تعداد خام و خصوصی در مقایسه با اجرای قبلی کمی کمتر است.

هنگام استفاده از پارتیشن های عمومی دو نکته مهم وجود دارد که باید در نظر داشته باشید:

  • وقتی لیست پارتیشن ها را از داده های خام استخراج می کنید مراقب باشید. اگر این کار را به روش خصوصی متفاوت انجام ندهید، خط لوله شما دیگر ضمانت‌های حریم خصوصی متفاوت را ارائه نمی‌کند. برای اطلاعات بیشتر، به Advanced: استخراج پارتیشن ها از داده ها مراجعه کنید.
  • اگر هیچ داده ای برای برخی از پارتیشن های عمومی وجود ندارد، برای حفظ حریم خصوصی دیفرانسیل باید نویز را روی آن پارتیشن ها اعمال کنید. به عنوان مثال، اگر از یک محصول اضافی مانند شلوار استفاده کرده‌اید که در مجموعه داده یا وب‌سایت شما وجود ندارد، همچنان نویز است و نتایج ممکن است برخی از بازدیدها از محصولات را در حالی که وجود نداشته باشد نشان دهد.

پیشرفته: پارتیشن ها را از داده ها استخراج کنید

اگر چندین تجمیع را با لیست یکسانی از پارتیشن‌های خروجی غیر عمومی در یک خط لوله اجرا کنید، می‌توانید فهرست پارتیشن‌ها را یک بار با متد dp_engine.select_private_partitions() استخراج کنید و پارتیشن‌ها را به عنوان ورودی public_partitions به هر تجمعی ارائه کنید. این نه تنها از منظر حریم خصوصی ایمن است، بلکه به شما امکان می دهد نویز کمتری اضافه کنید زیرا فقط یک بار برای کل خط لوله از بودجه حفظ حریم خصوصی در انتخاب پارتیشن استفاده می کنید.

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. آمارهای متعدد را محاسبه کنید

اکنون که می دانید PipelineDP چگونه کار می کند، می توانید ببینید که چگونه می توانید از آن برای موارد استفاده پیشرفته تر استفاده کنید. همانطور که در ابتدا ذکر شد، شما به سه آمار علاقه مند هستید. PipelineDP به شما امکان می دهد چندین آمار را همزمان محاسبه کنید تا زمانی که پارامترهای مشابهی در نمونه AggregateParams دارند که بعداً مشاهده خواهید کرد. نه تنها محاسبه چندین معیار در یک حرکت تمیزتر و آسانتر است، بلکه از نظر حریم خصوصی نیز بهتر است.

اگر پارامترهای epsilon و delta را که به کلاس NaiveBudgetAccountant ارائه می‌دهید به خاطر داشته باشید، آنها چیزی به نام بودجه حریم خصوصی را نشان می‌دهند که معیاری است برای میزان حریم خصوصی کاربر که از داده‌ها درز می‌کنید.

نکته مهمی که باید در مورد بودجه حفظ حریم خصوصی به خاطر بسپارید این است که افزودنی است. اگر خط لوله ای را با اپسیلون ε و دلتا δ خاص یک بار اجرا کنید، بودجه ای (ε,δ) خرج می کنید. اگر برای بار دوم آن را اجرا کنید، کل بودجه (2ε, 2δ) را خرج می کنید. به طور مشابه، اگر چندین آمار را با روش NaiveBudgetAccountant و به طور متوالی بودجه حفظ حریم خصوصی ε,δ محاسبه کنید، کل بودجه (2ε, 2δ) را خرج می کنید. این به این معنی است که شما ضمانت‌های حفظ حریم خصوصی را کاهش می‌دهید.

برای دور زدن این موضوع، باید از یک نمونه NaiveBudgetAccountant با کل بودجه ای که می خواهید برای محاسبه آمارهای متعدد بر روی یک داده استفاده کنید، استفاده کنید. سپس باید مقادیر epsilon و delta را که می خواهید برای هر تجمع استفاده کنید، مشخص کنید. در نهایت، شما با همان ضمانت حفظ حریم خصوصی کلی مواجه می‌شوید، اما هر چه مقادیر epsilon و delta بالاتری که یک مجموعه خاص داشته باشد، دقت بالاتری دارد.

برای مشاهده عملی این، می توانید آمار count ، mean و sum را محاسبه کنید.

شما آمار را بر روی دو معیار مختلف محاسبه می‌کنید: یک متریک conversion_value که از آن برای استنباط میزان درآمد تولید شده بر اساس محصولی که ابتدا مشاهده می‌شود، و یک معیار has_conversion که برای محاسبه تعداد بازدیدکنندگان وب‌سایت خود استفاده می‌کنید، استفاده می‌کنید. میانگین نرخ تبدیل

برای هر متریک، باید پارامترهایی را که محاسبه آمار خصوصی را هدایت می کنند، جداگانه مشخص کنید. شما بودجه حریم خصوصی خود را در دو معیار تقسیم می کنید. شما دو آمار را از معیار has_conversion محاسبه می کنید، بنابراین می خواهید دو سوم بودجه اولیه خود را به آن اختصاص دهید و یک سوم دیگر را به متریک conversion_value اختصاص دهید.

برای محاسبه آمار چندگانه:

  1. حسابدار بودجه حریم خصوصی خود را با مقادیر کل epsilon و delta تنظیم کنید که می خواهید در سه آمار استفاده کنید:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
     total_epsilon=1, total_delta=0)
  1. DPEngine برای محاسبه معیارهای خود راه اندازی کنید:
 dp_engine = pipeline_dp.DPEngine(budget_accountant, ops)
  1. پارامترهای این متریک را مشخص کنید.
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)

آخرین آرگومان به صورت اختیاری وزن بودجه حریم خصوصی شما را مشخص می کند. شما می توانید وزن یکسانی را برای همه قائل شوید، اما می خواهید این استدلال را همانطور که قبلا توضیح داده شد به یک سوم تنظیم کنید.

شما همچنین یک آرگومان min_value و max_value را برای تعیین کران پایین و بالای اعمال شده به مقداری که توسط واحد حریم خصوصی در یک پارتیشن اعمال می‌شود، تنظیم می‌کنید. این پارامترها زمانی مورد نیاز هستند که می خواهید یک مجموع خصوصی یا میانگین را محاسبه کنید. شما انتظار مقادیر منفی را ندارید، بنابراین می توانید 0 و 100 به عنوان کران معقول فرض کنید.

  1. داده های مربوطه را استخراج کنید و سپس آن را به تابع تجمع ارسال کنید:
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. برای محاسبه دو معیار بر اساس متغیر 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))

تنها تغییر در نمونه pipeline_dp.AggregateParams است که در آن اکنون mean تعریف کرده و به عنوان تجمیع count و دو سوم بودجه حریم خصوصی خود را به این محاسبه اختصاص می دهید. از آنجایی که می‌خواهید برای هر دو آمار مرزهای مشارکت یکسانی داشته باشید و آنها را در بالای همان متغیر has_conversion محاسبه کنید، می‌توانید آن‌ها را در یک نمونه pipeline_dp.AggregateParams ترکیب کرده و همزمان محاسبه کنید.

  1. متد budget_accountant.compute_budgets() را فراخوانی کنید:
budget_accountant.compute_budgets()

شما می توانید هر سه آمار خصوصی را در مقایسه با آمار اصلی آنها ترسیم کنید. بسته به نویز اضافه شده، می بینید که نتایج در واقع خارج از مقیاس قابل قبول است. در این مثال، نرخ تبدیل منفی و ارزش تبدیل کل را برای جامپرها مشاهده می کنید زیرا نویز اضافه شده متقارن در حدود صفر است. برای تجزیه و تحلیل و پردازش بیشتر، بهتر است آمار خصوصی را به صورت دستی پردازش نکنید، اما اگر می‌خواهید این نمودارها را به گزارش اضافه کنید، می‌توانید پس از آن حداقل را بدون نقض ضمانت‌های حفظ حریم خصوصی روی صفر قرار دهید.

cb1fc563f817eaf.png

7. خط لوله را با Beam اجرا کنید

امروزه پردازش داده ها به شما نیاز دارد که با حجم عظیمی از داده ها سروکار داشته باشید، به طوری که نمی توانید آنها را به صورت محلی پردازش کنید. در عوض، بسیاری از افراد از چارچوب‌هایی برای پردازش داده‌های بزرگ مقیاس مانند Beam یا Spark استفاده می‌کنند و خطوط لوله خود را در فضای ابری اجرا می‌کنند.

PipelineDP از Beam و Spark فقط با تغییرات کوچک در کد شما پشتیبانی می کند.

برای اجرای خط لوله با Beam با API private_beam :

  1. یک متغیر runner را راه‌اندازی کنید و سپس یک خط لوله ایجاد کنید که در آن عملیات حریم خصوصی خود را برای نمایش Beam از rows خود اعمال کنید:
runner = fn_api_runner.FnApiRunner()  # local runner

with beam.Pipeline(runner=runner) as pipeline:
   beam_data = pipeline | beam.Create(rows)
  1. یک متغیر budget_accountant با پارامترهای حریم خصوصی مورد نیاز خود ایجاد کنید:
budget_accountant = pipeline_dp.NaiveBudgetAccountant(
               total_epsilon=1, total_delta=0)
  1. یک متغیر pcol یا مجموعه خصوصی ایجاد کنید که تضمین می‌کند هر گونه تجمیع با الزامات حریم خصوصی شما مطابقت دارد:
pcol = beam_data | pbeam.MakePrivate(
                                 budget_accountant=budget_accountant,
                                 privacy_id_extractor=lambda 
                                                    row: row.user_id)
  1. پارامترهای تجمیع خصوصی خود را در کلاس مناسب مشخص کنید.

در اینجا، شما از کلاس pipeline_dp.aggregate_params.SumParams() استفاده می کنید زیرا مجموع بازدیدهای محصول را محاسبه می کنید.

  1. پارامترهای تجمع خود را به روش pbeam.Sum برای محاسبه آمار خود ارسال کنید:
dp_result = pcol | pbeam.Sum(params)
  1. در پایان، کد شما باید شبیه این قطعه کد باشد:
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. اختیاری: پارامترهای حریم خصوصی و ابزار مفید را تغییر دهید

شما چندین پارامتر ذکر شده در این کد را مشاهده کرده اید، مانند پارامترهای epsilon ، delta و max_partitions_contributed . تقریباً می توانید آنها را به دو دسته تقسیم کنید: پارامترهای حریم خصوصی و پارامترهای ابزار .

پارامترهای حریم خصوصی

پارامترهای epsilon و delta حریم خصوصی را که با حریم خصوصی تفاضلی ارائه می‌کنید، کمیت می‌کنند. به طور دقیق تر، آنها معیاری هستند برای اینکه یک مهاجم بالقوه چقدر اطلاعات می تواند در مورد داده های خروجی ناشناس به دست آورد. هر چه مقدار پارامترها بیشتر باشد، مهاجم اطلاعات بیشتری در مورد داده ها به دست می آورد که خطر حفظ حریم خصوصی است. از طرف دیگر، هر چه مقدار پارامترهای epsilon و delta کمتر باشد، باید نویز بیشتری به خروجی اضافه کنید تا آن را ناشناس کنید و تعداد کاربران منحصربه‌فردی که در هر پارتیشن برای نگه داشتن آن‌ها در حالت ناشناس نیاز دارید، بیشتر می‌شود. خروجی در این مورد، یک معاوضه بین ابزار و حریم خصوصی وجود دارد.

در PipelineDP، زمانی که کل بودجه حریم خصوصی را در نمونه NaiveBudgetAccountant تنظیم می کنید، باید تضمین های حریم خصوصی مورد نظر خود را برای خروجی ناشناس خود مشخص کنید. هشدار این است که اگر می‌خواهید تضمین‌های حریم خصوصی شما حفظ شود، باید به دقت از یک نمونه NaiveBudgetAccountant جداگانه برای هر تجمیع استفاده کنید یا خط لوله را چندین بار اجرا کنید تا از استفاده بیش از حد از بودجه خود جلوگیری کنید.

برای اطلاعات بیشتر در مورد حریم خصوصی دیفرانسیل و معنای پارامترهای حریم خصوصی، به فهرست خواندن در مورد حریم خصوصی تفاوت مراجعه کنید.

پارامترهای سودمند

پارامترهای Utility بر ضمانت‌های حفظ حریم خصوصی تأثیر نمی‌گذارند، اما بر دقت و در نتیجه، سودمندی خروجی تأثیر می‌گذارند. آنها در نمونه AggregateParams ارائه شده اند و برای مقیاس نویز اضافه شده استفاده می شوند.

یک پارامتر کاربردی ارائه شده در نمونه AggregateParams و قابل اجرا برای همه ادغام ها، پارامتر max_partitions_contributed است. یک پارتیشن مربوط به کلید داده ای است که توسط عملیات جمع آوری PipelineDP بازگردانده می شود، بنابراین پارامتر max_partitions_contributed تعداد مقادیر کلیدی متمایز را که کاربر می تواند در خروجی مشارکت دهد محدود می کند. اگر کاربر در تعدادی از کلیدها مشارکت کند که از مقدار پارامتر max_partitions_contributed بیشتر است، برخی از مشارکت‌ها حذف می‌شوند تا به مقدار دقیق پارامتر max_partitions_contributed کمک کنند.

به طور مشابه، اکثر تجمیع ها دارای یک پارامتر max_contributions_per_partition هستند. آنها همچنین در نمونه AggregateParams ارائه شده اند و هر تجمیع می تواند مقادیر جداگانه ای برای آنها داشته باشد. آنها سهم یک کاربر را برای هر کلید مقید کردند.

نویز اضافه شده به خروجی با پارامترهای max_partitions_contributed و max_contributions_per_partition مقیاس‌بندی می‌شود، بنابراین در اینجا یک مبادله وجود دارد: مقادیر بزرگ‌تر اختصاص داده‌شده به هر پارامتر به این معنی است که داده‌های بیشتری را نگه می‌دارید، اما نتیجه پر سر و صدای بیشتری دریافت می‌کنید.

برخی از تجمیع‌ها به پارامتر min_value و max_value نیاز دارند که مرزهای مشارکت هر کاربر را مشخص می‌کند. اگر کاربر مقداری کمتر از مقدار اختصاص داده شده به پارامتر min_value ارائه دهد، مقدار به مقدار پارامتر افزایش می یابد. به طور مشابه، اگر یک کاربر مقداری بزرگتر از مقدار پارامتر max_value ارائه دهد، مقدار به مقدار پارامتر کاهش می یابد. برای حفظ بیشتر مقادیر اصلی، باید کران های بزرگتری را مشخص کنید. نویز بر اساس اندازه مرزها مقیاس بندی می شود، بنابراین مرزهای بزرگتر به شما امکان می دهد داده های بیشتری را نگه دارید، اما در نهایت نتیجه نویزتری خواهید داشت.

در نهایت، پارامتر noise_kind از دو مکانیسم مختلف نویز در PipelineDP پشتیبانی می‌کند: نویز GAUSSIAN و LAPLACE . توزیع LAPLACE ابزار بهتری را با محدودیت های مشارکت کم ارائه می دهد، به همین دلیل است که PipelineDP به طور پیش فرض از آن استفاده می کند. با این حال، اگر می خواهید از نویز توزیع GAUSSIAN استفاده کنید، می توانید آن را در نمونه AggregateParams مشخص کنید.

9. تبریک می گویم

کار عالی! شما Codelab PipelineDP را تمام کردید و چیزهای زیادی در مورد حریم خصوصی دیفرانسیل و PipelineDP یاد گرفتید.

بیشتر بدانید