evannwilsonn/spamfilter

Spamfilter

Multinomial naive Bayes written from scratch in Rust, trained on 5,574 SMS, ported to JS. It runs in this tab; nothing leaves your browser.

– tokens in vocabulary
prior P(spam) –, α = 1.0

Messages0 classified
—
type something

Spam threshold

0.90

The model needs P(spam) above this to call spam. Higher means fewer real texts lost and more spam let through.

Evidence by token

Each bar is log P(token given spam) minus log P(token given ham). Struck-through tokens are not in the vocabulary and are ignored.

Show the arithmetic

How it was measured

Stratified 80/20 split, averaged over 10 random seeds. Spam is the positive class. The from-scratch model matches linfa's MultinomialNb to the confusion cell.

ModelAccuracyPrecisionRecallF1F1 sd
Majority baseline, always ham0.8660.0000.0000.0000.000
Naive Bayes, unigrams0.9850.9480.9420.9450.014
Naive Bayes, unigrams and bigrams0.9870.9660.9380.9520.016
Bigrams, threshold 0.900.9880.9810.9310.9550.014
Bigrams, threshold 0.990.9890.9920.9230.9560.015