Linear regression as a basic model
Case 1. Apartment valuation based on parameters
Implementation in pure PHP
(iterative optimization – gradient descent)
We will start without any libraries. This is useful not for production, but for building intuition. We will use gradient descent, a feature matrix $X$ of size $N$ x $4$, and a weight vector $w$ of length $4$.
We will add the bias as an extra feature with value 1.
Example of use
<?php
// Compute the dot product of two vectors: sum(a_i * b_i)
function dotProduct(array $a, array $b): float {
$sum = 0.0;
foreach ($a as $i => $v) {
$sum += $v * $b[$i];
}
return $sum;
}
// Training data: each row is an apartment described by features
// X: [area, floor, distance to city center, building age, bias]
$X = [
[50, 3, 5, 10, 1],
[70, 10, 3, 5, 1],
[40, 2, 8, 30, 1],
];
// Target values: apartment prices in dollars
$y = [
66_000,
95_000,
45_000,
];
// Initialize model parameters (weights) and training hyperparameters
$weights = array_fill(0, 5, 0.0);
$learningRate = 0.000001;
$epochs = 5_000;
// n – number of training examples, m – number of features (including bias)
$n = count($X);
$m = count($weights);
// Gradient descent loop: repeat several passes over the dataset
for ($epoch = 0; $epoch < $epochs; $epoch++) {
// Accumulate gradients for each weight over the whole dataset
$gradients = array_fill(0, $m, 0.0);
for ($i = 0; $i < $n; $i++) {
// Model prediction: y_hat = w · x
$prediction = dotProduct($weights, $X[$i]);
// Error for this example: true - predicted
$error = $y[$i] - $prediction;
// Accumulate gradient for each weight (derivative of MSE w.r.t. w_j)
for ($j = 0; $j < $m; $j++) {
$gradients[$j] += -2 * $X[$i][$j] * $error;
}
}
// Gradient descent update: move weights against the average gradient
for ($j = 0; $j < $m; $j++) {
$weights[$j] -= $learningRate * ($gradients[$j] / $n);
}
}
// Describe a new apartment with the same set of features as in X
// [square footage, number of bedrooms, number of bathrooms, number of floors, bias]
$newApartment = [60, 5, 4, 12, 1];
// Use the trained model to predict its price
$predictedPrice = dotProduct($weights, $newApartment);
echo 'Apartment valuation: $' . number_format($predictedPrice) . PHP_EOL . PHP_EOL;
echo 'Weights: ' . implode(', ', array_map(fn ($weight) => number_format($weight, 2, '.', ''), array_splice($weights, 0, 4))) . PHP_EOL;
echo 'Bias: ' . number_format(array_pop($weights), 2, '.', '') . PHP_EOL;
Charts:
Chart Type:
Result:
Memory: 0.003 Mb
Time running: 0.005 sec.
Apartment valuation: $78,374
Weights: 1333.29, 198.45, -0.94, -219.01
Bias: 16.06
The block above shows the result of the script: the predicted apartment price for the following features:
- Apartment area: 60 m²
- Number of rooms: 5
- Number of bathrooms: 4
- Number of floors: 12