GenAI Course · Module 2 · Session 5

Text Preprocessing

⏱ 12 min read🎯 Beginner friendly🖼 2 diagrams🧪 1 live demo🐍 Python code

Real text is messy: “Paid”, “paying” and “payments” are the same idea written three ways. Classic NLP cleans and normalises text before feeding it to a model. In this session you will run stemming, lemmatization, stopword removal, POS tagging and NER on real sentences, and learn when not to preprocess.

In this session

  • Stemming vs lemmatization, side by side
  • Stopword removal, and how it can flip meaning
  • Part-of-speech (POS) tagging
  • Named Entity Recognition (NER) with spaCy
  • Which steps still matter in the LLM era

01Lemmatization vs stemming

Both reduce a word to a base form so that “studies” and “study” count as the same word.

Stemming• chops endings with rules• fast, no dictionary• can produce non-words: “studi”• Porter, Snowball stemmersLemmatization• looks up the dictionary form• slower, needs the word type• gives real words: “study”• WordNet, spaCy lemmatizers
Stemming is a quick haircut; lemmatization looks the word up properly.
preprocess.py
from nltk.stem import PorterStemmer, WordNetLemmatizer
from nltk.corpus import stopwords
# once: nltk.download("wordnet"); nltk.download("stopwords")

words = ["running", "studies", "better", "paid", "payments", "flies"]
stem, lem = PorterStemmer(), WordNetLemmatizer()
print(f"{'word':10s}{'stem':10s}{'lemma (verb)':14s}lemma (noun)")
for w in words:
    print(f"{w:10s}{stem.stem(w):10s}{lem.lemmatize(w, pos='v'):14s}{lem.lemmatize(w, pos='n')}")
print("better as adjective ->", lem.lemmatize("better", pos="a"))

stop = set(stopwords.words("english"))
sentence = "I am not happy with the delay in my refund".split()
print("\nstopwords removed:", [w for w in sentence if w.lower() not in stop])
print("'not' is a stopword?", "not" in stop)
word stem lemma (verb) lemma (noun) running run run running studies studi study study better better better better paid paid pay paid payments payment payments payment flies fli fly fly better as adjective -> good stopwords removed: ['happy', 'delay', 'refund'] 'not' is a stopword? True
✂️

Stemming is like cutting every name to 4 letters. “Rajesh” and “Rajeev” both become “Raje”: fast, but sometimes wrong. Lemmatization is like checking the ID card.

02Stopword removal

Stopwords are very common words such as “the”, “is”, “in”, “a”. Removing them shrinks the data for keyword search and TF-IDF (Session 7). The output above shows the danger:

“I am not happy with the delay” became ['happy', 'delay', 'refund']. NLTK’s list includes “not”, so the complaint now looks positive! For sentiment, keep negations like not, no, never.
Demo · Should you remove stopwords?

03POS tagging and Named Entity Recognition

Part-of-speech (POS) tagging labels each word: noun, verb, adjective and so on. Named Entity Recognition (NER) finds real-world things: people, organisations, places, money, dates. spaCy does both with a small pre-trained model:

spacy_ner.py
# pip install spacy && python -m spacy download en_core_web_sm
import spacy
nlp = spacy.load("en_core_web_sm")

doc = nlp("Priya Sharma transferred ₹25,000 to HDFC Bank in Mumbai on 12 March 2025.")
print("POS tags:")
print("  ", [(t.text, t.pos_) for t in doc][:8])
print("Entities:")
for ent in doc.ents:
    print(f"   {ent.text:16s} {ent.label_:8s} {spacy.explain(ent.label_)}")
POS tags: [('Priya', 'PROPN'), ('Sharma', 'PROPN'), ('transferred', 'VERB'), ('₹', 'PROPN'), ('25,000', 'NUM'), ('to', 'ADP'), ('HDFC', 'PROPN'), ('Bank', 'PROPN')] Entities: Priya Sharma PERSON People, including fictional 25,000 MONEY Monetary values, including unit HDFC Bank ORG Companies, agencies, institutions, etc. Mumbai GPE Countries, cities, states 12 March 2025 DATE Absolute or relative dates or periods
TagMeaningExample
PROPNproper nounPriya, HDFC
VERBverbtransferred
NUMnumber25,000
ADPprepositionto, in, on
PERSON / ORG / GPEentity typesperson / organisation / city or country

NER is the first step in many banking workflows: pull the amount, payee and date out of an email, then fill a form automatically. Note that the small model tagged “₹” as a proper noun; bigger models, or a rule, would fix that.

04Preprocessing in the LLM era

Raw textemails, PDFs, chatsCleanHTML, spaces, encodingNormaliselowercase, lemma (classic ML)TokenizesubwordsModelTF-IDF / BERT / LLM
A typical text pipeline. The “Normalise” step is for classic ML and search; skip it for LLMs.
StepClassic ML (TF-IDF, Naive Bayes)LLMs and transformers
Lowercasingoften helpsnot needed: the tokenizer handles case
Stemming / lemmatizationhelpsskip: it removes useful information
Stopword removaloften helpsskip
Cleaning HTML, junk, duplicatesyesyes: still very important
Removing PIIyesyes: before sending data to any API (Session 6)
NERfeature extractionstill useful for routing, redaction and metadata

05Summary

06Quick quiz

1. Which gives a real dictionary word?

2. Porter stemmer turns “studies” into…

3. Why is removing stopwords risky for sentiment?

4. NER labels “HDFC Bank” as…

5. For an LLM prompt you should…

07References

Created by Ajeetkumar