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

۱. قبل از شروع

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

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

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

پیش‌نیازها

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

آنچه یاد خواهید گرفت

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

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

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

۲. حریم خصوصی تفاضلی را درک کنید

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

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

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

ea813c698889a4c6.png

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

این نمودار به شما نشان می‌دهد که تنها یک مشتری ابتدا به یک ژاکت نگاه کرده و سپس واقعاً آن را خریداری کرده است:

b7c6f7f891778366.png

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

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

b55e8d7f99f6d574.gif

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

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

۳. دانلود و نصب PipelineDP

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

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

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

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

  • آپاچی بیم را دانلود و نصب کنید:
pip install apache_beam

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

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

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

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

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

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

شناسه_کاربر

نمای_محصول_0

نمای_محصول_1

نمای_محصول_2

نمای_محصول_3

نمای_محصول_4

has_conversion

مقدار تبدیل

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)

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

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

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

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

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 خود را به لیستی از ردیف‌ها تبدیل کنید که از طریق آنها می‌توانید مستقیماً آمار خصوصی تفاضلی را محاسبه کنید:
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

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

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

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

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

این به دلیل انتخاب پارتیشن یا آستانه‌گذاری است، گامی مهم برای تضمین حریم خصوصی تفاضلی زمانی که وجود پارتیشن‌های خروجی به خود داده‌های کاربر بستگی دارد. در این صورت، صرف وجود یک پارتیشن در خروجی می‌تواند وجود یک کاربر خاص در داده‌ها را فاش کند. برای کسب اطلاعات بیشتر در مورد اینکه چرا این امر حریم خصوصی را نقض می‌کند، به این پست وبلاگ مراجعه کنید. برای جلوگیری از این نقض حریم خصوصی، 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

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

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

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

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

اگر چندین تجمیع را با لیست یکسانی از پارتیشن‌های خروجی غیرعمومی در یک خط لوله اجرا کنید، می‌توانید لیست پارتیشن‌ها را یک بار با متد 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

۶. محاسبه آمار چندگانه

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

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

نکته مهمی که باید در مورد بودجه حریم خصوصی به خاطر داشته باشید این است که افزایشی است. اگر یک خط لوله را با یک اپسیلون ε و دلتا δ خاص یک بار اجرا کنید، بودجه (ε,δ) را خرج می‌کنید. اگر آن را برای بار دوم اجرا کنید، بودجه کل (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

۷. اجرای خط لوله با Beam

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

PipelineDP از Beam و Spark تنها با تغییرات کوچکی در کد شما پشتیبانی می‌کند.

برای اجرای pipeline با Beam با API private_beam :

  1. یک متغیر runner را مقداردهی اولیه کنید و سپس یک pipeline ایجاد کنید که در آن عملیات حریم خصوصی خود را روی یک نمایش 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)

۸. اختیاری: پارامترهای حریم خصوصی و کاربردی را تغییر دهید

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

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

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

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

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

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

پارامترهای کاربردی بر تضمین‌های حریم خصوصی تأثیری ندارند، اما بر دقت و در نتیجه، بر کاربرد خروجی تأثیر می‌گذارند. آن‌ها در نمونه 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 مشخص کنید.

۹. تبریک

کارت عالی بود! شما آزمایشگاه کد PipelineDP را تمام کردید و چیزهای زیادی در مورد حریم خصوصی تفاضلی و PipelineDP یاد گرفتید.

بیشتر بدانید