১. ভূমিকা
আপনার মনে হতে পারে যে সমষ্টিগত পরিসংখ্যান সেইসব ব্যক্তিদের সম্পর্কে কোনো তথ্য ফাঁস করে না, যাদের ডেটা দিয়ে এই পরিসংখ্যান গঠিত। তবে, একজন আক্রমণকারী বিভিন্ন উপায়ে একটি সমষ্টিগত পরিসংখ্যান থেকে কোনো ডেটাসেটের ব্যক্তিদের সম্পর্কে সংবেদনশীল তথ্য জানতে পারে।
ব্যক্তিদের গোপনীয়তা রক্ষা করার জন্য, আপনি Privacy on Beam থেকে ডিফারেনশিয়ালি প্রাইভেট অ্যাগ্রিগেশন ব্যবহার করে কীভাবে ব্যক্তিগত পরিসংখ্যান তৈরি করতে হয় তা শিখবেন। Privacy on Beam হলো একটি ডিফারেনশিয়াল প্রাইভেসি ফ্রেমওয়ার্ক যা Apache Beam-এর সাথে কাজ করে।
'ব্যক্তিগত' বলতে আমরা কী বুঝি?
এই কোডল্যাব জুড়ে 'প্রাইভেট' শব্দটি ব্যবহার করার মাধ্যমে আমরা বোঝাতে চাই যে, আউটপুটটি এমনভাবে তৈরি করা হয় যাতে ডেটার মধ্যে থাকা ব্যক্তিদের কোনো ব্যক্তিগত তথ্য ফাঁস না হয়। আমরা ডিফারেনশিয়াল প্রাইভেসি ব্যবহার করে এটি করতে পারি, যা অ্যানোনিমাইজেশনের একটি শক্তিশালী প্রাইভেসি ধারণা। অ্যানোনিমাইজেশন হলো ব্যবহারকারীর গোপনীয়তা রক্ষা করার জন্য একাধিক ব্যবহারকারীর ডেটা একত্রিত করার একটি প্রক্রিয়া। সমস্ত অ্যানোনিমাইজেশন পদ্ধতি অ্যাগ্রিগেশন ব্যবহার করে, কিন্তু সব অ্যাগ্রিগেশন পদ্ধতি অ্যানোনিমাইজেশন অর্জন করতে পারে না। অন্যদিকে, ডিফারেনশিয়াল প্রাইভেসি তথ্য ফাঁস এবং গোপনীয়তার বিষয়ে পরিমাপযোগ্য নিশ্চয়তা প্রদান করে।
২. ডিফারেনশিয়াল প্রাইভেসি ওভারভিউ
ডিফারেনশিয়াল প্রাইভেসি আরও ভালোভাবে বোঝার জন্য, আসুন একটি সহজ উদাহরণ দেখি।
এই বার চার্টটি একটি নির্দিষ্ট সন্ধ্যায় একটি ছোট রেস্তোরাঁর ব্যস্ততা দেখাচ্ছে। সন্ধ্যা ৭টায় অনেক অতিথি আসেন, এবং রাত ১টায় রেস্তোরাঁটি সম্পূর্ণ খালি হয়ে যায়:

এটা বেশ কাজের মনে হচ্ছে!
তবে একটা ব্যাপার আছে। যখন কোনো নতুন অতিথি আসেন , এই তথ্যটি বার চার্টের মাধ্যমে সঙ্গে সঙ্গে প্রকাশ হয়ে যায়। চার্টটির দিকে তাকান: এটা স্পষ্ট যে একজন নতুন অতিথি এসেছেন, এবং এই অতিথি আনুমানিক রাত ১টার দিকে এসেছেন।

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

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

ডিফারেনশিয়াল প্রাইভেসি হলো স্বতন্ত্র অবদানকে আড়াল করার জন্য সঠিক পরিমাণে এলোমেলো নয়েজ যোগ করা ।
আমাদের বিশ্লেষণটি কিছুটা অতিসরলীকৃত ছিল। ডিফারেনশিয়াল প্রাইভেসি সঠিকভাবে প্রয়োগ করা আরও জটিল এবং এর বেশ কিছু অপ্রত্যাশিত সূক্ষ্মতা রয়েছে। ক্রিপ্টোগ্রাফির মতোই, ডিফারেনশিয়াল প্রাইভেসি নিজের মতো করে প্রয়োগ করা হয়তো খুব ভালো বুদ্ধি নয়। নিজের সমাধান প্রয়োগ করার পরিবর্তে আপনি ‘প্রাইভেসি অন বিম’ (Privacy on Beam) ব্যবহার করতে পারেন। নিজের মতো করে ডিফারেনশিয়াল প্রাইভেসি তৈরি করবেন না!
এই কোডল্যাবে আমরা দেখাবো কিভাবে Privacy on Beam ব্যবহার করে ডিফারেনশিয়ালি প্রাইভেট অ্যানালাইসিস করা যায়।
৩. বিম-এ গোপনীয়তা ডাউনলোড করা
কোডল্যাবটি অনুসরণ করার জন্য আপনার Privacy on Beam ডাউনলোড করার প্রয়োজন নেই, কারণ সমস্ত প্রাসঙ্গিক কোড এবং গ্রাফ এই ডকুমেন্টটিতেই পাওয়া যাবে। তবে, আপনি যদি কোডটি নিয়ে কাজ করতে, নিজে এটি রান করতে অথবা পরবর্তীতে Privacy on Beam ব্যবহার করার জন্য এটি ডাউনলোড করতে চান, তাহলে নিচের ধাপগুলো অনুসরণ করে তা করতে পারেন।
উল্লেখ্য যে, এই কোডল্যাবটি লাইব্রেরির ১.১.০ সংস্করণের জন্য।
প্রথমে, Privacy on Beam ডাউনলোড করুন:
https://github.com/google/differential-privacy/archive/refs/tags/v1.1.0.tar.gz
অথবা আপনি গিটহাব রিপোজিটরিটি ক্লোন করতে পারেন:
git clone --branch v1.1.0 https://github.com/google/differential-privacy.git
Privacy on Beam শীর্ষ স্তরের privacy-on-beam/ ডিরেক্টরিতে অবস্থিত।
এই কোডল্যাবের কোড এবং ডেটাসেটটি privacy-on-beam/codelab/ ডিরেক্টরিতে রয়েছে।
আপনার কম্পিউটারে বেজেলও ইনস্টল করা থাকতে হবে। বেজেল ওয়েবসাইটে আপনার অপারেটিং সিস্টেমের জন্য ইনস্টলেশনের নির্দেশাবলী খুঁজে নিন।
৪. প্রতি ঘন্টায় পরিদর্শনের সংখ্যা গণনা করা
ধরুন আপনি একজন রেস্তোরাঁর মালিক এবং আপনার রেস্তোরাঁ সম্পর্কে কিছু পরিসংখ্যান জানাতে চান, যেমন গ্রাহকদের আসার জনপ্রিয় সময়গুলো প্রকাশ করা। সৌভাগ্যবশত, আপনি ডিফারেনশিয়াল প্রাইভেসি এবং অ্যানোনিমাইজেশন সম্পর্কে জানেন, তাই আপনি এমনভাবে এটি করতে চান যাতে কোনো নির্দিষ্ট গ্রাহকের তথ্য ফাঁস না হয়।
এই উদাহরণটির কোড codelab/count.go ফাইলে রয়েছে।
চলুন, একটি নির্দিষ্ট সোমবারে আপনার রেস্তোরাঁয় আসা অতিথিদের তথ্য সম্বলিত একটি নমুনা ডেটাসেট লোড করার মাধ্যমে শুরু করা যাক। এই কোডল্যাবের জন্য এর কোডটি প্রাসঙ্গিক নয়, তবে আপনি codelab/main.go , codelab/utils.go এবং codelab/visit.go ফাইলগুলিতে এর কোড দেখে নিতে পারেন।
পরিদর্শক আইডি | প্রবেশ করানো সময় | ব্যয়িত সময় (মিনিট) | ব্যয়িত অর্থ (ইউরো) |
১ | সকাল ৯:৩০:০০ টা | ২৬ | ২৪ |
২ | সকাল ১১:৫৪:০০ | ৫৩ | ১৭ |
৩ | দুপুর ১:০৫:০০ টা | ৮১ | ৩৩ |
প্রথমে আপনি নিচের কোড স্যাম্পলটি ব্যবহার করে Beam-এর সাহায্যে আপনার রেস্তোরাঁয় পরিদর্শনের সময়ের একটি নন-প্রাইভেট বার চার্ট তৈরি করবেন। Scope হলো পাইপলাইনের একটি উপস্থাপনা, এবং ডেটার উপর আমাদের করা প্রতিটি নতুন অপারেশন Scope এ যুক্ত হয়। CountVisitsPerHour একটি Scope এবং ভিজিটের একটি কালেকশন গ্রহণ করে, যা Beam-এ একটি PCollection হিসাবে উপস্থাপিত হয়। এটি কালেকশনটির উপর extractVisitHour ফাংশনটি প্রয়োগ করে প্রতিটি পরিদর্শনের ঘন্টা বের করে। তারপর এটি প্রতিটি ঘন্টার পুনরাবৃত্তি গণনা করে এবং তা রিটার্ন করে।
func CountVisitsPerHour(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("CountVisitsPerHour")
visitHours := beam.ParDo(s, extractVisitHourFn, col)
visitsPerHour := stats.Count(s, visitHours)
return visitsPerHour
}
func extractVisitHourFn(v Visit) int {
return v.TimeEntered.Hour()
}
এটি বর্তমান ডিরেক্টরিতে count.png নামে একটি সুন্দর বার চার্ট তৈরি করে ( bazel run codelab -- --example="count" --input_file=$(pwd)/day_data.csv --output_stats_file=$(pwd)/count.csv --output_chart_file=$(pwd)/count.png চালানোর মাধ্যমে)।

পরবর্তী ধাপ হলো আপনার পাইপলাইন এবং বার চার্টকে একটি ব্যক্তিগত ফাইলে রূপান্তর করা। আমরা এটি নিম্নোক্তভাবে করে থাকি।
প্রথমে, একটি PrivatePCollection<V> PCollection<V> <V>-এর উপর MakePrivateFromStruct কল করুন। ইনপুট PCollection অবশ্যই স্ট্রাক্ট-এর একটি কালেকশন হতে হবে। MakePrivateFromStruct এর ইনপুট হিসেবে আমাদের একটি PrivacySpec এবং একটি idFieldPath দিতে হবে।
spec := pbeam.NewPrivacySpec(epsilon, delta) pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
PrivacySpec হলো একটি struct যা ডেটা বেনামী করার জন্য আমাদের ব্যবহৃত ডিফারেনশিয়াল প্রাইভেসি প্যারামিটারগুলো (এপসিলন এবং ডেল্টা) ধারণ করে। (আপাতত এগুলো নিয়ে আপনার চিন্তা করার দরকার নেই, আপনি যদি এ সম্পর্কে আরও জানতে চান তবে পরে একটি ঐচ্ছিক বিভাগ রয়েছে।)
idFieldPath হলো struct-এর (আমাদের ক্ষেত্রে Visit ) মধ্যে থাকা ব্যবহারকারী শনাক্তকারী ফিল্ডের পাথ। এখানে, পরিদর্শকদের ব্যবহারকারী শনাক্তকারী হলো Visit এর VisitorID ফিল্ড।
এরপর, আমরা stats.Count() ) এর পরিবর্তে pbeam.Count() কল করি। pbeam.Count() ইনপুট হিসেবে একটি CountParams struct গ্রহণ করে, যেখানে MaxValue মতো প্যারামিটারগুলো থাকে যা আউটপুটের নির্ভুলতাকে প্রভাবিত করে।
visitsPerHour := pbeam.Count(s, visitHours, pbeam.CountParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxValue: 1,
})
একইভাবে, MaxPartitionsContributed নির্ধারণ করে যে একজন ব্যবহারকারী কতগুলো ভিন্ন ভিজিট আওয়ার অবদান রাখতে পারবেন। আমরা আশা করি যে তারা দিনে সর্বোচ্চ একবার রেস্তোরাঁটিতে আসবেন (অথবা তারা দিনের বিভিন্ন সময়ে একাধিকবার আসলেও আমাদের কিছু যায় আসে না), তাই আমরা এটিকেও ১-এ সেট করেছি। আমরা একটি ঐচ্ছিক বিভাগে এই প্যারামিটারগুলো নিয়ে আরও বিস্তারিত আলোচনা করব।
MaxValue নির্ধারণ করে যে একজন ব্যবহারকারী আমরা যে মানগুলো গণনা করছি তাতে কতবার অবদান রাখতে পারবে। এই নির্দিষ্ট ক্ষেত্রে, আমরা পরিদর্শনের সময় গণনা করছি, এবং আমরা আশা করি একজন ব্যবহারকারী রেস্তোরাঁটিতে কেবল একবারই আসবে (অথবা তারা প্রতি ঘণ্টায় একাধিকবার আসলেও আমাদের কিছু যায় আসে না), তাই আমরা এই প্যারামিটারটির মান ১ নির্ধারণ করেছি।
অবশেষে, আপনার কোডটি দেখতে এইরকম হবে:
func PrivateCountVisitsPerHour(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("PrivateCountVisitsPerHour")
// Create a Privacy Spec and convert col into a PrivatePCollection
spec := pbeam.NewPrivacySpec(epsilon, delta)
pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
visitHours := pbeam.ParDo(s, extractVisitHourFn, pCol)
visitsPerHour := pbeam.Count(s, visitHours, pbeam.CountParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxValue: 1,
})
return visitsPerHour
}
আমরা ডিফারেনশিয়ালি প্রাইভেট পরিসংখ্যানের জন্য একটি অনুরূপ বার চার্ট ( count_dp.png ) দেখতে পাই (পূর্ববর্তী কমান্ডটি নন-প্রাইভেট এবং প্রাইভেট উভয় পাইপলাইনই চালায়):

অভিনন্দন! আপনি আপনার প্রথম ডিফারেনশিয়ালি প্রাইভেট পরিসংখ্যানটি গণনা করেছেন!
কোডটি রান করলে আপনি যে বার চার্টটি পাবেন, তা এটির থেকে ভিন্ন হতে পারে। তাতে কোনো সমস্যা নেই। ডিফারেনশিয়াল প্রাইভেসিতে থাকা নয়েজের কারণে, আপনি প্রতিবার কোডটি রান করলে একটি ভিন্ন বার চার্ট পাবেন, কিন্তু আপনি দেখতে পারেন যে সেগুলো আমাদের আগের নন-প্রাইভেট বার চার্টটির সাথে কমবেশি একই রকম।
অনুগ্রহ করে মনে রাখবেন যে, গোপনীয়তা রক্ষার জন্য পাইপলাইনটি একাধিকবার পুনরায় চালানো (উদাহরণস্বরূপ, আরও সুন্দর একটি বার চার্ট পাওয়ার জন্য) অত্যন্ত গুরুত্বপূর্ণ। কেন আপনার পাইপলাইনগুলো পুনরায় চালানো উচিত নয়, তার কারণ "একাধিক পরিসংখ্যান গণনা" বিভাগে ব্যাখ্যা করা হয়েছে।
৫. পাবলিক পার্টিশন ব্যবহার করা
পূর্ববর্তী অংশে, আপনারা হয়তো লক্ষ্য করেছেন যে আমরা কিছু পার্টিশনের, অর্থাৎ ঘন্টার, সমস্ত ভিজিট (ডেটা) বাদ দিয়েছি।

এর কারণ হলো পার্টিশন সিলেকশন/থ্রেশহোল্ডিং, যা ডিফারেনশিয়াল প্রাইভেসি নিশ্চিত করার জন্য একটি গুরুত্বপূর্ণ পদক্ষেপ, বিশেষ করে যখন আউটপুট পার্টিশনের অস্তিত্ব ব্যবহারকারীর ডেটার উপরই নির্ভর করে। যখন এমনটা হয়, তখন আউটপুটে একটি পার্টিশনের অস্তিত্বই ডেটার মধ্যে থাকা কোনো একজন ব্যবহারকারীর পরিচয় ফাঁস করে দিতে পারে (কেন এটি গোপনীয়তা লঙ্ঘন করে, তার ব্যাখ্যার জন্য এই ব্লগ পোস্টটি দেখুন)। এটি প্রতিরোধ করার জন্য, প্রাইভেসি অন বিম শুধুমাত্র সেই পার্টিশনগুলোই রাখে যেগুলোতে পর্যাপ্ত সংখ্যক ব্যবহারকারী রয়েছে।
যখন আউটপুট পার্টিশনের তালিকা ব্যক্তিগত ব্যবহারকারীর তথ্যের উপর নির্ভর করে না, অর্থাৎ সেগুলি সর্বজনীন তথ্য হয়, তখন আমাদের এই পার্টিশন নির্বাচনের ধাপটির প্রয়োজন হয় না। আমাদের রেস্তোরাঁর উদাহরণের ক্ষেত্রে বিষয়টি এমনই: আমরা রেস্তোরাঁটির কাজের সময় (সকাল ৯.০০ থেকে রাত ৯.০০) জানি।
এই উদাহরণটির কোড codelab/public_partitions.go ফাইলে রয়েছে।
আমরা সহজভাবে ৯টা থেকে ২১টার (উভয় সময় বাদে) মধ্যবর্তী ঘন্টাগুলোর একটি PCollection তৈরি করব এবং সেটি CountParams এর PublicPartitions ফিল্ডে ইনপুট করব:
func PrivateCountVisitsPerHourWithPublicPartitions(s beam.Scope,
col beam.PCollection) beam.PCollection {
s = s.Scope("PrivateCountVisitsPerHourWithPublicPartitions")
// Create a Privacy Spec and convert col into a PrivatePCollection
spec := pbeam.NewPrivacySpec(epsilon, /* delta */ 0)
pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
// Create a PCollection of output partitions, i.e. restaurant's work hours
// (from 9 am till 9pm (exclusive)).
hours := beam.CreateList(s, [12]int{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20})
visitHours := pbeam.ParDo(s, extractVisitHourFn, pCol)
visitsPerHour := pbeam.Count(s, visitHours, pbeam.CountParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxValue: 1,
// Visitors only visit during work hours
PublicPartitions: hours,
})
return visitsPerHour
}
উল্লেখ্য যে, যদি আপনি পাবলিক পার্টিশন এবং ল্যাপ্লেস নয়েজ (ডিফল্ট) ব্যবহার করেন, তাহলে ডেল্টা-কে ০-তে সেট করা সম্ভব, যেমনটি উপরের ক্ষেত্রে দেখা যাচ্ছে।
যখন আমরা পাবলিক পার্টিশন সহ পাইপলাইনটি রান করি ( bazel run codelab -- --example="public_partitions" --input_file=$(pwd)/day_data.csv --output_stats_file=$(pwd)/public_partitions.csv --output_chart_file=$(pwd)/public_partitions.png ), তখন আমরা ( public_partitions_dp.png ) পাই:

যেমনটা দেখতে পাচ্ছেন, আমরা এখন পূর্বে বাদ দেওয়া ৯, ১০ এবং ১৬ নম্বর পার্টিশনগুলো পাবলিক পার্টিশন ছাড়াই রেখে দিয়েছি।
পাবলিক পার্টিশন ব্যবহার করলে শুধু যে আপনি আরও বেশি পার্টিশন রাখতে পারেন তাই নয়, বরং পার্টিশন নির্বাচনের জন্য কোনো প্রাইভেসি বাজেট (অর্থাৎ এপসিলন ও ডেল্টা) খরচ না হওয়ায়, পাবলিক পার্টিশন ব্যবহার না করার তুলনায় প্রতিটি পার্টিশনে প্রায় অর্ধেক পরিমাণ নয়েজ যুক্ত হয়। এই কারণেই আগের রানের তুলনায় র এবং প্রাইভেট কাউন্টের মধ্যে পার্থক্য কিছুটা কম।
পাবলিক পার্টিশন ব্যবহার করার সময় দুটি গুরুত্বপূর্ণ বিষয় মনে রাখতে হবে:
- র ডেটা থেকে পার্টিশনের তালিকা তৈরি করার সময় সতর্ক থাকুন: যদি আপনি এটি ডিফারেনশিয়ালি প্রাইভেট পদ্ধতিতে না করেন, যেমন ইউজার ডেটা থেকে সমস্ত পার্টিশনের তালিকা সরাসরি পড়ে নেন, তাহলে আপনার পাইপলাইন আর ডিফারেনশিয়াল প্রাইভেসি নিশ্চয়তা প্রদান করবে না। এটি কীভাবে ডিফারেনশিয়ালি প্রাইভেট পদ্ধতিতে করতে হয়, তা জানতে নিচের অ্যাডভান্সড সেকশনটি দেখুন।
- যদি কিছু পাবলিক পার্টিশনের জন্য কোনো ডেটা (যেমন ভিজিট) না থাকে, তাহলে ডিফারেনশিয়াল প্রাইভেসি বজায় রাখার জন্য সেই পার্টিশনগুলিতে নয়েজ প্রয়োগ করা হবে। উদাহরণস্বরূপ, যদি আমরা ৯ থেকে ২১ ঘণ্টার পরিবর্তে ০ থেকে ২৪ ঘণ্টার মধ্যবর্তী সময় ব্যবহার করি, তাহলে সমস্ত ঘণ্টাই নয়েজযুক্ত হয়ে যাবে এবং যেখানে কোনো ভিজিট নেই, সেখানেও কিছু ভিজিট দেখাতে পারে।
(উন্নত) ডেটা থেকে পার্টিশন নির্ণয়
যদি আপনি একই পাইপলাইনে একই নন-পাবলিক আউটপুট পার্টিশনের তালিকা ব্যবহার করে একাধিক অ্যাগ্রিগেশন চালান, তাহলে আপনি SelectPartitions() ব্যবহার করে একবারই পার্টিশনের তালিকাটি তৈরি করতে পারেন এবং প্রতিটি অ্যাগ্রিগেশনে PublicPartition ইনপুট হিসেবে পার্টিশনগুলো সরবরাহ করতে পারেন। এটি কেবল গোপনীয়তার দৃষ্টিকোণ থেকেই নিরাপদ নয়, বরং পুরো পাইপলাইনের জন্য পার্টিশন নির্বাচনে প্রাইভেসি বাজেট শুধুমাত্র একবার ব্যবহার করার কারণে এটি ডেটাতে অপ্রয়োজনীয় পরিবর্তনও কম আনে।
৬. গড় অবস্থানকাল গণনা করা
এখন যেহেতু আমরা ডিফারেনশিয়ালি প্রাইভেট পদ্ধতিতে জিনিসপত্র গণনা করার পদ্ধতি জানি, চলুন গড় নির্ণয়ের দিকে নজর দেওয়া যাক। আরও নির্দিষ্টভাবে বললে, আমরা এখন দর্শনার্থীদের অবস্থানের গড় সময়কাল গণনা করব।
এই উদাহরণটির কোড codelab/mean.go ফাইলে রয়েছে।
সাধারণত, অবস্থানের সময়কালের একটি অ-ব্যক্তিগত গড় গণনা করার জন্য, আমরা stats.MeanPerKey() ব্যবহার করি। এর সাথে একটি প্রি-প্রসেসিং ধাপ থাকে যা আগত ভিজিটের PCollection কে একটি PCollection<K,V> তে রূপান্তরিত করে, যেখানে K হলো ভিজিটের ঘন্টা এবং V হলো পরিদর্শকের রেস্তোরাঁয় কাটানো সময়।
func MeanTimeSpent(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("MeanTimeSpent")
hourToTimeSpent := beam.ParDo(s, extractVisitHourAndTimeSpentFn, col)
meanTimeSpent := stats.MeanPerKey(s, hourToTimeSpent)
return meanTimeSpent
}
func extractVisitHourAndTimeSpentFn(v Visit) (int, int) {
return v.TimeEntered.Hour(), v.MinutesSpent
}
এটি বর্তমান ডিরেক্টরিতে mean.png নামে একটি সুন্দর বার চার্ট তৈরি করে ( bazel run codelab -- --example="mean" --input_file=$(pwd)/day_data.csv --output_stats_file=$(pwd)/mean.csv --output_chart_file=$(pwd)/mean.png চালানোর মাধ্যমে)।

এটিকে ডিফারেনশিয়ালি প্রাইভেট করার জন্য, আমরা আবার আমাদের PCollection একটি PrivatePCollection এ রূপান্তর করি এবং stats.MeanPerKey() কে pbeam.MeanPerKey() দিয়ে প্রতিস্থাপন করি। Count এর মতোই, আমাদের MeanParams আছে যা MinValue এবং MaxValue মতো কিছু প্যারামিটার ধারণ করে, যেগুলো নির্ভুলতাকে প্রভাবিত করে। MinValue এবং MaxValue প্রতিটি কী-তে প্রত্যেক ব্যবহারকারীর অবদানের জন্য আমাদের নির্ধারিত সীমা নির্দেশ করে।
meanTimeSpent := pbeam.MeanPerKey(s, hourToTimeSpent, pbeam.MeanParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxContributionsPerPartition: 1,
// Minimum time spent per user (in mins)
MinValue: 0,
// Maximum time spent per user (in mins)
MaxValue: 60,
})
এক্ষেত্রে, প্রতিটি 'key' এক ঘণ্টাকে এবং 'value' হলো দর্শনার্থীদের কাটানো সময়। আমরা MinValue কে 0 সেট করেছি, কারণ আমরা আশা করি না যে দর্শনার্থীরা রেস্তোরাঁয় 0 মিনিটের কম সময় কাটাবেন। আমরা MaxValue কে 60 সেট করেছি, যার অর্থ হলো, যদি কোনো দর্শনার্থী 60 মিনিটের বেশি সময় কাটান, তাহলে আমরা ধরে নেব যে সেই ব্যবহারকারী 60 মিনিটই কাটিয়েছেন।
অবশেষে, আপনার কোডটি দেখতে এইরকম হবে:
func PrivateMeanTimeSpent(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("PrivateMeanTimeSpent")
// Create a Privacy Spec and convert col into a PrivatePCollection
spec := pbeam.NewPrivacySpec(epsilon, /* delta */ 0)
pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
// Create a PCollection of output partitions, i.e. restaurant's work hours
// (from 9 am till 9pm (exclusive)).
hours := beam.CreateList(s, [12]int{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20})
hourToTimeSpent := pbeam.ParDo(s, extractVisitHourAndTimeSpentFn, pCol)
meanTimeSpent := pbeam.MeanPerKey(s, hourToTimeSpent, pbeam.MeanParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxContributionsPerPartition: 1,
// Minimum time spent per user (in mins)
MinValue: 0,
// Maximum time spent per user (in mins)
MaxValue: 60,
// Visitors only visit during work hours
PublicPartitions: hours,
})
return meanTimeSpent
}
আমরা ডিফারেনশিয়ালি প্রাইভেট পরিসংখ্যানের জন্য একটি অনুরূপ বার চার্ট ( mean_dp.png ) দেখতে পাই (পূর্ববর্তী কমান্ডটি নন-প্রাইভেট এবং প্রাইভেট উভয় পাইপলাইনই চালায়):

আবার, গণনার মতোই, যেহেতু এটি একটি ডিফারেনশিয়ালি প্রাইভেট অপারেশন, তাই প্রতিবার এটি চালালে আমরা ভিন্ন ভিন্ন ফলাফল পাব। কিন্তু আপনি দেখতে পাচ্ছেন যে ডিফারেনশিয়ালি প্রাইভেট অবস্থানকাল প্রকৃত ফলাফল থেকে খুব বেশি দূরে নয়।
৭. প্রতি ঘন্টায় আয় গণনা করা
আরেকটি আকর্ষণীয় পরিসংখ্যান যা আমরা খতিয়ে দেখতে পারি, তা হলো দিনব্যাপী প্রতি ঘণ্টার আয়।
এই উদাহরণটির কোড codelab/sum.go ফাইলে রয়েছে।
আবার, আমরা নন-প্রাইভেট সংস্করণটি দিয়ে শুরু করব। আমাদের মক ডেটাসেটে কিছু প্রি-প্রসেসিং করে, আমরা একটি PCollection<K,V> তৈরি করতে পারি, যেখানে K হলো পরিদর্শনের সময় এবং V হলো পরিদর্শকের রেস্তোরাঁয় ব্যয় করা অর্থ: প্রতি ঘন্টায় একটি নন-প্রাইভেট আয় গণনা করতে, আমরা stats.SumPerKey() কল করে পরিদর্শকদের ব্যয় করা সমস্ত অর্থ যোগ করতে পারি:
func RevenuePerHour(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("RevenuePerHour")
hourToMoneySpent := beam.ParDo(s, extractVisitHourAndMoneySpentFn, col)
revenues := stats.SumPerKey(s, hourToMoneySpent)
return revenues
}
func extractVisitHourAndMoneySpentFn(v Visit) (int, int) {
return v.TimeEntered.Hour(), v.MoneySpent
}
এটি বর্তমান ডিরেক্টরিতে sum.png নামে একটি সুন্দর বার চার্ট তৈরি করে ( bazel run codelab -- --example="sum" --input_file=$(pwd)/day_data.csv --output_stats_file=$(pwd)/sum.csv --output_chart_file=$(pwd)/sum.png কমান্ডটি চালানোর মাধ্যমে)।

এটিকে ডিফারেনশিয়ালি প্রাইভেট করার জন্য, আমরা আবার আমাদের PCollection একটি PrivatePCollection এ রূপান্তর করি এবং stats.SumPerKey() কে pbeam.SumPerKey() দিয়ে প্রতিস্থাপন করি। Count এবং MeanPerKey এর মতোই, আমাদের SumParams আছে যা MinValue এবং MaxValue মতো কিছু প্যারামিটার ধারণ করে, যেগুলো নির্ভুলতাকে প্রভাবিত করে।
revenues := pbeam.SumPerKey(s, hourToMoneySpent, pbeam.SumParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Minimum money spent per user (in euros)
MinValue: 0,
// Maximum money spent per user (in euros)
MaxValue: 40,
})
এক্ষেত্রে, MinValue এবং MaxValue হলো প্রত্যেক পরিদর্শকের খরচের সীমা। আমরা MinValue কে ০ নির্ধারণ করেছি, কারণ আমরা আশা করি না যে পরিদর্শকরা রেস্তোরাঁয় ০ ইউরোর কম খরচ করবে। আমরা MaxValue কে ৪০ নির্ধারণ করেছি, যার অর্থ হলো, যদি কোনো পরিদর্শক ৪০ ইউরোর বেশি খরচ করে, আমরা ধরে নিই যে সেই ব্যবহারকারী ৪০ ইউরোই খরচ করেছে।
অবশেষে, কোডটি দেখতে এইরকম হবে:
func PrivateRevenuePerHour(s beam.Scope, col beam.PCollection) beam.PCollection {
s = s.Scope("PrivateRevenuePerHour")
// Create a Privacy Spec and convert col into a PrivatePCollection
spec := pbeam.NewPrivacySpec(epsilon, /* delta */ 0)
pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
// Create a PCollection of output partitions, i.e. restaurant's work hours
// (from 9 am till 9pm (exclusive)).
hours := beam.CreateList(s, [12]int{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20})
hourToMoneySpent := pbeam.ParDo(s, extractVisitHourAndMoneySpentFn, pCol)
revenues := pbeam.SumPerKey(s, hourToMoneySpent, pbeam.SumParams{
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Minimum money spent per user (in euros)
MinValue: 0,
// Maximum money spent per user (in euros)
MaxValue: 40,
// Visitors only visit during work hours
PublicPartitions: hours,
})
return revenues
}
আমরা ডিফারেনশিয়ালি প্রাইভেট পরিসংখ্যানের জন্য একটি অনুরূপ বার চার্ট ( sum_dp.png ) দেখতে পাই (পূর্ববর্তী কমান্ডটি নন-প্রাইভেট এবং প্রাইভেট উভয় পাইপলাইনই চালায়):

আবার, গণনা এবং গড়ের মতোই, যেহেতু এটি একটি ডিফারেনশিয়ালি প্রাইভেট অপারেশন, তাই প্রতিবার এটি চালালে আমরা ভিন্ন ভিন্ন ফলাফল পাব। কিন্তু আপনি দেখতে পাচ্ছেন যে ডিফারেনশিয়ালি প্রাইভেট ফলাফলটি প্রতি ঘণ্টার প্রকৃত আয়ের খুব কাছাকাছি।
৮. একাধিক পরিসংখ্যান গণনা করা
বেশিরভাগ সময়, আপনি একই ডেটার উপর একাধিক পরিসংখ্যান গণনা করতে আগ্রহী হতে পারেন, যেমনটা আপনি গণনা, গড় এবং যোগফলের ক্ষেত্রে করেছেন। সাধারণত, একটি একক Beam পাইপলাইন এবং একটি একক বাইনারিতে এটি করা আরও পরিচ্ছন্ন ও সহজ। আপনি Privacy on Beam ব্যবহার করেও এটি করতে পারেন। আপনি আপনার রূপান্তর এবং গণনাগুলো চালানোর জন্য একটি একক পাইপলাইন লিখতে পারেন এবং পুরো পাইপলাইনটির জন্য একটি একক PrivacySpec ব্যবহার করতে পারেন।
একটিমাত্র PrivacySpec দিয়ে এটি করা কেবল সুবিধাজনকই নয়, গোপনীয়তার দিক থেকেও এটি শ্রেয়। PrivacySpec এ আমরা যে epsilon এবং delta প্যারামিটার সরবরাহ করি, তা যদি আপনার মনে থাকে, তবে দেখবেন যে এগুলো ‘প্রাইভেসি বাজেট’ নামক একটি বিষয়কে বোঝায়, যা পরিমাপ করে যে আপনি মূল ডেটার মধ্যে থাকা ব্যবহারকারীদের গোপনীয়তার কতটা ফাঁস করছেন।
প্রাইভেসি বাজেট সম্পর্কে মনে রাখার মতো একটি গুরুত্বপূর্ণ বিষয় হলো এটি সংযোজনযোগ্য: যদি আপনি একটি নির্দিষ্ট এপসিলন ε এবং ডেল্টা δ দিয়ে কোনো পাইপলাইন একবার চালান, তাহলে আপনি (ε,δ) বাজেট খরচ করছেন। যদি আপনি এটি দ্বিতীয়বার চালান, তাহলে আপনার মোট বাজেট হবে (2ε, 2δ)। একইভাবে, যদি আপনি (ε,δ) এর একটি PrivacySpec (এবং ধারাবাহিকভাবে একটি প্রাইভেসি বাজেট) দিয়ে একাধিক পরিসংখ্যান গণনা করেন, তাহলে আপনার মোট বাজেট হবে (2ε, 2δ)। এর মানে হলো, আপনি গোপনীয়তার নিশ্চয়তাগুলোকে অবনমিত করছেন।
এই সমস্যা এড়ানোর জন্য, যখন আপনি একই ডেটার উপর একাধিক পরিসংখ্যান গণনা করতে চান, তখন আপনার ব্যবহৃত মোট বাজেট সহ একটি একক PrivacySpec ব্যবহার করার কথা। এরপর প্রতিটি অ্যাগ্রিগেশনের জন্য আপনি যে এপসিলন (epsilon) এবং ডেল্টা (delta) ব্যবহার করতে চান, তা নির্দিষ্ট করে দিতে হবে। পরিশেষে, আপনি একই সামগ্রিক গোপনীয়তার নিশ্চয়তা পাবেন; কিন্তু কোনো নির্দিষ্ট অ্যাগ্রিগেশনের এপসিলন এবং ডেল্টা যত বেশি হবে, তার নির্ভুলতাও তত বেশি হবে।
এর কার্যকারিতা দেখতে, আমরা আগে আলাদাভাবে গণনা করা তিনটি পরিসংখ্যান (গণনা, গড় এবং যোগফল) একটি একক পাইপলাইনে গণনা করতে পারি।
এই উদাহরণটির কোড codelab/multiple.go তে রয়েছে। লক্ষ্য করুন, আমরা কীভাবে মোট (ε,δ) বাজেটকে তিনটি অ্যাগ্রিগেশনের মধ্যে সমানভাবে ভাগ করছি:
func ComputeCountMeanSum(s beam.Scope, col beam.PCollection) (visitsPerHour, meanTimeSpent, revenues beam.PCollection) {
s = s.Scope("ComputeCountMeanSum")
// Create a Privacy Spec and convert col into a PrivatePCollection
// Budget is shared by count, mean and sum.
spec := pbeam.NewPrivacySpec(epsilon, /* delta */ 0)
pCol := pbeam.MakePrivateFromStruct(s, col, spec, "VisitorID")
// Create a PCollection of output partitions, i.e. restaurant's work hours
// (from 9 am till 9pm (exclusive)).
hours := beam.CreateList(s, [12]int{9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20})
visitHours := pbeam.ParDo(s, extractVisitHourFn, pCol)
visitsPerHour = pbeam.Count(s, visitHours, pbeam.CountParams{
Epsilon: epsilon / 3,
Delta: 0,
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxValue: 1,
// Visitors only visit during work hours
PublicPartitions: hours,
})
hourToTimeSpent := pbeam.ParDo(s, extractVisitHourAndTimeSpentFn, pCol)
meanTimeSpent = pbeam.MeanPerKey(s, hourToTimeSpent, pbeam.MeanParams{
Epsilon: epsilon / 3,
Delta: 0,
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Visitors can visit the restaurant once within an hour
MaxContributionsPerPartition: 1,
// Minimum time spent per user (in mins)
MinValue: 0,
// Maximum time spent per user (in mins)
MaxValue: 60,
// Visitors only visit during work hours
PublicPartitions: hours,
})
hourToMoneySpent := pbeam.ParDo(s, extractVisitHourAndMoneySpentFn, pCol)
revenues = pbeam.SumPerKey(s, hourToMoneySpent, pbeam.SumParams{
Epsilon: epsilon / 3,
Delta: 0,
// Visitors can visit the restaurant once (one hour) a day
MaxPartitionsContributed: 1,
// Minimum money spent per user (in euros)
MinValue: 0,
// Maximum money spent per user (in euros)
MaxValue: 40,
// Visitors only visit during work hours
PublicPartitions: hours,
})
return visitsPerHour, meanTimeSpent, revenues
}
৯. (ঐচ্ছিক) ডিফারেনশিয়াল প্রাইভেসি প্যারামিটারগুলোর সমন্বয় সাধন
এই কোডল্যাবে আপনারা বেশ কিছু প্যারামিটারের উল্লেখ দেখেছেন: এপসিলন, ডেল্টা, ম্যাক্সপার্টিশনসকন্ট্রিবিউটেড, ইত্যাদি। আমরা এগুলিকে মোটামুটিভাবে দুটি ভাগে ভাগ করতে পারি: প্রাইভেসি প্যারামিটার এবং ইউটিলিটি প্যারামিটার।
গোপনীয়তা পরামিতি
এপসিলন এবং ডেল্টা হলো সেই প্যারামিটার যা ডিফারেনশিয়াল প্রাইভেসি ব্যবহার করে আমরা যে গোপনীয়তা প্রদান করছি তার পরিমাণ নির্ধারণ করে। আরও স্পষ্টভাবে বললে, এপসিলন এবং ডেল্টা হলো একটি পরিমাপ, যা দিয়ে বোঝা যায় যে একজন সম্ভাব্য আক্রমণকারী বেনামী আউটপুটটি দেখে মূল ডেটা সম্পর্কে কতটা তথ্য লাভ করতে পারে। এপসিলন এবং ডেল্টার মান যত বেশি হবে, আক্রমণকারী মূল ডেটা সম্পর্কে তত বেশি তথ্য লাভ করবে, যা গোপনীয়তার জন্য একটি ঝুঁকি।
অন্যদিকে, এপসিলন এবং ডেল্টা যত কম হবে, আউটপুটকে বেনামী রাখতে তত বেশি নয়েজ যোগ করতে হবে, এবং প্রতিটি পার্টিশনকে বেনামী আউটপুটে রাখতে সেটিতে তত বেশি সংখ্যক অনন্য ব্যবহারকারী থাকতে হবে। সুতরাং, এখানে উপযোগিতা এবং গোপনীয়তার মধ্যে একটি আপস রয়েছে।
Privacy on Beam-এ, PrivacySpec এ মোট প্রাইভেসি বাজেট নির্দিষ্ট করার সময় আপনার অ্যানোনিমাইজড আউটপুটে আপনি যে প্রাইভেসি গ্যারান্টিগুলো চান, সে বিষয়ে আপনাকে সচেতন থাকতে হবে। মনে রাখবেন যে, যদি আপনি চান আপনার প্রাইভেসি গ্যারান্টিগুলো বজায় থাকুক, তাহলে প্রতিটি অ্যাগ্রিগেশনের জন্য আলাদা PrivacySpec ব্যবহার করে বা পাইপলাইনটি একাধিকবার চালিয়ে আপনার বাজেট অতিরিক্ত ব্যবহার না করার বিষয়ে এই কোডল্যাবের পরামর্শ অনুসরণ করতে হবে।
ডিফারেনশিয়াল প্রাইভেসি এবং প্রাইভেসি প্যারামিটারগুলোর অর্থ সম্পর্কে আরও তথ্যের জন্য, আপনি সংশ্লিষ্ট বিবরণীগুলো দেখতে পারেন।
ইউটিলিটি প্যারামিটার
এগুলো এমন কিছু প্যারামিটার যা গোপনীয়তার নিশ্চয়তাকে প্রভাবিত করে না (যতক্ষণ পর্যন্ত Beam-এ Privacy ব্যবহারের পরামর্শ সঠিকভাবে অনুসরণ করা হয়), কিন্তু আউটপুটের নির্ভুলতা এবং ফলস্বরূপ এর উপযোগিতাকে প্রভাবিত করে। এগুলো প্রতিটি অ্যাগ্রিগেশনের Params স্ট্রাকচারে দেওয়া থাকে, যেমন CountParams , SumParams , ইত্যাদি। এই প্যারামিটারগুলো যোগ করা নয়েজের পরিমাণ নির্ধারণ করতে ব্যবহৃত হয়।
Params এ প্রদত্ত এবং সমস্ত অ্যাগ্রিগেশনের জন্য প্রযোজ্য একটি ইউটিলিটি প্যারামিটার হলো MaxPartitionsContributed । একটি পার্টিশন Privacy On Beam অ্যাগ্রিগেশন অপারেশন (যেমন Count , SumPerKey , ইত্যাদি) দ্বারা আউটপুট করা PCollection-এর একটি কী-এর সাথে সঙ্গতিপূর্ণ। সুতরাং, MaxPartitionsContributed নির্ধারণ করে যে একজন ব্যবহারকারী আউটপুটে কতগুলি স্বতন্ত্র কী ভ্যালুতে অবদান রাখতে পারবেন। যদি কোনো ব্যবহারকারী অন্তর্নিহিত ডেটাতে MaxPartitionsContributed এর চেয়ে বেশি কী-তে অবদান রাখেন, তবে তার কিছু অবদান বাদ দেওয়া হবে, যাতে তিনি ঠিক MaxPartitionsContributed সংখ্যক কী-তেই অবদান রাখেন।
MaxPartitionsContributed মতোই, বেশিরভাগ অ্যাগ্রিগেশনের একটি MaxContributionsPerPartition প্যারামিটার থাকে। এগুলো Params স্ট্রাকচারে দেওয়া থাকে এবং প্রতিটি অ্যাগ্রিগেশনের জন্য এগুলোর আলাদা আলাদা মান থাকতে পারে। MaxPartitionsContributed বিপরীতে, MaxContributionsPerPartition প্রতিটি কী-এর জন্য একজন ব্যবহারকারীর অবদানকে সীমাবদ্ধ করে। অন্য কথায়, একজন ব্যবহারকারী প্রতিটি কী-এর জন্য শুধুমাত্র MaxContributionsPerPartition পরিমাণ অবদান রাখতে পারেন।
আউটপুটে যুক্ত হওয়া নয়েজ MaxPartitionsContributed এবং MaxContributionsPerPartition দ্বারা স্কেল করা হয়, তাই এখানে একটি আপেক্ষিক সম্পর্ক রয়েছে: MaxPartitionsContributed এবং MaxContributionsPerPartition উভয়ের মান যত বেশি হবে, আপনি তত বেশি ডেটা রাখবেন, কিন্তু এর ফলে প্রাপ্ত ফলাফল তত বেশি নয়েজি হবে।
কিছু অ্যাগ্রিগেশনের জন্য MinValue এবং MaxValue প্রয়োজন হয়। এগুলো প্রতিটি ব্যবহারকারীর অবদানের সীমা নির্ধারণ করে। যদি কোনো ব্যবহারকারী MinValue চেয়ে কম মান অবদান রাখে, তবে সেই মানটি MinValue তে সীমাবদ্ধ করা হবে। একইভাবে, যদি কোনো ব্যবহারকারী MaxValue চেয়ে বেশি মান অবদান রাখে, তবে সেই মানটি MaxValue তে সীমাবদ্ধ করা হবে। এর মানে হলো, মূল মানগুলোর বেশি অংশ ধরে রাখার জন্য আপনাকে বৃহত্তর সীমা নির্দিষ্ট করতে হবে। MaxPartitionsContributed এবং MaxContributionsPerPartition এর মতোই, নয়েজ বা কোলাহল সীমার আকার দ্বারা পরিমাপ করা হয়, তাই বৃহত্তর সীমার অর্থ হলো আপনি বেশি ডেটা ধরে রাখতে পারবেন, কিন্তু এর ফলে আপনি আরও বেশি নয়েজযুক্ত ফলাফল পাবেন।
সর্বশেষ যে প্যারামিটারটি নিয়ে আমরা কথা বলব, তা হলো NoiseKind । Privacy On Beam-এ আমরা দুটি ভিন্ন নয়েজ মেকানিজম সমর্থন করি: GaussianNoise এবং LaplaceNoise । দুটিরই নিজস্ব সুবিধা ও অসুবিধা রয়েছে, কিন্তু Laplace ডিস্ট্রিবিউশন কম কন্ট্রিবিউশন বাউন্ডের সাথে আরও ভালো ইউটিলিটি প্রদান করে, যে কারণে Privacy On Beam ডিফল্টভাবে এটি ব্যবহার করে। তবে, আপনি যদি একটি Gaussian ডিস্ট্রিবিউশন নয়েজ ব্যবহার করতে চান, তাহলে আপনি Params এ একটি pbeam.GaussianNoise{} ভ্যারিয়েবল সরবরাহ করতে পারেন।
১০. সারসংক্ষেপ
চমৎকার কাজ! তুমি ‘প্রাইভেসি অন বিম’ কোডল্যাবটি শেষ করেছ। তুমি ডিফারেনশিয়াল প্রাইভেসি এবং ‘প্রাইভেসি অন বিম’ সম্পর্কে অনেক কিছু শিখেছ।
-
MakePrivateFromStructকল করার মাধ্যমে আপনারPCollectionPrivatePCollectionএ পরিণত করুন। - ডিফারেনশিয়ালি প্রাইভেট কাউন্ট গণনা করতে
Countব্যবহার করা হয়। -
MeanPerKeyব্যবহার করে ডিফারেনশিয়ালি প্রাইভেট মিনস গণনা করা হয়। - ডিফারেনশিয়ালি প্রাইভেট যোগফল গণনা করতে
SumPerKeyব্যবহার করা হয়। - একটি একক পাইপলাইনে একটিমাত্র
PrivacySpecব্যবহার করে একাধিক পরিসংখ্যান গণনা করা। - (ঐচ্ছিক)
PrivacySpecএবং অ্যাগ্রিগেশন প্যারামিটার (CountParams, MeanParams, SumParams) কাস্টমাইজ করা।
কিন্তু, Beam-এর Privacy ব্যবহার করে আপনি আরও অনেক ধরনের অ্যাগ্রিগেশন (যেমন কোয়ান্টাইল, স্বতন্ত্র মান গণনা) করতে পারেন! আপনি GitHub রিপোজিটরি বা godoc- এ এ সম্পর্কে আরও জানতে পারবেন।
আপনার সময় থাকলে, অনুগ্রহ করে একটি সমীক্ষা পূরণ করে কোডল্যাবটি সম্পর্কে আমাদের মতামত জানান।