Comparaciones métricas

# =============================================================
# COMPARACIÓN DE MÉTRICAS ENTRE DOS MODELOS
# =============================================================
# Este script compara las predicciones de dos modelos frente
# a los valores reales usando MSE, MAE y RMSE, y genera una
# gráfica para visualizar el ajuste de cada modelo.
# =============================================================

# Valores predichos por cada modelo para 4 observaciones
modelo1 = [20, 22, 23, 24]   # Modelo 1: predicciones más conservadoras
modelo2 = [21, 24, 26, 24]   # Modelo 2: predicciones más variables
real    = [21, 24, 20, 31]   # Valores reales que queremos acertar

# -------------------------------------------------------------
# MSE — Error Cuadrático Medio
# Eleva cada error al cuadrado antes de promediar, por lo que
# penaliza más los errores grandes. Unidades: valor² (ej: €²)
# -------------------------------------------------------------
from sklearn.metrics import mean_squared_error
mse1 = mean_squared_error(real, modelo1)  # MSE del modelo 1
mse2 = mean_squared_error(real, modelo2)  # MSE del modelo 2
print(f"MSE  → Modelo1: {mse1:.2f}  |  Modelo2: {mse2:.2f}")

# -------------------------------------------------------------
# MAE — Error Absoluto Medio
# Promedio de los errores en valor absoluto. No penaliza tanto
# los errores grandes; más robusto ante outliers. Unidades: las
# mismas que los datos originales.
# -------------------------------------------------------------
from sklearn.metrics import mean_absolute_error
mae1 = mean_absolute_error(real, modelo1)
mae2 = mean_absolute_error(real, modelo2)
print(f"MAE  → Modelo1: {mae1:.2f}  |  Modelo2: {mae2:.2f}")

# -------------------------------------------------------------
# RMSE — Raíz del Error Cuadrático Medio
# Es la raíz cuadrada del MSE. Devuelve el error en las mismas
# unidades que los datos originales, siendo más interpretable
# que el MSE pero manteniendo la penalización de errores grandes.
# -------------------------------------------------------------
from sklearn.metrics import root_mean_squared_error
rmse1 = root_mean_squared_error(real, modelo1)
rmse2 = root_mean_squared_error(real, modelo2)
print(f"RMSE → Modelo1: {rmse1:.2f}  |  Modelo2: {rmse2:.2f}")

# =============================================================
# GRÁFICA: Ajuste de los modelos a los datos reales
# =============================================================
import matplotlib.pyplot as plt
import numpy as np

# Eje X: índices de las 4 observaciones (puntos de tiempo o muestras)
x = np.arange(1, len(real) + 1)  # [1, 2, 3, 4]

fig, axes = plt.subplots(1, 2, figsize=(14, 5))
fig.suptitle("Ajuste de Modelos vs. Datos Reales", fontsize=15, fontweight="bold", y=1.01)

# ---- Colores ----
COLOR_REAL    = "#2C3E50"
COLOR_M1      = "#2980B9"
COLOR_M2      = "#E74C3C"
COLOR_ERROR1  = "#AED6F1"
COLOR_ERROR2  = "#F1948A"

# ----------------------------------------------------------
# Subgráfica izquierda: líneas de los tres conjuntos
# ----------------------------------------------------------
ax1 = axes[0]
ax1.plot(x, real,    "o-",  color=COLOR_REAL, linewidth=2.5, markersize=8,  label="Valores Reales",  zorder=3)
ax1.plot(x, modelo1, "s--", color=COLOR_M1,   linewidth=2,   markersize=7,  label=f"Modelo 1  (MSE={mse1:.1f})")
ax1.plot(x, modelo2, "^--", color=COLOR_M2,   linewidth=2,   markersize=7,  label=f"Modelo 2  (MSE={mse2:.1f})")

# Sombrear el área de error de cada modelo respecto a los reales
ax1.fill_between(x, real, modelo1, alpha=0.15, color=COLOR_M1, label="Error Modelo 1")
ax1.fill_between(x, real, modelo2, alpha=0.15, color=COLOR_M2, label="Error Modelo 2")

ax1.set_title("Líneas de ajuste y área de error", fontsize=12)
ax1.set_xlabel("Observación")
ax1.set_ylabel("Valor")
ax1.set_xticks(x)
ax1.set_xticklabels([f"Obs {i}" for i in x])
ax1.legend(fontsize=9)
ax1.grid(True, linestyle="--", alpha=0.5)
ax1.set_ylim(15, 36)

# ----------------------------------------------------------
# Subgráfica derecha: barras comparativas de métricas
# ----------------------------------------------------------
ax2 = axes[1]

metricas      = ["MSE", "MAE", "RMSE"]
valores_m1    = [mse1,  mae1,  rmse1]
valores_m2    = [mse2,  mae2,  rmse2]

ancho = 0.3
pos   = np.arange(len(metricas))

bars1 = ax2.bar(pos - ancho/2, valores_m1, width=ancho, color=COLOR_M1,
                label="Modelo 1", edgecolor="white", linewidth=0.8)
bars2 = ax2.bar(pos + ancho/2, valores_m2, width=ancho, color=COLOR_M2,
                label="Modelo 2", edgecolor="white", linewidth=0.8)

# Etiquetar el valor encima de cada barra
for bar in bars1:
    ax2.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.2,
             f"{bar.get_height():.2f}", ha="center", va="bottom", fontsize=9, color=COLOR_M1, fontweight="bold")
for bar in bars2:
    ax2.text(bar.get_x() + bar.get_width() / 2, bar.get_height() + 0.2,
             f"{bar.get_height():.2f}", ha="center", va="bottom", fontsize=9, color=COLOR_M2, fontweight="bold")

ax2.set_title("Comparativa de métricas de error", fontsize=12)
ax2.set_ylabel("Valor del error")
ax2.set_xticks(pos)
ax2.set_xticklabels(metricas, fontsize=11)
ax2.legend(fontsize=10)
ax2.grid(True, axis="y", linestyle="--", alpha=0.5)

plt.tight_layout()
plt.savefig("ajuste_modelos.png", dpi=150, bbox_inches="tight")
plt.show()
print("Gráfica guardada en ajuste_modelos.png")

Publicado por

Juan Pablo Fuentes

Formador de programación y bases de datos