Home »
Blog »
AI/ML Engineer সিরিজ » Series 03 » Episode 08
Data Preprocessing: encoding, scaling, আর 'data leakage'-এর ফাঁদ
model-এ ঢোকানোর আগে data প্রস্তুত করা (Series 03, Episode 08)
🟡 INTERMEDIATE
Series 03 — Data — AI-এর ভিত্তি
Episode 08 / 09
📑 এই পর্বে যা যা আছে
- ১. গল্প: Rahim-এর "৯৯% accuracy" model বাস্তবে ফেল
- ২. সমস্যা: ML model কাঁচা data নেয় না
- ৩. কেন preprocessing দরকার
- ৪. তিন Level-এ preprocessing বোঝা
- ৫. Missing value: চেনা ও সামলানো
- ৬. Categorical variable: encoding
- ৭. Normalization বনাম Standardization (scaling)
- ৮. Outlier: চেনা ও সিদ্ধান্ত
- ৯. Data leakage কী — সবচেয়ে বিপজ্জনক ভুল
- ১০. train/test split ও leakage এড়ানো
- ১১. scikit-learn Pipeline: leakage-proof উপায়
- ১২. বাস্তব উদাহরণ: BD churn data preprocessing
- ১৩. একজন AI Engineer-এর দৃষ্টিতে
- ১৪. Boss Question
- ১৫. Job Requirement Decoder
- ১৬. সাধারণ ভুল ধারণা
- ১৭. Interview Prep
- ১৮. হাতে-কলমে (Mini Exercise)
- ১৯. Project Connection
- ২০. সারসংক্ষেপ
- ২১. পরবর্তী পর্বে কী শিখব
🧩 ১. গল্প: Rahim-এর "৯৯% accuracy" model বাস্তবে ফেল
Rahim প্রথম ML model বানিয়ে উচ্ছ্বসিত — training-এ ৯৯% accuracy! কিন্তু production-এ দেওয়ার পর model
যাচ্ছেতাই prediction দিচ্ছে। Boss বিরক্ত, Rahim হতভম্ব।
Rahim: "Maya আপা, আমার model তো ৯৯% accuracy দিয়েছিল! বাস্তবে এত খারাপ কেন?"
Maya: "তোমার model cheat করেছে — তুমি বুঝতে পারোনি। এটাকে বলে data leakage।
আর তার আগে প্রশ্ন — তুমি কি missing value, categorical column আর scaling ঠিকমতো handle করেছিলে? Model যত
ভালোই হোক, garbage in → garbage out। আজ আমরা preprocessing শিখব — data-কে ML-এর যোগ্য করে
তোলা, আর সেই ভয়ংকর leakage কীভাবে এড়ানো যায়।"
❓ ২. সমস্যা: ML model কাঁচা data নেয় না
বাস্তব data সবসময় নোংরা। একটা সাধারণ job/customer dataset-এ থাকে:
- Missing value: কিছু cell খালি (salary নেই, age নেই)।
- Categorical text: "Dhaka", "Fintech" — model সংখ্যা চায়, text না।
- ভিন্ন scale: age (২০–৬০) আর salary (৩০০০০–২০০০০০) — একই scale-এ নেই।
- Outlier: কেউ ভুল করে salary লিখেছে ৫,০০,০০,০০০।
Preprocessing = এই সমস্যাগুলো ঠিক করে data-কে model-এর যোগ্য, পরিষ্কার সংখ্যার টেবিলে রূপান্তর করা।
🎯 ৩. কেন preprocessing দরকার
- Model শুধু সংখ্যা বোঝে: text/category সংখ্যায় রূপান্তর করতেই হবে।
- Scale-sensitive algorithm: অনেক algorithm (Linear/Logistic Regression, KNN, SVM, neural net) বড় সংখ্যার column-কে বেশি গুরুত্ব দিয়ে ফেলে যদি scale না করা হয়।
- Missing value crash করায়: বেশিরভাগ algorithm NaN নিয়ে চলতে পারে না।
- ভালো data = ভালো model: practice-এ model architecture-এর চেয়ে data quality বেশি ফল বদলায়।
Must Know / Good to Know / Learn Later:
Must Know: missing value handling, one-hot/label encoding, standardization, train/test split, data leakage ধারণা।
Good to Know: outlier treatment, scikit-learn Pipeline, target/frequency encoding।
Learn Later: advanced imputation (KNN/iterative), feature store, automated preprocessing।
🪜 ৪. তিন Level-এ preprocessing বোঝা
Level 1 — সহজ intuition
রান্নার আগে সবজি ধুয়ে, কেটে, বেছে নিতে হয় — পচা অংশ ফেলে দিতে হয়। Preprocessing হলো ML-এর সেই "সবজি
কাটার" ধাপ। নোংরা data সরাসরি model-এ দিলে রান্না নষ্ট হবেই।
Level 2 — technical ভাবে
Preprocessing মানে raw feature-গুলোকে এমন সংখ্যায় রূপান্তর করা যা model-friendly — missing value পূরণ
(imputation), category-কে সংখ্যায় (encoding), সব feature একই scale-এ (scaling), আর অস্বাভাবিক মান (outlier) নিয়ে সিদ্ধান্ত।
Level 3 — engineer দৃষ্টিতে
Engineer রা preprocessing-কে একটা reproducible pipeline হিসেবে দেখে — training-এ যা করা হয়,
হুবহু তাই inference/production-এ হতে হবে। আর সবচেয়ে বড় শঙ্কা — এই ধাপে যেন future/test তথ্য leak
না হয়। এটাই junior আর engineer-এর আসল পার্থক্য।
🕳️ ৫. Missing value: চেনা ও সামলানো
import pandas as pd
import numpy as np
df = pd.DataFrame({
"title": ["Python Dev", "ML Engineer", "Data Analyst", "Backend"],
"salary": [45000, np.nan, 40000, 70000],
"city": ["Dhaka", "Dhaka", np.nan, "Sylhet"],
})
# কোথায় কতগুলো missing?
print(df.isna().sum())
# কৌশল ১: বাদ দেওয়া (missing কম হলে)
df_dropped = df.dropna()
# কৌশল ২: number column পূরণ (median বেশি robust)
df["salary"] = df["salary"].fillna(df["salary"].median())
# কৌশল ৩: category column পূরণ (mode / "Unknown")
df["city"] = df["city"].fillna("Unknown")
কখন কোনটা? missing খুব কম হলে row বাদ দেওয়া চলে। বেশি হলে পূরণ (impute) করুন — number-এ
median (outlier-এ কম প্রভাবিত), category-তে mode বা আলাদা "Unknown" class। সতর্কতা: median/mean
হিসাব করতে হবে শুধু training data থেকে (নিচে leakage অংশে বিস্তারিত)।
🔤 ৬. Categorical variable: encoding
Model text বোঝে না — category-কে সংখ্যায় আনতে হবে। দুটো প্রধান উপায়:
# One-Hot Encoding: প্রতিটা category => আলাদা 0/1 column
# (nominal/ক্রমহীন category-র জন্য: city, industry)
df_ohe = pd.get_dummies(df, columns=["city"])
# city_Dhaka, city_Sylhet, city_Unknown => 0/1
# Label / Ordinal Encoding: category => 0,1,2...
# (ordinal/ক্রম-যুক্ত category-র জন্য: "Low<Mid<High")
from sklearn.preprocessing import OrdinalEncoder
levels = [["Low", "Mid", "High"]]
enc = OrdinalEncoder(categories=levels)
# enc.fit_transform(df[["level"]]) # Low=0, Mid=1, High=2
গুরুত্বপূর্ণ নিয়ম: ক্রমহীন category-তে (city, color) label encoding (0,1,2) দেবেন না —
তাহলে model ভুল করে ভাববে "Sylhet(2) > Dhaka(1)", যা অর্থহীন। সেখানে one-hot ব্যবহার করুন। শুধু সত্যিকারের
ক্রম থাকলে (Low/Mid/High) ordinal encoding ঠিক আছে।
📏 ৭. Normalization বনাম Standardization (scaling)
age (২০–৬০) আর salary (৩০০০০–২০০০০০) একই scale-এ না থাকলে অনেক algorithm বড় সংখ্যাকে বেশি গুরুত্ব দেয়। সমাধান scaling:
Normalization (Min-Max)
মানকে ০–১ range-এ আনে।
সূত্র: (x − min) / (max − min)
outlier-এ সংবেদনশীল।
Standardization (Z-score)
গড়=০, std=১ করে।
সূত্র: (x − mean) / std
সাধারণত বেশি ব্যবহৃত ও robust।
from sklearn.preprocessing import StandardScaler, MinMaxScaler
scaler = StandardScaler() # গড়=0, std=1
X_scaled = scaler.fit_transform(X_train[["age", "salary"]])
# একই scaler test-এ শুধু transform (fit নয়!) — নিচে কারণ
X_test_scaled = scaler.transform(X_test[["age", "salary"]])
Tree-based model (Decision Tree, Random Forest, XGBoost)-এ scaling সাধারণত লাগে না — এরা scale-invariant।
কিন্তু Linear/Logistic Regression, KNN, SVM, neural net-এ scaling প্রায় বাধ্যতামূলক।
🎯 ৮. Outlier: চেনা ও সিদ্ধান্ত
# IQR পদ্ধতিতে outlier চেনা
Q1 = df["salary"].quantile(0.25)
Q3 = df["salary"].quantile(0.75)
IQR = Q3 - Q1
low = Q1 - 1.5 * IQR
high = Q3 + 1.5 * IQR
outliers = df[(df["salary"] < low) | (df["salary"] > high)]
print(outliers)
সব outlier ফেলে দেবেন না! কিছু outlier আসল, গুরুত্বপূর্ণ signal (যেমন fraud detection-এ
অস্বাভাবিক transaction-ই তো target)। আগে বুঝুন এটা ভুল data (data entry error) নাকি সত্যিকারের
বিরল ঘটনা। ভুল হলে ঠিক করুন/বাদ দিন; আসল হলে রাখুন বা আলাদাভাবে model করুন।
💀 ৯. Data leakage কী — সবচেয়ে বিপজ্জনক ভুল
Data leakage হলো — model training-এর সময় এমন তথ্য দেখে ফেলা যা বাস্তবে prediction-এর
মুহূর্তে পাওয়া যাবে না (future বা test তথ্য)। ফল: training/test-এ দুর্দান্ত score, কিন্তু production-এ ভয়াবহ ফেল।
Leakage যেভাবে ঘটে (দুটো ক্লাসিক উদাহরণ):
১) পুরো data-তে scale/impute করে তারপর split
-> test-এর mean/std training-এ "leak" হলো
-> model আসলে test সম্পর্কে আগেই "জানে"
২) target থেকে তৈরি feature model-এ ঢোকানো
যেমন churn predict করতে "account_closed_date"
-> এটা তো churn হওয়ার পরেই পাওয়া যায়!
-> model cheat করছে, বাস্তবে থাকবে না
Rahim-এর "৯৯% accuracy"-র রহস্য এখানেই: সে পুরো dataset-এ scaling করেছিল তারপর train/test split
করেছিল — test-এর তথ্য training-এ leak করেছে। Model test data আগেই "চিনে ফেলেছিল"।
✂️ ১০. train/test split ও leakage এড়ানো
সঠিক ক্রম সবসময়: আগে split, তারপর শুধু training data থেকে fit — তারপর test-এ শুধু transform।
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# ধাপ ১: আগে split (leakage-এর প্রথম প্রতিরক্ষা)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
scaler = StandardScaler()
# ধাপ ২: fit শুধু training data-তে (mean/std শেখা)
X_train_scaled = scaler.fit_transform(X_train)
# ধাপ ৩: test-এ শুধু transform (একই mean/std প্রয়োগ)
X_test_scaled = scaler.transform(X_test) # fit নয়!
মন্ত্র মনে রাখুন: fit শুধু train-এ, transform সব জায়গায়। imputation, scaling, encoding —
সব preprocessing-এর statistic (mean, median, category তালিকা) শুধু training data থেকে শিখতে হবে।
🔧 ১১. scikit-learn Pipeline: leakage-proof উপায়
হাতে হাতে fit/transform মনে রাখা কঠিন — একটা ভুলেই leakage। এর সবচেয়ে নিরাপদ সমাধান
Pipeline + ColumnTransformer, যা cross-validation-এও leakage আটকায়:
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
num_cols = ["age", "salary"]
cat_cols = ["city", "industry"]
# number: median দিয়ে পূরণ + standardize
num_pipe = Pipeline([
("impute", SimpleImputer(strategy="median")),
("scale", StandardScaler()),
])
# category: mode দিয়ে পূরণ + one-hot
cat_pipe = Pipeline([
("impute", SimpleImputer(strategy="most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore")),
])
pre = ColumnTransformer([
("num", num_pipe, num_cols),
("cat", cat_pipe, cat_cols),
])
# পুরো flow এক object-এ: preprocess + model
model = Pipeline([
("pre", pre),
("clf", LogisticRegression(max_iter=1000)),
])
model.fit(X_train, y_train) # সব fit শুধু train-এ
model.score(X_test, y_test) # test-এ শুধু transform, নিরাপদ
কেন Pipeline? এটা preprocessing ও model-কে এক করে রাখে — তাই fit শুধু train-এ হয়, আর
cross-validation করলেও প্রতিটা fold-এ leakage আপনাআপনি এড়ানো হয়। production-এ deploy করাও সহজ (এক object)।
🇧🇩 ১২. বাস্তব উদাহরণ: BD churn data preprocessing
ধরুন একটা BD telecom (GP/Robi ধরনের) churn dataset — কে গ্রাহক ছেড়ে যাবে। column: age,
monthly_bill, plan_type (category), tenure, target churned।
একজন engineer যা করবে:
# ১. LEAKAGE ফাঁদ: এই column বাদ দিতে হবে!
# "disconnection_date" — churn হওয়ার পরেই জানা যায়
df = df.drop(columns=["disconnection_date"])
# ২. আগে split
X = df.drop(columns=["churned"])
y = df["churned"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
# ৩. Pipeline দিয়ে impute+scale+encode (সব fit train-এ)
model.fit(X_train, y_train)
stratify=y কেন? churn সাধারণত imbalanced (হয়তো ১০% churn); stratify নিশ্চিত করে train ও
test-এ churn-এর অনুপাত একই থাকে।
👷 ১৩. একজন AI Engineer-এর দৃষ্টিতে
Engineer রা তিনটা জিনিস কখনো ভোলে না:
১. আগে split, তারপর fit — leakage-এর এক নম্বর প্রতিরক্ষা।
২. Pipeline-এ সব preprocessing bundle করা — যাতে training ও production-এ হুবহু একই রূপান্তর হয়।
৩. প্রতিটা feature-কে প্রশ্ন করা: "prediction-এর মুহূর্তে এটা কি সত্যিই জানা থাকবে?" —
না হলে সেটা leakage, বাদ দিতে হবে।
"কাগজে দারুণ score কিন্তু বাস্তবে খারাপ" — এর ৯০% কারণ data leakage। তাই engineer সবার আগে এই ফাঁদটা খোঁজে।
💼 ১৪. Boss Question
Boss: "Model বানানোই তো আসল কাজ, এই data ধোয়ামোছায় এত সময় কেন? এটা business-এ কী দেয়?"
উত্তর: কারণ ভুল preprocessing মানে ভুল model — আর ভুল model ব্যবসায় সরাসরি ক্ষতি। ধরুন
churn model leakage-এর কারণে test-এ ৯৯% দেখাল, আমরা ভরসা করে marketing budget সাজালাম, বাস্তবে model
কিছুই ধরল না — টাকা নষ্ট, আস্থা নষ্ট। ভালো preprocessing মানে model বাস্তবেও যেমন score দেখায় তেমনই কাজ করে —
এটাই নির্ভরযোগ্য, তাই business-value-যুক্ত AI।
🔎 ১৫. Job Requirement Decoder
"Experience with data preprocessing, feature scaling, and building robust ML pipelines."
| প্রশ্ন | উত্তর |
| এর মানে কী? | আপনি কাঁচা data পরিষ্কার করে, encode/scale করে, leakage ছাড়া model-ready করতে পারেন। |
| কোম্পানি কেন চায়? | বাস্তবে সময়ের বড় অংশ data preprocessing-এ যায়; ভুল হলে পুরো model অকেজো। |
| কোন সমস্যা সমাধান করে? | "training-এ ভালো, production-এ খারাপ" model-এর মূল কারণ (leakage) দূর করে। |
| Junior-এর কী জানা লাগে? | missing value, one-hot/ordinal encoding, standardization, train/test split, leakage, sklearn Pipeline। |
| এখনই কী master লাগে না? | advanced imputation, feature store, automated feature engineering tool। |
| GitHub-এ কীভাবে দেখাবেন? | একটা project-এ Pipeline + ColumnTransformer ব্যবহার করে README-তে leakage-এড়ানোর কৌশল ব্যাখ্যা করুন। |
| Interview-তে কী জিজ্ঞেস করতে পারে? | "data leakage কী ও কীভাবে এড়াবেন?", "normalization vs standardization?", "কেন fit শুধু train-এ?" |
⚠️ ১৬. সাধারণ ভুল ধারণা
ভুল ১: পুরো data-তে scale/impute করে তারপর split। →
ঠিক: আগে split, তারপর শুধু train-এ fit — নাহলে leakage।
ভুল ২: test data-তে fit_transform করা। →
ঠিক: test-এ শুধু transform; statistic train থেকেই আসবে।
ভুল ৩: ক্রমহীন category-তে label encoding (0,1,2)। →
ঠিক: nominal-এ one-hot; ordinal encoding শুধু সত্যিকারের ক্রম থাকলে।
ভুল ৪: সব outlier অন্ধভাবে ফেলে দেওয়া। →
ঠিক: আগে বুঝুন ভুল data নাকি আসল বিরল ঘটনা।
ভুল ৫: target-নির্ভর/future column feature হিসেবে রাখা। →
ঠিক: prediction-মুহূর্তে পাওয়া যাবে না এমন column বাদ দিন (leakage)।
🎤 ১৭. Interview Prep
প্রশ্ন ১: Data leakage কী এবং কীভাবে এড়াবেন?
উত্তর: training-এ এমন তথ্য দেখা যা inference-এ পাওয়া যাবে না। এড়াতে — আগে split, fit শুধু train-এ,
target/future column বাদ, আর Pipeline ব্যবহার।
প্রশ্ন ২: Normalization আর standardization-এর পার্থক্য, কখন কোনটা?
উত্তর: normalization ০–১ range-এ আনে (min-max); standardization গড়=০/std=১ করে (z-score)। সাধারণত
standardization বেশি robust; distribution-নির্দিষ্ট algorithm-এ পছন্দমতো।
প্রশ্ন ৩: ক্রমহীন category-তে label encoding কেন খারাপ?
উত্তর: এটা কৃত্রিম ক্রম/দূরত্ব তৈরি করে (Sylhet>Dhaka), যা model ভুল ব্যাখ্যা করে। one-hot ভালো।
প্রশ্ন ৪: Tree-based model-এ কি scaling লাগে?
উত্তর: সাধারণত না; এরা scale-invariant। কিন্তু Linear/KNN/SVM/neural net-এ লাগে।
✍️ ১৮. হাতে-কলমে (Mini Exercise)
একটা ছোট dataset (নিজের বানানো বা Kaggle-এর Titanic) নিয়ে করুন:
১. প্রতিটা column-এ কতগুলো missing value আছে বের করুন।
২. number column median দিয়ে, category column mode দিয়ে পূরণ করুন।
৩. একটা category column one-hot encode করুন।
৪. train_test_split করে শুধু train-এ StandardScaler.fit করুন, test-এ শুধু transform।
৫. একই কাজ Pipeline + ColumnTransformer দিয়ে করুন এবং বলুন কেন এটা leakage থেকে নিরাপদ।
🚀 ১৯. Project Connection
flagship "Bangladesh Tech Career Assistant"-এ আমরা এবার job data-কে ML-ready করব —
city/industry one-hot, salary/experience standardize,
missing value impute — সব একটা leakage-proof Pipeline-এ।
Project P3 (Customer Churn Prediction)-এ এই preprocessing সরাসরি লাগবে — বিশেষ করে leakage এড়ানো ও
stratified split। এই পর্বের Pipeline-ই পরের সিরিজে (Series 05) model-এর সাথে জুড়ে যাবে।
📌 ২০. সারসংক্ষেপ
এই পর্বে আমরা শিখলাম:
✓ কেন ML model কাঁচা data নেয় না — garbage in, garbage out
✓ Missing value চেনা ও impute (median/mode/Unknown)
✓ Encoding — nominal-এ one-hot, ordinal-এ ordinal (label encoding-এর ফাঁদ)
✓ Scaling — normalization vs standardization, কোথায় লাগে কোথায় লাগে না
✓ Outlier — অন্ধভাবে ফেলবেন না, আগে বুঝুন
✓ Data leakage — সবচেয়ে বিপজ্জনক ভুল, "কাগজে ভালো, বাস্তবে ফেল"-এর মূল কারণ
✓ আগে split, fit শুধু train-এ, আর leakage-proof scikit-learn Pipeline
➡️ ২১. পরবর্তী পর্বে কী শিখব
পরবর্তী Episode (S03E09): "Project — Bangladesh Job Market Data দিয়ে প্রশ্নের উত্তর বের করা"।
NumPy, Pandas, Matplotlib, SQL আর preprocessing — এই সিরিজের সব শেখা এবার এক জায়গায়। আমরা flagship-এর
Project P1 (Bangladesh Job Market Data Analyzer) সম্পূর্ণ করব — একটা end-to-end EDA project
যা data দিয়ে বাস্তব প্রশ্নের উত্তর দেয়, আর হবে আপনার প্রথম portfolio piece।