OOP for ML: Class দিয়ে কেন model, dataset, pipeline লেখা হয়

কেন scikit-learn আর PyTorch পুরোটাই OOP (Series 02, Episode 04)

🟡 INTERMEDIATE Series 02 — AI Engineer-দের জন্য Python Episode 04 / 09

📑 এই পর্বে যা যা আছে

🧩 ১. গল্প: Rahim-এর sklearn confusion

Rahim একটা tutorial-এ দেখল: model = LinearRegression(), তারপর model.fit(X, y), তারপর model.predict(X_new)। সে অবাক — "model একটা variable, তাহলে তার ভেতরে .fit() এলো কোথা থেকে?"

Arif বলল:

"এটাই OOP, Rahim। LinearRegression একটা class, model তার একটা object। object-এর ভেতরে data (শেখা weight) আর behavior (fit/predict) দুটোই থাকে। পুরো scikit-learn আর PyTorch এই ধারণার ওপর দাঁড়িয়ে। OOP না বুঝলে তুমি এই library-গুলো ব্যবহার করবে ঠিকই, কিন্তু ভেতরে কী হচ্ছে বুঝবে না।"

২. আসল সমস্যা: data + behavior একসাথে

একটা model-এর দুটো জিনিস থাকে: state (শেখা parameter/weight) আর behavior (predict করার নিয়ম)। এগুলো আলাদা variable আর function দিয়ে সামলালে জট পাকিয়ে যায়। OOP এই দুটোকে একটা "object"-এ বেঁধে ফেলে — data আর তার ওপর কাজ একসাথে।

🏗️ ৩. class ও object কী

class হলো একটা নকশা (blueprint); object হলো সেই নকশা থেকে বানানো বাস্তব জিনিস (instance)। "গাড়ির নকশা" = class; "আপনার নির্দিষ্ট গাড়িটা" = object।

class LinearRegression: হলো নকশা। model = LinearRegression() হলো একটা object। আপনি একই class থেকে যত খুশি object বানাতে পারেন — প্রতিটির নিজস্ব state থাকবে।

🎯 ৪. তিন লেভেলে বোঝা: OOP-এর ৪ স্তম্ভ

Level 1 — সহজ intuition:
object = একটা বাক্স, যার ভেতরে জিনিস (data) আর সেই জিনিস নিয়ে কী কী করা যায় (function) — দুটোই থাকে।
Level 2 — technical (৪ স্তম্ভ):
Encapsulation: data + method একসাথে বাঁধা।
Abstraction: জটিলতা লুকিয়ে সহজ interface (.fit()) দেওয়া।
Inheritance: এক class অন্যটির বৈশিষ্ট্য পাওয়া।
Polymorphism: একই নাম (.fit()) ভিন্ন class-এ ভিন্নভাবে কাজ করা।
Level 3 — AI Engineer-এর দৃষ্টিকোণ:
polymorphism-এর কারণেই আপনি LinearRegression বদলে RandomForest বসিয়ে একই .fit()/.predict() কোড চালাতে পারেন। এটাই scikit-learn-এর সৌন্দর্য — সব estimator একই interface মানে।

💻 ৫. Code: প্রথম class — JobPost

class JobPost: def __init__(self, title, text, salary): # __init__ = constructor; object বানানোর সময় চলে self.title = title # self = এই নির্দিষ্ট object self.text = text self.salary = salary def has_skill(self, skill): """behavior: এই job-এ skill আছে কিনা।""" return skill.lower() in self.text.lower() def is_senior(self): return "senior" in self.title.lower() # object বানানো job = JobPost("Senior ML Engineer", "Python, PyTorch, MLOps", 150000) print(job.title) # Senior ML Engineer print(job.has_skill("pytorch")) # True print(job.is_senior()) # True

যা লক্ষ্য করবেন: self মানে "এই নির্দিষ্ট object"। __init__ object তৈরির সময় একবার চলে এবং state (title, text, salary) সেট করে। data (state) আর behavior (has_skill) একই বাক্সে — এটাই encapsulation।

🔍 ৬. কেন scikit-learn আর PyTorch পুরোটাই OOP

from sklearn.linear_model import LinearRegression model = LinearRegression() # object তৈরি (state: এখনো শেখেনি) model.fit(X_train, y_train) # method: শেখে, weight object-এ জমা হয় preds = model.predict(X_test)# method: জমানো weight দিয়ে prediction # PyTorch-এও একই ধারা: # class Net(nn.Module): # def __init__(self): ... # layers (state) সংজ্ঞায়িত # def forward(self, x): ... # behavior: input থেকে output
মূল distinction: fit() = training (data থেকে শেখা), predict() = inference (শেখা model দিয়ে উত্তর)। দুটো আলাদা কাজ — object-এর state (শেখা weight) দুটোকে জোড়ে। training ≠ inference, এটা সবসময় মনে রাখুন।

🖼️ ৭. Visual: fit/predict pattern

model = LinearRegression() # object (খালি state) │ ▼ model.fit(X_train, y_train) # TRAINING: state = শেখা weight │ (weight object-এর ভেতরে জমা) ▼ model.predict(X_new) # INFERENCE: জমানো weight ব্যবহার │ ▼ predictions

🧬 ৮. inheritance: base থেকে বিশেষায়িত

class BaseAnalyzer: def __init__(self, jobs): self.jobs = jobs def count(self): return len(self.jobs) class SkillAnalyzer(BaseAnalyzer): # BaseAnalyzer থেকে inherit def skill_share(self, skill): hits = sum(skill.lower() in j["text"].lower() for j in self.jobs) return hits / self.count() * 100 # base-এর count() reuse jobs = [{"text": "Python ML"}, {"text": "SQL"}] sa = SkillAnalyzer(jobs) print(sa.count()) # 2 (base থেকে পাওয়া) print(sa.skill_share("python"))# 50.0

SkillAnalyzer BaseAnalyzer-এর count() বিনা কষ্টে পেল — এটাই inheritance। scikit-learn-এ সব estimator একটা base class থেকে আসে, তাই সবার common আচরণ থাকে।

🧪 ৯. Experiment: নিজের mini-estimator

sklearn-এর ধাঁচে একটা খেলনা estimator বানাই — যা গড় salary "শেখে" আর সেটাই predict করে (এটা baseline model-এর ধারণা)।

class MeanSalaryPredictor: def __init__(self): self.mean_ = None # sklearn-এ শেখা জিনিসের নামে _ থাকে def fit(self, salaries): self.mean_ = sum(salaries) / len(salaries) return self # sklearn convention: fit self ফেরত দেয় def predict(self, n): if self.mean_ is None: raise ValueError("আগে fit() করুন") return [self.mean_] * n m = MeanSalaryPredictor() m.fit([60000, 80000, 100000]) print(m.mean_) # 80000.0 print(m.predict(2)) # [80000.0, 80000.0]
লক্ষ্য করুন: শেখা state self.mean_-এ জমা, fit না করে predict করলে error — ঠিক production model-এর মতো আচরণ।

🇧🇩 ১০. বাংলাদেশের বাস্তব context

একটা fintech (bKash/Nagad-ধাঁচের) fraud detection service-এ একটা FraudModel class থাকে — যার ভেতরে শেখা parameter (state) আর predict(transaction) method। নতুন model version এলে শুধু object বদলায়, বাকি সব কোড একই থাকে। এই সুবিধা OOP-এর জন্যই।

👷 ১১. AI Engineer-এর দৃষ্টিকোণ

💼 ১২. Boss Question

Boss: "function দিয়েই তো কাজ হচ্ছিল, class-এর দরকার কী?"

উত্তর: ছোট script-এ function যথেষ্ট। কিন্তু যখন একটা model-এর state (শেখা weight), config আর behavior একসাথে বহন করতে হয়, তখন class সব গুছিয়ে রাখে। ফলে নতুন model version আনা, A/B test করা, বা model swap করা কয়েক লাইনের কাজ হয় — মানে দ্রুত পরীক্ষা ও কম খরচে iteration।

🔎 ১৩. Job Requirement Decoder: "Solid understanding of OOP"

প্রশ্নউত্তর
এর মানে কী?class/object, encapsulation, inheritance বুঝে কোড লিখতে পারা।
কোম্পানি কেন চায়?ML library গুলো OOP; নিজের model/pipeline class লিখতে হয়।
কোন সমস্যা সমাধান করে?state ও behavior গুছিয়ে রাখা, model swap সহজ করা।
junior-এর কী জানা লাগে?class, __init__, self, method, basic inheritance।
এখনই কী master লাগে না?metaclass, multiple inheritance-এর MRO, abstract base class-এর গভীরে।
GitHub-এ কীভাবে দেখাবেন?flagship-এ একটা পরিষ্কার JobPost/Analyzer class।
Interview-তে কী?"OOP-এর ৪ স্তম্ভ?", "self কী?", "sklearn কেন OOP?"

⚠️ ১৪. সাধারণ ভুল

ভুল ১: method-এ self ভুলে যাওয়া — ঠিক: প্রতিটা instance method-এর প্রথম parameter self

ভুল ২: সবকিছুতে class — ঠিক: সরল কাজে function-ই ভালো; state থাকলে class।

ভুল ৩: fit না করে predict — ঠিক: state না থাকলে error দিন (আমাদের mini-estimator-এর মতো)।

ভুল ৪: class variable vs instance variable গুলিয়ে ফেলা — ঠিক: instance data সবসময় self.-এ রাখুন।

🎤 ১৫. Interview Prep

প্রশ্ন ১: OOP-এর ৪ স্তম্ভ?
উত্তর: Encapsulation, Abstraction, Inheritance, Polymorphism।

প্রশ্ন ২: self কী?
উত্তর: method-এর ভেতরে "এই নির্দিষ্ট object"-কে বোঝায়; instance state অ্যাক্সেসের রাস্তা।

প্রশ্ন ৩: class আর object পার্থক্য?
উত্তর: class blueprint, object সেই blueprint থেকে বানানো instance।

প্রশ্ন ৪: scikit-learn কেন OOP-নির্ভর?
উত্তর: সব estimator একই fit/predict interface মানে (polymorphism), তাই model swap সহজ।

✍️ ১৬. হাতে-কলমে (Mini Exercise)

১. একটা JobPost class লিখুন title, text, salary সহ, আর has_skill() method দিন।
২. একটা JobDataset class বানান যা list-of-JobPost রাখে ও average_salary() দেয়।
৩. sklearn-ধাঁচে fit()/predict() সহ একটা MedianSalaryPredictor লিখুন।

🚀 ১৭. Project Connection

flagship-এ এখন আমরা JobPostJobDataset class যোগ করব — প্রতিটি job এখন শুধু dict নয়, একটা object যার নিজস্ব behavior আছে। পরে (V3) যখন সত্যিকার sklearn model বসাব, এই OOP অভ্যাস সরাসরি কাজে দেবে।

📌 ১৮. সারসংক্ষেপ ও পরবর্তী পর্ব

✓ class = blueprint, object = instance; self = এই object
✓ OOP-এর ৪ স্তম্ভ: encapsulation, abstraction, inheritance, polymorphism
✓ sklearn/PyTorch পুরোটাই OOP; fit()=training, predict()=inference
✓ একই interface মানে model swap সহজ — এটাই OOP-এর বড় লাভ
পরবর্তী Episode (S02E05): "venv, pip, uv: 'আমার মেশিনে তো চলছিল' সমস্যার আসল সমাধান" — প্রতিটা project-এর আলাদা isolated environment কীভাবে বানাবেন, আর কেন এটা Docker-এর প্রথম ধাপ।
© 2025 Sheikh Thanbir Alam. All Rights Reserved. thanbirtamim.github.io
এই লেখা মূল লেখকের সম্পত্তি — লিখিত অনুমতি ছাড়া কপি করে অন্য কোনো ওয়েবসাইট, ব্লগ, বই বা প্ল্যাটফর্মে প্রকাশ/বিতরণ করা কঠোরভাবে নিষিদ্ধ। Content may not be copied or republished without permission.