Machine learning, L1 — Line#
Level 1 · Novice
Source: src/MLambda.AI.ML/Line.hb
A model is a formula you can read#
Here are four points: (1, 4), (2, 7), (3, 10), (4, 13). There is a straight line through all of them — y = 3x + 1 — and "fitting a line" means finding it from the points alone.
In Hilbert, the fit is one line:
And that is the thing worth noticing first. The model is a formula. Not a class with a Fit()
method hiding a loop somewhere — a formula you can read, and that the compiler turns into code.
What coefficients does#
coefficients comes from Prelude.Multivariate, and it is ordinary least squares: of all the
straight lines you could draw, pick the one whose total squared miss is smallest. Hand it the points
and it hands back two numbers — the slope and the intercept.
This sample opens one Prelude module, and it is the only L1 sample that has to. A first machine-learning example that rewrote least squares from scratch would be teaching least squares. That is not the subject. The subject is that a model is something you can read.
A note for the curious: least squares is in
Multivariate, notRegression. TheRegressionmodule's own first line says it holds "the linear models that are not least squares" — logistic, lasso and friends. It is an easy thing to look for in the wrong place.
The column of ones#
The inputs are written like this:
Why the second column of ones? Because coefficients only knows how to weight columns — slope
times the first column, something times the second. A column that is always one, weighted by some
number, is a constant. That is how a straight line gets its + 1.
Remember this column. It comes back at L2, where leaving it out breaks a neural network in a way no amount of training can fix.
A number without a spread#
The fit tells you where the line is. The spread tells you how much the data disagrees with it.
On the four clean points the spread is exactly zero — every point sits on the line. Nudge two of the y values and the spread becomes 0.775. The line barely moves; the spread is what tells you something changed.
A fit reported without its spread invites false confidence, and that habit is worth having from the first sample.
One formula, many methods#
Look inside Generated/Hilbert/Line.g.cs after a build and you will find something surprising. This
one line of Hilbert:
became a dozen C# methods:
- one for plain numbers (
double), - one for complex numbers,
- one each for vectors, matrices and tensors — with a plain number allowed on either side,
- and an ONNX graph, a format other machine-learning tools can run.
You wrote the formula once. So a whole batch of predictions costs one call and no extra source: hand
errorOf two vectors and it answers a vector.
Run it#
recovered y = 3.000x + 1.000
at x = 10 predicts 31.000 (the line says 31)
spread 0.000 no noise in, no spread out
What the tests assert#
- A fit recovers a line it was given. Points from y = 3x + 1, fitted, and 3 and 1 come back. This is the strongest test a fit can have: a fit that cannot recover a line with no noise in it is not a fit, whatever else it does.
- It predicts where the line goes next.
- No noise in, no spread out — and noisy data has a spread above zero.
- The same
errorOfruns over a whole vector at once, and a plain number broadcasts across one. - The formula is also an ONNX graph.
Try it yourself#
- Change the outputs to come from y = −2x + 5 and check the recovered line.
- Remove the column of ones from the inputs. What does the fit do without an intercept?
- Add a fifth point far off the line and watch the spread — and the line — respond.