Home »
Blog »
AI/ML Engineer সিরিজ » Series 07 » Episode 02
Bag of Words ও TF-IDF: প্রথম যুগের NLP (এখনও কাজের)
Project P5 — TF-IDF text classifier (Series 07, Episode 02)
🟢 BEGINNER
Series 07 — NLP, Transformers ও LLM
Episode 02 / 08
📑 এই পর্বে যা যা আছে
- ১. গল্প: token তো পেলাম, এখন সংখ্যা কই?
- ২. সমস্যা: model তো token খায় না, সংখ্যা খায়
- ৩. Bag of Words কী (intuition)
- ৪. Bag of Words-এর সমস্যা → TF-IDF-এর জন্ম
- ৫. তিন স্তরে TF-IDF
- ৬. Visual: text → matrix
- ৭. Code: sklearn দিয়ে TF-IDF
- ৮. Project P5: NLP Text Classifier
- ৯. Experiment: কোন শব্দ বেশি গুরুত্বপূর্ণ
- ১০. বাস্তব উদাহরণ ও AI Engineer perspective
- ১১. Boss Question
- ১২. Job Requirement Decoder: "TF-IDF / Feature Extraction"
- ১৩. সাধারণ ভুল
- ১৪. Interview Prep
- ১৫. হাতে-কলমে
- ১৬. Project Connection
- ১৭. সারসংক্ষেপ ও পরবর্তী পর্ব
🧩 ১. গল্প: token তো পেলাম, এখন সংখ্যা কই?
গত পর্বে Rahim শিখল কীভাবে CV থেকে token বের করতে হয়। কিন্তু এবার সে আটকে গেল — তার কাছে এখন
["python", "django", "sql"]-এর মতো token আছে, কিন্তু LogisticRegression-এ
(S05E04-এ শেখা) এই list পাঠাতেই error!
Rahim: "আপা, আমার তো token আছে। কিন্তু model বলছে সে string নেয় না, শুধু সংখ্যা নেয়। এখন কী করব?"
Nila: "এটাই তো NLP-র মূল প্রশ্ন — text-কে সংখ্যায় রূপান্তর করা। এই প্রক্রিয়ার নাম
text vectorization বা feature extraction। সবচেয়ে পুরনো কিন্তু এখনো
অসম্ভব কাজের দুটো পদ্ধতি হলো Bag of Words আর TF-IDF। মজার ব্যাপার —
অনেক production system আজও এগুলোই ব্যবহার করে, কারণ এরা দ্রুত, সস্তা আর ব্যাখ্যাযোগ্য।"
❓ ২. সমস্যা: model তো token খায় না, সংখ্যা খায়
S05-এ আমরা দেখেছি প্রতিটা ML model আসলে সংখ্যার matrix-এর উপর গণিত করে। text-এর ক্ষেত্রে আমাদের
প্রতিটা document (একটা review, একটা CV, একটা JD)-কে একটা সংখ্যার vector-এ রূপান্তর করতে হবে।
মূল ধারণা: প্রতিটা document → একটা row, প্রতিটা unique শব্দ → একটা column। সেই cell-এ থাকবে সংখ্যা
(শব্দটা কতবার এল, বা কতটা গুরুত্বপূর্ণ)। এই বড় সংখ্যার টেবিলটাকেই বলে document-term matrix।
🎒 ৩. Bag of Words কী (intuition)
নামটাই ইঙ্গিত দেয় — একটা "ব্যাগ ভর্তি শব্দ"। আমরা document-টাকে একটা ব্যাগ ধরে নিই যেখানে শুধু
কোন শব্দ কতবার আছে সেটা গুনি, কিন্তু শব্দের ক্রম (order) ভুলে যাই।
তিনটা ছোট document ধরুন:
D1: "python python job"
D2: "sql job"
D3: "python sql"
Vocabulary: [python, job, sql]
Bag of Words matrix (count):
python job sql
D1 2 1 0
D2 0 1 1
D3 1 0 1
এখন D1, D2, D3 প্রত্যেকেই একটা সংখ্যার vector — model-এ পাঠানোর জন্য প্রস্তুত!
⚖️ ৪. Bag of Words-এর সমস্যা → TF-IDF-এর জন্ম
BoW-এর একটা বড় দুর্বলতা: সে শুধু গোনে। কিন্তু "job", "the", "and" — এই শব্দগুলো তো প্রায় সব
document-এই থাকে। এগুলো অনেকবার এলেও আসলে কোন document-কে অন্যটা থেকে আলাদা করতে সাহায্য করে না।
আমরা চাই এমন একটা measure যা বলবে: এই শব্দটা কি এই document-এ common, কিন্তু বাকি সব
document-এ rare? তাহলে সেটাই এই document-এর জন্য গুরুত্বপূর্ণ। এই ধারণাই TF-IDF।
TF (Term Frequency): একটা document-এ শব্দটা কতবার এল (যত বেশি, তত গুরুত্বপূর্ণ — এই document-এ)।
IDF (Inverse Document Frequency): শব্দটা কত কম document-এ আছে (যত rare, তত গুরুত্বপূর্ণ — কারণ সে আলাদা করে)।
TF-IDF = TF × IDF। ফলে "python" (rare, তথ্যবহুল) বেশি score পায়, আর "job" (সব জায়গায় আছে) কম score পায়।
🪜 ৫. তিন স্তরে TF-IDF
Level 1 — সহজ intuition:
একটা ক্লাসে সবাই যদি "স্যার" শব্দটা বলে, তাহলে "স্যার" শুনে আপনি কাউকে চিনতে পারবেন না। কিন্তু কেউ যদি
"quantum" শব্দটা বারবার বলে আর বাকিরা না বলে — তাহলে "quantum" ওই লোকটার signature। TF-IDF ঠিক এভাবে
signature শব্দ খুঁজে বের করে।
Level 2 — technical:
tf(t,d) = document d-তে term t-এর frequency। idf(t) = log(মোট document / যত
document-এ t আছে)। TF-IDF weight = tf × idf। rare + local শব্দ high weight, global common শব্দ low weight।
Level 3 — AI Engineer perspective:
TF-IDF এখনো industry-তে ভীষণ কাজের — কারণ এটা দ্রুত, GPU লাগে না, ব্যাখ্যাযোগ্য (কোন শব্দে বেশি weight
দেখা যায়), আর ছোট dataset-এ প্রায়ই deep model-এর সমান বা ভালো করে। তাই সবসময় LLM লাগে না — একজন
engineer আগে সস্তা baseline (TF-IDF) দিয়ে শুরু করে।
গুরুত্বপূর্ণ: TF-IDF কিন্তু শব্দের অর্থ বোঝে না — "চাকরি" আর "job" তার কাছে
সম্পূর্ণ আলাদা দুটো column। শব্দের অর্থ ও মিল ধরতে লাগে embeddings — যেটা পরের পর্বের (S07E03) বিষয়।
🖼️ ৬. Visual: text → matrix
Documents Tokenize TF-IDF Vectorizer Matrix
"python job" --> [python,job] --> fit + transform --> [0.7, 0.7, 0.0]
"sql job" --> [sql,job] --> --> [0.0, 0.5, 0.8]
^col: python job sql
এই matrix এখন সরাসরি LogisticRegression / SVM-এ পাঠানো যায়
💻 ৭. Code: sklearn দিয়ে TF-IDF
কেন scikit-learn? — কারণ এর TfidfVectorizer preprocessing, vocabulary building
আর weighting একসাথে করে দেয়, আর সরাসরি sklearn model-এর সাথে খাপ খায়।
# pip install scikit-learn
from sklearn.feature_extraction.text import TfidfVectorizer
docs = [
"python developer needed with django",
"sql database administrator role",
"python and sql for data science",
]
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(docs) # sparse matrix
print(vectorizer.get_feature_names_out())
# ['administrator' 'and' 'database' 'data' 'developer' 'django'
# 'for' 'needed' 'python' 'role' 'science' 'sql' 'with']
print(X.shape) # (3, 13) -> 3 document, 13 unique word
print(X.toarray().round(2)[0]) # প্রথম document-এর TF-IDF vector
দরকারি প্যারামিটার, যেগুলো production-এ প্রায়ই লাগে:
vectorizer = TfidfVectorizer(
lowercase=True,
stop_words="english", # common ইংরেজি শব্দ বাদ
ngram_range=(1, 2), # unigram + bigram ("data science" ধরবে)
max_features=5000, # শুধু top 5000 শব্দ, memory বাঁচে
min_df=2, # অন্তত 2 document-এ থাকতে হবে
)
🛠️ ৮. Project P5: NLP Text Classifier
এবার একটা পূর্ণাঙ্গ classifier — job description থেকে বলা যে এটা কোন category (এখানে উদাহরণ: tech vs non-tech)।
এটাই আমাদের Project P5-এর ভিত্তি।
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# ছোট demo dataset (বাস্তবে bdjobs থেকে scrape করা যায়)
texts = [
"python django backend developer",
"machine learning engineer pytorch",
"sales executive fmcg field marketing",
"customer support call center agent",
"data scientist sql tensorflow",
"hr recruitment officer payroll",
]
labels = ["tech", "tech", "non-tech", "non-tech", "tech", "non-tech"]
X_tr, X_te, y_tr, y_te = train_test_split(
texts, labels, test_size=0.34, random_state=42
)
# Pipeline: vectorizer + classifier একসাথে (train/inference এ একই preprocessing)
clf = Pipeline([
("tfidf", TfidfVectorizer(ngram_range=(1, 2))),
("model", LogisticRegression(max_iter=1000)),
])
clf.fit(X_tr, y_tr)
print(clf.predict(["senior python engineer with fastapi"]))
# ['tech']
কেন Pipeline? কারণ এটা নিশ্চিত করে training আর inference-এ হুবহু একই
preprocessing হচ্ছে। এটা S03E08-এ শেখা data leakage এড়ানোরও চাবিকাঠি — vectorizer
শুধু training data দিয়ে fit হয়, test data দিয়ে নয়।
🔬 ৯. Experiment: কোন শব্দ বেশি গুরুত্বপূর্ণ
TF-IDF-এর সবচেয়ে সুন্দর দিক — এটা ব্যাখ্যাযোগ্য। model কোন শব্দকে "tech"-এর ইঙ্গিত ধরছে দেখুন:
import numpy as np
feat = clf.named_steps["tfidf"].get_feature_names_out()
coef = clf.named_steps["model"].coef_[0]
top = np.argsort(coef)[-5:] # সবচেয়ে "tech"-ঘেঁষা শব্দ
for i in reversed(top):
print(f"{feat[i]:20} weight={coef[i]:.3f}")
যা লক্ষ্য করবেন: "python", "pytorch", "sql"-এর মতো শব্দ high positive weight পায়।
এই ব্যাখ্যাযোগ্যতা (interpretability) interview-তে আর business stakeholder-দের বোঝাতে অসম্ভব কাজের —
একটা black-box deep model এত সহজে "কেন" বলতে পারে না।
🇧🇩 ১০. বাস্তব উদাহরণ ও AI Engineer perspective
- bdjobs / চাকরি.com: job auto-categorization (IT, Sales, HR…) — TF-IDF + LogisticRegression দিয়েই ভালো চলে।
- Daraz review: spam/fake review detection — দ্রুত ও সস্তা baseline।
- News portal: বাংলা সংবাদ auto-tagging (খেলা/রাজনীতি/অর্থনীতি)।
Must Know: BoW ও TF-IDF-এর পার্থক্য, sklearn দিয়ে vectorize + classify, Pipeline।
Good to Know: n-gram, max_features/min_df tuning, sparse matrix।
Learn Later: BM25, hashing vectorizer, বড় scale text search।
💼 ১১. Boss Question
Boss: "সবাই তো এখন ChatGPT-র কথা বলে। তুমি এই পুরনো TF-IDF কেন শেখাচ্ছ?"
উত্তর: কারণ আমাদের ৫০,০০০ product review classify করতে TF-IDF লাগে মাত্র কয়েক সেকেন্ড
আর প্রায় শূন্য টাকা — কোনো GPU বা API খরচ নেই। একই কাজ LLM দিয়ে করলে খরচ হাজার গুণ বেশি আর ধীর।
একজন ভালো engineer আগে সস্তা baseline বানায়, তারপর দরকার হলে দামি solution-এ যায়। এটাই সঠিক business সিদ্ধান্ত।
🔎 ১২. Job Requirement Decoder: "TF-IDF / Feature Extraction"
JD-তে:
"Familiarity with text feature extraction (Bag of Words, TF-IDF)."
| প্রশ্ন | উত্তর |
| কী বোঝায়? | text-কে সংখ্যার vector-এ রূপান্তর করে ML model-এ দিতে পারা। |
| কেন চায়? | classical NLP task (classification, search) এর ভিত্তি; সস্তা ও নির্ভরযোগ্য baseline। |
| কোন সমস্যা সমাধান করে? | string data → numeric feature, যা model process করতে পারে। |
| junior-এর কী জানা লাগে? | TfidfVectorizer ব্যবহার, Pipeline, একটা text classifier train ও evaluate করা। |
| এখনই কী master লাগে না? | IDF-এর গাণিতিক variant, custom weighting scheme। |
| GitHub-এ কীভাবে দেখাবেন? | একটা text classifier repo — dataset, pipeline, metrics ও top-feature ব্যাখ্যা। |
| Interview-তে? | "BoW vs TF-IDF?", "IDF কেন দরকার?", "TF-IDF কি অর্থ বোঝে?" |
⚠️ ১৩. সাধারণ ভুল
ভুল ১: পুরো dataset (train+test) দিয়ে vectorizer fit করা। →
data leakage! শুধু train দিয়ে fit, test শুধু transform।
ভুল ২: TF-IDF থেকে semantic similarity আশা করা। → সে অর্থ বোঝে না; "job" ≠ "চাকরি" তার কাছে।
ভুল ৩: max_features/min_df ছাড়া বিশাল vocabulary → memory ও overfitting সমস্যা।
ভুল ৪: বাংলা text-এ ইংরেজি stopword list ব্যবহার — কাজ করবে না, বাংলার জন্য আলাদা list লাগে।
🎤 ১৪. Interview Prep
প্রশ্ন ১: Bag of Words আর TF-IDF-এর পার্থক্য?
উত্তর: BoW শুধু count রাখে; TF-IDF সেই count-কে "শব্দটা কত rare" দিয়ে weight করে, ফলে common
শব্দের গুরুত্ব কমে, তথ্যবহুল শব্দের বাড়ে।
প্রশ্ন ২: IDF না থাকলে কী সমস্যা?
উত্তর: "the", "job"-এর মতো সব জায়গায় থাকা শব্দ বেশি weight পেয়ে model-কে বিভ্রান্ত করত।
প্রশ্ন ৩: TF-IDF-এর সীমাবদ্ধতা কী?
উত্তর: শব্দের ক্রম আর অর্থ ধরে না; synonym বোঝে না; খুব বড় sparse matrix তৈরি করে। এসব সমাধানে লাগে embeddings।
✍️ ১৫. হাতে-কলমে
১. উপরের P5 classifier-এ আরও কয়েকটা example যোগ করে classification_report দিয়ে
precision/recall দেখুন (S05E05 recall করুন)।
২. ngram_range=(1,1) বনাম (1,2) — accuracy-তে পার্থক্য দেখুন।
৩. একটা document জোড়ার cosine similarity বের করুন sklearn.metrics.pairwise.cosine_similarity দিয়ে,
আর ভাবুন কেন synonym থাকলেও similarity কম আসতে পারে।
🚀 ১৬. Project Connection
flagship "Bangladesh Tech Career Assistant"-এ এখন আমরা JD text-কে TF-IDF vector-এ রূপান্তর
করে দুটো নতুন feature যোগ করছি: (১) JD auto-categorize করা, (২) দুটো JD-র মধ্যে similarity মাপা।
এটাই আমাদের standalone Project P5 (NLP Text Classifier)-এরও ভিত্তি — portfolio-তে এটা
আপনার প্রথম "NLP" project হিসেবে দেখাবেন। তবে মনে রাখুন: এই TF-IDF similarity "python"≈"পাইথন" ধরতে পারবে না —
সেই সীমা টপকাতেই পরের পর্বে embeddings আসছে।
📌 ১৭. সারসংক্ষেপ ও পরবর্তী পর্ব
এই পর্বে শিখলাম:
✓ Text vectorization = text-কে সংখ্যার vector বানানো, model-এ দেওয়ার জন্য
✓ Bag of Words = শুধু count; order ভুলে যায়
✓ TF-IDF = count × rarity; তথ্যবহুল শব্দকে বেশি weight দেয়
✓ sklearn Pipeline দিয়ে leakage-free text classifier (Project P5) বানানো
✓ TF-IDF দ্রুত, সস্তা, ব্যাখ্যাযোগ্য — সবসময় LLM লাগে না
✓ কিন্তু TF-IDF অর্থ/synonym বোঝে না — এটাই তার বড় সীমা
পরবর্তী পর্ব (S07E03): TF-IDF-এর কাছে "job" আর "চাকরি" সম্পূর্ণ অচেনা দুটো শব্দ।
কিন্তু আমরা তো জানি এদের অর্থ এক! computer-কে এই "অর্থ" শেখাব কীভাবে? পরের পর্বে
Word Embeddings — শব্দ কীভাবে vector space-এ meaning সহ বসে, আর কীভাবে semantic
similarity মাপা যায়।