পাঠ ১৬ · ৫৭-এর মধ্যে · মডিউল ৪
Home / Courses / Ethics in Computing & AI Safety / অ্যালগরিদমিক বায়াস ও ফেয়ারনেস

ফেয়ারনেস মেট্রিক্স — ডেমোগ্রাফিক প্যারিটি ও ইকুয়ালাইজড অডস

Fairness metrics: demographic parity and equalized odds
১১ মিনিট পড়া মধ্যবর্তী · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • চারটি মূল ফেয়ারনেস মেট্রিক্সের সংজ্ঞা ও সূত্র (KaTeX-এ)
  • কেন একটি মেট্রিক্সে "ফেয়ার" হওয়া অন্য মেট্রিক্সে "ফেয়ার" হওয়ার গ্যারান্টি দেয় না
  • Python দিয়ে একটি পুনর্ব্যবহারযোগ্য ফেয়ারনেস-মেট্রিক্স ক্যালকুলেটর — যা L17-L19-এও ব্যবহৃত হবে
  • কীভাবে দুটি গোষ্ঠীর ভিন্ন base rate (প্রকৃত পজিটিভ হার) থাকলেও ডেমোগ্রাফিক প্যারিটি মিলে যেতে পারে, অথচ অন্য মেট্রিক্স ভিন্ন থাকে

১ · কেন একটি সংখ্যা যথেষ্ট নয়

L15-এ দেখা গেছে বায়াস বিভিন্ন জায়গা থেকে আসতে পারে। কিন্তু একবার একটি মডেল ডিপ্লয় হয়ে গেলে, "এটি কি ফেয়ার?" প্রশ্নের উত্তর দিতে হলে একটি সুনির্দিষ্ট, গণনাযোগ্য সংজ্ঞা দরকার। সমস্যা হলো — ফেয়ারনেসFairnessএকটি ক্লাসিফায়ারের সিদ্ধান্ত বিভিন্ন গোষ্ঠীর মধ্যে ন্যায্যভাবে বণ্টিত হচ্ছে কিনা তা মাপার একটি গাণিতিক মানদণ্ড — যার একাধিক, পরস্পর থেকে স্বতন্ত্র সংজ্ঞা আছে। -এর একটি একক সংজ্ঞা নেই। নিচের চারটি মেট্রিক প্রতিটি একটি ভিন্ন, বৈধ প্রশ্নের উত্তর দেয় — এবং L19-এ দেখা যাবে এই প্রশ্নগুলোর উত্তর একসাথে "হ্যাঁ" হওয়া গাণিতিকভাবে সবসময় সম্ভব নয়।

প্রকৃত (Actual) প্রেডিকশন পজিটিভ নেগেটিভ পজিটিভ নেগেটিভ TP সঠিক পজিটিভ FP FPR-এর ভিত্তি FN FNR-এর ভিত্তি TN সঠিক নেগেটিভ
চারটি ফেয়ারনেস মেট্রিক্সই এই একই চারটি সংখ্যা (TP, FP, FN, TN) থেকে গণনা করা হয় — শুধু ভিন্নভাবে ভাগ করে।

২ · চারটি মেট্রিক ও তাদের সূত্র

ডেমোগ্রাফিক প্যারিটি
$P(\hat{y}=1)$ প্রতিটি গোষ্ঠীতে সমান কিনা — মোট কতজনকে পজিটিভ প্রেডিক্ট করা হলো।
ফলস পজিটিভ রেট (FPR)
$FPR = \dfrac{FP}{FP+TN}$ — প্রকৃত নেগেটিভদের মধ্যে কতজনকে ভুলভাবে পজিটিভ বলা হলো।
ফলস নেগেটিভ রেট (FNR)
$FNR = \dfrac{FN}{FN+TP}$ — প্রকৃত পজিটিভদের মধ্যে কতজনকে ভুলভাবে নেগেটিভ বলা হলো। FPR ও FNR উভয়ই সমান হলে তাকে ইকুয়ালাইজড অডস বলে।
ক্যালিব্রেশন
$P(y=1 \mid \hat{y}=1)$ ও $P(y=1 \mid \hat{y}=0)$ — যাদের একই প্রেডিকশন দেওয়া হয়েছে, তাদের মধ্যে প্রকৃত পজিটিভ হার।

৩ · একটি সত্যিকারের ফেয়ারনেস-মেট্রিক্স ক্যালকুলেটর

নিচের কোড সেলে দুটি সিন্থেটিক গোষ্ঠী আছে — একটি হাইপোথেটিক্যাল স্ক্রিনিং অ্যালগরিদমের প্রেডিকশন (predicted_positive) ও প্রকৃত ফলাফল (actual_positive) সহ, কোনো বাস্তব কোম্পানি বা প্রকৃত ডেটাসেট নয়। একটি একক fairness_metrics() ফাংশন চারটি মেট্রিকই গণনা করবে — এই ফাংশনটিই L17-L19-এ পুনরায় ব্যবহার ও সম্প্রসারিত হবে।

Python
# সিন্থেটিক, ইলাস্ট্রেটিভ উদাহরণ -- একটি hypothetical স্ক্রিনিং অ্যালগরিদমের প্রেডিকশন,
# বাস্তব কোনো কোম্পানি বা প্রকৃত ডেটাসেট নয়

def make_group(tp, fp, fn, tn):
    records  = [{"predicted_positive": True,  "actual_positive": True}]  * tp
    records += [{"predicted_positive": True,  "actual_positive": False}] * fp
    records += [{"predicted_positive": False, "actual_positive": True}]  * fn
    records += [{"predicted_positive": False, "actual_positive": False}] * tn
    return records

# Group A: TP=16, FP=4, FN=4, TN=16  (n=40, base rate 50%)
group_a = make_group(tp=16, fp=4, fn=4, tn=16)
# Group B: TP=10, FP=10, FN=6, TN=14  (n=40, base rate 40% -- A-এর চেয়ে ভিন্ন)
group_b = make_group(tp=10, fp=10, fn=6, tn=14)

def fairness_metrics(records):
    n = len(records)
    pred_pos   = [r for r in records if r["predicted_positive"]]
    pred_neg   = [r for r in records if not r["predicted_positive"]]
    actual_pos = [r for r in records if r["actual_positive"]]
    actual_neg = [r for r in records if not r["actual_positive"]]

    demographic_parity = len(pred_pos) / n

    fp = len([r for r in actual_neg if r["predicted_positive"]])
    fpr = fp / len(actual_neg) if actual_neg else 0.0

    fn = len([r for r in actual_pos if not r["predicted_positive"]])
    fnr = fn / len(actual_pos) if actual_pos else 0.0

    calib_pos = (len([r for r in pred_pos if r["actual_positive"]]) / len(pred_pos)) if pred_pos else 0.0
    calib_neg = (len([r for r in pred_neg if r["actual_positive"]]) / len(pred_neg)) if pred_neg else 0.0

    return {
        "n": n, "demographic_parity": demographic_parity,
        "fpr": fpr, "fnr": fnr,
        "calibration_pred_positive": calib_pos,
        "calibration_pred_negative": calib_neg,
    }

for name, group in [("Group A", group_a), ("Group B", group_b)]:
    m = fairness_metrics(group)
    print(f"{name}  (n={m['n']})")
    print(f"  ডেমোগ্রাফিক প্যারিটি:            {m['demographic_parity']*100:.1f}%")
    print(f"  False Positive Rate:            {m['fpr']*100:.1f}%")
    print(f"  False Negative Rate:            {m['fnr']*100:.1f}%")
    print(f"  ক্যালিব্রেশন (predicted-positive): {m['calibration_pred_positive']*100:.1f}%")
    print(f"  ক্যালিব্রেশন (predicted-negative): {m['calibration_pred_negative']*100:.1f}%")
    print()

    
লক্ষ্য করুন: দুটি গোষ্ঠীরই ডেমোগ্রাফিক প্যারিটি ঠিক ৫০.০% — অর্থাৎ এই একটি মেট্রিক্সে সিস্টেমটি "ফেয়ার"। কিন্তু Group A-এর FPR ও FNR উভয়ই ২০.০%, অথচ Group B-এর FPR ৪১.৭% ও FNR ৩৭.৫% — অনেক বেশি। ক্যালিব্রেশনও ভিন্ন (A: ৮০.০%/২০.০%, B: ৫০.০%/৩০.০%)। একই ডেটা, চারটি ভিন্ন উত্তর — এটিই দেখায় "ফেয়ার" শব্দটি একটি প্রশ্ন নয়, বরং একাধিক প্রশ্নের সেট।
মূল কথা · Key takeaway

দুটি গোষ্ঠীর base rate (প্রকৃত পজিটিভ হার — এখানে A-তে ৫০%, B-তে ৪০%) ভিন্ন হলে, একটি মেট্রিক্সে সমতা অর্জন করলেও অন্য মেট্রিক্সে সমতা আসে না, এটি প্রায়ই স্বাভাবিক গাণিতিক ফলাফল, নকশার ত্রুটি নয় — এই সম্পর্কটিই L19-এ গভীরভাবে অন্বেষণ করা হবে। L17-এ এই একই ক্যালকুলেটর প্রয়োগ করা হবে এমন একটি সিন্থেটিক ডেটাসেটে যা বাস্তব-জগতের একটি সুপরিচিত কেস স্টাডির প্যাটার্ন মিরর করে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ দুটি গোষ্ঠীর ডেমোগ্রাফিক প্যারিটি সমান হওয়া সত্ত্বেও FPR ও FNR কীভাবে এত ভিন্ন হতে পারে?

ডেমোগ্রাফিক প্যারিটি শুধু মোট কতজনকে পজিটিভ বলা হলো তা মাপে — কাদের ভুলভাবে বলা হলো তা নয়। Group A ও B-তে সমানসংখ্যক (২০ জন করে) পজিটিভ প্রেডিকশন থাকলেও, কারা সঠিকভাবে বনাম ভুলভাবে সেই লেবেল পেয়েছে তা সম্পূর্ণ ভিন্ন হতে পারে — বিশেষত যখন দুই গোষ্ঠীর প্রকৃত পজিটিভ হার (base rate) নিজেই ভিন্ন।

প্র ০২ একটি ঋণদাতা প্রতিষ্ঠান হয়তো ক্যালিব্রেশনকে সবচেয়ে গুরুত্বপূর্ণ মনে করে, একজন সমাজকর্মী হয়তো FNR-কে — কেন এই পার্থক্য?

ক্যালিব্রেশন উত্তর দেয় "এই স্কোরটি কি বিশ্বাসযোগ্য?" — একটি ঝুঁকি-ব্যবস্থাপনা দৃষ্টিকোণ থেকে গুরুত্বপূর্ণ। FNR উত্তর দেয় "যোগ্য মানুষদের মধ্যে কতজনকে ভুলভাবে বাদ দেওয়া হলো?" — একজন সমাজকর্মীর কাছে এটিই আসল উদ্বেগ, কারণ এটি সরাসরি ক্ষতিগ্রস্ত মানুষের সংখ্যা নির্দেশ করে। কোন মেট্রিক্স "সবচেয়ে গুরুত্বপূর্ণ" তা প্রেক্ষাপট ও মূল্যবোধের উপর নির্ভর করে — এটি একটি প্রযুক্তিগত প্রশ্নের চেয়ে বেশি একটি নীতিগত প্রশ্ন।

প্র ০৩ যদি Group B-এর tn মান ১৪ থেকে বাড়িয়ে ২০ করা হয় (এবং fp কমিয়ে ৪ করা হয়), FPR-এর কী হবে?

নতুন FPR = FP/(FP+TN) = 4/(4+20) = 4/24 ≈ ১৬.৭% — যা আগের ৪১.৭% থেকে অনেক কম, এবং এখন Group A-এর ২০.০%-এর কাছাকাছি। এটি দেখায় FPR শুধুমাত্র প্রকৃত-নেগেটিভদের (FP + TN) মধ্যে ভাগের উপর নির্ভর করে — TP বা FN-এর কোনো পরিবর্তন ছাড়াই এটি বদলাতে পারে।

অনুশীলন

  1. চিন্তা করুন: একটি চাকরির আবেদন-স্ক্রিনিং টুলের জন্য, "ভুলভাবে প্রত্যাখ্যাত হওয়া" (FNR বেশি) আর "ভুলভাবে এগিয়ে দেওয়া" (FPR বেশি) — কোনটি আবেদনকারীর জন্য বেশি ক্ষতিকর, আর কোনটি নিয়োগকর্তার জন্য বেশি ক্ষতিকর?

    একজন যোগ্য আবেদনকারীর জন্য ভুলভাবে প্রত্যাখ্যাত হওয়া (FNR) সরাসরি ক্ষতিকর — একটি সুযোগ হারানো। নিয়োগকর্তার জন্য ভুলভাবে এগিয়ে দেওয়া (FPR) ক্ষতিকর — সময় ও সম্পদ অপচয়। এই দুটি ভিন্ন পক্ষের ভিন্ন স্বার্থ প্রতিফলিত করে, এবং একটি থ্রেশহোল্ড পরিবর্তন করলে একটি কমলে অন্যটি সাধারণত বাড়ে (L18-এ এই ট্রেড-অফ আরও বিস্তারিত)।

  2. পরীক্ষা করুন: উপরের কোড সেলে group_b-এর fn=6-কে fn=2 করে (এবং tp বাড়িয়ে 14 করে, যাতে base rate একই থাকে) Run চেপে দেখুন FNR ও ক্যালিব্রেশন কীভাবে বদলায়।

    নতুন FNR = FN/(FN+TP) = 2/16 = ১২.৫% — অনেক কমে যাবে। predicted-positive ক্যালিব্রেশনও বদলাবে কারণ pred_pos-এর সংখ্যা (tp+fp) বেড়ে ২৪ হবে এবং তার মধ্যে actual positive (tp=14) অনুপাত ৫৮.৩%-এ দাঁড়াবে — দেখাচ্ছে কীভাবে একটি একক কনফিউশন-ম্যাট্রিক্স সংখ্যা বদলালে একাধিক মেট্রিক্স একই সাথে প্রভাবিত হয়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
বায়াস কোথা থেকে আসে — ডেটা, মডেল, ডিপ্লয়মেন্ট