Chapter 17 of 18
When a model can cheat its way to a good-looking score
এই কোর্সের এখন পর্যন্ত প্রতিটা classification উদাহরণই নীরবে একটা জিনিস ধরে নিয়েছে: একটা ডেটাসেটে প্রতিটা ক্লাসের জন্য মোটামুটি সমান সংখ্যক উদাহরণ আছে। বাস্তব ডেটাসেট প্রায়ই তা করে না। Class imbalance হলো যখন একটা classification প্রবলেমের ক্লাসগুলো training data-তে সমানভাবে প্রতিনিধিত্ব করা হয় না — একটা ক্লাসে আরেকটার চেয়ে অনেক বেশি উদাহরণ থাকে।
জালিয়াতিমূলক ক্রেডিট কার্ড লেনদেন সনাক্ত করার একটা ডেটাসেট কল্পনা করুন: প্রতি ১০,০০০ লেনদেনের মধ্যে, হয়তো ৯,৯৫০টা বৈধ আর শুধু ৫০টা জালিয়াতি। "বৈধ" ক্লাস "জালিয়াতি" ক্লাসকে মোটামুটি ২০০ থেকে ১ অনুপাতে ছাড়িয়ে যায়। এটাই class imbalance-এর সবচেয়ে সাধারণ বাস্তব-জগতের রূপ — যে ক্লাসটা সবচেয়ে বেশি গুরুত্বপূর্ণ (জালিয়াতি ধরা) সেটাই ঠিক সেই বিরল ক্লাস।
Class imbalance হলো যখন একটা classification ডেটাসেটের একটা বা একাধিক ক্লাসে বাকিগুলোর চেয়ে যথেষ্ট কম training উদাহরণ থাকে।
Imbalance বাস্তব প্রবলেমের একটা বিশাল রেঞ্জ জুড়ে দেখা যায়: বিরল রোগ নির্ণয় (বেশিরভাগ রোগী সুস্থ), উৎপাদন ত্রুটি সনাক্তকরণ (বেশিরভাগ প্রোডাক্ট পরীক্ষায় পাশ করে), স্প্যাম সনাক্তকরণ (মেইল উৎসের উপর নির্ভর করে, স্প্যাম হয় মেজরিটি নয়তো মাইনরিটি ক্লাস হতে পারে), আর churn প্রেডিকশন (বেশিরভাগ কাস্টমার কোনো নির্দিষ্ট মাসে বাতিল করে না)। যখনই আসল আগ্রহের ঘটনাটা তুলনামূলকভাবে বিরল, কোনো না কোনো মাত্রার class imbalance প্রায় নিশ্চিত।
একটা নতুন classification ডেটাসেট নিয়ে অন্য কিছু করার আগে প্রতিটা ক্লাসের উদাহরণ গুনুন। একটা মোটামুটি নির্দেশিকা: হালকা imbalance হয়তো ৬০/৪০ বিভাজন, আর গুরুতর imbalance ৯৯/১ বা তার চেয়েও বেশি হতে পারে। Imbalance যত চরম, তত বেশি ইচ্ছাকৃত মনোযোগ দরকার।
Class imbalance গুরুত্বপূর্ণ কারণ ট্রেনিং আসলে কীভাবে কাজ করে — Loss Functions আর Gradient & Gradient Descent চ্যাপ্টার থেকে মনে করুন যে ট্রেনিং training উদাহরণ জুড়ে একটা গড় loss ছোট করে। যদি ৯৯% উদাহরণ একটা ক্লাসের হয়, একটা মডেল শুধু সেই majority ক্লাস সবসময় প্রেডিক্ট করার দিকে ভারীভাবে ঝুঁকে খুব কম গড় loss অর্জন করতে পারে, minority ক্লাসকে বেশিরভাগ সম্পূর্ণভাবে উপেক্ষা করে।
আবার জালিয়াতি সনাক্তকরণ উদাহরণটা নিন: এমন একটা মডেল যা প্রতিটা লেনদেনের জন্য "জালিয়াতি না" প্রেডিক্ট করে, কোনো ব্যতিক্রম ছাড়া, এই ডেটাসেটে ৯৯.৫% সময় সঠিক হবে। সংখ্যাটা চমৎকার শোনায়, কিন্তু মডেলটা জালিয়াতি সম্পর্কে আদৌ কিছুই শেখেনি — এটা এমন একটা শর্টকাট খুঁজে পেয়েছে যা সংখ্যায় ভালো স্কোর করে মডেলটা যে আসল কাজের জন্য বানানো হয়েছিল সেটা না করেই।
একটা মারাত্মকভাবে imbalanced ডেটাসেটে, একটা নিষ্পাপ "সবসময় majority ক্লাস প্রেডিক্ট করো" মডেল এমন accuracy অর্জন করতে পারে যা যেকোনো আকস্মিক নজরে চমৎকার দেখায়, যখন minority ক্লাসের জন্য সম্পূর্ণভাবে অকার্যকর যা সাধারণত সবচেয়ে গুরুত্বপূর্ণ। এই কারণেই imbalanced ডেটায় শুধু accuracy বিশ্বাস করা একটা বিপজ্জনক মেট্রিক — এই চ্যাপ্টার Evaluation Considerations-এ এই থিমে ফিরে আসে।
গভীর সমস্যাটা gradient descent নিজেই থেকে আসে: প্রতিটা mini-batch-এ (Batch, Mini-Batch, Iteration & Epoch চ্যাপ্টার থেকে) অনেক বেশি majority-class উদাহরণ থাকায়, সেই উদাহরণ থেকে হিসাব করা gradient প্রতিটা আপডেটে ব্যবহৃত গড় gradient-কে দখল করে। মডেলের weight majority ক্লাসে loss কমায় এমন যেকোনো কিছুর দিকে ব্যাপকভাবে টানা হয়, minority ক্লাসের সিগন্যাল শুধু সংখ্যায় কম হওয়ার কারণে চাপা পড়ে যায়।
Class imbalance গুরুত্বপূর্ণ কারণ ট্রেনিং উদাহরণ জুড়ে একটা গড় loss অপ্টিমাইজ করে, আর একটা মডেল একটা বিরল minority ক্লাস কার্যকরভাবে উপেক্ষা করে একটা প্রতারণামূলকভাবে কম গড় loss অর্জন করতে পারে।
Oversampling imbalance সমাধান করে মডেল আসলে যতগুলো minority-class উদাহরণে ট্রেন করে তার সংখ্যা বাড়িয়ে, যাতে majority আর minority ক্লাস প্রতিটা mini-batch আর প্রতিটা gradient আপডেটে বেশি সমানভাবে অবদান রাখে।
সবচেয়ে সহজ রূপ, random oversampling, বিদ্যমান minority-class উদাহরণ কপি করে যতক্ষণ না ক্লাসগুলো বেশি ব্যালেন্সড হয় — যদি ৫০টা জালিয়াতি উদাহরণ আর ৯,৯৫০টা বৈধ থাকে, random oversampling প্রতিটা জালিয়াতি উদাহরণ প্রায় ১৯৯ বার কপি করতে পারে majority ক্লাসের সংখ্যার মোটামুটি সমান হতে। প্রতিটা কপি করা কপি ট্রেনিংয়ে ঠিক একটা স্বাধীন উদাহরণের মতোই ব্যবহৃত হয়, minority ক্লাসকে প্রতিটা ধাপে gradient-এর উপর অনুপাতিকভাবে বেশি প্রভাব দেয়।
একটা বেশি পরিশীলিত পদ্ধতি, SMOTE (Synthetic Minority Oversampling Technique), শুধু বিদ্যমান উদাহরণ কপি করে না — এটা নতুন, সিন্থেটিক minority-class উদাহরণ তৈরি করে ফিচার স্পেসে একে অপরের কাছাকাছি থাকা বিদ্যমান minority উদাহরণের মধ্যে ইন্টারপোলেট করে। ঠিক একই জালিয়াতি উদাহরণ ১৯৯ বার দেখার বদলে, মডেল ১৯৯টা সামান্য ভিন্ন সিন্থেটিক ভ্যারিয়েশন দেখে, যা মডেলের অল্প কয়েকটা নির্দিষ্ট উদাহরণ মুখস্থ করার প্রবণতা কমাতে পারে।
| Random Oversampling | SMOTE | |
|---|---|---|
| নতুন উদাহরণ কীভাবে তৈরি হয় | বিদ্যমান minority উদাহরণের সঠিক নকল | আসল minority উদাহরণের মধ্যে ইন্টারপোলেট করা সিন্থেটিক উদাহরণ |
| ঝুঁকি | অল্প কয়েকটা আসল উদাহরণ মুখস্থ করাকে উৎসাহিত করতে পারে (Underfitting vs Overfitting চ্যাপ্টারের overfitting-এর সাথে সম্পর্কিত) | সিন্থেটিক উদাহরণ সবসময় বাস্তবসম্মত ডেটা প্রতিনিধিত্ব নাও করতে পারে, বিশেষ করে নয়েজি অঞ্চলে |
| Oversampling-এর পরে ডেটাসেট সাইজ | মোটামুটি majority ক্লাসের সংখ্যার সাথে মিলতে বাড়ে | একইভাবে বাড়ে, কিন্তু যোগ করা উদাহরণের মধ্যে বেশি বৈচিত্র্য নিয়ে |
Oversampling minority-class training উদাহরণের সংখ্যা বাড়ায়, হয় বিদ্যমানগুলো কপি করে বা নতুন সিন্থেটিক তৈরি করে, যাতে minority ক্লাস ট্রেনিংয়ের সময় প্রভাবের একটা ন্যায্য অংশ পায়।
Undersampling বিপরীত পদ্ধতি নেয়: বেশি minority-class উদাহরণ যোগ করার বদলে, এটা কিছু majority-class উদাহরণ সরিয়ে দেয় যাতে বাকি ডেটাসেটটা বেশি ব্যালেন্সড হয়।
সবচেয়ে সহজ রূপ, random undersampling, majority-class উদাহরণ র্যান্ডমলি বাদ দেয় যতক্ষণ না দুইটা ক্লাস সংখ্যায় মোটামুটি সমান হয় — ৯,৯৫০টা বৈধ লেনদেন আর ৫০টা জালিয়াতি উদাহরণ দিয়ে, random undersampling হয়তো বৈধ উদাহরণের প্রায় ৫০টা বাদে সবগুলো বাদ দেবে, প্রায় ১০০টা মোট উদাহরণের একটা অনেক ছোট কিন্তু ব্যালেন্সড ডেটাসেট রেখে।
ডেটা বাদ দেওয়া কখনো বিনামূল্যে না — undersampling এমন majority-class উদাহরণ ফেলে দিতে পারে যা সত্যিকারের কার্যকর প্যাটার্ন ধরেছিল, বিশেষ করে ইতিমধ্যে-ছোট ডেটাসেটে, যেখানে undersampling মডেলের নির্ভরযোগ্যভাবে শেখার জন্য সামগ্রিকভাবে খুব কম ডেটা রেখে দিতে পারে। এই ট্রেড-অফটাই কেন undersampling বেশি আকর্ষণীয় হয় যখন majority ক্লাসের ছাড় দেওয়ার মতো একটা অনেক বড় উদাহরণ উদ্বৃত্ত থাকে, আর কম আকর্ষণীয় হয় যখন সামগ্রিকভাবে ডেটা কম থাকে।
আরও পরিশীলিত undersampling পদ্ধতি majority-class উদাহরণ পুরোপুরি র্যান্ডমলি না বরং বেশি বুদ্ধিমানের মতো বাদ দেওয়ার চেষ্টা করে — উদাহরণস্বরূপ, এমন majority উদাহরণ সরানোকে অগ্রাধিকার দেওয়া যা আশেপাশের অনেক একই রকম উদাহরণের সাথে রিডানডেন্ট, যখন ক্লাসগুলোর মাঝের সীমানার কাছে অবস্থিত majority উদাহরণ রাখা, কারণ সেগুলো সাধারণত decision boundary (Decision Boundaries চ্যাপ্টার থেকে) আসলে কোথায় বসা উচিত সেই সম্পর্কে সবচেয়ে কার্যকর তথ্য বহন করে।
Undersampling majority-class training উদাহরণের সংখ্যা কমায়, ট্রেনিংয়ের সময় একটা বেশি ব্যালেন্সড ক্লাস ডিস্ট্রিবিউশনের জন্য কিছু ডেটা ভলিউম বিনিময় করে।
Oversampling সাধারণত পছন্দ হয় যখন সামগ্রিক ডেটাসেট ছোট আর প্রতিটা উদাহরণ মূল্যবান। Undersampling একটা যুক্তিসঙ্গত পছন্দ হতে পারে যখন majority ক্লাস বিশাল আর সম্পূর্ণভাবে ব্যবহার করা কম্পিউটেশনালি ব্যয়বহুল — কিন্তু দুটোই মেলানো যায়, আর কোনোটাই নির্দিষ্ট ডেটাসেটের সাইজ আর মান থেকে স্বাধীন একটা সার্বজনীন উত্তর না।
মডেল কোন উদাহরণ দেখে সেটা বদলানোর বদলে, class weighting প্রতিটা উদাহরণের loss মোট loss-এ কতটা গোনা হয় সেটা বদলায়, ডেটাসেটের বদলে সরাসরি loss function নিজেই অ্যাডজাস্ট করে।
Loss Functions চ্যাপ্টার থেকে loss function মনে করুন, যেমন binary cross-entropy — সাধারণত, প্রতিটা উদাহরণ গড় loss-এ সমানভাবে অবদান রাখে। Class weighting প্রতিটা উদাহরণের ইন্ডিভিজুয়াল loss অবদানকে এর ক্লাসের উপর নির্ভর করা একটা weight দিয়ে গুণ করে, সাধারণত minority-class উদাহরণকে একটা বড় weight আর majority-class উদাহরণকে একটা ছোট weight দিয়ে।
এখানে হলো সেই weight যা প্রয়োগ হয় যখন সত্যিকারের লেবেল পজিটিভ (প্রায়ই minority) ক্লাস, আর হলো সেই weight যা প্রয়োগ হয় যখন সত্যিকারের লেবেল নেগেটিভ (প্রায়ই majority) ক্লাস। একটা সাধারণ শুরুর পছন্দ প্রতিটা ক্লাসের weight এর ফ্রিকোয়েন্সির বিপরীত অনুপাতে সেট করে — একটা ক্লাস যত বিরল, এর weight তত বড়, তাই একটা মাত্র minority-class ভুল loss-এ অনেকগুলো majority-class ভুল মিলিয়ে যতটা ভারী গোনা হয় ততটাই ভারী গোনা হয়।
Class weighting loss function অ্যাডজাস্ট করে যাতে minority-class উদাহরণে ভুলগুলো majority-class উদাহরণে ভুলের চেয়ে বেশি ভারীভাবে শাস্তি পায়, মডেল আসলে কোন উদাহরণ দেখে তা না বদলিয়ে।
Class weighting ডেটা কপি করে না (oversampling-এর মতো) বা বাদ দেয় না (undersampling-এর মতো) — প্রতিটা আসল training উদাহরণ প্রতি epoch-এ ঠিক একবারই ব্যবহৃত হয়, সিন্থেটিক বা পুনরাবৃত্তি হওয়া উদাহরণে কোনো অতিরিক্ত মেমরি বা হিসাব খরচ ছাড়াই। এটা এটাকে চেষ্টা করার জন্য একটা আকর্ষণীয় প্রথম জিনিস বানায়, বিশেষ করে যেহেতু বেশিরভাগ আধুনিক ট্রেনিং ফ্রেমওয়ার্ক class weight সরাসরি একটা ট্রেনিং আর্গুমেন্ট হিসেবে পাস করা সমর্থন করে।
ট্রেনিংয়ের সময় imbalance ঠিক করা শুধু সমস্যার অর্ধেক সমাধান করে — একটা মডেল কীভাবে মূল্যায়ন করা হয় সেটাও বদলাতে হবে, Why It Matters সেকশনের accuracy সম্পর্কে সতর্কতাকে প্রতিধ্বনিত করে।
Accuracy — যে ভগ্নাংশ প্রেডিকশন সঠিক — imbalanced ডেটায় একটা খারাপ প্রাথমিক মেট্রিক, ঠিক এই কারণে যে minority ক্লাসকে সম্পূর্ণভাবে উপেক্ষা করা একটা মডেল তবুও প্রতারণামূলকভাবে উচ্চ স্কোর করতে পারে। কয়েকটা বিকল্প মেট্রিক বিশেষভাবে minority-class পারফরম্যান্সের অনেক পরিষ্কার ছবি দেয়:
Precision
মডেল পজিটিভ (প্রায়ই minority) ক্লাস হিসেবে প্রেডিক্ট করা প্রতিটা উদাহরণের মধ্যে, কত ভগ্নাংশ আসলে সঠিক ছিল? উচ্চ precision মানে কম ফলস অ্যালার্ম।
Recall
যেসব উদাহরণ সত্যিই পজিটিভ ক্লাসের, তার মধ্যে মডেল কত ভগ্নাংশ সঠিকভাবে ধরেছে? উচ্চ recall মানে কম মিস করা কেস — প্রায়ই জালিয়াতি বা রোগ সনাক্তকরণের মতো প্রবলেমে প্রাধান্য।
F1 Score
Precision আর recall-এর ভারসাম্য রাখা একটা মাত্র মিলিত স্কোর, উপযোগী যখন ফলস অ্যালার্ম আর মিস করা কেস দুটোই গুরুত্বপূর্ণ আর কোনোটাই একা পুরো গল্প বলে না।
Confusion Matrix
প্রতিটা ক্লাসের সঠিক আর ভুল প্রেডিকশনের একটা সম্পূর্ণ বিভাজন, দেখায় ঠিক কোন ধরনের ভুল একটা মডেল করে — শুধু এটা সামগ্রিকভাবে কতবার ভুল সেটা না।
জালিয়াতি সনাক্তকরণে, আসল জালিয়াতি মিস করা (কম recall) সাধারণত একটা বৈধ লেনদেন দুইবার চেক করানো একটা ফলস অ্যালার্মের চেয়ে (কম precision) অনেক বেশি ব্যয়বহুল — তাই minority ক্লাসে recall সামগ্রিক accuracy-র চেয়ে বেশি গুরুত্বপূর্ণ। একটা ভিন্ন প্রবলেমে, যেমন ম্যানুয়াল রিভিউয়ের জন্য কনটেন্ট ফ্ল্যাগ করা, খুব বেশি ফলস অ্যালার্ম একটা রিভিউ টিমকে অভিভূত করে দিতে পারে, precision-কে বরং বেশি প্রাধান্য দিয়ে। কোনো সার্বজনীন উত্তর নেই; এটা নির্ভর করে নির্দিষ্ট প্রবলেমের জন্য কোন ধরনের ভুল বেশি ব্যয়বহুল তার উপর।
Oversampling, undersampling, আর class weighting শুধু ট্রেনিং-কেই প্রভাবিত করা উচিত — validation আর test ডেটা (Underfitting vs Overfitting চ্যাপ্টার থেকে) সবসময় প্রোডাকশনে মডেল আসলে যে আসল, মূল ক্লাস ডিস্ট্রিবিউশনের মুখোমুখি হবে সেটাই প্রতিফলিত করা উচিত। কৃত্রিমভাবে পুনরায় ব্যালেন্স করা validation ডেটায় মূল্যায়ন করা ঠিক এই চ্যাপ্টারের সমস্যাটাই লুকিয়ে ফেলবে।