1. Turning an SMS into numbers
Models only understand numbers. To catch spam SMS, we turn each message into a few counts:
- how many “spammy” words it has (free, win, prize, offer…)
- how many
! marks it has
“WIN a FREE prize!!! Click now” → [4, 3]. “Mummy, bring dhaniya on the way home” → [0, 0].
Choosing good features is half of machine learning. A model can’t learn from what it never sees.
Challenge: Spam counter
Write smsFeatures(text) that returns [spammyCount, bangCount]:
spammyCount: lowercase the text, split it into words with split(/[^a-z0-9]+/), and count words that are in SPAMMYbangCount: how many ! characters the text has
2. Accuracy
Run the model on the test set and compare its predictions with the true labels.
accuracy = correct predictions / total predictions
If the model got 9 of 12 test SMS right, accuracy is 0.75 (75%).
Remember: measure on test data the model never trained on. Accuracy on training data is like marking your own homework with the answer key open.
const predicted = ["spam", "ham", "spam"];
const actual = ["spam", "ham", "ham"];
let right = 0;
for (let i = 0; i < actual.length; i++) {
if (predicted[i] === actual[i]) right++;
}
console.log(right, "of", actual.length);
Challenge: Score the model
Write accuracy(predicted, actual): both are arrays of labels of the same length. Return the fraction of positions where they match, as a number from 0 to 1.
3. Not all mistakes are equal
Imagine 100 SMS: 95 normal, 5 spam. A lazy model that always says “ham” gets 95% accuracy — and catches zero spam! Accuracy alone can fool you.
So we count four boxes (we call spam the positive class):
- tp true positive: said spam, was spam ✅
- fp false positive: said spam, was normal (your friend’s message lost!)
- tn true negative: said normal, was normal ✅
- fn false negative: said normal, was spam (a scam slipped through)
This table is called the confusion matrix. Which mistake is worse depends on the job: missing a cancer test is far worse than a false alarm.
Challenge: Count the four boxes
Write confusion(predicted, actual, positive) that returns an object { tp, fp, tn, fn }. A prediction is “positive” when it equals positive (for example "spam").