অধ্যায় 5 · সম্ভাবনা
শর্তসাপেক্ষ সম্ভাবনা ও বেইজের উপপাদ্য
- পৃষ্ঠা 14 / 17
- 3 মিনিট পড়া
শর্তসাপেক্ষ সম্ভাবনা হলো অন্য কিছু আগে থেকে জানা থাকলে কোনো কিছুর সম্ভাবনা। লেখা হয় P(A | B): "B দেওয়া থাকলে A-এর সম্ভাবনা"। একটা ইমেইল স্প্যাম হওয়ার সম্ভাবনা এক জিনিস; তাতে "free" শব্দটা আছে জানলে সেটা স্প্যাম হওয়ার সম্ভাবনা আরেক জিনিস — আর প্রতিটা ক্লাসিফায়ার আসলে দ্বিতীয় ধরনটাই হিসাব করে।
বেইজের উপপাদ্য
বেইজের উপপাদ্য বলে নতুন প্রমাণ দেখলে একটা বিশ্বাস কীভাবে হালনাগাদ করতে হয়:
P(A | B) = P(B | A) × P(A) / P(B)P(A)— প্রায়োর: প্রমাণের আগে যা বিশ্বাস করতেন (বেস রেট)।P(B | A)— লাইকলিহুড: A সত্য হলে প্রমাণটা কতটা সম্ভাব্য।P(A | B)— পোস্টেরিয়র: আপনার হালনাগাদ করা বিশ্বাস।
অবাক করা মেডিকেল টেস্ট
একটা রোগ ১% মানুষের হয়। একটা পরীক্ষা আসল রোগীদের ৯৯% ধরে, আর সুস্থদের ৫%-কে ভুল করে "পজিটিভ" বলে। আপনার ফল পজিটিভ এল। রোগটা থাকার সম্ভাবনা কত? বেশিরভাগ মানুষ আন্দাজ করেন প্রায় ৯৫%। আসল উত্তর — প্রথমে সূত্র দিয়ে, তারপর দশ লাখ মানুষ সিমুলেট করে:
import numpy as np
p_disease = 0.01 # ১% মানুষের রোগটা আছে (বেস রেট)
p_pos_if_disease = 0.99 # সেনসিটিভিটি: পরীক্ষা আসল রোগীদের ৯৯% ধরে
p_pos_if_healthy = 0.05 # সুস্থদের ৫%-ও পজিটিভ আসে
p_pos = p_pos_if_disease * p_disease + p_pos_if_healthy * (1 - p_disease)
p_disease_if_pos = p_pos_if_disease * p_disease / p_pos
print(f"P(disease | positive test) = {p_disease_if_pos:.1%}")
# দশ লাখ মানুষ সিমুলেট করে যাচাই
rng = np.random.default_rng(2)
sick = rng.random(1_000_000) < p_disease
positive = np.where(sick, rng.random(1_000_000) < p_pos_if_disease,
rng.random(1_000_000) < p_pos_if_healthy)
print(f"simulated: {sick[positive].mean():.1%}")P(disease | positive test) = 16.7%
simulated: 16.5%মাত্র প্রায় ১৭%। ১০,০০০ জনের কথা ভাবুন: ১০০ জন অসুস্থ, আর তাদের ৯৯ জনের ফল পজিটিভ। কিন্তু ৯,৯০০ জন সুস্থের ৫% — ৪৯৫ জন — তাদেরও পজিটিভ আসে। ৫৯৪টা পজিটিভের মধ্যে আসলে অসুস্থ মাত্র ৯৯ জন। কিছু যখন বিরল, তখন ভালো পরীক্ষাও সত্যিকারের সংকেতের চেয়ে বেশি মিথ্যা সতর্কতা দেয়। বেস রেট উপেক্ষা করাকে বলে বেস-রেট ভ্রান্তি, আর বিরল কিছু খোঁজা প্রতিটা AI সিস্টেমে এর প্রভাব পড়ে: প্রতারণা, অনুপ্রবেশ, ত্রুটি, রোগ।
স্প্যাম ফিল্টার
প্রথম সফল স্প্যাম ফিল্টারগুলো বেইজের উপপাদ্যের ওপর গড়া হয়েছিল। একটা শব্দ স্প্যামে আর সাধারণ ইমেইলে কতবার আসে গুনুন, তারপর সম্ভাবনা হালনাগাদ করুন:
# ১,০০০টা ইমেইলের মধ্যে: ২০০টা স্প্যাম, ৮০০টা না।
# "free" আছে ১২০টা স্প্যামে আর বাকিগুলোর ৪০টায়।
spam, ham = 200, 800
free_in_spam, free_in_ham = 120, 40
p_spam = spam / (spam + ham)
p_free_given_spam = free_in_spam / spam
p_free = (free_in_spam + free_in_ham) / (spam + ham)
print(f"P(spam) = {p_spam:.2f}")
print(f"P(spam | 'free') = {p_free_given_spam * p_spam / p_free:.2f}")P(spam) = 0.20
P(spam | 'free') = 0.75ইমেইল পড়ার আগে স্প্যামের সম্ভাবনা ২০%। "free" দেখার পর ৭৫%। একটা নাইভ বেইজ ক্লাসিফায়ার প্রতিটা শব্দের জন্য এটা করে আর প্রমাণগুলো মেলায়। টেক্সট ক্লাসিফিকেশনে এটা এখনো দ্রুত, শক্তিশালী একটা বেসলাইন — scikit-learn-এ এটা আছে MultinomialNB নামে।
নিজে চেষ্টা করুন
- মেডিকেল উদাহরণে রোগের হার বদলে ১০% করুন। এখন P(রোগ | পজিটিভ) কত?
- ফলস-পজিটিভের হার ৫% থেকে কমে ১% হলে কী হয়?
- "win" আছে ৫০টা স্প্যামে আর ১০টা সাধারণ ইমেইলে। P(স্প্যাম | "win") হিসাব করুন।