Split: a study set and an exam set
The model learns from the training set and is graded on the test set it has never seen. Change the split and see what changes.
All 5,169 messages, one square each
What to notice
- The test messages are scattered at random through the data.
- The same
random_stategives exactly the same split every time; another number gives another exam. stratify=ykeeps the spam share the same in both parts. Without it, the share drifts a little.
Try this
Words to numbers: what CountVectorizer builds
A model only understands numbers. fit learns the vocabulary from the training messages; transform counts words using that vocabulary only.
The count table (bag of words)
In the real model
What to notice
- One row per message, one column per word, each cell a count. Word order is lost.
- Words never seen in training (like "tomorrow") get no column: they are ignored.
- One-letter words ("a", "u") are skipped by default, and punctuation is dropped.
Try this
Train and evaluate: an honest score
Multinomial Naive Bayes trained in your browser on the split from tab 1, giving the same numbers as scikit-learn. Then judge it on the test set, and compare with doing nothing.
Confusion matrix (click a cell to see its messages)
P(spam) for every test message
Messages in this cell
What to notice
- Rows are the truth, columns the prediction. The diagonal is right; the other two cells are the two kinds of mistake.
- Lowering the threshold catches more spam but sends more real messages to the spam folder.
- The score depends on the split: another random_state gives a slightly different number.
Try this
Try your own: what does the model see?
Type any message. Each word the model knows pushes towards spam or towards ham; words it never saw are ignored.
Evidence word by word
What did it learn? Strongest clue words in this model
What to notice
- The model starts from the share of spam in training (about 13%), then each known word adds evidence.
- "150p" and "tone" are clues because the data is from the UK around 2011, not because they are universally spammy.
- A modern parcel scam slips through: it looks nothing like 2011 spam.
- "gt" and "lt" are strong ham clues only because the raw data contains
<#>placeholders in normal messages: a data quirk, not language.