W3docs

Regresión Múltiple

Aprende cómo funciona la regresión lineal múltiple, interpreta coeficientes, gestiona la multicolinealidad y construye un modelo en Python con scikit-learn.

La regresión lineal múltiple extiende la regresión lineal simple para usar dos o más variables independientes con el fin de predecir un objetivo continuo. En lugar de trazar una línea en dos dimensiones, el modelo ajusta un hiperplano a través de tantas dimensiones como variables haya. Comprender cómo interactúan los coeficientes — y cuándo pueden inducir a error — es la habilidad fundamental que enseña esta página.

Esta página cubre:

  • La ecuación de regresión múltiple y qué significa cada coeficiente
  • Cómo construir un pipeline completo con scikit-learn: cargar, preprocesar, entrenar, evaluar
  • Por qué es importante el escalado de características y cómo hacerlo correctamente
  • Cómo interpretar y comparar coeficientes escalados frente a no escalados
  • Diagnóstico de multicolinealidad — el problema más frecuente en la regresión múltiple
  • Análisis de residuos para verificar los supuestos del modelo
  • Cuándo elegir la regresión múltiple y qué probar cuando no es suficiente

La Ecuación de Regresión Múltiple

La regresión lineal múltiple modela el objetivo y como una combinación lineal de n variables de entrada:

y = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ + ε
  • β₀ — la intersección: el valor predicho de y cuando todas las variables son cero
  • β₁ … βₙ — los coeficientes: cuánto cambia y ante un incremento de una unidad en cada xᵢ, manteniendo constantes las demás variables
  • ε — el término de error: la parte de y que el modelo no puede explicar

El algoritmo encuentra los coeficientes minimizando la suma de cuadrados de los residuos (mínimos cuadrados ordinarios):

SSR = Σ(yᵢ - ŷᵢ)²

Esto tiene una solución cerrada exacta, por lo que LinearRegression de scikit-learn no necesita descenso de gradiente iterativo — el entrenamiento es casi instantáneo incluso en conjuntos de datos con cientos de miles de filas.

Diferencia con la Regresión Lineal Simple

La regresión lineal simple usa una sola variable. La regresión múltiple agrega más variables para que cada coeficiente capture el efecto parcial de esa variable — su impacto en el objetivo mientras las demás se mantienen constantes. Esto es más potente pero introduce nuevos riesgos, especialmente la multicolinealidad (ver Diagnóstico de Multicolinealidad).

El Conjunto de Datos

Los ejemplos a continuación utilizan el conjunto de datos California Housing incluido en scikit-learn. Registra estadísticas de viviendas a nivel de bloque censal para California en 1990, con 20.640 muestras y 8 variables.

import pandas as pd
from sklearn.datasets import fetch_california_housing

housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing.target  # median house value in $100,000s

print(df.shape)      # (20640, 9)
print(df.head())

Las 8 variables de entrada son:

VariableDescripción
MedIncIngreso mediano en el bloque (en decenas de miles de dólares)
HouseAgeEdad mediana de las viviendas en el bloque
AveRoomsNúmero promedio de habitaciones por hogar
AveBedrmsNúmero promedio de dormitorios por hogar
PopulationPoblación del bloque
AveOccupOcupación promedio por hogar
LatitudeLatitud del bloque
LongitudeLongitud del bloque

El objetivo MedHouseVal es el valor mediano de las viviendas en unidades de $100.000, por lo que un valor de 2.0 representa $200.000.

Construcción del Modelo Paso a Paso

Paso 1 — Dividir los Datos

Siempre divide los datos antes de cualquier preprocesamiento. Ajustar un escalador con el conjunto de datos completo filtraría las estadísticas del conjunto de prueba al entrenamiento, dando una evaluación demasiado optimista. Consulta Train/Test Split para una explicación completa.

from sklearn.model_selection import train_test_split

X = df[housing.feature_names]
y = df['MedHouseVal']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

print(f"Training samples: {len(X_train)}")  # 16512
print(f"Test samples:     {len(X_test)}")   # 4128

Paso 2 — Escalar las Variables

Los coeficientes de la regresión múltiple reflejan las unidades de cada variable. MedInc se mide en decenas de miles de dólares; Population es un conteo absoluto que puede llegar a 35.000. Sin escalado, el coeficiente de Population será pequeño no porque la población sea poco importante, sino porque su unidad es pequeña.

StandardScaler transforma cada variable para tener media cero y desviación estándar unitaria, haciendo que las magnitudes de los coeficientes sean directamente comparables. Consulta Feature Scaling para más detalles sobre los escaladores disponibles.

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)   # fit ONLY on training data
X_test_scaled  = scaler.transform(X_test)         # apply the same transformation

La regla fundamental: usa fit_transform con los datos de entrenamiento y transform (sin ajuste) con los datos de prueba. Ajustar con los datos de prueba contaminaría la evaluación.

Paso 3 — Entrenar el Modelo

from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train_scaled, y_train)

LinearRegression.fit() resuelve el problema de OLS de forma analítica. No hay hiperparámetros que ajustar en la regresión múltiple estándar — lo que eliges es qué variables incluir.

Paso 4 — Evaluar el Modelo

import numpy as np
from sklearn.metrics import mean_squared_error, r2_score

y_pred = model.predict(X_test_scaled)

mse  = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2   = r2_score(y_test, y_pred)

print(f"Mean Squared Error:      {mse:.4f}")
print(f"Root Mean Squared Error: {rmse:.4f}  (±${rmse * 100_000:,.0f})")
print(f"R-squared:               {r2:.4f}")

Salida esperada:

Mean Squared Error:      0.5559
Root Mean Squared Error: 0.7456  (±$74,558)
R-squared:               0.5758

Qué significan las métricas:

  • MSE (Error Cuadrático Medio) — promedio de las diferencias al cuadrado entre predicciones y valores reales. Elevar al cuadrado penaliza los errores grandes más que los pequeños. Las unidades son el cuadrado del objetivo ($100.000s²), por lo que es difícil de interpretar directamente.
  • RMSE (Raíz del Error Cuadrático Medio) — la raíz cuadrada del MSE, en las mismas unidades que el objetivo. Un RMSE de 0,75 significa que las predicciones del modelo se desvían aproximadamente $75.000 en promedio.
  • R² (coeficiente de determinación) — la fracción de varianza en el objetivo que explica el modelo. Un R² de 0,58 significa que el modelo captura el 58% de la variación en los precios de las viviendas. Los valores van de 0 (no mejor que predecir la media) a 1 (predicciones perfectas). Un R² negativo es posible si el modelo es peor que la media — es una señal clara de que algo está mal.

Un R² de ~0,58 es típico para este conjunto de datos con regresión lineal estándar. La relación entre los precios de las viviendas y estas variables es parcialmente no lineal e implica agrupaciones geográficas que un hiperplano no puede capturar bien. Algoritmos como los árboles con gradient boosting alcanzan habitualmente 0,80 o más en este conjunto de datos.

Paso 5 — Inspeccionar los Coeficientes

Tras el escalado, las magnitudes de los coeficientes son directamente comparables — muestran qué variables influyen más fuertemente en la predicción:

coef_df = pd.DataFrame({
    'Feature':     housing.feature_names,
    'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)

print(coef_df.to_string(index=False))
print(f"\nIntercept: {model.intercept_:.4f}")

Salida esperada:

   Feature  Coefficient
  Latitude    -0.8969
 Longitude    -0.8698
    MedInc     0.8544
 AveBedrms     0.3393
  AveRooms    -0.2944
  HouseAge     0.1225
  AveOccup    -0.0408
Population    -0.0023

Intercept: 2.0719

Lectura de los coeficientes tras el escalado estándar:

  • MedInc = 0,854 — el predictor individual más potente. Un incremento de una desviación estándar en el ingreso mediano predice un aumento de $85.400 en el valor de la vivienda, manteniendo todo lo demás constante.
  • Latitude = -0,897 y Longitude = -0,869 — el modelo ha aprendido que los bloques censales más al norte y más al este tienden a ser más baratos. Sin embargo, estas dos variables geográficas están muy correlacionadas (r = -0,93), lo que puede hacer que sus coeficientes individuales sean inestables (ver Diagnóstico de Multicolinealidad).
  • AveBedrms = +0,339 frente a AveRooms = -0,294 — tienen signos opuestos aunque más habitaciones y más dormitorios generalmente implican casas más grandes y caras. Esta es una señal clásica de multicolinealidad: AveRooms y AveBedrms están correlacionadas (r = 0,85), por lo que sus coeficientes se compensan mutuamente. No los interpretes por separado.
  • Population = -0,002 — muy cercano a cero tras el escalado. La población del bloque tiene un poder predictivo mínimo una vez que se tienen en cuenta las demás variables.

La intersección (2,07) es el valor predicho de MedHouseVal cuando todas las variables escaladas son cero — es decir, cuando todas las variables están en su media del conjunto de entrenamiento. Es igual a la media de los objetivos de entrenamiento y no tiene un significado directo más allá de eso.

Paso 6 — Realizar Predicciones con Nuevos Datos

# A new census block: high income, older house, San Francisco Bay Area
new_block = pd.DataFrame([[8.0, 41.0, 6.0, 1.0, 322, 2.5, 37.88, -122.23]],
                         columns=housing.feature_names)

new_block_scaled = scaler.transform(new_block)
prediction = model.predict(new_block_scaled)

print(f"Predicted median house value: ${prediction[0] * 100_000:,.0f}")

Salida esperada:

Predicted median house value: $410,895

El escalador debe ser el mismo escalador ajustado con los datos de entrenamiento. Nunca vuelvas a ajustar el escalador con los nuevos datos — eso desplazaría las entradas respecto a lo que el modelo aprendió.

Diagnóstico de Multicolinealidad

La multicolinealidad ocurre cuando dos o más variables independientes están muy correlacionadas entre sí. No impide que el modelo haga predicciones precisas, pero hace que los coeficientes individuales sean poco fiables y difíciles de interpretar. Los coeficientes pueden volverse grandes, cambiar de signo o volverse estadísticamente insignificantes incluso para variables genuinamente importantes.

Verificación con una Matriz de Correlación

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

corr = df[housing.feature_names].corr()
print(corr.round(2))

Pares clave a considerar:

Par de variablesCorrelaciónPreocupación
AveRooms / AveBedrms0,85Alta — los coeficientes se compensan mutuamente
Latitude / Longitude-0,93Muy alta — movimiento geográfico conjunto
MedInc / MedHouseVal (objetivo)0,69Buen predictor, no es un problema de colinealidad

Una correlación superior a 0,80 entre dos variables es una señal de advertencia. Cuando la detectes, considera:

  1. Eliminar una de las variables correlacionadas. Si AveRooms y AveBedrms están ambas en el modelo, intenta eliminar AveBedrms y comprueba si el rendimiento predictivo cambia significativamente.
  2. Combinarlas. Crea una variable derivada (p. ej., rooms_per_bedroom = AveRooms / AveBedrms) que capture la relación sin redundancia.
  3. Usar un modelo regularizado. La regresión Ridge añade una penalización L2 que acerca los coeficientes correlacionados entre sí, estabilizándolos. Lasso (L1) puede eliminar completamente las variables redundantes.

Análisis de Residuos

Un residuo es la diferencia entre un valor real y la predicción del modelo: residual = y_actual - y_predicted. Graficar los residuos revela si los supuestos del modelo se cumplen.

residuals = y_test - y_pred

print(f"Mean of residuals: {residuals.mean():.4f}")  # should be close to 0
print(f"Std of residuals:  {residuals.std():.4f}")

Salida esperada:

Mean of residuals: 0.0035
Std of residuals:  0.7457

La media está cerca de cero — señal de que el modelo es imparcial en promedio. Pero la desviación estándar de 0,75 (±$75.000) muestra una dispersión considerable.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 4))

# Predicted vs Actual
axes[0].scatter(y_test, y_pred, alpha=0.2, s=8)
axes[0].plot([0, 5], [0, 5], 'r--')
axes[0].set_xlabel('Actual')
axes[0].set_ylabel('Predicted')
axes[0].set_title('Predicted vs Actual')

# Residuals vs Predicted
axes[1].scatter(y_pred, residuals, alpha=0.2, s=8)
axes[1].axhline(0, color='r', linestyle='--')
axes[1].set_xlabel('Predicted')
axes[1].set_ylabel('Residual')
axes[1].set_title('Residuals vs Predicted')

plt.tight_layout()
plt.savefig('residuals.png', dpi=120)
print("Saved residuals.png")

Qué buscar:

  • Predicho vs Real — idealmente, los puntos caen sobre la diagonal. Una desviación sistemática de la diagonal (una curva, o un aplanamiento en valores altos) indica que el supuesto lineal es incorrecto para parte del rango.
  • Residuos vs Predicho — idealmente, los residuos se dispersan aleatoriamente alrededor de cero en todos los niveles de predicción. Una forma de embudo (mayor dispersión en predicciones más altas) indica heterocedasticidad — el error del modelo no es constante, lo que puede hacer que las estimaciones de intervalos sean poco fiables.
  • Agrupaciones — grupos distintos en el gráfico de residuos pueden revelar que el conjunto de datos contiene subpoblaciones (p. ej., urbano vs rural) que justifican modelos separados o variables adicionales.

Pipeline Completo

A continuación se presenta todo lo anterior como un único script ejecutable:

import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score

# 1. Load data
housing = fetch_california_housing()
df = pd.DataFrame(housing.data, columns=housing.feature_names)
df['MedHouseVal'] = housing.target

# 2. Split — before any preprocessing
X = df[housing.feature_names]
y = df['MedHouseVal']
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 3. Scale
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled  = scaler.transform(X_test)

# 4. Train
model = LinearRegression()
model.fit(X_train_scaled, y_train)

# 5. Evaluate
y_pred = model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2   = r2_score(y_test, y_pred)
print(f"RMSE: {rmse:.4f}")
print(f"R²:   {r2:.4f}")

# 6. Coefficients (most important first)
coef_df = pd.DataFrame({
    'Feature':     housing.feature_names,
    'Coefficient': model.coef_
}).sort_values('Coefficient', key=abs, ascending=False)
print(coef_df.to_string(index=False))

Cuándo Usar la Regresión Múltiple

La regresión múltiple es una buena primera opción cuando:

  • La relación entre cada variable y el objetivo es aproximadamente lineal
  • La interpretabilidad importa — cada coeficiente tiene un significado claro
  • Quieres una línea base rápida antes de probar modelos más complejos
  • Tienes suficientes muestras en relación con el número de variables (una regla aproximada: al menos 10–20 observaciones por variable)

Considera alternativas cuando:

SituaciónAlternativa
Relaciones no lineales entre variables y objetivoPolynomial Regression
Muchas variables, riesgo de sobreajusteRidge o Lasso (modelos lineales regularizados)
El objetivo es una categoría, no un númeroLogistic Regression
Interacciones complejas y no linealidadÁrboles con gradient boosting o bosques aleatorios

Errores Comunes

Ajustar el escalador con todos los datos antes de dividir. Esto filtra la media y la varianza del conjunto de prueba al entrenamiento. Siempre divide primero, luego ajusta el escalador solo con la porción de entrenamiento.

Creer que agregar más variables siempre ayuda. Agregar variables irrelevantes o redundantes puede reducir la interpretabilidad, introducir multicolinealidad y perjudicar la generalización. Usa el conocimiento del dominio o una técnica de selección de variables para elegirlas deliberadamente.

Confiar en los coeficientes cuando las variables están correlacionadas. Cuando AveRooms y AveBedrms están ambas en el modelo, ninguno de los coeficientes refleja de forma fiable el efecto real de esa variable. Revisa la matriz de correlación antes de interpretar los coeficientes individuales.

Ignorar los gráficos de residuos. Un R² de 0,58 parece razonable en papel, pero los patrones de residuos pueden revelar que el modelo es sistemáticamente incorrecto para propiedades de alto valor o para regiones geográficas específicas.

Extrapolar más allá del rango de entrenamiento. Un modelo lineal entrenado en casas con precios entre $50.000 y $500.000 no debería usarse para predecir propiedades de $5.000.000. Verifica que las nuevas entradas estén dentro del rango observado durante el entrenamiento.

Próximos Pasos

  • Linear Regression — la base: la regresión simple (con una variable) y el método OLS explicados en detalle
  • Polynomial Regression — extiende el modelo lineal para capturar curvas añadiendo términos polinómicos
  • Feature Scaling — análisis profundo de StandardScaler, MinMaxScaler y RobustScaler
  • Train/Test Split — por qué la división correcta es fundamental y cómo hacerla sin filtrar datos
  • Cross-Validation — una alternativa más robusta a una única división entrenamiento/prueba
Was this page helpful?