Home »
Blog »
AI/ML Engineer সিরিজ » Series 05 » Episode 08
Overfitting, Underfitting, Cross-Validation ও Hyperparameter Tuning
model কেন generalize করে না (Series 05, Episode 08)
🟡 INTERMEDIATE
Series 05 — Classical Machine Learning
Episode 08 / 11
📑 এই পর্বে যা যা আছে
- ১. গল্প: Rahim-এর "৯৯% accuracy" ফাঁদ
- ২. সমস্যা: training-এ দারুণ, real data-তে ধরাশায়ী
- ৩. Overfitting ও Underfitting কী? (৩ স্তরে)
- ৪. Visual: bias-variance আর fitting curve
- ৫. কেন একটা test set যথেষ্ট না — data leakage of decisions
- ৬. Cross-Validation: k-fold কীভাবে কাজ করে
- ৭. কোড: k-fold CV হাতে-কলমে (scikit-learn)
- ৮. Hyperparameter কী, আর কেন tune করতে হয়
- ৯. GridSearchCV ও RandomizedSearchCV
- ১০. Experiment: overfit model-কে ধরা ও সারানো
- ১১. Bangladesh উদাহরণ ও Boss Question
- ১২. Job Requirement Decoder
- ১৩. সাধারণ ভুল
- ১৪. Interview Prep
- ১৫. হাতে-কলমে
- ১৬. Project Connection ও সারসংক্ষেপ
📝 ১. গল্প: Rahim-এর "৯৯% accuracy" ফাঁদ
Rahim একটা churn model বানাল। Training-এ accuracy ৯৯%! সে খুশিতে Maya-কে দেখাতে গেল।
Maya শুধু একটা প্রশ্ন করল — "এই ৯৯% কি training data-তে, নাকি নতুন, আগে-না-দেখা data-তে?"
Maya: "একজন ছাত্র যদি পরীক্ষার প্রশ্নপত্র আগে থেকে মুখস্থ করে ফেলে, সে ওই পরীক্ষায় ১০০ পাবে।
কিন্তু নতুন প্রশ্ন দিলে ধরা খাবে। তোমার model এখন ঠিক তাই করছে — data মুখস্থ (memorize)
করেছে, শেখেনি (generalize করেনি)। এটাই overfitting। Production-এ এই model খারাপ
prediction দেবে, আর আমরা বুঝতেও পারব না কেন।"
এই episode-এ আমরা শিখব — কেন model generalize করে না, কীভাবে সেটা ধরব (cross-validation),
আর কীভাবে সেরা model বাছব (hyperparameter tuning)। এটা classical ML-এর সবচেয়ে জরুরি
practical skill-গুলোর একটা।
❓ ২. সমস্যা: training-এ দারুণ, real data-তে ধরাশায়ী
আমরা model train করি অতীত data দিয়ে, কিন্তু আসল লক্ষ্য হলো ভবিষ্যতের, আগে-না-দেখা
data-তে ভালো করা। Model যদি training data-র প্রতিটা খুঁটিনাটি (এমনকি noise-ও) মুখস্থ করে ফেলে, তাহলে
সে training-এ চমৎকার কিন্তু বাস্তবে দুর্বল।
মূল প্রশ্ন: model কি pattern (নিয়ম) শিখেছে, নাকি data মুখস্থ করেছে? পার্থক্য বোঝার একমাত্র উপায় —
model-কে আগে-না-দেখা data-তে যাচাই করা।
🎯 ৩. Overfitting ও Underfitting কী? (৩ স্তরে)
Level 1 — সহজ intuition
Underfitting: model বড্ড সরল — কিছুই ঠিকমতো শেখেনি (যেমন সব প্রশ্নের উত্তরে "জানি না")।
Overfitting: model বড্ড জটিল — সব মুখস্থ করেছে, কিন্তু বুঝে শেখেনি।
Good fit: মাঝামাঝি — আসল নিয়মটা ধরেছে, noise বাদ দিয়েছে।
Level 2 — technical ভাবে কী হচ্ছে
Underfitting = high bias (model assumption বড্ড কড়া, data-র জটিলতা ধরতে পারে না)।
Overfitting = high variance (model training data-র সামান্য পরিবর্তনেও অনেক বদলে যায়,
noise-কেও signal ভাবে)। লক্ষ্য — bias আর variance-এর মধ্যে balance (bias-variance trade-off,
Series 04-এ আলোচিত)।
Level 3 — engineer perspective
একজন engineer শুধু training accuracy দেখে খুশি হয় না। সে সবসময় দুটো সংখ্যা পাশাপাশি দেখে —
training score আর validation score। যদি training অনেক বেশি আর validation অনেক কম → overfitting।
দুটোই কম → underfitting। এই gap-টাই আসল diagnostic tool।
| অবস্থা | Training score | Validation score | সমাধানের দিক |
| Underfitting | কম | কম | আরও শক্তিশালী model, বেশি feature, কম regularization |
| Overfitting | খুব বেশি | অনেক কম | আরও data, regularization, model সরল করা |
| Good fit | ভালো | কাছাকাছি ভালো | এটাই লক্ষ্য |
🖼️ ৪. Visual: bias-variance আর fitting curve
Underfitting Good Fit Overfitting
(high bias) (high variance)
o o o o o o
--------- _/ \_ /\ o /\ o
o o o o o \/ \/ o
(সরল রেখা, (মসৃণ curve, (প্রতিটা বিন্দু
কিছুই ধরেনি) নিয়ম ধরেছে) ছুঁয়ে গেছে = noise
মুখস্থ)
Training error: বেশি কম খুব কম
Validation err: বেশি কম বেশি <-- সমস্যা!
খেয়াল করুন — overfitting-এ curve প্রতিটা training বিন্দু ছুঁয়ে যায় (এমনকি noise-ও), কিন্তু নতুন
data এলে ভুল করে। Good fit noise উপেক্ষা করে মূল trend ধরে।
🚧 ৫. কেন একটা test set যথেষ্ট না
আপনি হয়তো ভাবছেন — "একটা test set রাখলেই তো হলো।" সমস্যা হলো, আপনি যদি বারবার একই test set দেখে
model বা hyperparameter বদলান, তাহলে ধীরে ধীরে আপনি test set-এর উপরেও overfit করে ফেলেন।
এটা এক ধরনের সূক্ষ্ম data leakage — সিদ্ধান্ত নেওয়ার সময় test data-র তথ্য চুইয়ে ঢুকে পড়ে।
সঠিক ভাগ: Train (শেখার জন্য) → Validation (model/hyperparameter
বাছাইয়ের জন্য) → Test (একদম শেষে, একবার, honest final score-এর জন্য)। Test set-কে
"সিন্দুকে তালা মেরে" রাখুন — শুধু একবার খুলবেন।
কিন্তু ছোট dataset-এ আলাদা validation set রাখা মানে শেখার data আরও কমে যাওয়া। এই সমস্যার সুন্দর
সমাধান — Cross-Validation।
🔁 ৬. Cross-Validation: k-fold কীভাবে কাজ করে
k-fold CV-তে data-কে k ভাগে (fold) ভাগ করা হয়। প্রতিবার ১টা fold validation, বাকি
(k-1)টা training। এভাবে k বার train-validate করা হয়, প্রতিবার ভিন্ন fold validation হিসেবে। শেষে
k-টা score-এর গড় নেওয়া হয়।
5-fold Cross-Validation (k=5):
Fold 1: [VAL][TRN][TRN][TRN][TRN] -> score1
Fold 2: [TRN][VAL][TRN][TRN][TRN] -> score2
Fold 3: [TRN][TRN][VAL][TRN][TRN] -> score3
Fold 4: [TRN][TRN][TRN][VAL][TRN] -> score4
Fold 5: [TRN][TRN][TRN][TRN][VAL] -> score5
Final CV score = (score1 + ... + score5) / 5
লাভ: প্রতিটা data point কোনো-না-কোনো বার validation-এ যায়, তাই score অনেক বেশি নির্ভরযোগ্য এবং কম
"ভাগ্য-নির্ভর"। classification-এ সাধারণত StratifiedKFold ব্যবহার হয় — যাতে প্রতিটা fold-এ
class-এর অনুপাত ঠিক থাকে (imbalanced data-তে খুব জরুরি, যা Episode 05-এ দেখেছি)।
💻 ৭. কোড: k-fold CV হাতে-কলমে (scikit-learn)
কেন scikit-learn? কারণ এটাই industry-তে classical ML-এর standard, আর CV/tuning এর মধ্যে built-in।
import numpy as np
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold
# একটা উদাহরণ dataset (বাস্তবে এখানে আপনার churn/job data বসবে)
X, y = make_classification(
n_samples=1000, n_features=20, n_informative=8,
weights=[0.7, 0.3], random_state=42,
)
model = RandomForestClassifier(n_estimators=200, random_state=42)
# StratifiedKFold: প্রতিটা fold-এ class অনুপাত ঠিক রাখে
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=cv, scoring="f1")
print("প্রতি fold f1:", np.round(scores, 3))
print("গড় f1: %.3f (+/- %.3f)" % (scores.mean(), scores.std()))
একটা মাত্র সংখ্যা (একবারের accuracy) বিশ্বাস করবেন না। CV আপনাকে গড় ± স্ট্যান্ডার্ড ডেভিয়েশন
দেয় — যা বলে model কতটা স্থিতিশীল। বড় std মানে model অস্থির, ভরসা কম।
🎛️ ৮. Hyperparameter কী, আর কেন tune করতে হয়
দুই ধরনের "parameter" আছে। Parameter = model নিজে data থেকে শেখে (যেমন linear
regression-এর coefficient)। Hyperparameter = আপনি training-এর আগে সেট করেন,
model এগুলো শেখে না (যেমন Random Forest-এর n_estimators, max_depth; XGBoost-এর
learning_rate)।
Parameter
data থেকে শেখা হয় (training-এ)।
উদাহরণ: weight, coefficient, split threshold।
Hyperparameter
আপনি হাতে সেট করেন (training-এর আগে)।
উদাহরণ: max_depth, n_estimators, learning_rate।
ভুল hyperparameter মানেই overfitting বা underfitting। যেমন — খুব বেশি max_depth = tree
সব মুখস্থ করে (overfit); খুব কম = কিছুই শেখে না (underfit)। সঠিক মান খুঁজে বের করার প্রক্রিয়াই
hyperparameter tuning।
🔍 ৯. GridSearchCV ও RandomizedSearchCV
GridSearchCV: আপনি কিছু মান দেন, এটা প্রতিটা সম্ভাব্য combination CV দিয়ে যাচাই করে
সেরাটা বেছে দেয় (নিখুঁত কিন্তু ধীর)। RandomizedSearchCV: combination থেকে random কিছু
চেষ্টা করে (দ্রুত, বড় search space-এ বেশি কার্যকর)।
from sklearn.model_selection import GridSearchCV
param_grid = {
"n_estimators": [100, 200, 400],
"max_depth": [4, 8, 16, None],
"min_samples_leaf": [1, 2, 5],
}
grid = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid=param_grid,
cv=cv, # উপরের StratifiedKFold
scoring="f1",
n_jobs=-1, # সব CPU core ব্যবহার
)
grid.fit(X, y)
print("সেরা hyperparameter:", grid.best_params_)
print("সেরা CV f1: %.3f" % grid.best_score_)
best_model = grid.best_estimator_ # এটাই final model
খুব গুরুত্বপূর্ণ: preprocessing (scaling, encoding) সবসময় Pipeline-এর
ভেতরে রাখুন, তারপর সেই pipeline-কে CV-তে দিন। নাহলে scaling পুরো data-র উপর হয়ে গেলে validation
fold-এর তথ্য চুইয়ে ঢুকে data leakage হয় — CV score মিথ্যা রকম ভালো দেখায়।
🧪 ১০. Experiment: overfit model-কে ধরা ও সারানো
নিজে চালিয়ে দেখুন — একটা ইচ্ছাকৃত overfit model বানান, তারপর সারান:
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
from sklearn.tree import DecisionTreeClassifier
X_tr, X_te, y_tr, y_te = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42,
)
# ধাপ ১: ইচ্ছাকৃত overfit (গভীর tree, কোনো সীমা নেই)
over = DecisionTreeClassifier(random_state=42) # max_depth=None
over.fit(X_tr, y_tr)
print("Overfit -> train:", f1_score(y_tr, over.predict(X_tr)))
print("Overfit -> test :", f1_score(y_te, over.predict(X_te)))
# আশা করুন: train ~1.0, test অনেক কম => বড় gap = overfitting
# ধাপ ২: সারানো (depth সীমিত + leaf সীমা = regularization)
fixed = DecisionTreeClassifier(
max_depth=5, min_samples_leaf=10, random_state=42,
)
fixed.fit(X_tr, y_tr)
print("Fixed -> train:", f1_score(y_tr, fixed.predict(X_tr)))
print("Fixed -> test :", f1_score(y_te, fixed.predict(X_te)))
# আশা করুন: train একটু কমবে, কিন্তু test বাড়বে; gap ছোট হবে
কী দেখবেন: ধাপ ১-এ train আর test-এর মধ্যে বিশাল gap = overfitting-এর স্পষ্ট প্রমাণ।
ধাপ ২-এ gap ছোট হয়ে test score উন্নত — এটাই regularization-এর শক্তি। মনে রাখবেন, সামান্য কম train
score কিন্তু ভালো test score = ভালো model।
🇧🇩 ১১. Bangladesh উদাহরণ ও Boss Question
ধরুন একটা fintech (যেমন bKash/Nagad ধরনের) fraud detection model বানাল, past ৬ মাসের data-তে ৯৮%
accuracy। Production-এ গিয়ে সেটা ভুয়া transaction ধরতে পারল না — কারণ model পুরনো fraud pattern
মুখস্থ করেছিল, নতুন pattern-এ generalize করেনি। CV দিয়ে আগে যাচাই করলে এই ঝুঁকি অনেকটা ধরা পড়ত।
💼 Boss Question
Boss: "তুমি বললে model ৯৯% accurate। তাহলে আসল customer-দের উপর চালানোর পর এত ভুল কেন? আমার তো
টাকা যাচ্ছে!"
উত্তর: "স্যার, ৯৯% ছিল training data-তে — অর্থাৎ model যা আগে দেখেছে তার উপর। আসল
পরীক্ষা হয় আগে-না-দেখা data-তে। আমরা এখন থেকে cross-validation দিয়ে deploy করার আগেই
realistic performance মাপব, আর hyperparameter tuning দিয়ে model যেন generalize করে সেটা নিশ্চিত করব।
তাহলে production-এর ভুল, মানে আপনার আর্থিক ঝুঁকি, অনেক কমবে।" — এটাই CV/tuning-এর business value:
deploy-এর আগে বাস্তব ঝুঁকি জানা।
🔎 ১২. Job Requirement Decoder
JD-তে প্রায়ই দেখবেন: "Experience with model evaluation, cross-validation and hyperparameter tuning."
১. কী বোঝায়? আপনি model-কে honestly যাচাই করতে জানেন — শুধু train accuracy দেখে
সিদ্ধান্ত নেন না।
২. কেন চায়? Overfit model production-এ টাকা ও বিশ্বাস নষ্ট করে; কোম্পানি এমন কাউকে
চায় যে এই ফাঁদ চেনে।
৩. কোন সমস্যা সমাধান করে? "lab-এ ভালো, বাস্তবে খারাপ" — এই gap ধরা ও কমানো।
৪. junior-এর কী জানা লাগে? train/val/test split, k-fold ও StratifiedKFold, overfit
vs underfit ধরা, GridSearchCV/RandomizedSearchCV, Pipeline দিয়ে leakage এড়ানো।
৫. এখনই কী master লাগে না? Bayesian optimization, Optuna, nested CV — এগুলো পরে।
৬. GitHub-এ কীভাবে দেখাবে? একটা notebook-এ train vs val curve, CV score (mean±std),
আর tuning-এর আগে-পরে তুলনা দেখান।
৭. Interview-তে কী জিজ্ঞেস করতে পারে? "Overfitting কীভাবে ধরবেন/কমাবেন?",
"k-fold CV কেন?", "Grid vs Random search?", "Pipeline ছাড়া CV করলে সমস্যা কী?"
Must Know: overfit/underfit, k-fold CV, GridSearchCV, Pipeline।
Good to Know: RandomizedSearchCV, learning curve, StratifiedKFold।
Learn Later: Optuna/Bayesian tuning, nested CV। — চাকরির আগে Must+Good, বাকিটা পরে শিখলেও চলবে।
⚠️ ১৩. সাধারণ ভুল
ভুল ১: শুধু training accuracy দেখে খুশি হওয়া। → validation/CV score দেখুন।
ভুল ২: test set বারবার দেখে model tune করা। → test একদম শেষে, একবার।
ভুল ৩: পুরো data-তে scaling/encoding করে তারপর split করা। → leakage; Pipeline + CV ব্যবহার করুন।
ভুল ৪: imbalanced data-তে সাধারণ KFold ব্যবহার। → StratifiedKFold নিন।
ভুল ৫: "overfitting = সবসময় খারাপ, কম train score = খারাপ" ভাবা। → সামান্য কম train
কিন্তু ভালো test = ভালো model। gap-টাই আসল কথা।
🎤 ১৪. Interview Prep
প্রশ্ন ১: Overfitting কী এবং কীভাবে কমাবেন?
উত্তর: model training data (noise সহ) মুখস্থ করে, নতুন data-তে খারাপ করে। কমানোর উপায় —
আরও data, regularization, model সরল করা (কম depth), cross-validation দিয়ে যাচাই।
প্রশ্ন ২: Cross-validation কেন দরকার, একটা test set যথেষ্ট নয় কেন?
উত্তর: একবারের split ভাগ্য-নির্ভর; CV প্রতিটা data point-কে validation-এ নেয়, তাই স্থিতিশীল ও
নির্ভরযোগ্য estimate দেয়, বিশেষত ছোট data-তে।
প্রশ্ন ৩: Parameter আর hyperparameter-এর পার্থক্য?
উত্তর: parameter model data থেকে শেখে (coefficient); hyperparameter আপনি training-এর আগে সেট
করেন (max_depth, learning_rate)।
প্রশ্ন ৪: Grid search বনাম random search?
উত্তর: grid সব combination দেখে (নিখুঁত, ধীর); random কিছু random combination দেখে (দ্রুত, বড়
search space-এ বেশি কার্যকর)।
✍️ ১৫. হাতে-কলমে
Episode 06-এর Random Forest churn model নিন (P3)। এবার:
১. train_test_split করে train ও test আলাদা করুন (test সিন্দুকে তালা)।
২. train-এ StratifiedKFold(5) দিয়ে cross_val_score বের করুন — mean±std লিখুন।
৩. GridSearchCV দিয়ে max_depth ও n_estimators tune করুন।
৪. tuning-এর আগের ও পরের test f1 তুলনা করুন।
৫. একটা DecisionTree-কে ইচ্ছাকৃত overfit করান, train vs test gap দেখান।
প্রশ্ন: tuning কি সবসময় বড় উন্নতি দেয়? কখন দেয় না?
🚀 ১৬. Project Connection ও সারসংক্ষেপ
আমাদের flagship "Bangladesh Tech Career Assistant"-এ যখন আমরা JD থেকে role/seniority
predict করব (V3), তখন CV দিয়ে যাচাই করব model সত্যিই generalize করে কি না — নাহলে একটা নির্দিষ্ট
কোম্পানির JD-তে ভালো, বাকিতে ভুল করবে। P2 (House Price) ও P3 (Churn) দুটোতেই এই CV+tuning প্রয়োগ
করলে portfolio অনেক শক্ত দেখাবে।
এই Episode-এ শিখলাম:
✓ Overfitting = data মুখস্থ (high variance); Underfitting = কিছুই শেখেনি (high bias)
✓ শুধু training score মিথ্যা আশা দেয় — train vs validation gap দেখুন
✓ Train → Validation → Test-এর সঠিক ভূমিকা, আর test set "তালাবদ্ধ" রাখা
✓ k-fold ও StratifiedKFold cross-validation নির্ভরযোগ্য estimate দেয় (mean±std)
✓ Parameter ≠ hyperparameter; GridSearchCV/RandomizedSearchCV দিয়ে tuning
✓ Pipeline + CV দিয়ে preprocessing leakage এড়ানো — নাহলে score মিথ্যা ভালো
পরবর্তী Episode: Unsupervised Learning — K-Means ও PCA। এতক্ষণ আমরা label নিয়ে
(supervised) কাজ করেছি; এবার দেখব label ছাড়াই data-তে কীভাবে pattern ও গঠন খুঁজে বের করা যায়।