Sentiment classifier
Three ways to tell a good movie review from a bad one, and why the two transformers lost to the simplest model until they were allowed to read the ending.
- 87.5%
- DistilBERT, reading the ending
- 75.5%
- MiniLM, whole review
- 84.5%
- TF-IDF baseline
What it does
The same 2,000 movie reviews classified three ways: TF-IDF with logistic regression, frozen MiniLM embeddings with logistic regression, and a fine-tuned DistilBERT. The simplest model won by 20 points, because both transformers were reading only the first 256 tokens of reviews that run to about 800, and reviewers tend to give their verdict at the end. Letting them read the end took DistilBERT from 73.0% to 87.5%, ahead of TF-IDF.
- Classifies a review as positive or negative
- Three models trained and tested on the same split of NLTK's movie_reviews: 1,600 reviews to train on, 400 held out, stratified, one seed. Each reports accuracy, F1 and ROC-AUC, a confusion matrix, and every review it got wrong.
- Explains what the simple model learned
- TF-IDF with logistic regression is readable: its strongest words are bad, worst, boring and great, excellent, best. They also include film titles like truman and bulworth, which means it partly learned which films people liked, and that is worth knowing before trusting it on new ones.
- Lets the transformers read the whole review
- MiniLM now embeds every 254-token chunk of a review and averages them; DistilBERT keeps the opening 128 tokens and the closing 382. Nothing else changed: same split, same seed, same classifier settings, same two epochs.
- Scores any text from the command line
- predict.py runs one model or all three side by side on a sentence, a file, or standard input, reading the text the same way each model was trained.
Demo
What each model read
Five reviews, five versions of the models. Pick a review, then pick a model: whatever it never read is greyed out. The first versions of the transformers stop at 256 tokens.
Showing what TF-IDF + logistic regression reads
Each version's verdict
Written for this page, not taken from the dataset. The scores are the trained models' real outputs, computed once and stored here: the transformers are far too large to run in a browser.
How it works
Why the transformers lost
The reviews are long: 797 tokens at the median and 1,312 at the 90th percentile. MiniLM reads at most 256 tokens, and the DistilBERT script truncated at 256 too, so 98.8% of reviews were cut, and each transformer saw 36% of an average review. The part it never saw is where a reviewer usually says what they thought. TF-IDF reads every word, so the oldest and simplest model won by 20 points.
The first write-up claimed MiniLM was the more accurate model, and its own results said the opposite: 64.8% against 84.5%, with a McNemar test putting the gap well beyond chance.
What changed
Only how much of each review the models read:
| Model | First version | Revised | Reads |
|---|---|---|---|
| TF-IDF + logistic regression | 84.5% | 84.5% | every word |
| MiniLM + logistic regression | 64.8% | 75.5% | every 254-token chunk, averaged |
| DistilBERT, fine-tuned | 73.0% | 87.5% | the first 128 and last 382 tokens |
Is it the extra length, or the ending? A third DistilBERT run spent the same 510-token budget on the first 510 tokens and scored 81.5%. So doubling what it reads is worth about eight points, and spending part of it on the ending is worth six more: 50 reviews right only with the ending against 25 right only without it, an exact McNemar p of 0.005.
MiniLM is still behind after the fix. A frozen sentence encoder averages away the shape of an argument, and standardising its features with a cross-validated penalty did not help (75.25%).
The face-off
The five reviews above were written for this page, about films that do not exist, to put the finding in front of the reader. The letdown praises its cast for half its length and turns at the end: every model that cannot see the end calls it positive. The revised DistilBERT is not perfect either. It calls the two-sentence review negative, by a thousandth.
Testing
400 held-out reviews, one fixed split
Every model is scored on the same 400 held-out reviews, never seen in training, and the comparisons are paired: the same reviews, so a difference can be tested rather than eyeballed. The first-version results were reproduced exactly before anything was changed.
What the tests defend
- DistilBERT's lead over TF-IDF is not statistically significant on this test set: 40 reviews are wrong only for TF-IDF and 28 only for DistilBERT, and an exact McNemar test gives p = 0.18. The page says ahead, not better.
- The ending is tested, not assumed: with the same 510-token budget spent on the first 510 tokens, DistilBERT scores 81.5%. Keeping the ending instead fixes 50 reviews and breaks 25 (exact McNemar p = 0.005).
- Each number is one run with one seed on one split, which is the honest limit of what it shows.
Built with
- Models
- scikit-learnSentence-TransformersHugging Face TransformersPyTorch
- Data
- NLTK movie_reviewspandasNumPy
- Evaluation
- accuracyF1ROC-AUCMcNemar's test