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

কেস স্টাডি: COMPAS ও রিসিডিভিজম প্রেডিকশন

Case study: COMPAS and recidivism prediction
১২ মিনিট পড়া মধ্যবর্তী · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

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

  • COMPAS কী এবং ProPublica-র ২০১৬ তদন্তে ঠিক কী পাওয়া গিয়েছিল
  • কেন "সামগ্রিক নির্ভুলতা সমান" এবং "ত্রুটির ধরন সমানভাবে বণ্টিত" — এই দুটো ভিন্ন দাবি
  • Northpointe/Equivant-এর পাল্টা যুক্তি এবং কেন এটিও গাণিতিকভাবে বৈধ
  • L16-এর ফেয়ারনেস-মেট্রিক্স ক্যালকুলেটর দিয়ে এই প্যাটার্নের একটি সিন্থেটিক পুনর্গঠন — প্রকৃত সংখ্যা দিয়ে যাচাই

১ · COMPAS কী

COMPAS একটি ঝুঁকি-মূল্যায়ন (risk-assessment) অ্যালগরিদম যা যুক্তরাষ্ট্রের কিছু আদালত ব্যবস্থায় একজন আসামি ভবিষ্যতে আবার অপরাধ করবে কিনা (রিসিডিভিজমRecidivismএকজন ব্যক্তির মুক্তি বা সাজার পর আবার অপরাধ করার প্রবণতা।) তার একটি স্কোর তৈরি করে — এই স্কোর জামিন বা সাজা-সংক্রান্ত সিদ্ধান্তে প্রভাব ফেলতে ব্যবহৃত হয়েছে। ২০১৬ সালে সাংবাদিকতা প্রতিষ্ঠান ProPublica "Machine Bias" শিরোনামে একটি বহুল-আলোচিত তদন্ত প্রকাশ করে, যেখানে COMPAS-এর ত্রুটির হার জাতিগত গোষ্ঠী অনুযায়ী বিশ্লেষণ করা হয়েছিল।

২ · ঠিক কী পাওয়া গিয়েছিল

ProPublica-র বিশ্লেষণ অনুযায়ী, ত্রুটিগুলো সমানভাবে বণ্টিত ছিল না: যে কৃষ্ণাঙ্গ আসামিরা পরে আর অপরাধ করেননি, তাদের ভুলভাবে "উচ্চ-ঝুঁকি" হিসেবে চিহ্নিত করার হার (উচ্চতর FPR) ছিল বেশি; আর যে শ্বেতাঙ্গ আসামিরা পরে আবার অপরাধ করেছিলেন, তাদের ভুলভাবে "নিম্ন-ঝুঁকি" হিসেবে চিহ্নিত করার হার (উচ্চতর FNR) ছিল বেশি — অথচ টুলটির সামগ্রিক নির্ভুলতা এবং ক্যালিব্রেশন (একই স্কোর পাওয়া মানুষদের মধ্যে প্রকৃত রিসিডিভিজম হার) উভয় গোষ্ঠীতে তুলনামূলক ছিল। টুলটির নির্মাতা প্রতিষ্ঠান এই ফ্রেমিংয়ের সাথে দ্বিমত পোষণ করে যুক্তি দেয় যে ক্যালিব্রেশনের সমতা নিজেই একটি বৈধ ও তারা পূরণ করেছে এমন একটি ফেয়ারনেস মানদণ্ড। এই ঘটনাটিই হয়ে ওঠে সেই ক্যানোনিক্যাল দৃষ্টান্ত যা দেখায়: ভিন্ন ভিন্ন যুক্তিসঙ্গত ফেয়ারনেস-সংজ্ঞা (ক্যালিব্রেশন বনাম সমান ত্রুটি-হার) — যখন দুই গোষ্ঠীর base rate ভিন্ন হয় — একসাথে গাণিতিকভাবে সন্তুষ্ট করা যায় না। এই কাঠামোগত টেনশনটিই L19-এ সরাসরি বিস্তারিতভাবে আলোচিত হবে।

এই পাঠের কোড সেল বাস্তব COMPAS ডেটা ব্যবহার করে না। এই কোর্সের কাছে প্রকৃত COMPAS/ProPublica ডেটাসেট নেই এবং আমরা কোনো নির্দিষ্ট সংখ্যা ("এক্স শতাংশ") উদ্ভাবন করব না। বরং, নিচে সম্পূর্ণ সিন্থেটিক সংখ্যা দিয়ে দুটি জেনেরিক গোষ্ঠী ("Group A" ও "Group B") তৈরি করা হয়েছে, যেন শুধু উপরের সুপরিচিত প্যাটার্নটি — সমান ক্যালিব্রেশন, ভিন্ন FPR/FNR — গাণিতিকভাবে কীভাবে ঘটে তা প্রকৃত সংখ্যা দিয়ে দেখানো যায়। এই সংখ্যাগুলোকে বাস্তব COMPAS পরিসংখ্যান হিসেবে গণ্য করবেন না।

৩ · প্যাটার্নের একটি সিন্থেটিক পুনর্গঠন

নিচের কোড সেলে L16-এর fairness_metrics() ফাংশনটিই পুনরায় ব্যবহার করা হয়েছে। দুটি সিন্থেটিক গোষ্ঠীর কনফিউশন-ম্যাট্রিক্স সংখ্যা এমনভাবে বেছে নেওয়া হয়েছে যাতে উভয় গোষ্ঠীর ক্যালিব্রেশন ঠিক একই থাকে (predicted-positive-দের মধ্যে প্রকৃত-পজিটিভ হার একই, predicted-negative-দের মধ্যেও একই) — কিন্তু গোষ্ঠী দুটির প্রকৃত base rate ভিন্ন হওয়ায় FPR ও FNR স্বাভাবিকভাবেই ভিন্ন হয়ে যায়। এই ফলাফলটি জোর করে বসানো নয় — সংখ্যাগুলো এমনভাবে বাছা হয়েছে যাতে এই প্যাটার্নটি গণনা থেকে নিজে থেকেই বেরিয়ে আসে।

Python
# সম্পূর্ণ সিন্থেটিক, ইলাস্ট্রেটিভ পুনর্গঠন -- বাস্তব COMPAS/ProPublica ডেটা নয়।
# লক্ষ্য: "সমান ক্যালিব্রেশন কিন্তু ভিন্ন FPR/FNR" প্যাটার্নটি সংখ্যায় দেখা,
# যা ২০১৬ সালের ProPublica তদন্তে রিপোর্ট করা প্যাটার্নের ধরন অনুকরণ করে (প্রকৃত সংখ্যা নয়)

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

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
    accuracy = (len([r for r in records if r["predicted_positive"] == r["actual_positive"]])) / n
    return {"n": n, "demographic_parity": demographic_parity, "fpr": fpr, "fnr": fnr,
            "calibration_pred_positive": calib_pos, "calibration_pred_negative": calib_neg,
            "accuracy": accuracy}

# Group A: predicted-positive ৭০ জন, predicted-negative ৩০ জন (n=100)
group_a = make_group(tp=49, fp=21, fn=6, tn=24)
# Group B: predicted-positive ৩০ জন, predicted-negative ৭০ জন (n=100)
# -- ইচ্ছাকৃতভাবে ভিন্ন predicted-positive অনুপাত, যা ভিন্ন base rate তৈরি করে
group_b = make_group(tp=21, fp=9, fn=14, tn=56)

for name, group in [("Group A", group_a), ("Group B", group_b)]:
    m = fairness_metrics(group)
    base_rate = (sum(1 for r in group if r["actual_positive"])) / m["n"]
    print(f"{name}  (n={m['n']}, প্রকৃত base rate={base_rate*100:.0f}%)")
    print(f"  সামগ্রিক নির্ভুলতা (accuracy):    {m['accuracy']*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 ও Group B-এর ক্যালিব্রেশন হুবহু একই (predicted-positive ৭০.০%, predicted-negative ২০.০% — উভয় গোষ্ঠীতে), এবং সামগ্রিক নির্ভুলতাও কাছাকাছি (৭৩% বনাম ৭৭%)। অথচ FPR সম্পূর্ণ ভিন্ন — Group A-এর ৪৬.৭%, Group B-এর মাত্র ১৩.৮% — আর FNR-ও উল্টো দিকে ভিন্ন — Group A-এর ১০.৯%, Group B-এর ৪০.০%। এটিই সেই প্যাটার্ন যা ProPublica রিপোর্ট করেছিল: একটি গোষ্ঠীর FPR বেশি, অন্য গোষ্ঠীর FNR বেশি, কিন্তু ক্যালিব্রেশন প্রায় সমান — আবারও: এই নির্দিষ্ট সংখ্যাগুলো সিন্থেটিক, বাস্তব COMPAS পরিসংখ্যান নয়।
মূল কথা · Key takeaway

এই সিন্থেটিক পুনর্গঠন দেখায় প্যাটার্নটি কোনো কাকতালীয় ঘটনা বা "খারাপ" নকশার ফল হতে হয় না — এটি ঘটে যখন দুটি গোষ্ঠীর প্রকৃত base rate ভিন্ন হয় এবং টুলটি উভয় গোষ্ঠীতে সমান ক্যালিব্রেশন বজায় রাখে। এখানে কোনো একক "ভিলেন" নেই — বরং একটি কাঠামোগত গাণিতিক টেনশন, যা L19-এ পূর্ণাঙ্গভাবে প্রমাণসহ ব্যাখ্যা করা হবে।

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

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

প্র ০১ Northpointe/Equivant-এর পাল্টা যুক্তি ("আমরা ক্যালিব্রেশনে ন্যায্য") কি সৎ, নাকি এটি শুধু একটি অজুহাত?

গাণিতিকভাবে, ক্যালিব্রেশনের সমতা একটি বৈধ ও অর্থপূর্ণ ফেয়ারনেস মানদণ্ড — এটি নিশ্চিত করে যে স্কোরটি উভয় গোষ্ঠীর জন্য সমানভাবে "বিশ্বাসযোগ্য"। সমস্যাটি এই নয় যে কোনো পক্ষ মিথ্যা বলছে — বরং এটি যে ক্যালিব্রেশন ও ইকুয়ালাইজড অডস উভয়ই যুক্তিসঙ্গত মানদণ্ড, কিন্তু ভিন্ন base rate থাকলে দুটো একসাথে অর্জন করা গাণিতিকভাবে অসম্ভব (L19)। তাই এটি কোনো পক্ষের সততার প্রশ্ন নয়, বরং কোন মানদণ্ডটি এই প্রেক্ষাপটে সবচেয়ে গুরুত্বপূর্ণ তা বেছে নেওয়ার একটি নীতিগত প্রশ্ন।

প্র ০২ ফৌজদারি বিচারব্যবস্থার প্রেক্ষাপটে, উচ্চ FPR (নিরপরাধকে উচ্চ-ঝুঁকি বলা) আর উচ্চ FNR (প্রকৃত ঝুঁকিপূর্ণ ব্যক্তিকে নিম্ন-ঝুঁকি বলা) — কোনটির সামাজিক পরিণতি বেশি গুরুতর মনে হয়, এবং কেন এই প্রশ্নের কোনো "সঠিক" উত্তর সহজে নেই?

উচ্চ FPR একজন ব্যক্তিকে অন্যায়ভাবে দীর্ঘ আটক বা কঠোর সাজার ঝুঁকিতে ফেলে; উচ্চ FNR সমাজের নিরাপত্তা ঝুঁকিতে ফেলে। দুটোই গুরুতর, কিন্তু ভিন্ন পক্ষের উপর ভার চাপায় — একটি ব্যক্তি-স্বাধীনতার উপর, অন্যটি জনসাধারণের নিরাপত্তার উপর। এই দুটোর মধ্যে ভারসাম্য কোথায় হওয়া উচিত তা একটি মূল্যবোধ-নির্ভর নীতিগত সিদ্ধান্ত, যা কোনো একক গাণিতিক সূত্র দিয়ে "সমাধান" করা যায় না।

প্র ০৩ উপরের কোড সেলে যদি উভয় গ্রুপেরই predicted-positive সংখ্যা সমান (যেমন উভয়ই ৫০) করা হতো, তাহলে কি ক্যালিব্রেশন সমান রাখা সম্ভব হতো?

না, যদি উভয় গোষ্ঠীর base rate ভিন্ন থাকে। predicted-positive-দের অনুপাত একই রাখলেও, যেহেতু base rate = P(pred+) × ক্যালিব্রেশন(pred+) + P(pred-) × ক্যালিব্রেশন(pred-), তাই একই predicted-positive অনুপাতে ভিন্ন base rate পেতে হলে ক্যালিব্রেশনের মানই ভিন্ন হতে বাধ্য হবে। অর্থাৎ predicted-positive অনুপাত, base rate, এবং ক্যালিব্রেশন — এই তিনটি রাশি একে অপরের সাথে গাণিতিকভাবে আবদ্ধ (L19-এ বিস্তারিত)।

অনুশীলন

  1. চিন্তা করুন: COMPAS-এর মতো একটি টুল ব্যবহারের আগে, একজন বিচারক বা নীতিনির্ধারকের কী কী প্রশ্ন করা উচিত যা শুধু "সামগ্রিক নির্ভুলতা কত?" প্রশ্নের বাইরেও যায়?

    উদাহরণ প্রশ্ন: এই টুলের FPR ও FNR প্রতিটি জনতাত্ত্বিক গোষ্ঠীতে কেমন? ক্যালিব্রেশন সব গোষ্ঠীতে সমান কিনা? কোন ফেয়ারনেস মানদণ্ডকে অগ্রাধিকার দেওয়া হয়েছে এবং কেন? স্কোরের বিরুদ্ধে আপিলের সুযোগ আছে কিনা? এই প্রশ্নগুলো "সামগ্রিক নির্ভুলতা" সংখ্যাটি একা কখনো উত্তর দিতে পারে না।

  2. পরীক্ষা করুন: উপরের কোড সেলে group_b-এর fp=9-কে fp=21 করে (Group A-এর সমান) Run চেপে দেখুন ক্যালিব্রেশন ও FPR-এ কী পরিবর্তন আসে।

    fp বাড়ালে Group B-এর predicted-positive ক্যালিব্রেশন কমে যাবে (কারণ predicted-positive-দের মধ্যে ভুল অন্তর্ভুক্তি বেড়ে যাচ্ছে), ফলে এটি আর Group A-এর ৭০.০%-এর সমান থাকবে না — অর্থাৎ ক্যালিব্রেশনের সমতা ভেঙে যাবে। এটি দেখায় ক্যালিব্রেশন বজায় রাখতে হলে fp ও tp-এর একটি নির্দিষ্ট অনুপাত বজায় রাখতেই হয় — যা এলোমেলোভাবে বদলানো যায় না।

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

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