Classification পরিচিতি
Machine Learning আসলে কী?
ধরো, তুমি ছোটবেলায় বহুবার আম খেয়েছ। এখন তোমাকে চোখ বন্ধ করে শুধু গন্ধ শুঁকিয়ে বলা হলো — "এটা কাঁচা আম না পাকা আম?" তুমি সাথে সাথে বলে দিতে পারবে, কারণ তুমি আগে বহু আম খেয়ে একটা প্যাটার্ন (pattern) শিখে ফেলেছ। তোমাকে কেউ শেখায়নি "যদি গন্ধ এমন হয় তাহলে পাকা" — তুমি নিজে অভিজ্ঞতা থেকে শিখেছ।
Machine Learning হলো কম্পিউটারকে ঠিক এভাবেই — অনেক পুরনো উদাহরণ (ডেটা) দেখিয়ে একটা প্যাটার্ন শিখিয়ে দেওয়া, যাতে সে ভবিষ্যতে নতুন কিছু দেখলে নিজে থেকে সিদ্ধান্ত নিতে পারে। কেউ তাকে হাতে হাতে নিয়ম (rule) লিখে দেয় না — সে ডেটা থেকে নিয়মটা নিজেই বের করে।
Classification কী?
Classification মানে হলো — কোনো জিনিসকে দেখে তাকে আগে থেকে ঠিক করা কয়েকটা ক্যাটাগরির (category) মধ্যে একটাতে ফেলে দেওয়া। যেমন: ইমেইল দেখে বলা "এটা Spam নাকি Not Spam", অথবা রোগীর রিপোর্ট দেখে বলা "এই রোগী অসুস্থ নাকি সুস্থ"।
লক্ষ করো — এখানে উত্তরটা সবসময় একটা নির্দিষ্ট ক্যাটাগরি থেকে আসে (হ্যাঁ/না, এই ৩টার একটা ইত্যাদি) — কোনো সংখ্যা প্রেডিক্ট করা নয় (সেটাকে বলে Regression, আজকের ক্লাসের বিষয় না)।
কেন Classification গুরুত্বপূর্ণ?
আমাদের চারপাশের প্রায় প্রতিটা সিদ্ধান্ত-নেওয়ার সিস্টেম আসলে একটা Classification সমস্যা। ব্যাংক ঠিক করে কাকে লোন দেবে, ডাক্তার ঠিক করেন কে অসুস্থ, ইমেইল সার্ভার ঠিক করে কোনটা স্প্যাম — এই সবগুলো প্রতিদিন কোটি কোটি বার ম্যানুয়ালি করা সম্ভব না, তাই আমরা মেশিনকে শিখিয়ে দিই এই সিদ্ধান্তগুলো নিজে নিতে।
| ক্ষেত্র | ইনপুট (যা দেখে সিদ্ধান্ত নেওয়া হয়) | সম্ভাব্য ক্যাটাগরি |
|---|---|---|
| ইমেইল সিস্টেম | ইমেইলের লেখা, প্রেরকের ঠিকানা | Not Spam / Spam |
| চিকিৎসা | রোগীর লক্ষণ, টেস্ট রিপোর্ট | Disease / Healthy |
| শিক্ষাপ্রতিষ্ঠান | পড়াশোনার সময়, উপস্থিতি, আগের নম্বর | Pass / Fail |
| ব্যাংকিং | আয়, ক্রেডিট হিস্টোরি, চাকরির ধরন | Loan Approved / Loan Rejected |
| টেলিকম / ই-কমার্স | ব্যবহারের ধরন, অভিযোগ, বিল | Retained Customer / Customer Churn |
Probability বোঝা
Probability কী?
Probability (সম্ভাবনা) মানে হলো — কোনো একটা ঘটনা ঘটার "সম্ভাবনা কতটুকু" তার একটা সংখ্যায় মাপ। এটা আমাদের বলে দেয় একটা জিনিস কতটা "নিশ্চিত" বা কতটা "অনিশ্চিত"।
যেমন, তুমি যদি বলো "আজ বৃষ্টি হতে পারে" — এই "হতে পারে" কথাটার পেছনে একটা মাত্রা আছে। আকাশ যদি কালো মেঘে ঢাকা থাকে, তাহলে বৃষ্টির সম্ভাবনা বেশি। আকাশ পরিষ্কার থাকলে সম্ভাবনা কম। Probability এই "কতটা বেশি বা কম" — সেটাকেই সংখ্যায় প্রকাশ করে।
কেন Probability দরকারি?
আমরা ভবিষ্যতে কী ঘটবে তা ১০০% নিশ্চিতভাবে জানতে পারি না। কিন্তু আমরা অতীতের অভিজ্ঞতা দিয়ে অনুমান করতে পারি — এবং এই অনুমানকে সংখ্যায় প্রকাশ করলে সিদ্ধান্ত নেওয়া অনেক সহজ হয়ে যায়। Machine Learning-এর অনেক অ্যালগরিদম, বিশেষ করে Naive Bayes, পুরোপুরি এই "সম্ভাবনার হিসাব" এর উপর দাঁড়িয়ে থাকে।
Probability-র স্কেল (0 থেকে 1)
Probability সবসময় ০ থেকে ১ এর মধ্যে থাকে (অথবা ০% থেকে ১০০%)।
| মান | নাম | উদাহরণ |
|---|---|---|
| 0 | Impossible Event (অসম্ভব ঘটনা) | একটা সাধারণ ডাইসে (dice) ৭ ওঠা |
| 0.1 – 0.3 | Unlikely Event (অসম্ভাব্য) | লটারি জেতা |
| 0.5 | Fifty-Fifty | কয়েন টস করলে হেড ওঠা |
| 0.7 – 0.9 | Likely Event (সম্ভাব্য) | নিয়মিত পড়াশোনা করা ছাত্রের পাস করা |
| 1 | Certain Event (নিশ্চিত ঘটনা) | সূর্য পূর্ব দিকে ওঠা |
উদাহরণ দিয়ে অনুশীলন
১. কয়েন টস (Tossing a Coin)
একটা কয়েনে দুইটা দিক থাকে — Head এবং Tail। তাই:
২. ডাইস রোলিং (Rolling a Dice)
একটা ডাইসে ৬টা মুখ থাকে (1,2,3,4,5,6)। "৪ ওঠার" সম্ভাবনা কত?
৩. তাস থেকে কার্ড তোলা (Drawing a Card)
৫২টা তাসের একটা প্যাকেটে ৪টা স্যুট (Heart, Spade, Club, Diamond), প্রতিটাতে ১৩টা করে কার্ড। একটা "Heart" কার্ড ওঠার সম্ভাবনা:
৪. বৃষ্টির পূর্বাভাস (Rain Prediction)
ধরো, গত ১০ দিনের মধ্যে ৩ দিন বৃষ্টি হয়েছে। তাহলে সাধারণভাবে (শুধু এই ডেটার ভিত্তিতে):
৫. পরীক্ষায় পাস করা (Student Passing an Exam)
গত ৫ বছরে একটা ক্লাসে ৪০ জনের মধ্যে ৩৬ জন পাস করেছে:
Certain vs Impossible
| সূর্য পশ্চিমে অস্ত যাবে | Certain (P=1) |
| মানুষ পানি ছাড়া বাঁচবে | Impossible (P=0) |
Likely vs Unlikely
| নিয়মিত পড়ুয়া ছাত্রের পাস | Likely (P বেশি) |
| না পড়েই A+ পাওয়া | Unlikely (P কম) |
Conditional Probability
Conditional Probability কী?
এখন পর্যন্ত আমরা যে probability বের করেছি সেটা ছিল "একা একা" — অন্য কোনো তথ্য ছাড়া। কিন্তু বাস্তবে আমরা প্রায়ই বলি — "যদি এটা সত্যি হয়, তাহলে ওটার সম্ভাবনা কত?" এটাকেই বলে Conditional Probability — মানে একটা শর্ত (condition) দেওয়ার পরের সম্ভাবনা।
উদাহরণ ১: বৃষ্টি হলে ছাতা নেওয়া
সাধারণভাবে কারো ছাতা নেওয়ার সম্ভাবনা হয়তো ৩০%। কিন্তু যদি আমরা জানি যে আজ বৃষ্টি হচ্ছে, তাহলে ছাতা নেওয়ার সম্ভাবনা হুট করে বেড়ে যায় — ধরো ৯০%। এটাই হলো:
লক্ষ করো — শর্তটা (বৃষ্টি হচ্ছে) যোগ হওয়ায় সম্ভাবনাটা সম্পূর্ণ বদলে গেছে। এটাই Conditional Probability-র মূল শক্তি — নতুন তথ্য পেলে আমরা আমাদের অনুমান আপডেট করি।
উদাহরণ ২: পড়াশোনা করলে পাস করা
| Studied (পড়েছে) | Didn't Study (পড়েনি) | মোট | |
|---|---|---|---|
| Pass | 12 | 2 | 14 |
| Fail | 1 | 5 | 6 |
| মোট | 13 | 7 | 20 |
অর্থাৎ, যে ছাত্র পড়াশোনা করেছে তার পাস করার সম্ভাবনা প্রায় ৯২% — যেখানে সামগ্রিকভাবে (না জেনে) পাসের সম্ভাবনা ছিল মাত্র 14÷20 = 70%। "পড়াশোনা করেছে" এই তথ্যটা যোগ হওয়ায় সম্ভাবনা বদলে গেল।
উদাহরণ ৩: বিজ্ঞাপনে ক্লিক করার পর কেনা
| Clicked Ad | Didn't Click | |
|---|---|---|
| Bought | 40 | 5 |
| Didn't Buy | 10 | 45 |
ভিজ্যুয়াল বোঝাপড়া: Probability Tree
নিচের গাছের মতো ডায়াগ্রামে দেখো — প্রথমে ভাগ হচ্ছে "পড়েছে/পড়েনি" দিয়ে, তারপর প্রতিটা শাখা আবার ভাগ হচ্ছে "Pass/Fail" দিয়ে। এটাই Conditional Probability-র ভিজ্যুয়াল রূপ:
Bayes' Theorem
কেন Bayes' Theorem দরকার হলো?
আগের পার্টে আমরা দেখেছি P(Pass | Studied) — মানে "পড়েছে জেনে পাসের সম্ভাবনা"। কিন্তু বাস্তব জীবনে অনেক সময় আমরা উল্টোটা জানতে চাই। যেমন:
- একজন ছাত্র পাস করেছে — এখন সে পড়াশোনা করেছিল এমন সম্ভাবনা কত? P(Studied | Pass) = ?
- একটা রোগীর টেস্ট পজিটিভ এসেছে — তার আসলে রোগ থাকার সম্ভাবনা কত? P(Disease | Positive Test) = ?
- একটা ইমেইলে "Free" শব্দটা আছে — এটা আসলে Spam হওয়ার সম্ভাবনা কত? P(Spam | "Free") = ?
এই প্রশ্নগুলোর ধরনটা লক্ষ করো — আমরা "ফলাফল" জেনে "কারণ" এর সম্ভাবনা বের করতে চাইছি। এটা করতে গেলে আমাদের P(A|B) থেকে P(B|A) এ যাওয়ার একটা পথ দরকার। ঠিক এই কাজটাই করে Bayes' Theorem — এটা একটা সম্ভাবনাকে "উল্টে" দিয়ে অন্য দিক থেকে হিসাব করার সূত্র।
Bayes' Theorem — সূত্র
প্রতিটা অংশের মানে
| টার্ম | নাম | মানে |
|---|---|---|
| P(A) | Prior Probability | কোনো প্রমাণ দেখার আগেই A ঘটার সম্ভাবনা (আগের অভিজ্ঞতা থেকে) |
| P(B | A) | Likelihood | যদি A সত্যি হয়, তাহলে B (প্রমাণ) দেখা যাওয়ার সম্ভাবনা |
| P(B) | Evidence | সামগ্রিকভাবে B ঘটার সম্ভাবনা (সব ক্ষেত্রে মিলিয়ে) |
| P(A | B) | Posterior Probability | B প্রমাণ দেখার পর A ঘটার (আপডেট করা) সম্ভাবনা — এটাই আমাদের উত্তর |
ধাপে ধাপে উদাহরণ: রোগ নির্ণয় টেস্ট
ধরো, একটা রোগ জনসংখ্যার মধ্যে খুবই বিরল — মাত্র ১%। একটা টেস্ট আছে যেটা:
- রোগ থাকলে ৯০% সময় সঠিকভাবে পজিটিভ দেখায় (Likelihood)
- রোগ না থাকলেও ৫% সময় ভুলভাবে পজিটিভ দেখায় (False Positive)
প্রশ্ন: একজনের টেস্ট পজিটিভ এসেছে। তার আসলেই রোগ থাকার সম্ভাবনা কত? — অনেকেই ভুল করে বলে ৯০%, কিন্তু Bayes' Theorem দিয়ে হিসাব করলে দেখা যায় বাস্তব উত্তর অনেক কম।
| P(Disease) — Prior | 0.01 |
| P(No Disease) | 0.99 |
| P(Positive | Disease) — Likelihood | 0.90 |
| P(Positive | No Disease) — False Positive Rate | 0.05 |
= (0.90 × 0.01) + (0.05 × 0.99)
= 0.009 + 0.0495 = 0.0585
ভিজ্যুয়াল: ১০,০০০ মানুষের ডায়াগ্রামে
ধরো ১০,০০০ জন মানুষ আছে। ১% রোগী মানে ১০০ জনের রোগ আছে, ৯৯০০ জনের নেই।
| রোগ আছে (100 জন) | রোগ নেই (9900 জন) | মোট পজিটিভ | |
|---|---|---|---|
| টেস্ট পজিটিভ | 90 (90%) | 495 (5%) | 585 |
| টেস্ট নেগেটিভ | 10 | 9405 | 9415 |
🔬 Interactive — Medical Test (Bayes' Theorem)
Slider চালান — P(Disease|Positive) live হিসাব দেখুন
Posterior P(Disease|+): 15.4%
টেস্ট positive ≠ 90% রোগ নিশ্চিত — Prior (বিরল রোগ) গুরুত্বপূর্ণ!
Naive Bayes কী?
"Bayes" নামটা কেন?
আমরা এইমাত্র যে Bayes' Theorem শিখলাম — Naive Bayes অ্যালগরিদম হুবহু এই সূত্রটাই ব্যবহার করে classification করার জন্য। তাই নামের মধ্যে "Bayes" আছে।
"Naive" নামটা কেন?
"Naive" শব্দের বাংলা মানে "সরলমনা" বা "অতি সরলীকৃত"। এই অ্যালগরিদম একটা বড় ধরে নেওয়া (assumption) করে — যে, একটা জিনিসের সবগুলো ফিচার (feature/বৈশিষ্ট্য) একে অপরের থেকে সম্পূর্ণ স্বাধীন (independent), একটা আরেকটাকে প্রভাবিত করে না।
বাস্তবে এটা প্রায়ই সত্যি হয় না — তাই এই ধরে নেওয়াটাকে "সরলমনা" বা "naive" বলা হয়। কিন্তু মজার ব্যাপার হলো, এই সরলীকরণ করা সত্ত্বেও অ্যালগরিদমটা বাস্তবে খুব ভালো কাজ করে!
Feature Independence বোঝার সহজ উদাহরণ
বাস্তবে হয়তো Action মুভির সাথে English ভাষার একটা সম্পর্ক থাকতে পারে (correlation) — কিন্তু Naive Bayes এই সম্পর্কটা উপেক্ষা করে প্রতিটা ফিচারকে আলাদা আলাদাভাবে বিবেচনা করে। এই সরলীকরণের কারণেই হিসাব করাটা অনেক দ্রুত এবং সহজ হয়ে যায়।
| বিষয় | Naive Bayes কী ধরে নেয় | বাস্তবে কী হয় |
|---|---|---|
| ফিচারগুলোর সম্পর্ক | একদম স্বাধীন, একে অপরকে প্রভাবিত করে না | অনেক সময় ফিচারগুলো একে অপরের সাথে সম্পর্কিত থাকে |
| ফলাফলের উপর প্রভাব | প্রতিটা ফিচার আলাদাভাবে posterior probability-তে যোগ হয় | বাস্তবে প্রভাব যৌথ (joint) হতে পারে |
| ফলাফল কেমন হয় | সরলীকরণ সত্ত্বেও, বেশিরভাগ ক্ষেত্রে দারুণ কার্যকর | টেক্সট ক্লাসিফিকেশনের মতো ক্ষেত্রে বিশেষভাবে ভালো কাজ করে |
Naive Bayes কীভাবে কাজ করে
সম্পূর্ণ ওয়ার্কফ্লো
Dataset → Prior → Likelihood → Bayes → Posterior → Prediction। নিচের ★ Pipeline Visual-এ প্রতিটি ধাপ live দেখুন।
উদাহরণ: Spam Email Detection (ম্যানুয়াল হিসাব)
ধরো আমাদের কাছে ৮টা পুরনো ইমেইলের একটা ছোট ডেটাসেট আছে:
| # | ইমেইলে "Free" শব্দ আছে? | ইমেইলে "Offer" শব্দ আছে? | ক্লাস |
|---|---|---|---|
| 1 | হ্যাঁ | হ্যাঁ | Spam |
| 2 | হ্যাঁ | না | Spam |
| 3 | হ্যাঁ | হ্যাঁ | Spam |
| 4 | না | না | Not Spam |
| 5 | না | হ্যাঁ | Not Spam |
| 6 | না | না | Not Spam |
| 7 | হ্যাঁ | না | Spam |
| 8 | না | হ্যাঁ | Not Spam |
নতুন ইমেইল: যেখানে "Free" আছে, কিন্তু "Offer" নেই। এটা কি Spam নাকি Not Spam?
| শর্ত | Spam-এর মধ্যে | Not Spam-এর মধ্যে |
|---|---|---|
| P(Free = হ্যাঁ | Class) | 4/4 = 1.0 | 0/4 = 0.0 |
| P(Offer = না | Class) | 2/4 = 0.5 | 2/4 = 0.5 |
যেহেতু সব ক্লাসের জন্য P(Evidence) একই থাকে, তাই তুলনা করার সময় সেটা বাদ দিয়ে শুধু নিচেরটুকু হিসাব করলেই চলে:
= 0.5 × 1.0 × 0.5 = 0.25
Score(Not Spam) ∝ P(Not Spam) × P(Free=হ্যাঁ|Not Spam) × P(Offer=না|Not Spam)
= 0.5 × 0.0 × 0.5 = 0.0 (Laplace Smoothing ছাড়া)
Score(Spam) = 0.25 যেটা Score(Not Spam) = 0.0 এর চেয়ে বড়। তাই:
Pipeline Visual — Spam Email NB
এক লাইনে পুরো গল্প
Training emails → Prior P(Spam) → Likelihood P(feature|class) → Score = Prior × ∏ Likelihood → Posterior normalize → Predict class।
💡 এক লাইনে মনে রাখো
Prior × Likelihood₁ × Likelihood₂ → Score → Normalize → Posterior → argmax = Prediction
Naive Bayes-এর প্রকারভেদ
Gaussian Naive Bayes
যখন ফিচারগুলো সংখ্যাসূচক (numerical) এবং তা মোটামুটি একটা normal distribution (ঘণ্টার আকৃতির curve) অনুসরণ করে, তখন Gaussian Naive Bayes ব্যবহার করা হয়। যেমন — উচ্চতা, ওজন, তাপমাত্রা, বয়স ইত্যাদি।
ব্যবহার: Iris ফুলের species prediction (পাপড়ির length/width দিয়ে), মেডিকেল ডেটাতে রক্তচাপ/সুগার লেভেল দিয়ে prediction।
Multinomial Naive Bayes
যখন ফিচার হলো "কোনো কিছুর সংখ্যা কতবার ঘটেছে" (count/frequency) — বিশেষ করে টেক্সট ডেটা-তে একটা শব্দ কতবার এসেছে। এটাই সবচেয়ে বেশি ব্যবহৃত হয় Text Classification-এ।
ব্যবহার: Spam Detection (ইমেইলে শব্দের ফ্রিকোয়েন্সি), News Category Classification, Sentiment Analysis।
Bernoulli Naive Bayes
যখন ফিচার শুধু Binary (0/1, Yes/No) — অর্থাৎ একটা জিনিস "আছে কি নেই" সেটাই গুরুত্বপূর্ণ, কতবার আছে সেটা না। যেমন — একটা নির্দিষ্ট শব্দ ইমেইলে "আছে" (1) নাকি "নেই" (0)।
ব্যবহার: ছোট টেক্সট ডকুমেন্টে শব্দের presence/absence দেখে classification, স্প্যাম ফিল্টার যেখানে শুধু নির্দিষ্ট কিছু কিওয়ার্ডের উপস্থিতি ম্যাটার করে।
| ধরন | ডেটার ধরন | উদাহরণ ফিচার | মূল ব্যবহার |
|---|---|---|---|
| Gaussian | Continuous Numerical | উচ্চতা, তাপমাত্রা | সেন্সর/মেডিকেল ডেটা |
| Multinomial | Count/Frequency | শব্দের সংখ্যা | টেক্সট ও স্প্যাম ক্লাসিফিকেশন |
| Bernoulli | Binary (0/1) | শব্দের উপস্থিতি/অনুপস্থিতি | ছোট টেক্সট ডকুমেন্ট |
সুবিধা ও সীমাবদ্ধতা
🔧 Laplace Smoothing — Live Demo
Part 6-এ P(Free=হ্যাঁ|Not Spam)=0 সমস্যা দেখেছ। ★ Pipeline Visual-এ Laplace α slider চালিয়ে zero probability কীভাবে fix হয় তা live দেখুন।
✅ সুবিধা
| খুব দ্রুত | ট্রেনিং ও প্রেডিকশন দুটোই খুব কম সময়ে হয় |
| ট্রেইন করা সহজ | কম ডেটা ও কম কম্পিউটিং পাওয়ার লাগে |
| টেক্সট ডেটায় শক্তিশালী | স্প্যাম ফিল্টার, সেন্টিমেন্ট বিশ্লেষণে দারুণ কাজ করে |
| ছোট ডেটাসেটেও ভালো | অনেক অ্যালগরিদমের বিপরীতে অল্প ডেটাতেও রিজনেবল ফলাফল দেয় |
⚠️ সীমাবদ্ধতা
| Independence Assumption | ফিচারগুলো স্বাধীন ধরে নেয়, যা বাস্তবে সবসময় সত্যি না |
| Assumption ভাঙলে পারফরম্যান্স কমে | ফিচারের মধ্যে শক্তিশালী সম্পর্ক থাকলে ভুল প্রেডিকশন হতে পারে |
| জটিল সম্পর্ক ধরতে পারে না | ফিচারগুলোর মধ্যে জটিল, non-linear সম্পর্ক বোঝাতে দুর্বল |
বাস্তব প্রয়োগ (Applications)
| প্রয়োগক্ষেত্র | ব্যাখ্যা |
|---|---|
| Spam Email Detection | জিমেইলের মতো সার্ভিসে ইমেইলের শব্দ বিশ্লেষণ করে স্প্যাম ফিল্টার করা |
| News Classification | একটা নিউজ আর্টিকেল Sports/Politics/Tech কোন ক্যাটাগরির তা নির্ণয় |
| Sentiment Analysis | একটা রিভিউ বা কমেন্ট Positive/Negative/Neutral কিনা নির্ণয় |
| Language Detection | একটা টেক্সট কোন ভাষায় লেখা তা চিহ্নিত করা |
| Medical Diagnosis | লক্ষণ দেখে রোগ থাকার সম্ভাবনা অনুমান করা |
| Product Recommendation | গ্রাহকের আচরণ দেখে পণ্য পছন্দ হওয়ার সম্ভাবনা অনুমান |
| Fake News Detection | একটা খবরের লেখার ধরন দেখে সেটা fake না real তা নির্ণয় |
Google Colab কোডিং সেশন
উদাহরণ ১: Student Pass/Fail Prediction
ফিচার: Study Hours, Attendance, Previous Marks | টার্গেট: Pass (1) / Fail (0)
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.naive_bayes import GaussianNB from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
লাইন বাই লাইন ব্যাখ্যা: pandas ডেটা টেবিল হ্যান্ডেল করতে ব্যবহার হয়, numpy সংখ্যা নিয়ে কাজ করার জন্য, sklearn.model_selection থেকে ডেটা ভাগ করার ফাংশন, GaussianNB হলো আমাদের numerical ফিচারের জন্য উপযুক্ত Naive Bayes মডেল, আর শেষের অংশটা মডেল কতটা ভালো তা মাপার জন্য।
GaussianNB() ব্যবহার করার চেষ্টা করা — এতে NameError আসবে। সবসময় প্রথমে import সেল রান করতে হবে।data = {
'Study_Hours': [1, 2, 3, 4, 5, 6, 7, 8, 2, 6],
'Attendance': [40, 50, 55, 60, 70, 80, 85, 95, 45, 75],
'Previous_Marks': [30, 40, 35, 50, 60, 65, 70, 90, 38, 68],
'Result': [0, 0, 0, 1, 1, 1, 1, 1, 0, 1]
}
df = pd.DataFrame(data)
df.head()
ব্যাখ্যা: df.head() ডিফল্টভাবে প্রথম ৫টা সারি দেখায়, যাতে আমরা ডেটার গঠন বুঝতে পারি রান করার আগেই।
X = df[['Study_Hours', 'Attendance', 'Previous_Marks']]
y = df['Result']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
print("Train size:", X_train.shape, "Test size:", X_test.shape)
ব্যাখ্যা: X হলো ফিচারগুলো (independent variables), y হলো টার্গেট (dependent variable)। test_size=0.3 মানে ৩০% ডেটা টেস্টিং-এর জন্য আলাদা রাখা হচ্ছে, আর random_state=42 নিশ্চিত করে যে প্রতিবার একই ভাগ হবে (reproducibility)।
model = GaussianNB()
model.fit(X_train, y_train)
print("মডেল ট্রেইনিং সম্পন্ন ✅")
ব্যাখ্যা: .fit() মেথডটাই আসল "শেখার" কাজ করে — এটা ট্রেনিং ডেটা থেকে প্রতিটা ক্লাসের Prior এবং প্রতিটা ফিচারের mean/variance হিসাব করে রাখে (Gaussian distribution ফিট করার জন্য)।
predictions = model.predict(X_test)
print("Predictions:", predictions)
print("Actual: ", y_test.values)
probs = model.predict_proba(X_test) print(probs)
ব্যাখ্যা: প্রতিটা সারিতে দুইটা সংখ্যা — প্রথমটা "Fail (0)" হওয়ার সম্ভাবনা, দ্বিতীয়টা "Pass (1)" হওয়ার সম্ভাবনা। যোগফল সবসময় 1.0 হবে। এটাই আসলে আমাদের হাতে-কলমে হিসাব করা Posterior Probability — শুধু sklearn নিজে নিজে করে দিচ্ছে।
print("Accuracy:", accuracy_score(y_test, predictions))
print("\nConfusion Matrix:\n", confusion_matrix(y_test, predictions))
উদাহরণ ২: Spam Email Detection (টেক্সট ক্লাসিফিকেশন)
emails = [
"Win a free lottery now",
"Limited offer just for you, claim free gift",
"Meeting scheduled for tomorrow at 10am",
"Please review the attached project report",
"You have won a free prize, click here",
"Let's discuss the client requirements",
"Free money guaranteed, act now",
"Reminder: submit your assignment by Friday"
]
labels = [1, 1, 0, 0, 1, 0, 1, 0] # 1 = Spam, 0 = Not Spam
import re
def clean_text(text):
text = text.lower()
text = re.sub(r'[^a-z\s]', '', text)
return text
cleaned_emails = [clean_text(e) for e in emails]
print(cleaned_emails[0])
ব্যাখ্যা: lower() সব অক্ষরকে ছোট হাতের করে দেয় (যাতে "Free" ও "free" একই শব্দ হিসেবে গণ্য হয়), আর re.sub সংখ্যা/বিশেষ চিহ্ন সরিয়ে শুধু অক্ষর রাখে।
from sklearn.feature_extraction.text import CountVectorizer vectorizer = CountVectorizer() X = vectorizer.fit_transform(cleaned_emails) print(vectorizer.get_feature_names_out()) print(X.toarray())
ব্যাখ্যা: কম্পিউটার টেক্সট বোঝে না, শুধু সংখ্যা বোঝে। CountVectorizer প্রতিটা ইমেইলকে একটা সংখ্যার তালিকায় (vector) রূপান্তর করে, যেখানে প্রতিটা কলাম একটা শব্দ এবং মান হলো সেই শব্দটা কতবার এসেছে।
from sklearn.naive_bayes import MultinomialNB
X_train, X_test, y_train, y_test = train_test_split(
X, labels, test_size=0.25, random_state=1
)
nb_model = MultinomialNB()
nb_model.fit(X_train, y_train)
ব্যাখ্যা: এখানে MultinomialNB ব্যবহার হয়েছে (GaussianNB না), কারণ আমাদের ফিচার হলো "শব্দ কতবার এসেছে" — যা count-based ডেটা, numerical measurement না।
new_email = ["Claim your free prize today"]
cleaned_new = [clean_text(e) for e in new_email]
new_vector = vectorizer.transform(cleaned_new)
prediction = nb_model.predict(new_vector)
probability = nb_model.predict_proba(new_vector)
print("Prediction (1=Spam, 0=Not Spam):", prediction)
print("Probability [Not Spam, Spam]:", probability)
test_predictions = nb_model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, test_predictions))
print(classification_report(y_test, test_predictions))
- নতুন ডেটার উপর
fit_transform()ব্যবহার করা (উচিত শুধুtransform(), কারণ vectorizer আগেই ট্রেনিং ডেটা দিয়ে "শেখা" হয়ে গেছে) - Text cleaning না করে সরাসরি raw টেক্সট vectorize করা — এতে "Free" এবং "free" আলাদা শব্দ হিসেবে গণ্য হবে
- ছোট ডেটাসেটে (মাত্র ৮টা ইমেইল) পাওয়া Accuracy কে বাস্তব পারফরম্যান্স মনে করা
random_state ফিক্স করে রাখো (reproducibility-র জন্য), বড় ডেটাসেটে Stopwords বাদ দাও, TF-IDF ব্যবহার করে দেখো (CountVectorizer-এর চেয়ে প্রায়ই ভালো ফলাফল দেয়), এবং সবসময় Accuracy-র পাশাপাশি Precision/Recall/F1 দেখো।মডেল ইভ্যালুয়েশন
Confusion Matrix — বোঝার আগে ইনটুইশন
ধরো, তুমি একজন শিক্ষক এবং তোমার মডেল প্রতিটা ছাত্রকে "Pass" বা "Fail" বলে ভবিষ্যদ্বাণী করছে। এখন চারটা সম্ভাবনা হতে পারে:
| মডেল বলল "Pass" (Positive) | মডেল বলল "Fail" (Negative) | |
|---|---|---|
| আসলে Pass ছিল | True Positive (TP) ✅ | False Negative (FN) ❌ |
| আসলে Fail ছিল | False Positive (FP) ❌ | True Negative (TN) ✅ |
- True Positive (TP): মডেল "Pass" বলেছে, সত্যিই Pass ছিল
- True Negative (TN): মডেল "Fail" বলেছে, সত্যিই Fail ছিল
- False Positive (FP): মডেল "Pass" বলেছে, কিন্তু আসলে Fail ছিল (ভুল অ্যালার্ম)
- False Negative (FN): মডেল "Fail" বলেছে, কিন্তু আসলে Pass ছিল (মিস করে ফেলেছে)
মেট্রিক্স — ইনটুইশন আগে, ফর্মুলা পরে
Accuracy — "মোট কতটা ঠিক বলেছে"
Precision — "যতগুলো Positive বলেছে, তার মধ্যে কতগুলো আসলেই Positive ছিল"
যেমন — স্প্যাম ফিল্টারে Precision কম হলে ভালো ইমেইলও স্প্যাম বলে ফেলে দেবে (বিরক্তিকর!)।
Recall — "যতগুলো আসলেই Positive ছিল, তার মধ্যে কতগুলো ধরতে পেরেছে"
যেমন — রোগ নির্ণয়ে Recall কম হলে অনেক আসল রোগীকে "সুস্থ" বলে মিস করে ফেলবে (বিপজ্জনক!)।
F1 Score — Precision ও Recall-এর ব্যালেন্স
অন্য অ্যালগরিদমের সাথে তুলনা
| বিষয় | Naive Bayes | Logistic Regression | Decision Tree | KNN | SVM |
|---|---|---|---|---|---|
| গতি | ⚡ খুব দ্রুত | দ্রুত | মাঝারি | প্রেডিকশনে ধীর | বড় ডেটায় ধীর |
| টেক্সট ডেটায় পারফরম্যান্স | ✅ চমৎকার | ভালো | মাঝারি | দুর্বল | ভালো |
| প্রয়োজনীয় ডেটার পরিমাণ | কম হলেও চলে | মাঝারি | মাঝারি | বেশি | মাঝারি-বেশি |
| ফিচার সম্পর্ক ধরার ক্ষমতা | ❌ দুর্বল (independence ধরে নেয়) | মাঝারি | ✅ ভালো | ভালো | ✅ ভালো |
| ইন্টারপ্রিটেশন সহজ? | মোটামুটি সহজ | সহজ | ✅ সবচেয়ে সহজ | মাঝারি | কঠিন |
কখন কোনটা ব্যবহার করবে?
- টেক্সট/স্প্যাম/সেন্টিমেন্ট: Naive Bayes → দ্রুত ও কার্যকর, প্রথম বেসলাইন হিসেবে আদর্শ
- Interpretable probability দরকার: Logistic Regression
- নিয়ম বুঝিয়ে দেখাতে হবে (business rules): Decision Tree
- ছোট ডেটাসেট, non-linear প্যাটার্ন: KNN বা SVM
- জটিল, উচ্চ-মাত্রার ডেটায় সর্বোচ্চ accuracy: SVM বা Ensemble মেথড
কমন বিগিনার ভুল
এন্ড-টু-এন্ড ম্যানুয়াল উদাহরণ
ক্লাসিক "Play Cricket?" ডেটাসেট — আবহাওয়া দেখে সিদ্ধান্ত নেওয়া হবে ক্রিকেট খেলা হবে কিনা।
| # | Weather | Temperature | Humidity | Play Cricket? |
|---|---|---|---|---|
| 1 | Sunny | Hot | High | No |
| 2 | Sunny | Hot | High | No |
| 3 | Overcast | Hot | High | Yes |
| 4 | Rainy | Mild | High | Yes |
| 5 | Rainy | Cool | Normal | Yes |
| 6 | Rainy | Cool | Normal | No |
| 7 | Overcast | Cool | Normal | Yes |
| 8 | Sunny | Mild | High | No |
| 9 | Sunny | Cool | Normal | Yes |
| 10 | Rainy | Mild | Normal | Yes |
| 11 | Sunny | Mild | Normal | Yes |
| 12 | Overcast | Mild | High | Yes |
| 13 | Overcast | Hot | Normal | Yes |
| 14 | Rainy | Mild | High | No |
প্রশ্ন: নতুন দিন — Weather=Sunny, Humidity=Normal — এই দিনে কি ক্রিকেট খেলা হবে?
| শর্ত | Yes-এর মধ্যে | No-এর মধ্যে |
|---|---|---|
| P(Sunny | Class) | 2/9 ≈ 0.222 | 3/5 = 0.6 |
| P(Normal Humidity | Class) | 6/9 ≈ 0.667 | 1/5 = 0.2 |
= 0.643 × 0.222 × 0.667 ≈ 0.0952
Score(No) = P(No) × P(Sunny|No) × P(Normal|No)
= 0.357 × 0.6 × 0.2 ≈ 0.0428
P(No | evidence) = 0.0428 ÷ (0.0952 + 0.0428) ≈ 0.31 (৩১%)
মিনি বিজনেস প্রজেক্ট
ধাপ ১: Data Understanding
টিম প্রথমে বোঝে — তাদের কাছে কী ডেটা আছে (পুরনো ইমেইলগুলো, যেগুলো ব্যবহারকারীরা আগে ম্যানুয়ালি স্প্যাম হিসেবে চিহ্নিত করেছে), এবং কী কী ফিচার ব্যবহারযোগ্য (subject line, body text, sender domain)।
ধাপ ২: Text Cleaning
সব ইমেইল lowercase করা হয়, বিশেষ চিহ্ন সরানো হয়, HTML ট্যাগ থাকলে সরানো হয়, এবং common stopwords ("the", "is", "a" ইত্যাদি) বাদ দেওয়া হয় যাতে মূল অর্থবহ শব্দগুলো নজরে আসে।
ধাপ ৩: Feature Extraction
TF-IDF Vectorizer ব্যবহার করে প্রতিটা ইমেইলকে সংখ্যার vector-এ রূপান্তর করা হয়, যেখানে প্রতিটা শব্দের গুরুত্ব শুধু ফ্রিকোয়েন্সি না, বরং সেই শব্দ কতটা "distinctive" (অন্যান্য ডকুমেন্টের তুলনায় বিরল ও গুরুত্বপূর্ণ) তার ভিত্তিতে ওজন পায়।
ধাপ ৪: Train Naive Bayes
যেহেতু ফিচারগুলো word-frequency ভিত্তিক, তাই MultinomialNB ব্যবহার করা হয়। ডেটা Train ও Test সেটে ভাগ করে মডেল ট্রেইন করা হয়।
ধাপ ৫: Prediction ও Evaluation
Test সেটে Accuracy, Precision, Recall, F1 মাপা হয়। এখানে Precision-কে বেশি গুরুত্ব দেওয়া হয় — কারণ ভুলবশত একটা গুরুত্বপূর্ণ ইমেইলকে Spam বলে ফেলা (False Positive) ব্যবহারকারীর জন্য অনেক বেশি ক্ষতিকর তুলনায় একটা স্প্যাম ইমেইল Inbox-এ চলে আসার চেয়ে।
ধাপ ৬: Business Insights
- যেসব শব্দ সবচেয়ে বেশি Spam-এর সাথে যুক্ত (যেমন "free", "winner", "click now") — সেগুলো marketing টিমকেও জানানো যায় যাতে তারা নিজেদের বৈধ প্রমোশনাল ইমেইলে এই শব্দগুলো এড়িয়ে চলে।
- মডেলের Precision/Recall ট্রেড-অফ বিজনেস টিমকে বুঝিয়ে বলা হয়, যাতে তারা ঠিক করতে পারে কোন থ্রেশহোল্ডে মডেল ডিপ্লয় করা উচিত।
- নিয়মিত রিট্রেইনিং দরকার — কারণ স্প্যামারদের কৌশল সময়ের সাথে বদলায় (concept drift)।
রিভিশন সেকশন
📌 Quick Revision Notes
- Probability = কতবার ঘটবে ÷ মোট সম্ভাব্য ফলাফল, মান থাকে 0 থেকে 1 এর মধ্যে
- Conditional Probability P(A|B) = শর্ত জেনে সম্ভাবনা আপডেট করা
- Bayes' Theorem: P(A|B) = [P(B|A) × P(A)] ÷ P(B)
- Prior = আগের বিশ্বাস, Likelihood = প্রমাণের মানানসই, Evidence = normalizer, Posterior = আপডেটেড বিশ্বাস
- Naive Bayes = Bayes' Theorem + Feature Independence Assumption
- তিন প্রকার: Gaussian (numerical), Multinomial (count/text), Bernoulli (binary)
- Zero Probability সমস্যার সমাধান = Laplace Smoothing
- শক্তি: দ্রুত, সহজ, টেক্সটে চমৎকার। দুর্বলতা: independence assumption বাস্তবে সবসময় সত্যি না
🎤 Viva Questions
💼 Interview Preparation (Top Questions)
ফলো-আপ: "এই assumption ভাঙলে কী হয়?" — মডেলের probability estimate কম নির্ভরযোগ্য হতে পারে, যদিও classification decision প্রায়ই ঠিক থাকে।
📝 MCQs with Answers
১. Naive Bayes কোন থিওরির উপর ভিত্তি করে তৈরি?
২. টেক্সট ক্লাসিফিকেশনের জন্য সাধারণত কোন Naive Bayes variant ব্যবহার হয়?
৩. Probability-র মান কোন সীমার মধ্যে থাকে?
৪. Zero Probability সমস্যার সমাধান কী?
৫. Naive Bayes-এর মূল "সরলীকৃত" ধারণা (assumption) কোনটা?
৬. Gaussian Naive Bayes কোন ধরনের ডেটার জন্য?
৭. predict_proba() কী দেয়?
৮. Bernoulli Naive Bayes-এ ফিচার কেমন?
🏫 Classroom Exercises
- একটা কয়েন ২ বার টস করলে দুইবারই Head আসার probability ম্যানুয়ালি হিসাব করো।
- Part 3-এর "পড়াশোনা vs পাস" টেবিলে Attendance যোগ করে নতুন একটা conditional probability টেবিল বানাও।
- Part 6-এর Spam Email উদাহরণে Laplace Smoothing (+1) যোগ করে নতুন করে Score(Spam) এবং Score(Not Spam) হিসাব করো।
- Part 14-এর Weather ডেটাসেটে নতুন একটা query চালাও: Weather=Overcast, Humidity=High — প্রেডিকশন কী হবে?
🏠 Homework Assignment
টাস্ক: নিজের একটা ছোট ডেটাসেট (১৫-২০টা সারি) তৈরি করো যেখানে অন্তত ৩টা ফিচার এবং একটা Binary টার্গেট থাকবে (যেমন — "Restaurant Recommend করবে কিনা: Price, Taste, Location দেখে")। তারপর:
- Prior Probability হাতে হিসাব করো
- Likelihood টেবিল বানাও
- একটা নতুন উদাহরণের জন্য ম্যানুয়ালি Posterior Probability হিসাব করো
- Google Colab-এ sklearn দিয়ে একই কাজ কোড করে ফলাফল মিলিয়ে দেখো