বায়াস মিটিগেশন টেকনিক
এই পাঠে যা শিখবেন
- বায়াস মিটিগেশনের তিনটি প্রধান পন্থা — প্রি-প্রসেসিং, ইন-প্রসেসিং, পোস্ট-প্রসেসিং
- প্রতিটি পন্থা কীভাবে কাজ করে ও কোথায় প্রয়োগ হয় (ধারণাগত স্তরে)
- পোস্ট-প্রসেসিং-এ সিদ্ধান্ত পর্যায়ে গ্রুপ-সদস্যতা ব্যবহারের একটি গুরুত্বপূর্ণ নৈতিক/আইনি সতর্কতা
- একটি সত্যিকারের, গণনা করা পোস্ট-প্রসেসিং থ্রেশহোল্ড-অ্যাডজাস্টমেন্ট ডেমো রান করা ও গ্যাপ কমার প্রমাণ দেখা
১ · তিনটি প্রধান পন্থার পরিচিতি
L09-L11-এ আমরা দেখেছি বায়াস কীভাবে ডেটা, মডেল ও ডিপ্লয়মেন্ট স্তরে ঢুকতে পারে, এবং L10-এ শিখেছি এটি ফরমালি কীভাবে মাপা যায়। এখন প্রশ্ন হলো: বায়াস কমানো যায় কীভাবে? গবেষণা ও প্র্যাকটিসে এই কৌশলগুলোকে সাধারণত পাইপলাইনে তারা কোথায় হস্তক্ষেপ করে তার ভিত্তিতে তিনটি শ্রেণীতে ভাগ করা হয়:
ট্রেনিং ডেটাকেই সংশোধন করা — মডেল ট্রেন হওয়ার আগে।
ট্রেনিং প্রক্রিয়ার মধ্যেই ফেয়ারনেস কনস্ট্রেইন্ট যোগ করা।
ট্রেনিং শেষ হওয়া মডেলের আউটপুট/থ্রেশহোল্ড সমন্বয় করা।
২ · প্রি-প্রসেসিং — ডেটাকেই সংশোধন করা
প্রি-প্রসেসিং কৌশলগুলো মডেল ট্রেন হওয়ার আগেই ডেটাসেটে হস্তক্ষেপ করে। দুটি সাধারণ কৌশল:
- রিওয়েটিং (reweighting): প্রতিটি ট্রেনিং উদাহরণকে একটি ওয়েট দেওয়া হয় যাতে কম- প্রতিনিধিত্বপ্রাপ্ত গ্রুপ/আউটকাম কম্বিনেশনগুলো ট্রেনিং প্রক্রিয়ায় আপেক্ষিকভাবে বেশি গুরুত্ব পায়।
- রিস্যাম্পলিং (resampling): কম-প্রতিনিধিত্বপ্রাপ্ত গ্রুপ থেকে অতিরিক্ত নমুনা (আপস্যাম্পলিং) নেওয়া অথবা সংখ্যাগরিষ্ঠ গ্রুপ থেকে নমুনা কমানো (ডাউনস্যাম্পলিং), যাতে ট্রেনিং সেটে গ্রুপগুলোর প্রতিনিধিত্ব আরও সুষম হয়।
সুবিধা: মডেল আর্কিটেকচার অপরিবর্তিত থাকে, তাই যেকোনো মডেলের সাথে ব্যবহারযোগ্য। সীমাবদ্ধতা: L09-এ আলোচিত মেজারমেন্ট বায়াস (যেমন একটি ফিচার নিজেই ভুলভাবে পরিমাপ করা) প্রি-প্রসেসিং দিয়ে ঠিক করা যায় না — এটি শুধু প্রতিনিধিত্ব/ভারসাম্য ঠিক করে, ফিচারের অন্তর্নিহিত মান নয়।
৩ · ইন-প্রসেসিং — ট্রেনিং প্রক্রিয়ার মধ্যেই ফেয়ারনেস
ইন-প্রসেসিং কৌশলগুলো মডেলের অপ্টিমাইজেশন লক্ষ্যকেই পরিবর্তন করে — শুধু অ্যাকুরেসি সর্বোচ্চ করা নয়, বরং অ্যাকুরেসির সাথে একটি ফেয়ারনেস কনস্ট্রেইন্ট/পেনাল্টিও যোগ করে ট্রেনিং করা (যেমন "গ্রুপ জুড়ে ডেমোগ্রাফিক প্যারিটির গ্যাপ একটি নির্দিষ্ট সীমার মধ্যে রাখতে হবে" — এমন একটি শর্ত অপ্টিমাইজেশনে যোগ করা)। এর কারিগরি বাস্তবায়ন (constrained optimization, adversarial debiasing ইত্যাদি) Machine Learning কোর্সের অপ্টিমাইজেশন-সম্পর্কিত বিষয়ের সম্প্রসারণ। সুবিধা: সরাসরি একটি নির্দিষ্ট ফেয়ারনেস মেট্রিক্স লক্ষ্য করে অপ্টিমাইজ করা যায়। সীমাবদ্ধতা: মডেল-নির্দিষ্ট বাস্তবায়ন প্রয়োজন, এবং অ্যাকুরেসি ও ফেয়ারনেসের মধ্যে একটি ট্রেড-অফ প্রায়ই দেখা যায়।
৪ · পোস্ট-প্রসেসিং — সিদ্ধান্ত পর্যায়ে সমন্বয়
পোস্ট-প্রসেসিং কৌশলগুলো মডেলকে সম্পূর্ণ অপরিবর্তিত রাখে — শুধু মডেলের আউটপুট স্কোর থেকে চূড়ান্ত সিদ্ধান্তে রূপান্তরের নিয়মটি (যেমন থ্রেশহোল্ড) গ্রুপভেদে ভিন্নভাবে সেট করা হয়, যাতে একটি নির্দিষ্ট ফেয়ারনেস মেট্রিক্স (যেমন ডেমোগ্রাফিক প্যারিটি) সন্তুষ্ট হয়। এটি প্রয়োগ করা সবচেয়ে সহজ — বিদ্যমান মডেল পুনরায় ট্রেন করার প্রয়োজন নেই।
৫ · একটি সত্যিকারের পোস্ট-প্রসেসিং ডেমো
নিচের কোডে L09/L10-এর মতোই একটি বায়াসড স্কোরিং মডেল আছে — গ্রুপ A-এর স্কোরে একটি সিস্টেমেটিক নিম্নমুখী শিফট যোগ করা হয়েছে। প্রথমে একটি একক (shared) থ্রেশহোল্ডে সিলেকশন-রেট গ্যাপ দেখানো হচ্ছে, তারপর গ্রুপ A-এর জন্য একটি নতুন, কম থ্রেশহোল্ড খুঁজে বের করে (এমনভাবে যাতে গ্রুপ A-এর সিলেকশন রেট গ্রুপ B-এর রেটের কাছাকাছি আসে) গ্যাপ সত্যিই কতটা কমে তা গণনা করে দেখানো হচ্ছে।
import random
random.seed(5)
def generate_group(n, group, bias_shift):
people = []
for _ in range(n):
base_score = random.gauss(0.55, 0.15)
score = max(0.0, min(1.0, base_score + bias_shift))
people.append({"group": group, "score": score})
return people
group_a = generate_group(500, "A", bias_shift=-0.12) # গ্রুপ A-এর স্কোরে সিস্টেমেটিক নিম্নমুখী বায়াস
group_b = generate_group(500, "B", bias_shift=0.0)
def selection_rate(people, threshold):
selected = [1 for p in people if p["score"] >= threshold]
return len(selected) / len(people)
SHARED_THRESHOLD = 0.55
rate_a_shared = selection_rate(group_a, SHARED_THRESHOLD)
rate_b_shared = selection_rate(group_b, SHARED_THRESHOLD)
gap_shared = abs(rate_a_shared - rate_b_shared) * 100
print("=== একক (shared) থ্রেশহোল্ড -- পোস্ট-প্রসেসিং অ্যাডজাস্টমেন্টের আগে ===")
print(f"গ্রুপ A সিলেকশন রেট: {rate_a_shared*100:.1f}%")
print(f"গ্রুপ B সিলেকশন রেট: {rate_b_shared*100:.1f}%")
print(f"গ্যাপ: {gap_shared:.1f} পার্সেন্টেজ পয়েন্ট")
# পোস্ট-প্রসেসিং: প্রতিটি গ্রুপের জন্য আলাদা থ্রেশহোল্ড খুঁজে বের করা, যাতে সিলেকশন রেট লক্ষ্য-মানের কাছাকাছি হয়
TARGET_RATE = rate_b_shared # গ্রুপ B-এর রেটকে লক্ষ্য (বেঞ্চমার্ক) হিসেবে ধরা হলো
def find_threshold_for_target_rate(people, target_rate):
scores = sorted((p["score"] for p in people), reverse=True)
n = len(scores)
best_threshold = 1.0
best_diff = float("inf")
for candidate in scores: # প্রতিটি প্রার্থীর স্কোরকে সম্ভাব্য থ্রেশহোল্ড হিসেবে পরীক্ষা করা হচ্ছে
rate = sum(1 for s in scores if s >= candidate) / n
diff = abs(rate - target_rate)
if diff < best_diff:
best_diff = diff
best_threshold = candidate
return best_threshold
threshold_a_adjusted = find_threshold_for_target_rate(group_a, TARGET_RATE)
threshold_b_adjusted = SHARED_THRESHOLD # গ্রুপ B আগের থ্রেশহোল্ডেই থাকছে -- এটিই লক্ষ্য রেট
rate_a_adjusted = selection_rate(group_a, threshold_a_adjusted)
rate_b_adjusted = selection_rate(group_b, threshold_b_adjusted)
gap_adjusted = abs(rate_a_adjusted - rate_b_adjusted) * 100
print()
print("=== গ্রুপ-ভিত্তিক পৃথক থ্রেশহোল্ড -- পোস্ট-প্রসেসিং অ্যাডজাস্টমেন্টের পরে ===")
print(f"গ্রুপ A-এর নতুন থ্রেশহোল্ড: {threshold_a_adjusted:.3f} (আগে ছিল {SHARED_THRESHOLD})")
print(f"গ্রুপ A সিলেকশন রেট: {rate_a_adjusted*100:.1f}%")
print(f"গ্রুপ B সিলেকশন রেট: {rate_b_adjusted*100:.1f}%")
print(f"গ্যাপ: {gap_adjusted:.1f} পার্সেন্টেজ পয়েন্ট")
print()
print(f"গ্যাপ কমেছে: {gap_shared:.1f} → {gap_adjusted:.1f} পার্সেন্টেজ পয়েন্ট")
পোস্ট-প্রসেসিং ডেমোগ্রাফিক প্যারিটির গ্যাপ কার্যকরভাবে কমাতে পারে — কিন্তু এটি স্বয়ংক্রিয়ভাবে ইকুয়ালাইজড অডস বা ক্যালিব্রেশনও সমান করে দেয় না (L10-এর তিনটি মেট্রিক্স মনে করুন — এগুলো স্বাধীন)। একটি মেট্রিক্সে গ্যাপ বন্ধ করলে অন্য মেট্রিক্সে নতুন গ্যাপ তৈরি হতে পারে। L13-এ আমরা দেখব কেন এই ট্রেড-অফ কখনো কখনো গাণিতিকভাবে অনিবার্য।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ যদি একটি ফিচার নিজেই ভুলভাবে পরিমাপ করা হয় (L09-এর মেজারমেন্ট বায়াস), শুধু প্রি-প্রসেসিং (রিওয়েটিং/রিস্যাম্পলিং) দিয়ে কি সমস্যাটি সম্পূর্ণ সমাধান করা যাবে? কেন বা কেন নয়?
না, সম্পূর্ণভাবে নয়। রিওয়েটিং/রিস্যাম্পলিং গ্রুপগুলোর প্রতিনিধিত্ব/ভারসাম্য ঠিক করে, কিন্তু ফিচারের অন্তর্নিহিত মান পরিবর্তন করে না — যদি একটি ফিচার নিজেই ভুলভাবে/অসমভাবে পরিমাপ করা হয়ে থাকে (যেমন গ্রেপ্তারের সংখ্যা প্রকৃত অপরাধের বদলে নজরদারির তীব্রতা প্রতিফলিত করে), সেই সমস্যা ডেটা রিওয়েটিং-এর পরেও থেকে যাবে — এখানে প্রয়োজন হতে পারে ফিচার নির্বাচন পুনর্বিবেচনা করা বা ফিচারটি সম্পূর্ণ বাদ দেওয়া।
প্র ০২ পোস্ট-প্রসেসিং-এ সিদ্ধান্ত পর্যায়ে গ্রুপ-সদস্যতা ব্যবহার করার সতর্কতাটি ঠিক কী, এবং প্রি/ইন- প্রসেসিং-এর সাথে এর পার্থক্য কী?
পোস্ট-প্রসেসিং-এ সিদ্ধান্ত নেওয়ার মুহূর্তে একজন ব্যক্তির গ্রুপ-সদস্যতা জেনে ইচ্ছাকৃতভাবে ভিন্ন থ্রেশহোল্ড প্রয়োগ করা হয় — কিছু প্রেক্ষাপটে এটি "disparate treatment" (protected attribute-ভিত্তিক প্রত্যক্ষ ভিন্ন আচরণ) হিসেবে আইনগতভাবে বিবেচিত হতে পারে। প্রি-প্রসেসিং শুধু ট্রেনিং ডেটায় হস্তক্ষেপ করে এবং ইন-প্রসেসিং ট্রেনিং-এর সময় ফেয়ারনেস কনস্ট্রেইন্ট ব্যবহার করে — উভয় ক্ষেত্রেই মডেল ডিপ্লয় হওয়ার পর প্রতিটি ব্যক্তির সিদ্ধান্ত নেওয়ার মুহূর্তে গ্রুপ-সদস্যতা জানার প্রয়োজন সাধারণত হয় না।
প্র ০৩ উপরের ডেমোতে আমরা ডেমোগ্রাফিক প্যারিটি (সিলেকশন রেট) সমান করেছি। এটি কি স্বয়ংক্রিয়ভাবে ইকুয়ালাইজড অডসও সমান করে দেয়?
না, নিশ্চিতভাবে নয়। L10-এ আমরা দেখেছি ডেমোগ্রাফিক প্যারিটি, ইকুয়ালাইজড অডস ও ক্যালিব্রেশন তিনটি স্বাধীন মেট্রিক্স — একটি সমান করলে অন্যগুলো স্বয়ংক্রিয়ভাবে সমান হয়ে যায় এমন কোনো গ্যারান্টি নেই। প্রকৃত অডিটে সাধারণত কোন মেট্রিক্স সবচেয়ে গুরুত্বপূর্ণ তা প্রেক্ষাপট অনুযায়ী আগে থেকে ঠিক করে নিতে হয়, এবং সেই নির্দিষ্ট মেট্রিক্সের জন্যই মিটিগেশন ডিজাইন করতে হয়।
অনুশীলন
-
চিন্তা করুন: উপরের কোড সেলে গ্রুপ A-এর
bias_shift-কে-0.12থেকে আরও বড় করে-0.25-এ পরিবর্তন করলে (অর্থাৎ প্রাথমিক বায়াস আরও বেশি হলে), পোস্ট- প্রসেসিং অ্যাডজাস্টমেন্টের পরের গ্যাপ কেমন হবে বলে আপনার ধারণা?অ্যাডজাস্টমেন্টের আগের গ্যাপ (
gap_shared) অনেক বড় হবে, কিন্তুfind_threshold_for_target_rateফাংশনটি তখনও গ্রুপ A-এর জন্য একটি নতুন থ্রেশহোল্ড খুঁজে বের করবে যা সিলেকশন রেটকে লক্ষ্য-মানের কাছাকাছি নিয়ে আসে — তাই অ্যাডজাস্টমেন্টের পরের গ্যাপ তখনও প্রায় শূন্যের কাছাকাছি থাকবে, শুধু নতুন থ্রেশহোল্ডের মান আরও কম হবে। -
পরীক্ষা করুন: উপরের কোড সেলে
bias_shift=-0.12-কেbias_shift=-0.25-এ পরিবর্তন করে Run চেপে আপনার অনুমান যাচাই করুন।পরিবর্তনের পর
gap_sharedআগের চেয়ে অনেক বড় দেখাবে (যেহেতু প্রাথমিক বায়াস বেশি), কিন্তুgap_adjustedতখনও প্রায় ০.০ পার্সেন্টেজ পয়েন্টের কাছাকাছি থাকবে — এটি দেখায় থ্রেশহোল্ড-সার্চ পদ্ধতিটি প্রাথমিক বায়াসের মাত্রা যাই হোক না কেন, লক্ষ্য রেটের কাছাকাছি পৌঁছাতে সক্ষম, যতক্ষণ পর্যাপ্ত সংখ্যক প্রার্থী থাকে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পরবর্তী পাঠ L13 নিখুঁত ফেয়ারনেসের অসম্ভাব্যতা — কেন ক্যালিব্রেশন ও ইকুয়ালাইজড অডস একসাথে পূরণ করা সাধারণত গাণিতিকভাবে অসম্ভব, একটি সত্যিকারের কম্পিউটেড সুইপ দিয়ে দেখানো হবে।
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ নৈতিক ফ্রেমওয়ার্ক, বায়াস-ফেয়ারনেস, প্রাইভেসি, ট্রান্সপারেন্সি, AI অ্যালাইনমেন্ট, জেনারেটিভ AI/LLM এথিক্স, সামাজিক প্রভাব, গভর্নেন্স ও রেগুলেশন, সেক্টর-স্পেসিফিক এথিক্স ও এক্সিস্টেনশিয়াল রিস্ক বিতর্ক।
- Machine Learning কোর্স প্রাসঙ্গিক ফাউন্ডেশন ইন-প্রসেসিং কৌশলের পেছনের অপ্টিমাইজেশন কারিগরি বিস্তারিত এই কোর্সে কভার করা হয়েছে।