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
- R² 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 datos | MAE o RMSE |
| Penalizar errores grandes | MSE o RMSE |
| Comparar con un baseline (predicir la media) | R² |
| Comunicar error a no-técnicos | MAPE |
| Comparar modelos con diferente número de features | R² Ajustado |
Uso en Minerva
import com.minerva.metrics.RegressionMetrics.RegressionMetrics; RegressionMetrics metrics = new RegressionMetrics();Todas las métricas reciben dos vectores: los valores reales y los predichos.
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 featuresdouble r2adj = metrics.R2adj(actual, predicted, numFeatures);Ejemplo Completo
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)); }}=== Métricas de Evaluación ===MAE: 0.0000MSE: 0.0000RMSE: 0.0000R²: 1.0000R² adj: 1.0000MAPE: 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étrica | Rango | Mejor valor | Unidades |
|---|---|---|---|
| MAE | [0, inf) | 0 | Igual a y |
| MSE | [0, inf) | 0 | Cuadrado de y |
| RMSE | [0, inf) | 0 | Igual a y |
| R² | (-inf, 1] | 1 | Adimensional |
| R² Ajustado | (-inf, 1] | 1 | Adimensional |
| MAPE | [0, inf) | 0% | Porcentaje |