Metrics meansquaredlogerror score - CyrilB1531/lodestar GitHub Wiki
Development build. This page describes
main, not a released package. The latest published Lodestar.Metrics is 0.4.0 โ read its documentation.
Home โบ Metrics โบ Regression metrics
The mean of the squared differences of log(1 + y).
public static double Score(ReadOnlySpan<double> yTrue, ReadOnlySpan<double> yPred, int outputCount = 1, ReadOnlySpan<double> sampleWeight = default, ReadOnlySpan<double> outputWeights = default)Parameters โ yTrue and yPred are the true and predicted values, row-major when there is
more
than one output, and every value must be above โ1. outputCount is how many outputs each row
holds, sampleWeight weights the rows, and outputWeights weights the outputs in the reduction.
Returns โ double, never negative, 0 only for an exact prediction. In squared log units,
which
are not the target's units and not a fraction either.
Exceptions โ ArgumentException when a length disagrees with the shape, the input is empty,
it
holds a non-finite value, or either array holds a value at or below โ1;
ArgumentOutOfRangeException when outputCount is below one.
outputWeights holding NaN or an infinity is ArgumentException too, with scikit-learn's "Input contains NaN." or its infinity counterpart (#1461), and so is any outputWeights on a single output, with "Custom weights are useful only in multi-output cases." (#1533).
Example โ four counts, one of them predicted 60% high.
using Lodestar.Metrics;
double[] yTrue = [3.0, 5.0, 2.5, 7.0];
double[] yPred = [2.5, 5.0, 4.0, 8.0];
double error = MeanSquaredLogError.Score(yTrue, yPred); // => 0.0397โฆRemarks โ taking the logarithm first turns a ratio into a difference, so this charges
"predicted twice the truth" the same whether the truth was 10 or 10 000. That makes it the natural
metric for counts, demand, page views โ anything that grows multiplicatively and where the small
values are as interesting as the large ones. MeanSquaredError.Score on such a target is decided
entirely by the largest few samples.
It is also asymmetric on purpose, and this is the reason to choose it over
MeanAbsolutePercentageError.Score: because log compresses upward, under-predicting is charged
more than over-predicting by the same factor. If running out of stock is worse than holding too
much, that asymmetry is the feature.
Two traps. The units are not interpretable โ 0.0397โฆ is neither a count nor a percentage โ so
report RootMeanSquaredLogError.Score if a human is going to read it, and even then it is a log
ratio. And negative targets are refused, not clamped: any value at or below โ1 raises
ArgumentException, because log(1 + y) is undefined there. The exception additionally names
which
side the offending value was on, which scikit-learn's does not.
The logarithm is numpy's log1p, reached through Kahan's identity rather than Math.Log(1.0 + x).
That is not decoration: on targets around 1e-9 the naive spelling is out by 1.7e-8 relative,
where this agrees with scikit-learn to a unit in the last place, because
log(1 + x) ยท x / ((1 + x) โ 1) divides out the rounding the addition made.
Applies to โ net10.0, netstandard2.0.
See also โ MeanSquaredLogError.PerOutput, RootMeanSquaredLogError.Score,
MeanAbsolutePercentageError.Score,
the Python equivalence table.