← All simulations · Pillar 5: Making decisions
Spam-or-not (toy)
What it is
A spam filter reads an incoming message and decides: junk, or keep? This toy does it the classic way — with naive Bayes. During training it counted how often each word showed up in spam versus normal mail. Now, for a new message, every word casts a little vote, and the filter multiplies those votes together into one belief: “this looks 94% spam.”
Go deeper: this is the same algorithm as the bell-curve classifier in the Naive Bayes sim — only the features changed. There, each clue was a number read off a bell curve. Here, each word is a feature, and its “chance” is simply how common it was in each kind of mail. Words the filter never saw in spam (like “meeting”) vote loudly for “normal”; words it mostly saw in spam (like “free”) vote for junk.
Why care
Naive Bayes spam filters were one of the first machine-learning tools millions of people used every day — quietly cleaning inboxes since the late 1990s. The same idea (let each piece of evidence vote, then combine the votes) powers sentiment detectors, topic sorters, and medical screening tools. And spam-versus-not is the perfect first look at text classification, where the features are words instead of numbers.
The idea, intuitively
Build a message by clicking words. Each word lights up a vote bar — red means “I smell spam,” green means “looks normal” — sized by how lopsided that word was in training. The filter stacks all the votes into a single verdict. Add a spammy word and the needle jumps toward junk; add a few ordinary words and it slides back. No single word decides; the whole message does.
Peek at the data first
The model trained on a tiny pile of pretend messages, each just a short list of harmless made-up
words plus a label. No real emails, no names, nothing personal — the same shape of labelled
data Spectra’s describe_data would show before training.
Try it
Click words to add or remove them from your message. The big bar shows the filter’s verdict (red = spam, green = not), and each word’s own vote appears below. Start from the spammy “free prize” and add normal words to watch the verdict flip. Turn on Show what each word learned to see the filter’s whole brain — every word ranked by how spammy it looked in training.
Where it shows up
- Email spam filters. The original killer app of naive Bayes — fast, tiny, and good enough to clean billions of inboxes.
- Sorting text. Tagging reviews as positive or negative, routing support tickets, flagging toxic comments — all “words vote, then combine.”
- Screening and triage. Anywhere many weak clues should add up to one confident call.
Where it came from
The math is Bayes’ theorem, written down by Thomas Bayes in the 1700s. Using it to filter spam took off around 2002, when Paul Graham’s essay “A Plan for Spam” showed that a simple word-counting Bayesian filter could catch junk mail astonishingly well. For years it was the workhorse behind the “Junk” folder before fancier models arrived.
Try it in code
In the Studio, a naive-Bayes classifier learns votes from features and combines them the same way;
show_model reveals what it learned per class:
data = load "fruits" train, test = split data, hold_out: 20% model = make_model "bayes" train_model model, on: train, predict: "type", using: ["sweetness", "size"] check model, with: test show_model model
Check your understanding
- Why does the word “free” vote for spam while “meeting” votes for normal?
- If a message has one spammy word and three ordinary ones, how does the filter decide?
- Why is it risky for a spam filter to judge a message on a single word?