deepbox/metrics
Regression Metrics
Error, scale-aware and variance-based metrics for regression models.
- Regression
Overview
- Inputs are 1-D (or single-column) float tensors of equal length. There is no multi-output mode. NaN or infinite values throw
DataValidationError, andint64tensors throwDTypeError. mapereturns a percentage (32.7 means 32.7 percent) and skips targets that are exactly zero. scikit-learn returns a fraction and guards zeros with an epsilon. UsemeanAbsolutePercentageErrorfor the scikit-learn result, which also takessampleWeight.mse,rmse,maeandr2Scoreaccept{ sampleWeight }.r2Scoreis 1 for a perfect fit, 0 for a model that predicts the mean, and negative for anything worse.tensor()createsfloat32data by default, so decimal inputs carry rounding error of about 1e-7. CreateyTrueandyPredwith{ dtype: "float64" }when you compare results with scikit-learn to many digits.adjustedR2Score(yTrue, yPred, nFeatures)needs the number of features.meanSquaredError,meanAbsoluteErrorandrootMeanSquaredErrorare long names formse,maeandrmse.
adjustedR2Score
function adjustedR2Score(yTrue: Tensor, yPred: Tensor, nFeatures: number): number;Calculate Adjusted R² score.
Details
R² adjusted for the number of features in the model. Penalizes the addition of features that don't improve the model. More appropriate than R² when comparing models with different numbers of features.
Formula: Adjusted R² = 1 - ((1 - R²) * (n - 1)) / (n - p - 1) - n = number of samples - p = number of features
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
Constraints: Requires n > p + 1 (more samples than features + 1)
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
nFeaturesnumber- Number of features (predictors) used in the model
Returns
numberAdjusted R² score
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectorsDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIf nFeatures is not a non-negative integer, n <= p + 1, or inputs are emptyDataValidationErrorIf inputs contain NaN or infinite values
import { adjustedR2Score } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const score = adjustedR2Score(yTrue, yPred, 2); // 0.8458244111349038explainedVarianceScore
function explainedVarianceScore(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate explained variance score.
Details
Measures the proportion of variance in the target variable that is explained by the model. Similar to R² but uses variance instead of sum of squares. Best possible score is 1.0, lower values are worse.
Formula: explained_variance = 1 - Var(y_true - y_pred) / Var(y_true)
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight both variances are weighted (weighted means and weighted sums of squares).
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberExplained variance score (1.0 is perfect, lower is worse)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIf inputs are empty orsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { explainedVarianceScore } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const score = explainedVarianceScore(yTrue, yPred); // 0.9571734475374732const weighted = explainedVarianceScore(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.9689988623435722mae
function mae(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Mean Absolute Error (MAE).
Measures the average absolute difference between predictions and actual values. MAE is less sensitive to outliers than MSE.
Formula: MAE = (1/n) * Σ|y_true - y_pred|
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the mean is weighted: Σ w_i * |y_i - p_i| / Σ w_i.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberMAE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { mae } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = mae(yTrue, yPred); // 0.5const weighted = mae(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.55mape
function mape(yTrue: Tensor, yPred: Tensor): number;Calculate Mean Absolute Percentage Error (MAPE).
Details
Measures the average absolute percentage difference between predictions and actual values. Expressed as a percentage, making it scale-independent and easy to interpret.
Formula: MAPE = (100/m) * Σ|((y_true - y_pred) / y_true)| where m is the number of non-zero targets.
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
Difference from scikit-learn: mape returns a percentage (32.7 means 32.7 %), while scikit-learn's mean_absolute_percentage_error returns a fraction (0.327). mape also skips zero values in yTrue instead of guarding with an epsilon, and returns 0 if all targets are zero. For the scikit-learn result, including sampleWeight support, use meanAbsolutePercentageError.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
Returns
numberMAPE value as percentage (0 is perfect, lower is better)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectorsDTypeErrorIf yTrue or yPred is non-numeric or int64DataValidationErrorIf inputs contain NaN or infinite values
import { mape } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = mape(yTrue, yPred); // 32.73809523809524 (percent)maxError
function maxError(yTrue: Tensor, yPred: Tensor): number;Calculate maximum residual error.
Returns the maximum absolute difference between predictions and actual values. Useful for identifying the worst-case prediction error.
Formula: max_error = max(|y_true - y_pred|)
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
Returns
numberMaximum absolute error (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectorsDTypeErrorIf yTrue or yPred is non-numeric or int64DataValidationErrorIf inputs contain NaN or infinite values
import { maxError } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = maxError(yTrue, yPred); // 1.0 (worst prediction)meanAbsoluteError
function meanAbsoluteError(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Mean Absolute Error (MAE).
Measures the average absolute difference between predictions and actual values. MAE is less sensitive to outliers than MSE.
Formula: MAE = (1/n) * Σ|y_true - y_pred|
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the mean is weighted: Σ w_i * |y_i - p_i| / Σ w_i.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberMAE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { mae } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = mae(yTrue, yPred); // 0.5const weighted = mae(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.55meanAbsolutePercentageError
function meanAbsolutePercentageError(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate the Mean Absolute Percentage Error with scikit-learn's definition.
Details
Formula: MAPE = (1/n) * Σ |y_true - y_pred| / max(|y_true|, ε) where ε = 2.220446049250313e-16 (the float64 machine epsilon). A zero target therefore produces a very large term instead of being skipped.
The result is a fraction (0.25 means 25 %), exactly like scikit-learn's mean_absolute_percentage_error. mape returns a percentage and skips zero targets instead; use this function for scikit-learn compatible numbers.
With options.sampleWeight the mean is weighted: Σ w_i * term_i / Σ w_i.
Time Complexity: O(n) where n is the number of samples Space Complexity: O(n)
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberMAPE as a fraction (0 is perfect). Returns 0 for empty input.
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { meanAbsolutePercentageError } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);meanAbsolutePercentageError(yTrue, yPred); // 0.3273809523809524meanSquaredError
function meanSquaredError(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Mean Squared Error (MSE).
Measures the average squared difference between predictions and actual values. MSE is sensitive to outliers due to squaring the errors.
Formula: MSE = (1/n) * Σ(y_true - y_pred)²
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the mean is weighted: Σ w_i * (y_i - p_i)² / Σ w_i.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberMSE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { mse } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = mse(yTrue, yPred); // 0.375const weighted = mse(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.475medianAbsoluteError
function medianAbsoluteError(yTrue: Tensor, yPred: Tensor): number;Calculate Median Absolute Error (MedAE).
Measures the median of absolute differences between predictions and actual values. Less sensitive to outliers than MAE or MSE because it uses the median instead of the mean.
Formula: MedAE = median(|y_true - y_pred|)
Time Complexity: O(n log n) due to sorting for median calculation Space Complexity: O(n) for storing error array
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
Returns
numberMedian absolute error (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectorsDTypeErrorIf yTrue or yPred is non-numeric or int64DataValidationErrorIf inputs contain NaN or infinite values
import { medianAbsoluteError } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = medianAbsoluteError(yTrue, yPred); // 0.5mse
function mse(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Mean Squared Error (MSE).
Measures the average squared difference between predictions and actual values. MSE is sensitive to outliers due to squaring the errors.
Formula: MSE = (1/n) * Σ(y_true - y_pred)²
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the mean is weighted: Σ w_i * (y_i - p_i)² / Σ w_i.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberMSE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { mse } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = mse(yTrue, yPred); // 0.375const weighted = mse(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.475r2Score
function r2Score(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate R² (coefficient of determination) score.
Details
Represents the proportion of variance in the target variable that is explained by the model. R² of 1 indicates perfect predictions, 0 indicates the model is no better than predicting the mean, and negative values indicate the model is worse than predicting the mean.
Formula: R² = 1 - (SS_res / SS_tot) - SS_res = Σ(y_true - y_pred)² (residual sum of squares) - SS_tot = Σ(y_true - mean(y_true))² (total sum of squares)
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight both sums are weighted and SS_tot is taken around the weighted mean of y_true.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberR² score (1 is perfect, 0 is baseline, negative is worse than baseline)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIf inputs are empty orsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { r2Score } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const score = r2Score(yTrue, yPred); // 0.9486081370449679const weighted = r2Score(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }); // 0.9459613196814562rmse
function rmse(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Root Mean Squared Error (RMSE).
Square root of MSE, expressed in the same units as the target variable. RMSE is more interpretable than MSE as it's in the original scale.
Formula: RMSE = √(MSE) = √((1/n) * Σ(y_true - y_pred)²)
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the underlying MSE is weighted, see mse.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberRMSE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { rmse } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = rmse(yTrue, yPred); // √0.375 ≈ 0.612rootMeanSquaredError
function rootMeanSquaredError(yTrue: Tensor, yPred: Tensor, options?: WeightedMetricOptions): number;Calculate Root Mean Squared Error (RMSE).
Square root of MSE, expressed in the same units as the target variable. RMSE is more interpretable than MSE as it's in the original scale.
Formula: RMSE = √(MSE) = √((1/n) * Σ(y_true - y_pred)²)
Time Complexity: O(n) where n is the number of samples Space Complexity: O(1)
With options.sampleWeight the underlying MSE is weighted, see mse.
Parameters
yTrueTensor- Ground truth (correct) target values
yPredTensor- Estimated target values
optionsoptionalWeightedMetricOptions- Optional
sampleWeight, one weight per sample
Returns
numberRMSE value (always non-negative, 0 is perfect)
Throws
ShapeErrorIf yTrue and yPred have different sizes or are not 1D/column vectors, orsampleWeighthas the wrong lengthDTypeErrorIf yTrue or yPred is non-numeric or int64InvalidParameterErrorIfsampleWeightsums to zeroDataValidationErrorIf inputs contain NaN or infinite values
import { rmse } from 'deepbox/metrics';import { tensor } from 'deepbox/ndarray'; const yTrue = tensor([3, -0.5, 2, 7]);const yPred = tensor([2.5, 0.0, 2, 8]);const error = rmse(yTrue, yPred); // √0.375 ≈ 0.612import { adjustedR2Score, mae, mape, meanAbsolutePercentageError, mse, r2Score, rmse,} from "deepbox/metrics";import { tensor } from "deepbox/ndarray"; // float64 keeps decimal inputs exact. The default float32 rounds them to about 7 digits.const yTrue = tensor([3, 5, 2.5, 7], { dtype: "float64" });const yPred = tensor([2.8, 4.9, 2.0, 7.4], { dtype: "float64" }); console.log(mse(yTrue, yPred), rmse(yTrue, yPred), mae(yTrue, yPred));console.log(mape(yTrue, yPred)); // percentconsole.log(meanAbsolutePercentageError(yTrue, yPred)); // fraction, as in scikit-learnconsole.log(r2Score(yTrue, yPred), r2Score(yTrue, yPred, { sampleWeight: [1, 2, 3, 4] }));console.log(adjustedR2Score(yTrue, yPred, 1));Found a mistake? Open an issue.