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

Building Your First AI Classifier: A Complete Project

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

Open the Messages app on any phone in India and you will usually find two folders: the regular inbox, and a second one — sometimes called "Spam" or "Other" — quietly holding the "Congrats!!! You have WON a prize!!!" texts that never even buzzed the phone. Somebody had to decide, in a few milliseconds, which folder each incoming SMS belongs to. That decision-maker is a classifier — one of the simplest and most widely deployed kinds of AI system there is. In this chapter you will build one yourself, from the very first line of code to a working prediction, and you will understand every single number it produces. No hidden library, no magic — just counting, distance, and a vote.

What Exactly Is a Classifier?

Before any formal definition, think about how you already sort things. If a stranger describes a fruit as "green, round, sour, about 6 cm across," you don't need a dictionary entry — you compare it in your head to fruits you already know, and guess "lime" because it's closer to your mental picture of a lime than a mango or a watermelon. You just ran a classification algorithm using your own brain: you took a new example, compared it to remembered examples with known answers, and picked the label of whichever memory it resembled most.

An AI classifier does exactly this, except the "memory" is a stored table of past examples (called training data), the "comparison" is arithmetic on numbers, and the "known answers" are called labels. Formally: a classifier is a function that takes an input, described by a fixed set of measurable numbers called features, and outputs one label from a fixed, finite set of categories. For our project, the input is an SMS message, the output category is one of exactly two labels — "Spam" or "Not Spam" — and the whole rest of this chapter is about deciding what those "measurable numbers" should be and how the comparison should work.

Stage 1: Problem Scoping — Say Precisely What You're Building

CBSE's AI curriculum calls this first stage of any AI project Problem Scoping, and skipping it is the single most common reason student AI projects fail before they even start. "Detect spam" is not a scoped problem — it's a wish. A scoped version looks like this: given the text of one SMS message, and only the message text, decide whether it is "Spam" (unsolicited promotional or fraudulent content) or "Not Spam" (personal messages, OTPs, and genuine transaction alerts), using a small set of counted features rather than reading or understanding the sentence. Notice what that scoping does: it fixes exactly two output categories, it fixes the only information the system is allowed to use, and — importantly — it admits upfront that the classifier will never actually "read" the message the way you do. It will only ever see numbers. Keep that sentence in mind; we will come back to it, because it is the single most common misconception people have about how these systems work.

Stage 2: Data Acquisition — Where Do Labelled Examples Come From?

A classifier is only as good as the examples it learns from, so real-world spam filters are trained on tens of thousands of messages collected and hand-labelled by humans — the well-known UCI SMS Spam Collection dataset, for instance, contains several thousand real text messages labelled "spam" or "ham" (not-spam) by their original recipients. In India specifically, unsolicited commercial SMS is common enough that the Telecom Regulatory Authority of India (TRAI) runs a formal Do-Not-Disturb registry and regulation framework for it — which tells you this isn't a toy problem invented for a textbook; it's a real classification task that real regulators and real telecom systems deal with daily.

For this chapter, we will work with a small, fully-labelled set of six SMS messages so that every step remains checkable by hand — a real project would use thousands, but the arithmetic is identical whether you have 6 examples or 6,000.

Stage 3: Data Exploration — Turning Sentences Into Numbers

A computer cannot compare "sentences" the way you compare fruits — it can only compare numbers. So before any classification can happen, we must invent a small number of features: measurable properties, extracted from the text, that (we hope) differ systematically between spam and legitimate messages. For this project we will use exactly two:

  • x = the number of exclamation marks (!) in the message — spammy marketing text tends to shout.
  • y = the number of digit characters (0–9) in the message — OTPs, bank alerts, and prize amounts are all digit-heavy.

Every message, no matter how long, collapses to a single point (x, y). Here are our six training examples, with the count shown so the process is completely transparent — you can verify each one character by character:

LabelMessagex (! marks)y (digits)Class
A"See you at practice at 9"01Not Spam
B"Your OTP is 482196, valid 07 min"08Not Spam
C"Rs 15000 debited from a/c XX9834 on 05-08!"113Not Spam
D"FREE!!! WIN CASH NOW!!! Click here!"70Spam
E"Congrats!!! You WON Rs 50000!!!"65Spam
F"URGENT!! Claim Rs 900000 now!!!"56Spam

Let's verify the trickiest row, C, by hand, since it mixes digits with letters: "Rs 15000 debited from a/c XX9834 on 05-08!" — the digits are 1,5,0,0,0 (from 15000, that's 5 digits), then 9,8,3,4 (from XX9834 — the X's are letters and don't count, so only 4 digits), then 0,5,0,8 (from 05-08, 4 digits). Adding these: 5 + 4 + 4 = 13 digits total. There is exactly one exclamation mark, right at the end. So C = (1, 13), exactly as the table shows.

Now look at what the table is quietly teaching you: message C has the highest digit count of all six messages — higher than any of the spam messages — and it is completely legitimate. This matters a lot, because it exposes a common misconception before it can take root: a classifier that used digit count (y) alone, with some simple threshold like "more than 4 digits means spam," would misclassify C as the most suspicious message in the entire dataset, when it is in fact an ordinary bank debit alert. One feature, by itself, is not enough — the digit-heavy legitimate messages (B and C) can only be told apart from the digit-heavy spam messages (E and F) because we also track exclamation marks. This is precisely why real classifiers combine multiple features rather than relying on any single one, and it's a fact you can now demonstrate with real numbers rather than take on faith.

Plotting all six points on a graph with x on one axis and y on the other makes the pattern visible at a glance — the "Not Spam" messages cluster near the left (few exclamation marks) regardless of their digit count, while the "Spam" messages cluster toward the right:

0 2 4 6 8 x = number of exclamation marks (!) 0 2 4 6 8 10 12 14 y = number of digits SMS features: exclamation marks vs. digits √13 ≈ 3.61 √13 ≈ 3.61 √13 ≈ 3.61 A (0,1) B (0,8) C (1,13) D (7,0) E (6,5) F (5,6) Q (3,3) new message Not Spam (training) Spam (training) New message to classify dashed = 3 nearest neighbours

Stage 4: Modelling — Teaching the Computer to Compare

Now for the algorithm. We'll build the simplest classifier that actually works well in practice: k-Nearest Neighbours, almost always written k-NN. The idea is exactly your fruit-guessing intuition from earlier, made precise: to classify a new point, find the k training points closest to it, and let them vote. Whichever label has the most votes among those k neighbours becomes the prediction.

The only new machinery we need is a way to measure "closest" between two points (x₁, y₁) and (x₂, y₂). You already know this — it's the Pythagoras theorem you use in coordinate geometry. If you walk a horizontal distance of (x₁ − x₂) and a vertical distance of (y₁ − y₂), the straight-line distance between the two points is the hypotenuse of a right triangle with those two legs:

distance = √[ (x₁ − x₂)² + (y₁ − y₂)² ]

This is called the Euclidean distance, and it's nothing more than the Pythagoras theorem applied to two arbitrary points instead of two sides of a drawn triangle. Let's classify a brand-new message: "Claim your Rs 200 cashback now!!!". Counting its features exactly as before — three exclamation marks (!!!) and three digits (2, 0, 0) — gives us the query point Q = (3, 3), already marked on the graph above.

We compute the distance from Q to all six training points:

  • to A (0,1): √[(3−0)² + (3−1)²] = √[9+4] = √13 ≈ 3.606
  • to B (0,8): √[(3−0)² + (3−8)²] = √[9+25] = √34 ≈ 5.831
  • to C (1,13): √[(3−1)² + (3−13)²] = √[4+100] = √104 ≈ 10.198
  • to D (7,0): √[(3−7)² + (3−0)²] = √[16+9] = √25 = 5.000
  • to E (6,5): √[(3−6)² + (3−5)²] = √[9+4] = √13 ≈ 3.606
  • to F (5,6): √[(3−5)² + (3−6)²] = √[4+9] = √13 ≈ 3.606

Something interesting happens here: A, E, and F are all exactly the same distance from Q — all equal to √13 — while D, B, and C are all strictly farther away. So if we choose k = 3, the three nearest neighbours are unambiguously {A, E, F}, with no need to break any tie, because no fourth point is competing for that third spot. Their labels are Not Spam (A), Spam (E), and Spam (F) — a 2-to-1 vote for Spam. That is our classifier's prediction.

Notice this was not a landslide. One of the three nearest neighbours was legitimate. This is realistic and important: real classifiers are rarely 100% certain, and a message that mixes a moderate exclamation count with a moderate digit count genuinely sits in ambiguous territory between "an enthusiastic real offer" and "a scam." k-NN doesn't hide that ambiguity — the closeness of the vote is itself useful information.

Here is the entire classifier as runnable Python — notice it is barely fifteen lines, because k-NN does no "training" in the usual sense. It simply memorises the training data and does all its work at prediction time (which is why k-NN is often called a lazy learner — compare this to other algorithms you may meet later, like decision trees, which spend time upfront building rules before ever seeing a new example):

training_data = [
    (0, 1, "Not Spam"),   # A
    (0, 8, "Not Spam"),   # B
    (1, 13, "Not Spam"),  # C
    (7, 0, "Spam"),       # D
    (6, 5, "Spam"),       # E
    (5, 6, "Spam"),       # F
]

def euclidean_distance(p1, p2):
    return ((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5

def knn_predict(query, data, k=3):
    distances = []
    for x, y, label in data:
        d = euclidean_distance((x, y), query)
        distances.append((d, label))
    distances.sort(key=lambda pair: pair[0])
    nearest = distances[:k]
    votes = {}
    for d, label in nearest:
        votes[label] = votes.get(label, 0) + 1
    prediction = max(votes, key=votes.get)
    return prediction, nearest

query_point = (3, 3)
prediction, neighbours = knn_predict(query_point, training_data, k=3)
print("3 nearest neighbours:", neighbours)
print("Prediction:", prediction)

Tracing this by hand confirms the arithmetic above: the six distances computed inside the loop are approximately 3.606, 5.831, 10.198, 5.000, 3.606, 3.606, in that order (matching A, B, C, D, E, F). Python's sort is stable, so after sorting, the tied entries keep their original relative order — A first, then E, then F — followed by D, B, C. Slicing the first three gives exactly [A, E, F], the votes dictionary ends up as {"Not Spam": 1, "Spam": 2}, and max(votes, key=votes.get) returns "Spam". The program prints Prediction: Spam, matching our hand calculation exactly.

Stage 5: Evaluation — Is the Classifier Actually Good?

Building a classifier that runs is not the same as building one that works. Suppose we later confirm the true label of two new messages: our Q = "Claim your Rs 200 cashback now!!!" (3,3) turns out, once reported by users, to have been a genuine scam — true label Spam, matching our prediction. And a second message, G = "Fee of Rs 3500 due by 15-08, pay now!" — count it yourself: digits 3,5,0,0 from 3500 plus 1,5,0,8 from 15-08 gives y = 8, and there is one exclamation mark, so G = (1, 8) — is a genuine fee reminder, true label Not Spam.

Running G through the same algorithm: distance to B(0,8) is √[1²+0²] = 1.0; to F(5,6) is √[16+4] = √20 ≈ 4.47; to C(1,13) is √[0+25] = 5.0; to E(6,5) is √34 ≈ 5.83; to A(0,1) is √50 ≈ 7.07; to D(7,0) is √100 = 10.0. The three nearest are B, F, C — labels Not Spam, Spam, Not Spam — a 2-to-1 vote for Not Spam, which matches the true label.

Both predictions were correct, giving an accuracy of 2 out of 2, or 100%, on this tiny test set. But two examples prove almost nothing — a classifier that simply always predicted "Not Spam" would also score 50% or better on a small enough sample by luck. Real evaluation needs a much larger held-out test set that the classifier never saw during any stage of development, and accuracy alone can still be misleading if spam and non-spam messages aren't roughly balanced in that test set. Two other numbers matter more in practice: how often a real spam message slips through disguised as safe (a false negative), and how often a genuine message — worse, a genuine OTP or bank alert — gets wrongly blocked (a false positive). Both have real costs, and they are rarely equal.

Ethics: When Your Classifier Gets It Wrong

This is where "AI Applications & Ethics" earns its place in the title. A false positive that blocks message B ("Your OTP is 482196...") is not a minor inconvenience — it can lock a student out of a UPI payment or an exam-portal login at the exact moment they need the code. A false negative that lets a scam message like D through can lead to real financial loss for someone who trusts the "Not Spam" folder to have filtered it out. Neither error is free, and a classifier tuned to minimise one almost always increases the other — there is no setting that eliminates both.

There's also a subtler ethical issue in Stage 2. Our training data of six messages, and even a "real" dataset of a few thousand, reflects the language, slang, and message patterns of whoever contributed those examples. A classifier trained mostly on English-language spam may perform far worse on Hinglish or regional-language SMS scams that are extremely common on Indian phones, simply because its training data never saw that pattern. This is called data bias, and it is not a hypothetical concern — it's a direct, checkable consequence of Stage 2's choices showing up as unfair performance in Stage 5.

Finally, remember the sentence from Problem Scoping: this classifier never reads or understands the message. It sees only two numbers, x and y, that we chose to extract. It has no concept of "urgency," "trust," or "money" — it cannot tell that "cashback" and "prize" mean something to a human reader. Every ounce of intelligence in this system lives in the feature choices a human made in Stage 3 and the labelled examples a human collected in Stage 2. That is true of nearly every classifier you will meet, not just this toy one — and it's the most important idea in this entire chapter to hold onto.

Check Your Understanding

Q1. A message reads: "Rs 20 cashback on your next 3 rides, no code needed". Count its features by hand (x = exclamation marks, y = digits), then use k = 3 nearest-neighbour voting against the six training points to classify it.

Answer: Digits: 2,0 (from "20") + 3 (from "3 rides") = 3 digits, y = 3. There are zero exclamation marks, x = 0. So the point is (0, 3). Distances: to A(0,1) = √4 = 2.0; to B(0,8) = √25 = 5.0; to C(1,13) = √[1+100] ≈ 10.05; to D(7,0) = √[49+9] ≈ 7.62; to E(6,5) = √[36+4] ≈ 6.32; to F(5,6) = √[25+9] ≈ 5.83. The three smallest are A(2.0), B(5.0), F(5.83) — labels Not Spam, Not Spam, Spam — a 2-to-1 vote for Not Spam, which fits: this message has no exclamation marks at all, the single strongest signal our two-feature model has for "not shouting."

Q2. Why would a classifier that used only y (digit count), with a rule like "more than 6 digits = spam," get message C wrong?

Answer: Because C = (1, 13) has the highest digit count of all six training messages — 13 digits — yet it is a legitimate bank debit alert, not spam. A digit-only rule would flag it as the most suspicious message in the whole dataset. It is only correctly classified because we also track x (exclamation marks), where C scores just 1 — far lower than any spam message. This is exactly why single-feature classifiers are fragile: the feature that separates most examples well can still be completely wrong for others.

Q3. What would change if we used k = 1 instead of k = 3 when classifying Q = (3, 3) from Stage 4?

Answer: With k = 1, the prediction depends on picking a single "nearest" neighbour — but A, E, and F are all tied at exactly √13. Python's stable sort would return A first (since A appears first in the training list among the tied entries), giving a prediction of Not Spam — the opposite of the k = 3 result. This is a genuine weakness of small, even, or tie-prone k values: the outcome can hinge on data order rather than on a real numerical difference. It's one reason k is usually chosen to be odd and reasonably larger than 1 for real classifiers.

Summary

You built a complete AI classifier by walking CBSE's AI Project Cycle stage by stage: you scoped the problem precisely (two labels, fixed features, no "reading" of text); you identified where labelled data comes from (human-tagged datasets like the UCI SMS collection, and India's own TRAI-regulated spam landscape); you explored data by turning six real-sounding messages into (x, y) points through careful character counting, discovering along the way that digit count alone can be actively misleading; you built a working model — k-Nearest Neighbours — grounded in nothing more exotic than the Pythagoras theorem, traced its Python implementation line by line, and got a correct, verifiable prediction; and you evaluated it honestly, distinguishing accuracy from the very different real-world costs of false positives and false negatives, and connecting both to genuine ethical stakes — a blocked OTP, a missed scam warning, a dataset that silently favours one language over another. Every number in this chapter, from exclamation-mark counts to square roots to vote tallies, was something you could recompute yourself. That is the whole point: an AI system you can trace by hand is one you actually understand, not one you merely trust.

← Data Science with Pandas: Analyzing Real DataBackpropagation: How Neural Networks Learn →

Found this useful? Share it!

📱 WhatsApp 🐦 Twitter 💼 LinkedIn