Logistic regression
MNIST. Binary classification: 0 vs 1
Implementation in pure PHP
This is one of the most famous teaching cases in machine learning. It is simple to state, yet it clearly shows how the model works – and where it starts to break down. Here we make an important turn in the book: we move from tabular data to images. Case goal: learn to classify digit images as "0" or "1" with logistic regression and understand the limitations of a linear model.
Pure PHP implementation uses a toy MNIST-like dataset with flattened 28x28 images and the standard logistic regression training loop.
Example of use
<?php
use app\classes\LogisticRegression;
use app\classes\MnistLoader;
// оценка
$correct = 0;
[$X_train, $y_train] = MnistLoader::loadMNIST('train.csv');
[$X_test, $y_test] = MnistLoader::loadMNIST('test.csv');
echo 'Train samples handled: ' . number_format(count($X_train)) . PHP_EOL;
echo 'Test samples handled: ' . number_format(count($X_test)) . PHP_EOL . PHP_EOL;
$model = new LogisticRegression(784, 0.1);
$model->train($X_train, $y_train, epochs: $epochs = 5);
echo 'Number of epochs: ' . $epochs . PHP_EOL . PHP_EOL;
foreach ($X_test as $i => $x) {
if ($model->predict($x) === $y_test[$i]) {
$correct++;
}
}
$accuracy = $correct / count($X_test);
echo 'Accuracy: ' . round($accuracy * 100, 2) . '%';
Sample of digit 0
Probability of digit 0: 1
Predicted digit: 0
Sample of digit 1
Probability of digit 1: 1
Predicted digit: 1
Result:
Memory: 0 Mb
Time running: < 0.001 sec.
Train samples handled: 12,666
Test samples handled: 2,116
Number of epochs: 5
Accuracy: 99.91%