AI Computer Institute
Expert-curated CS & AI curriculum aligned to CBSE standards. A bharath.ai initiative. About Us

Topic Modeling: Discovering Hidden Themes

📚 NLP⏱️ 24 min read🎓 Grade 10
✍️ AI Computer Institute Editorial Team Updated: September 2026 CBSE-aligned · Peer-reviewed · 24 min read
Content curated by subject matter experts with IIT/NIT backgrounds. All chapters are fact-checked against official CBSE/NCERT syllabi.

A Lakh Reviews, Zero Labels

A new smartphone launches on Flipkart on a Friday morning. By the following Friday, it has crossed one lakh customer reviews. Somewhere on Flipkart's product team, someone needs to answer a simple question before Monday's review meeting: what are customers actually talking about? Not the star-rating average — that single number hides more than it reveals — but the real themes buried inside those reviews. Are people complaining about the battery? Praising the camera? Furious about a delayed shipment? Reading all one lakh reviews by hand is not a realistic option for a small team with a weekend to work with.

The tempting shortcut is to search for keywords: count how many reviews contain "battery," how many contain "camera," how many contain "delivery." This only works if you already know which words matter. It misses a review that says "backup barely lasts a day" without ever using the word "battery," and it cannot tell you about a theme nobody thought to search for in the first place — say, a sudden wave of reviews about a confusing return policy. What the team actually needs is a way to read one lakh documents and let the themes emerge on their own, without anyone deciding in advance what those themes should be called. This is exactly the problem topic modeling was built to solve.

Why This Is Different From Classification

By now you know how to turn a sentence into numbers a computer can work with: build a vocabulary of every distinct word across a set of documents, then represent each document as a vector counting how often each vocabulary word appears — the bag-of-words representation, often refined with TF-IDF weighting so that rare, distinctive words count for more than words like "the" or "is." Both techniques answer the question "which words appear where?" Neither answers the harder question the Flipkart team is actually asking: which words tend to show up together, often enough, across enough reviews, that they represent the same underlying theme?

That harder question is different in kind from a task like spam detection or sentiment tagging. In classification, a human has already decided the categories — "spam" or "not spam," "positive" or "negative" — and labeled thousands of examples so a model can learn to sort new ones into those same fixed bins. That is supervised learning: the labels come first, from a human, and the algorithm's job is to reproduce them. Topic modeling flips this around. Nobody tells the algorithm that "battery," "camera," and "delivery" are the themes to look for — nobody even tells it there are exactly three themes, beyond a rough guess at how many to search for. It has to notice, purely from patterns of which words keep appearing in the same documents, that a hidden structure exists at all. This is unsupervised learning: no labels, just raw text, and a demand that the algorithm organize it in a way that makes sense.

What a "Topic" Actually Is

Formally, a topic is nothing more than a probability distribution over the entire vocabulary — a ranked weighting that says how likely each word is to turn up in a document about that theme. A "battery" topic would place high probability on words like battery, charge, backup, and drain, and near-zero probability on words like courier or lens. A document, in turn, is treated as a mixture of several topics rather than belonging to just one — a single review might be built mostly from the "battery" topic's vocabulary with a small trace of the "delivery" topic's vocabulary mixed in, which matches how people actually write: a review titled "Battery is weak" might still end with "also the delivery took a week."

Two things about this are worth sitting with. First, the algorithm has no idea what English words mean. It never "knows" that battery and charge are related the way a person does — it only notices that these words keep turning up in the same documents far more often than chance would predict, and that statistical pattern is enough. Second, and just as important, the algorithm never produces the label "battery" on its own. It hands back a numbered list — Topic 0, Topic 1, Topic 2 — each one just a ranked list of words. A human still has to glance at Topic 1's top words and decide "this is clearly about battery life" before writing that label on a dashboard. Topic modeling automates the grouping. It does not automate the naming.

Latent Dirichlet Allocation: Imagining How the Reviews Were Written

The most widely used algorithm for this task is called Latent Dirichlet Allocation, or LDA, introduced in 2003 by researchers David Blei, Andrew Ng, and Michael Jordan. The name sounds intimidating, but it splits apart sensibly: "latent" simply means hidden — the topics are never observed directly, only the words are — and "Dirichlet" is the name of the particular kind of probability distribution the algorithm uses to describe mixtures and proportions, such as "70% battery, 20% camera, 10% delivery." You do not need the mathematics of the Dirichlet distribution to understand what LDA does; you need its generative story.

LDA asks you to imagine, backward, how each review could have been written if a slightly mechanical process had produced it. First, the process rolls a weighted die to decide this review's topic mixture — say, 70% battery, 20% camera, 10% delivery. Then, to write each individual word, it rolls that same weighted die again to pick which topic will supply this particular word — most rolls will land on "battery," given the 70% weighting. Whichever topic gets picked, the process then rolls a second, topic-specific die — the battery topic's own die, heavily weighted toward words like battery, charge, and backup — to choose the actual word that gets written down. This repeats, word after word, until the review is complete, and the whole process repeats independently for every review in the corpus, with each review free to choose its own topic-mixture weighting.

Nobody believes real customers write reviews by rolling dice. The generative story is a deliberate fiction — a precise, mechanical description of what "documents built from a mixture of topics" would look like if you could watch them being assembled. LDA's actual job is to run this story in reverse: given only the finished reviews, search for the set of topic-mixture dice (one per document) and word dice (one per topic) that would have made those exact reviews the most probable output of the imagined process. Everything the algorithm eventually outputs — the document-topic mixtures, the topic-word distributions — comes from solving that reverse problem.

Working Backward: How the Algorithm Actually Learns

When training starts, LDA has no idea which dice are the right ones. So it begins by guessing: every single word occurrence in every document gets tagged with a topic number at random — pure noise. Training itself is a long sequence of small corrections to this initial guess, one word occurrence at a time, repeated over and over until the guesses settle down.

Here is what one of those corrections looks like. Suppose training is partway through on our Flipkart-style review corpus, and one particular occurrence of the word "photos," sitting inside an obviously camera-themed review, is still wearing an early, wrong, random tag: Delivery. To decide whether to keep that tag or switch it, the algorithm temporarily removes it and asks two separate questions.

Question 1 — what does the rest of this document look like? Set the word "photos" aside and look at how the other content words in this same review are currently tagged. Suppose the count comes out to five words tagged Camera, one tagged Battery, one tagged Delivery. The document, minus this one word, leans heavily Camera.

Question 2 — how has this exact word behaved everywhere else? Set this occurrence aside and look at every other place the word "photos" appears across the whole corpus. Suppose those other occurrences are currently tagged nine Camera, zero Battery, two Delivery. The word itself, historically, also leans heavily Camera.

LDA combines these two answers by multiplying them, topic by topic, to get a score:

Camera:   5 x 9 = 45
Battery:  1 x 0 = 0
Delivery: 1 x 2 = 2
                 -----
Total              47

Turning those scores into proportions gives Camera ≈ 45/47 ≈ 0.957, Delivery ≈ 2/47 ≈ 0.043, and Battery ≈ 0. The word "photos" gets reassigned to Camera — not because of a rule that says "photos means camera," but because both its document's context and its own history across the corpus happen to point the same way, and multiplying two agreeing signals produces a far more confident answer than either signal alone. Battery's score collapses to zero mainly because this document's context barely touched Battery to begin with, which is one reason real implementations add tiny smoothing numbers, commonly called alpha and beta, to every count so that no topic is ever scored as flatly impossible.

This single correction is repeated for every word occurrence in every document, one at a time, and then the entire sweep is repeated again — each full sweep is called an iteration, and real training runs for hundreds of them. Early iterations look almost random, since the counts everything depends on are themselves still mostly noise. But every correction slightly sharpens the counts the next correction will lean on, so genuine patterns snowball: words that truly tend to co-occur keep reinforcing each other's topic assignment, iteration after iteration, while chance co-occurrences get out-voted and fade. Eventually the tags stop changing much between sweeps — training has converged — and counting up which words ended up mostly tagged with each topic number produces exactly the ranked word lists a fitted topic model hands back.

Seeing It Run

The counting-and-multiplying process from the previous section is exactly what a library like scikit-learn automates over hundreds of iterations. Here it is running on twelve short, invented reviews — four each about battery, camera, and delivery — deliberately written so the underlying themes are visible to a human reader, which makes it easy to check whether the algorithm finds what we already know is there.

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation

reviews = [
    "battery backup is excellent lasts two full days on a single charge",
    "battery drains very fast and charging takes too long disappointed with battery life",
    "battery life is short so I have to charge my phone twice a day",
    "the battery discharges quickly even in standby and charging is slow",
    "camera quality is amazing night mode photos are sharp and clear",
    "camera lens has scratches and photos are blurry in low light",
    "camera app is smooth and portrait mode photos look very sharp",
    "camera performance is poor and photos taken indoors are grainy and dark",
    "delivery was delayed by five days and the packaging was damaged badly",
    "delivery was quick and the executive was polite and professional",
    "delivery agent was rude and the package arrived a week late",
    "delivery was on time and the box was neatly packaged and sealed",
]

# Step 1: turn text into a document-term matrix (bag of words)
vectorizer = CountVectorizer(stop_words="english")
doc_term_matrix = vectorizer.fit_transform(reviews)
vocabulary = vectorizer.get_feature_names_out()
print("Vocabulary size:", len(vocabulary))

# Step 2: fit LDA, asking it to find 3 topics
lda_model = LatentDirichletAllocation(
    n_components=3,
    random_state=0,
    doc_topic_prior=0.9,
    topic_word_prior=0.9,
    max_iter=500,
)
lda_model.fit(doc_term_matrix)

# Step 3: show the top words that define each discovered topic
for topic_id, word_weights in enumerate(lda_model.components_):
    top_word_ids = word_weights.argsort()[::-1][:6]
    top_words = [vocabulary[i] for i in top_word_ids]
    print(f"Topic {topic_id}: {top_words}")

# Step 4: see how much of each topic is present in a few reviews
doc_topic_distribution = lda_model.transform(doc_term_matrix)
for i in [0, 4, 8]:
    proportions = [float(round(p, 2)) for p in doc_topic_distribution[i]]
    print(f"Review {i} -> topic mix {proportions}: \"{reviews[i]}\"")

Running this prints:

Vocabulary size: 65
Topic 0: ['delivery', 'days', 'week', 'rude', 'arrived', 'late']
Topic 1: ['battery', 'life', 'charging', 'charge', 'days', 'long']
Topic 2: ['camera', 'photos', 'mode', 'sharp', 'look', 'smooth']
Review 0 -> topic mix [0.12, 0.77, 0.11]: "battery backup is excellent lasts two full days on a single charge"
Review 4 -> topic mix [0.1, 0.1, 0.8]: "camera quality is amazing night mode photos are sharp and clear"
Review 8 -> topic mix [0.74, 0.13, 0.12]: "delivery was delayed by five days and the packaging was damaged badly"

The algorithm was never told the words "battery," "camera," or "delivery" mattered, and it was never shown a single label. It only saw twelve unlabeled strings and a request for three topics. Yet Topic 1's top words — battery, life, charging, charge, long — are unmistakably about battery life, Topic 2 is unmistakably about camera quality, and Topic 0 is unmistakably about delivery. This is the naming step from earlier, in action: LatentDirichletAllocation only hands back numbered topics and ranked word lists; a human reads Topic 1's words and writes "battery" on the dashboard.

The last three printed lines show why topics are mixtures rather than single labels. Review 0, a battery review, comes back as 77% Topic 1, 12% Topic 0, and 11% Topic 2 — dominant, but not 100% pure, because a couple of its words are common enough elsewhere in the corpus that a little weight leaks into other topics (the totals for review 8 add up to 99% rather than 100% for the same reason: each number was rounded on its own). Review 4 comes back 80% Topic 2, and review 8 comes back 74% Topic 0 — each one dominated by exactly the topic a human reader would assign it to by hand, recovered without that human ever labeling a single example.

Topic Modeling, Clustering, and Classification Are Not the Same Job

It is worth being precise about how topic modeling relates to two techniques it often gets confused with, since all three take in text and produce some kind of grouping.

  • Text classification is supervised: a human decides the categories in advance and labels thousands of examples, and every new document is sorted into exactly one of those fixed categories.
  • Clustering algorithms such as k-means, run on TF-IDF vectors, are unsupervised like topic modeling — no labels required — but they still make a hard, all-or-nothing decision, pushing each document into exactly one cluster.
  • Topic modeling is unsupervised like clustering, but soft in a way neither of the other two is: a document is described as a percentage blend across every topic the model found, not forced into a single bucket.

That soft blending is often the most useful part of the output. A review that comes back 55% battery and 40% delivery is telling the team something a hard cluster label never could: this customer's battery complaint arrived bundled with a delivery complaint, and if that pairing keeps showing up review after review, it might be worth investigating on its own — perhaps units sitting too long in a warehouse are arriving with partially drained, degraded batteries. A hard clustering algorithm, forced to pick one bucket per review, would erase that signal by filing the review under whichever theme happened to edge out the other.

Choosing How Many Topics to Look For

The number of topics — usually called k, or n_components in the code above — is not something LDA discovers on its own. It is a choice made before training even starts, the same way choosing the number of clusters is a decision you make before running k-means. Set it too low, and genuinely distinct themes get forced together into one blurry topic — asking our review corpus for two topics instead of three would likely blend camera and delivery complaints into a single, less coherent word list. Set it too high, and one real theme splinters into two or three near-duplicate topics that mostly repeat each other's top words, which is not useful either.

Because there is rarely a single mathematically "correct" value of k, practitioners lean on a mix of automated scoring and human judgment. One common automated signal is a coherence score, which checks whether a topic's top words tend to actually appear near each other in real text — a topic whose top words are battery, charge, backup, and drain scores high, because those words genuinely keep company with each other, while a topic whose top words look like a random grab-bag scores low. But no automated score fully replaces a person reading the output and asking the plain question: do these grouped words actually make sense together? That final check is still normally done by a human, which is exactly why the earlier point — that topic modeling hands back numbers rather than names — matters so much in practice.

Where This Shows Up Beyond a Review Dashboard

The Flipkart scenario that opened this chapter is one small instance of a pattern that shows up anywhere unlabeled text arrives faster than people can read it. Government grievance systems are a good example: a portal like CPGRAMS, the Centralized Public Grievance Redress and Monitoring System run by the Government of India, exists precisely because citizens across the country submit large volumes of free-form complaints covering everything from pension delays to railway refunds. A topic model run over a month's submissions could not resolve any individual grievance, but it could surface that complaints about "delayed pension disbursal" or "ration card correction" are trending sharply upward this month compared to last — a pattern a small staff, however diligent, would struggle to notice by reading complaints one at a time. News aggregation apps face a related problem in the opposite direction: a large number of fresh articles are published across the country every single day, and grouping them into clusters like elections, cricket, or markets before a reader ever opens the app is the same "discover the categories from the text itself" problem, solved at newsroom scale. Researchers scanning a large archive of academic papers to spot which subfields are growing, and support teams triaging incoming tickets at a telecom company or a bank, are both running smaller versions of the identical idea: turn a pile of unlabeled text into a short list of themes a human can actually act on.

What Topic Modeling Cannot Do

Topic modeling has real limits worth knowing before you reach for it.

  • Word order disappears. Built on bag-of-words counts, classic LDA cannot tell "battery life is not good" from "good battery, life is not" — both produce identical word counts, even though a human reader would read them rather differently.
  • Ambiguous words get one distribution, not several. A word like mouse could belong equally to a topic about computer peripherals or a topic about pest control; because LDA reasons purely from which words co-occur, it has no built-in way to tell those uses apart the way a human reader instinctively does from context.
  • Small corpora produce messy topics. The twelve reviews used earlier in this chapter were deliberately written with strong, repeated vocabulary per theme to make the pattern easy to find; a handful of short, noisy real reviews will often produce topics that blur into each other far more than that clean example did.
  • The number of topics is still a human guess. Nothing about the algorithm tells you in advance whether three, five, or twelve topics is the right number to ask for, and getting it wrong in either direction produces output that is harder to act on.

These limitations are exactly what more recent techniques try to fix. Approaches such as BERTopic replace the bag-of-words foundation with sentence embeddings from transformer models, which capture meaning and context far better than raw word counts, and then cluster those embeddings instead of running LDA's classic dice-rolling story. LDA remains the clearest starting point for understanding what topic modeling is actually trying to do, which is exactly why it is the version taught first.

Back to the Product Team's Monday

By Monday morning, running LDA over the lakh reviews would not tell the Flipkart team why battery complaints are trending, or what to fix about it — that part is still human judgment, applied to a much smaller, much more manageable list. What it would deliver is the part that made the original problem impossible: a short, ranked set of themes, pulled out of unlabeled text with no one having read every review, each theme backed by the words that define it and a sense of how strongly each review leans into it. Bag-of-words counts turned the reviews into numbers. LDA's generative story, run backward through hundreds of quiet corrections, turned those numbers into topics. And one last, unavoidably human step — someone glancing at a ranked word list and writing "battery" at the top of a slide — turned the topics into something a Monday morning meeting can actually act on. That handoff, from a lakh unread reviews to a short list a person can reason about, is the entire point of discovering hidden themes.

Key Takeaways — Summary and Recap

Let us recap what we covered: the core ideas behind topic modeling: discovering hidden themes, how they connect to real-world applications, and why they matter for your journey in computer science. Remember these key points as you move forward. For competitive exam preparation (CBSE, JEE, BITSAT), focus on understanding the WHY behind each concept, not just the WHAT.

← Text Classification: Categorizing DocumentsDocument Clustering: Grouping Similar Texts →

Found this useful? Share it!

📱 WhatsApp 🐦 Twitter 💼 LinkedIn