balanced reviews
Machine learning, without the theatre
Can you trust
what you read?
An honest detector for computer-generated product reviews—built to show its reasoning, its limits, and the experiment behind every result.
Held-out accuracy
across 8,087 unseen reviews
Inference happens locally. No account, API, cookie, or uploaded text.
139,295 learned termsThe evidence
Representation beats
optimisation.
Five controlled configurations. One held-out split. Changing the text representation moves accuracy by 41 points; changing the learning algorithm moves it by less than one.
unseen reviews
best model
surface → TF-IDF
Held-out accuracy
The comparison
The finding
Features mattered roughly fifty times more than the optimiser.
The from-scratch Adaline and scikit-learn baseline finish within 0.41 percentage points on identical TF-IDF features. That validates the custom gradient descent while keeping the conclusion appropriately modest.
Error analysis
Where the best model misses.
TF-IDF + Adaline · 8,087 held-out reviews
Conservative by accident,
not by design.
The model produces fewer false positives than false negatives—a useful tendency for moderation, where accusing a real customer is the costlier error. A production system should tune that trade-off explicitly.
Under the bonnet
Four lines of maths.
No black box.
Adaline learns a linear decision boundary by minimising mean squared error. The optimisation is written from scratch in NumPy; scikit-learn supplies only pipeline plumbing and the comparison baseline.
Represent
Convert reviews into sparse word and phrase weights with TF-IDF.
Learn
Update 139,295 weights with transparent batch gradient descent.
Decide
Threshold the continuous Adaline activation at 0.500.
Objective
A differentiable, convex loss surface with a global optimum—provided the learning rate is stable.
errors = y - self.activation(
self.net_input(X)
)
self.w_ += self.lr * 2.0 * (
X.T @ errors
) / n_samples
self.b_ += self.lr * 2.0 * errors.mean()
Sparse by necessity
The TF-IDF matrix would need roughly 35 GB if densified. Every operation preserves SciPy sparse matrices end to end.
Divergence fails loudly
A large learning rate can explode while remaining a finite float. Explicit guards reject the run instead of returning silent garbage.
Limits are part of the result
One dataset, one GPT-2 generator, one split. This is a research demonstration—not a universal truth machine.