Is this text message spam?
Linear SVM on word and character TF-IDF, trained on the UCI SMS Spam Collection (CC BY 4.0)
The model runs in your browser. What you type is never sent anywhere.
Try a message
Loading the model…
Prediction
The message as the model read it
- pushes toward spam
- pushes toward ham
- ignored
Top contributing words
Toward spam
Toward ham
How it works
- Two views of the message. The message is lowercased and read twice. The word view cuts it into runs of two or more letters, digits or underscores (so “Free!!” becomes
free) and drops common English stop words such asyouandthe. The character view cuts every white-space-separated word, padded with a space on each side, into pieces of 2 to 5 characters (so “free!!” gives pieces such as␣fr,reeande!!). Pieces that were not seen at least twice in training are ignored. - Weight with TF-IDF. Each known word or piece gets its count (for pieces, one plus the log of its count) times its inverse document frequency: rarer across the training messages means heavier. Each view’s vector is scaled to length 1.
- Add up the evidence. A linear SVM learned one weight for each of the 40,299 words and pieces. The decision value is the starting point (the bias) plus the sum of weight times TF-IDF value over everything found in the message. Above 0 means spam. The bars above split that sum over the pieces of the message that are separated by spaces: each word’s own weight plus the weights of its character pieces.
The SVM sees short spans of characters, so it can pick up shapes such as 08 at the start of a phone number or £ before a price, but not word order or meaning. Its decision value is a margin, not a probability.
- Split into words. The message is lowercased and cut into runs of two or more letters, digits or underscores, so “Free!!” becomes
freeand a single “u” is dropped. - Drop stop words. Common English words such as
you,theandtoare removed using scikit-learn’s built-in list. Words the model never saw in training are ignored too. - Weight with TF-IDF. Each remaining word gets its count times its inverse document frequency: words that are rare across the training messages weigh more. The vector is then scaled to length 1.
- Add up the evidence. For each class, Naive Bayes adds the log-probability of every word under that class, weighted by its TF-IDF value, to the class’s starting point (its share of the training data). The class with the higher total wins. The bars above show each word’s share of the difference.
Naive Bayes treats words independently, so word order and context are invisible to it. It ignores any word it did not see in training.
Both models only know English text messages from a research corpus published in 2011, drawn mostly from UK and Singapore sources. The measured results, with a majority-class baseline and a comparison of the models, are in the README.
This page re-implements the scikit-learn pipelines in JavaScript. Parity tests check that it gives the same prediction as scikit-learn on all 1,672 held-out test messages, for both models.