PipelineDP এর সাথে ব্যক্তিগত পরিসংখ্যান গণনা করুন

১. শুরু করার আগে

আপনার মনে হতে পারে যে সমষ্টিগত পরিসংখ্যান সংশ্লিষ্ট ব্যক্তিদের সম্পর্কে কোনো তথ্য ফাঁস করে না। তবে, এমন অনেক উপায় আছে যার মাধ্যমে একজন আক্রমণকারী সমষ্টিগত পরিসংখ্যান থেকে ব্যক্তিদের সম্পর্কে সংবেদনশীল তথ্য জানতে পারে।

এই কোডল্যাবে, আপনি শিখবেন কীভাবে PipelineDP থেকে ডিফারেনশিয়ালি প্রাইভেট অ্যাগ্রিগেশন ব্যবহার করে ব্যক্তিগত পরিসংখ্যান তৈরি করে ব্যক্তিদের গোপনীয়তা রক্ষা করা যায়। PipelineDP হলো একটি পাইথন ফ্রেমওয়ার্ক যা আপনাকে Apache Spark এবং Apache Beam- এর মতো ব্যাচ-প্রসেসিং সিস্টেম ব্যবহার করে বড় ডেটাসেটে ডিফারেনশিয়াল প্রাইভেসি প্রয়োগ করতে দেয়। Go- তে কীভাবে ডিফারেনশিয়ালি প্রাইভেট পরিসংখ্যান গণনা করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, Privacy on Beam কোডল্যাবটি দেখুন।

ব্যক্তিগত বলতে বোঝায় যে আউটপুটটি এমনভাবে তৈরি করা হয় যাতে ডেটার মধ্যে থাকা ব্যক্তিদের কোনো ব্যক্তিগত তথ্য ফাঁস না হয়। আপনি ডিফারেনশিয়াল প্রাইভেসি-র মাধ্যমে এই ফলাফল অর্জন করতে পারেন, যা অ্যানোনিমাইজেশনের একটি শক্তিশালী গোপনীয়তার ধারণা। অ্যানোনিমাইজেশন হলো ব্যবহারকারীর গোপনীয়তা রক্ষার জন্য একাধিক ব্যবহারকারীর ডেটা একত্রিত করার একটি প্রক্রিয়া। সমস্ত অ্যানোনিমাইজেশন পদ্ধতিই ডেটা একত্রিতকরণ ব্যবহার করে, কিন্তু সব পদ্ধতিই অ্যানোনিমাইজেশন অর্জন করতে পারে না। অন্যদিকে, ডিফারেনশিয়াল প্রাইভেসি তথ্য ফাঁস এবং গোপনীয়তা সম্পর্কে পরিমাপযোগ্য নিশ্চয়তা প্রদান করে।

পূর্বশর্ত

  • পাইথনের সাথে পরিচিতি
  • প্রাথমিক ডেটা একত্রীকরণের সাথে পরিচিতি
  • পান্ডাস, স্পার্ক এবং বিম-এর অভিজ্ঞতা

আপনি যা শিখবেন

  • ডিফারেনশিয়াল প্রাইভেসি
  • PipelineDP ব্যবহার করে ডিফারেনশিয়ালি প্রাইভেট সামারি স্ট্যাটিস্টিকস কীভাবে গণনা করবেন
  • অতিরিক্ত গোপনীয়তা এবং ইউটিলিটি প্যারামিটার ব্যবহার করে কীভাবে আপনার ফলাফল পরিবর্তন করবেন

আপনার যা যা লাগবে

  • আপনি যদি আপনার নিজের পরিবেশে কোডল্যাবটি চালাতে চান, তাহলে আপনার কম্পিউটারে পাইথন ৩.৭ বা তার উচ্চতর সংস্করণ ইনস্টল করা থাকতে হবে।
  • আপনি যদি নিজের পরিবেশ ছাড়া কোডল্যাবটি অনুসরণ করতে চান, তাহলে আপনার কোলাবোরেটরি -তে প্রবেশাধিকার প্রয়োজন হবে।

২. ডিফারেনশিয়াল প্রাইভেসি বুঝুন

ডিফারেনশিয়াল প্রাইভেসি আরও ভালোভাবে বোঝার জন্য এই সহজ উদাহরণটি দেখুন।

ধরুন, আপনি একটি অনলাইন ফ্যাশন রিটেইলারের মার্কেটিং বিভাগে কাজ করেন এবং আপনি বুঝতে চান আপনার কোন পণ্যগুলো সবচেয়ে বেশি বিক্রি হওয়ার সম্ভাবনা রয়েছে।

এই চার্টটি দেখাচ্ছে যে, দোকানের ওয়েবসাইটে প্রবেশ করার পর গ্রাহকরা প্রথমে কোন পণ্যগুলো দেখেছিলেন: টি-শার্ট, জাম্পার, মোজা, নাকি জিন্স। টি-শার্ট হলো সবচেয়ে জনপ্রিয় পণ্য, অন্যদিকে মোজা হলো সবচেয়ে কম জনপ্রিয় পণ্য।

ea813c698889a4c6.png

এটা বেশ কাজের মনে হলেও, এর একটি সমস্যা আছে। যখন আপনি অতিরিক্ত তথ্য বিবেচনা করতে চান, যেমন গ্রাহকরা কোনো কেনাকাটা করেছেন কিনা বা তারা দ্বিতীয়বার কোন পণ্যটি দেখেছেন, তখন আপনার ডেটা থেকে ব্যক্তিদের পরিচয় প্রকাশ হয়ে যাওয়ার ঝুঁকি থাকে।

এই চার্টটি আপনাকে দেখাচ্ছে যে, মাত্র একজন গ্রাহক প্রথমে একটি জাম্পার দেখেছিলেন এবং তারপরেই সেটি কিনেছিলেন:

b7c6f7f891778366.png

গোপনীয়তার দৃষ্টিকোণ থেকে এটি ভালো নয়। পরিচয় গোপন রাখা পরিসংখ্যানে ব্যক্তিগত অবদান প্রকাশ পাওয়ার কথা নয়, তাহলে কী করা হয়? বার চার্টগুলোকে কিছুটা কম নির্ভুল করে তোলার জন্য আপনি সেগুলোতে এলোমেলো নয়েজ যোগ করেন!

এই বার চার্টটি পুরোপুরি নির্ভুল নয়, কিন্তু এটি এখনও দরকারী এবং এটি স্বতন্ত্র অবদান প্রকাশ করে না:

b55e8d7f99f6d574.gif

ডিফারেনশিয়াল প্রাইভেসি হলো স্বতন্ত্র অবদানকে আড়াল করার জন্য সঠিক পরিমাণে র‍্যান্ডম নয়েজ যোগ করা।

এই উদাহরণটি অতি সরলীকৃত। ডিফারেনশিয়াল প্রাইভেসি-র সঠিক বাস্তবায়ন আরও জটিল এবং এর সাথে বেশ কিছু অপ্রত্যাশিত ও সূক্ষ্ম বিষয় জড়িত। ক্রিপ্টোগ্রাফির মতোই, ডিফারেনশিয়াল প্রাইভেসি-র নিজস্ব বাস্তবায়ন তৈরি করাটা হয়তো বুদ্ধিমানের কাজ হবে না। এর পরিবর্তে, আপনি PipelineDP ব্যবহার করতে পারেন।

৩. PipelineDP ডাউনলোড এবং ইনস্টল করুন

এই কোডল্যাবটি অনুসরণ করার জন্য আপনার PipelineDP ইনস্টল করার প্রয়োজন নেই, কারণ সমস্ত প্রাসঙ্গিক কোড এবং গ্রাফ আপনি এই ডকুমেন্টটিতেই খুঁজে পাবেন।

PipelineDP নিয়ে কাজ করতে, এটি নিজে চালান, অথবা পরে ব্যবহার করুন:

  • PipelineDP ডাউনলোড এবং ইনস্টল করুন:
pip install pipeline-dp

আপনি যদি অ্যাপাচি বিম ব্যবহার করে উদাহরণটি চালাতে চান:

  • অ্যাপাচি বিম ডাউনলোড এবং ইনস্টল করুন:
pip install apache_beam

আপনি এই কোডল্যাবের কোড এবং ডেটাসেটটি PipelineDP/examples/codelab/ ডিরেক্টরিতে খুঁজে পাবেন।

৪. প্রথমবার দেখা প্রতিটি পণ্যের জন্য রূপান্তর মেট্রিক্স গণনা করুন।

ধরুন, আপনি একটি অনলাইন ফ্যাশন রিটেইলারে কাজ করেন এবং আপনি বুঝতে চান যে আপনার বিভিন্ন প্রোডাক্ট ক্যাটাগরির মধ্যে কোনটি প্রথমে দেখলে সবচেয়ে বেশি সংখ্যক ও মূল্যের কনভার্সন তৈরি করে। আপনি এই তথ্য আপনার মার্কেটিং এজেন্সির পাশাপাশি অন্যান্য অভ্যন্তরীণ টিমের সাথেও শেয়ার করতে চান, কিন্তু কোনো নির্দিষ্ট গ্রাহকের তথ্য ফাঁস হওয়া আটকাতে চান।

ওয়েবসাইটের জন্য প্রথম দেখা পণ্যের রূপান্তর মেট্রিক্স গণনা করতে:

  1. PipelineDP/examples/codelab/ ডিরেক্টরিতে থাকা আপনার ওয়েবসাইটের ভিজিটের মক ডেটাসেটটি পর্যালোচনা করুন।

এই স্ক্রিনশটটি ডেটাসেটের একটি উদাহরণ। এতে ব্যবহারকারীর আইডি, ব্যবহারকারীর দেখা পণ্যগুলো, পরিদর্শকটি ক্রয় সম্পন্ন করেছেন কিনা এবং যদি করে থাকেন, তবে সেই ক্রয়ের পরিমাণ রয়েছে।

ব্যবহারকারীর আইডি

পণ্য_ভিউ_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 ক্লাস ব্যবহার করে আপনার গোপনীয়তার প্যারামিটারগুলো নির্ধারণ করুন, এবং তারপর আপনার বিশ্লেষণের জন্য যে epsilondelta আর্গুমেন্টগুলো ব্যবহার করতে চান, তা নির্দিষ্ট করুন।

আপনি এই আর্গুমেন্টগুলো কীভাবে সেট করবেন তা আপনার নির্দিষ্ট সমস্যার উপর নির্ভর করে। এ সম্পর্কে আরও জানতে, দেখুন ঐচ্ছিক: ডিফারেনশিয়াল-প্রাইভেসি প্যারামিটারগুলো পরিবর্তন করুন।

এই কোড স্নিপেটে উদাহরণ মান ব্যবহার করা হয়েছে:

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

কোডটি চালালে আপনি যে বার চার্টটি পাবেন, তা এটির থেকে ভিন্ন হতে পারে, এবং তাতে কোনো সমস্যা নেই। ডিফারেনশিয়াল প্রাইভেসিতে থাকা নয়েজের কারণে, প্রতিবার কোডটি চালালে আপনি একটি ভিন্ন বার চার্ট পাবেন, কিন্তু আপনি দেখতে পারেন যে সেগুলো মূল নন-প্রাইভেট বার চার্টটির মতোই।

অনুগ্রহ করে মনে রাখবেন যে, গোপনীয়তা রক্ষার স্বার্থে পাইপলাইনটি একাধিকবার না চালানো অত্যন্ত গুরুত্বপূর্ণ। আরও তথ্যের জন্য, ‘একাধিক পরিসংখ্যান গণনা করুন’ দেখুন।

৫. পাবলিক পার্টিশন ব্যবহার করুন

পূর্ববর্তী অংশে, আপনি হয়তো লক্ষ্য করেছেন যে আপনি একটি পার্টিশনের সমস্ত ভিজিট ডেটা বাদ দিয়েছেন, অর্থাৎ সেইসব ভিজিটরদের, যারা আপনার ওয়েবসাইটে প্রথম সক্স দেখেছিল।

এর কারণ হলো পার্টিশন সিলেকশন বা থ্রেশহোল্ডিং, যা ডিফারেনশিয়াল-প্রাইভেসি নিশ্চয়তা প্রদানের জন্য একটি গুরুত্বপূর্ণ পদক্ষেপ, বিশেষত যখন আউটপুট পার্টিশনের অস্তিত্ব ব্যবহারকারীর ডেটার উপরই নির্ভর করে। এমন পরিস্থিতিতে, আউটপুটে শুধুমাত্র একটি পার্টিশনের অস্তিত্বই ডেটার মধ্যে থাকা কোনো একজন ব্যবহারকারীর পরিচয় ফাঁস করে দিতে পারে। এটি কেন গোপনীয়তা লঙ্ঘন করে সে সম্পর্কে আরও জানতে, এই ব্লগ পোস্টটি দেখুন। এই গোপনীয়তা লঙ্ঘন রোধ করতে, 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

পাবলিক পার্টিশন আপনাকে শুধু বেশি পার্টিশন রাখার সুযোগই দেয় না, বরং এটি প্রায় অর্ধেক পরিমাণ নয়েজও যোগ করে, কারণ পার্টিশন নির্বাচনের জন্য আপনি কোনো প্রাইভেসি বাজেট খরচ করেন না। ফলে, আগের বারের তুলনায় র এবং প্রাইভেট কাউন্টের মধ্যে পার্থক্য কিছুটা কম থাকে।

পাবলিক পার্টিশন ব্যবহার করার সময় দুটি গুরুত্বপূর্ণ বিষয় মনে রাখতে হবে:

  • কাঁচা ডেটা থেকে পার্টিশনের তালিকা তৈরি করার সময় সতর্ক থাকুন। যদি আপনি এটি ডিফারেনশিয়ালি প্রাইভেট পদ্ধতিতে না করেন, তাহলে আপনার পাইপলাইন আর ডিফারেনশিয়াল প্রাইভেসি নিশ্চয়তা প্রদান করবে না। আরও তথ্যের জন্য, দেখুন অ্যাডভান্সড: ডেটা থেকে পার্টিশন তৈরি করা।
  • যদি কিছু পাবলিক পার্টিশনের জন্য কোনো ডেটা না থাকে, তাহলে ডিফারেনশিয়াল প্রাইভেসি বজায় রাখার জন্য আপনাকে সেই পার্টিশনগুলোতে নয়েজ প্রয়োগ করতে হবে। উদাহরণস্বরূপ, যদি আপনি ট্রাউজারের মতো একটি অতিরিক্ত পণ্য ব্যবহার করেন, যা আপনার ডেটাসেটে বা আপনার ওয়েবসাইটে নেই, তাহলেও এটি একটি নয়েজ এবং এর ফলে ফলাফলে এমন কিছু ভিজিট দেখা যেতে পারে যেখানে বাস্তবে কোনো ভিজিট হয়নি।

উন্নত: ডেটা থেকে পার্টিশন তৈরি করুন

যদি আপনি একই পাইপলাইনে একই নন-পাবলিক আউটপুট পার্টিশনের তালিকা ব্যবহার করে একাধিক অ্যাগ্রিগেশন চালান, তাহলে আপনি 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 ইনস্ট্যান্সে একই প্যারামিটার থাকে, যা আপনি পরে দেখতে পাবেন। একবারে একাধিক মেট্রিক গণনা করা কেবল পরিচ্ছন্ন এবং সহজই নয়, এটি গোপনীয়তার দিক থেকেও ভালো।

আপনার যদি NaiveBudgetAccountant ক্লাসে সরবরাহ করা epsilon এবং delta প্যারামিটারগুলোর কথা মনে থাকে, তবে সেগুলো ‘প্রাইভেসি বাজেট’ নামক একটি বিষয়কে বোঝায়, যা ডেটা থেকে ব্যবহারকারীর গোপনীয়তার কী পরিমাণ ফাঁস হয় তার একটি পরিমাপ।

প্রাইভেসি বাজেট সম্পর্কে মনে রাখার মতো একটি গুরুত্বপূর্ণ বিষয় হলো এটি সংযোজনযোগ্য। যদি আপনি একটি নির্দিষ্ট এপসিলন ε এবং ডেল্টা δ দিয়ে কোনো পাইপলাইন একবার চালান, তাহলে আপনার (ε,δ) বাজেট খরচ হয়। যদি আপনি এটি দ্বিতীয়বার চালান, তাহলে আপনার মোট (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 উভয়কেই সাপোর্ট করে।

private_beam API ব্যবহার করে Beam-এর মাধ্যমে পাইপলাইনটি চালাতে:

  1. একটি runner ভেরিয়েবল ইনিশিয়ালাইজ করুন এবং তারপরে একটি পাইপলাইন তৈরি করুন যেখানে আপনি আপনার 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 প্যারামিটারের মানের চেয়ে বেশি মান অবদান রাখে, তবে মানটি কমিয়ে প্যারামিটারের মান করা হয়। মূল মানগুলোর বেশি অংশ ধরে রাখার জন্য, আপনাকে বৃহত্তর সীমা নির্দিষ্ট করতে হবে। নয়েজ সীমার আকারের সাথে সামঞ্জস্যপূর্ণ হয়, তাই বৃহত্তর সীমা আপনাকে আরও বেশি ডেটা ধরে রাখতে দেয়, কিন্তু এর ফলে আপনি একটি নয়েজি ফলাফল পাবেন।

অবশেষে, PipelineDP-তে noise_kind প্যারামিটারটি দুটি ভিন্ন নয়েজ মেকানিজম সমর্থন করে: GAUSSIAN এবং LAPLACE নয়েজ। LAPLACE ডিস্ট্রিবিউশনটি কম কন্ট্রিবিউশন বাউন্ডের সাথে আরও ভালো ইউটিলিটি প্রদান করে, যে কারণে PipelineDP ডিফল্টরূপে এটি ব্যবহার করে। তবে, আপনি যদি GAUSSIAN ডিস্ট্রিবিউশন নয়েজ ব্যবহার করতে চান, তাহলে AggregateParams ইনস্ট্যান্সে তা নির্দিষ্ট করে দিতে পারেন।

৯. অভিনন্দন

চমৎকার কাজ! তুমি PipelineDP কোডল্যাবটি শেষ করেছ এবং ডিফারেনশিয়াল প্রাইভেসি ও PipelineDP সম্পর্কে অনেক কিছু শিখেছ।

আরও জানুন