Métricas de Regresión

¿Cómo sabemos si nuestro modelo de regresión es "bueno"?

Cuando entrenamos un modelo como LinearRegression para predecir valores numéricos (como el precio de una casa, las ventas del próximo mes, o la temperatura de mañana), necesitamos una forma de medir qué tan cerca están nuestras predicciones de los valores reales. Aquí es donde entran las métricas de regresión.

La idea fundamental

Imagina que tu modelo predice que una casa costará $250,000, pero en realidad se vendió por $240,000. El error de esa predicción es de $10,000. Ahora, si tienes 1000 casas con sus predicciones, ¿cómo resumes todos esos errores en un solo número?

Cada métrica responde esta pregunta de forma diferente:

  • MAE calcula el promedio de los errores (en valor absoluto)
  • MSE eleva los errores al cuadrado antes de promediar
  • RMSE hace lo mismo que MSE pero luego saca la raíz cuadrada
  • mide qué proporción de la variación en los datos explica el modelo
  • MAPE expresa el error como porcentaje

¿Cuál métrica usar?

Si necesitas...Usa
Error en las mismas unidades que tus datosMAE o RMSE
Penalizar errores grandesMSE o RMSE
Comparar con un baseline (predicir la media)
Comunicar error a no-técnicosMAPE
Comparar modelos con diferente número de featuresR² Ajustado

Uso en Minerva

Example.java
1
2
3
import com.minerva.metrics.RegressionMetrics.RegressionMetrics;
RegressionMetrics metrics = new RegressionMetrics();

Todas las métricas reciben dos vectores: los valores reales y los predichos.

Example.java
1
2
3
4
5
6
7
8
double mae = metrics.MAE(actual, predicted);
double mse = metrics.MSE(actual, predicted);
double rmse = metrics.RMSE(actual, predicted);
double r2 = metrics.R2(actual, predicted);
double mape = metrics.MAPE(actual, predicted);
// R² Ajustado necesita el número de features
double r2adj = metrics.R2adj(actual, predicted, numFeatures);

Ejemplo Completo

Example.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import com.minerva.core.primitives.Matrix;
import com.minerva.core.primitives.Vector;
import com.minerva.metrics.RegressionMetrics.RegressionMetrics;
import com.minerva.models.regression.impl.LinearRegression;
public class EvaluacionModelo {
public static void main(String[] args) {
Matrix X = new Matrix(new double[][] {
{1.0, 1.0}, {1.0, 2.0}, {2.0, 2.0}, {2.0, 3.0}
});
Vector y = new Vector(new double[] {6.0, 8.0, 9.0, 11.0});
LinearRegression model = new LinearRegression();
model.fit(X, y);
Vector yPred = model.predict(X);
RegressionMetrics metrics = new RegressionMetrics();
System.out.println("=== Métricas de Evaluación ===");
System.out.printf("MAE: %.4f%n", metrics.MAE(y, yPred));
System.out.printf("MSE: %.4f%n", metrics.MSE(y, yPred));
System.out.printf("RMSE: %.4f%n", metrics.RMSE(y, yPred));
System.out.printf("R²: %.4f%n", metrics.R2(y, yPred));
System.out.printf("R² adj: %.4f%n", metrics.R2adj(y, yPred, X.cols()));
System.out.printf("MAPE: %.2f%%%n", metrics.MAPE(y, yPred));
}
}
java EvaluacionModelo
=== Métricas de Evaluación ===
MAE: 0.0000
MSE: 0.0000
RMSE: 0.0000
R²: 1.0000
R² adj: 1.0000
MAPE: 0.00%

¿Por qué todo es 0 o 1?

En este ejemplo, el modelo se ajusta perfectamente a los datos (los datos siguen exactamente una relación lineal). Por eso el error es 0 y R² es 1. En datos reales, esto casi nunca ocurre.

Resumen de Métricas

MétricaRangoMejor valorUnidades
MAE[0, inf)0Igual a y
MSE[0, inf)0Cuadrado de y
RMSE[0, inf)0Igual a y
(-inf, 1]1Adimensional
R² Ajustado(-inf, 1]1Adimensional
MAPE[0, inf)0%Porcentaje