Regresión Lineal
Aprende cómo funciona la regresión lineal, entiende las matemáticas detrás e implementa regresión simple y múltiple en Python con scikit-learn.
La regresión lineal es uno de los algoritmos más fundamentales en el aprendizaje automático. Modela la relación entre una variable dependiente (lo que deseas predecir) y una o más variables independientes (las entradas) ajustando una línea recta — o un hiperplano — a través de los datos.
Esta página cubre:
- Cómo funcionan matemáticamente la regresión lineal simple y múltiple
- El método de mínimos cuadrados ordinarios (OLS) para ajustar una línea
- Los supuestos clave que debes verificar antes de confiar en tu modelo
- Un recorrido completo con scikit-learn: cargar datos, entrenar, evaluar e interpretar resultados
- Cómo leer los coeficientes del modelo e identificar errores comunes
Cómo Funciona la Regresión Lineal
La Ecuación
La regresión lineal simple (una sola característica de entrada) ajusta esta línea:
y = β₀ + β₁x + εy— la variable dependiente (objetivo)x— la variable independiente (característica)β₀— la ordenada al origen (valor de y cuando x = 0)β₁— la pendiente (cambio en y por un incremento unitario en x)ε— el término de error (ruido que el modelo no puede explicar)
La regresión lineal múltiple extiende esto a n características:
y = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ + εCada coeficiente βᵢ indica cuánto cambia y cuando xᵢ aumenta en una unidad, manteniendo constantes todas las demás características.
Mínimos Cuadrados Ordinarios (OLS)
El modelo aprende los coeficientes minimizando la suma de residuos al cuadrado — la diferencia entre cada valor real yᵢ y la predicción del modelo ŷᵢ:
SSR = Σ(yᵢ - ŷᵢ)²Elevar al cuadrado los residuos penaliza más los errores grandes que los pequeños y garantiza que los errores positivos y negativos no se cancelen entre sí. Este criterio tiene una solución exacta en forma cerrada, razón por la cual la regresión lineal se entrena casi de forma instantánea incluso en grandes conjuntos de datos.
Supuestos Clave
La regresión lineal produce predicciones confiables solo cuando se cumplen estas condiciones:
| Supuesto | Qué verificar |
|---|---|
| Linealidad | La relación entre las características y el objetivo es aproximadamente lineal |
| Independencia | Las observaciones son independientes entre sí |
| Homocedasticidad | La varianza de los residuos es aproximadamente constante en todas las predicciones |
| Normalidad de los residuos | Los residuos siguen una distribución aproximadamente normal |
| Sin multicolinealidad | Las variables independientes no están altamente correlacionadas entre sí |
Cuando estos supuestos se violan, las estimaciones de los coeficientes pueden estar sesgadas o el modelo puede rendir mal con datos no vistos.
Ejemplo de Regresión Lineal Simple
Antes de pasar a múltiples características, veamos cómo el algoritmo ajusta una línea a una sola característica. Esto hace que la geometría sea fácil de visualizar.
import numpy as np
import matplotlib
matplotlib.use('Agg') # non-interactive backend for scripts
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# Simulate: house size (sq ft) vs price ($1000s)
rng = np.random.default_rng(42)
X_simple = rng.uniform(500, 3000, 50).reshape(-1, 1)
y_simple = 50 + 0.1 * X_simple.ravel() + rng.normal(0, 15, 50)
model = LinearRegression()
model.fit(X_simple, y_simple)
print(f"Intercept (β₀): {model.intercept_:.2f}")
print(f"Slope (β₁): {model.coef_[0]:.4f}")
print(f"Interpretation: each extra sq ft adds ${model.coef_[0]*1000:.0f} to the predicted price")Salida esperada:
Intercept (β₀): 46.17
Slope (β₁): 0.1007
Interpretation: each extra sq ft adds $101 to the predicted priceLos valores de la ordenada al origen y la pendiente son recuperados automáticamente por OLS — no necesitas hacer ninguna operación algebraica por tu cuenta.
Regresión Lineal Múltiple con scikit-learn
Los conjuntos de datos reales tienen muchas características. Esta sección recorre una canalización completa sobre el conjunto de datos California Housing, que registra estadísticas de vivienda a nivel de bloque censal para California en 1990.
Paso 1: Importar Librerías
import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_scorePaso 2: Cargar y Explorar el Conjunto de Datos
california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['MedHouseVal'] = california.target # median house value in $100,000s
print(df.shape) # (20640, 9)
print(df.head())
print(df.describe())El conjunto de datos tiene 20.640 filas y 8 características de entrada:
| Característica | Descripción |
|---|---|
MedInc | Ingreso mediano del bloque (en decenas de miles de dólares) |
HouseAge | Edad mediana de las viviendas en el bloque |
AveRooms | Número promedio de habitaciones por hogar |
AveBedrms | Número promedio de dormitorios por hogar |
Population | Población del bloque |
AveOccup | Ocupación promedio por hogar |
Latitude | Latitud del bloque |
Longitude | Longitud del bloque |
El objetivo MedHouseVal es el valor mediano de la vivienda en unidades de $100.000.
Paso 3: Elegir Características y Dividir los Datos
Para una demostración sencilla, usamos las 8 características. Consulta Train/Test Split para una explicación detallada de por qué dividimos los datos.
X = df[california.feature_names] # all 8 features
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)}") # 4128El random_state=42 garantiza divisiones reproducibles cada vez que ejecutes el script.
Paso 4: Entrenar el Modelo
model = LinearRegression()
model.fit(X_train, y_train)Eso es todo lo que se necesita. El método fit() resuelve el problema OLS analíticamente usando álgebra matricial — por defecto no hay descenso de gradiente iterativo involucrado.
Paso 5: Inspeccionar los Coeficientes Aprendidos
Entender lo que aprendió el modelo es tan importante como su precisión:
coef_df = pd.DataFrame({
'Feature': california.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 típica:
Feature Coefficient
AveBedrms 0.7831
MedInc 0.4487
Longitude -0.4337
Latitude -0.4198
AveRooms -0.1233
HouseAge 0.0097
AveOccup -0.0035
Population -0.0000
Intercept: -37.0233Lectura de los coeficientes:
AveBedrms = 0.783: un incremento unitario en el promedio de dormitorios predice un aumento de $78.300 en el valor de la vivienda — pero esto está entrelazado conAveRooms(están correlacionados). Cuando características correlacionadas están ambas presentes, los coeficientes individuales pueden volverse grandes, inestables o incluso contraintuitivos. Esto es multicolinealidad.MedInc = 0.449: un incremento unitario en el ingreso mediano (aproximadamente $10.000) predice un aumento de $44.900 en el valor de la vivienda, manteniendo todo lo demás constante.Longitude = -0.434yLatitude = -0.420: controles puramente geográficos; el modelo los usa para capturar efectos de ubicación aunque no puede modelar bien la geografía no lineal.
Paso 6: Evaluar el Modelo
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)
print(f"RMSE: {rmse:.4f} (in $100,000s, so ±${rmse*100_000:,.0f})")
print(f"R²: {r2:.4f}")Salida esperada:
RMSE: 0.7456 (in $100,000s, so ±$74,560)
R²: 0.5758Interpretación de las métricas:
- RMSE (Error Cuadrático Medio Raíz) — el error de predicción promedio en las mismas unidades que el objetivo. Menor es mejor.
- R² (coeficiente de determinación) — la proporción de varianza en
yque el modelo explica. Un R² de 0.58 significa que el modelo explica aproximadamente el 58% de la varianza en los precios de las viviendas. Los valores más cercanos a 1.0 son mejores; los valores cercanos a 0 significan que el modelo apenas supera la predicción de la media.
Un R² de ~0.58 es típico para este conjunto de datos con regresión lineal. La relación entre los precios de las viviendas y estas características es en parte no lineal, razón por la cual métodos como la regresión polinomial o el gradient boosting suelen obtener puntuaciones más altas.
Paso 7: Visualizar Valores Predichos vs. Reales
El gráfico diagnóstico más claro para un modelo de regresión es el de predichos vs. reales — funciona independientemente de cuántas características tengas:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.figure(figsize=(7, 5))
plt.scatter(y_test, y_pred, alpha=0.3, s=10, color='steelblue')
plt.plot([y_test.min(), y_test.max()],
[y_test.min(), y_test.max()],
'r--', linewidth=1.5, label='Perfect prediction')
plt.xlabel('Actual Median House Value ($100,000s)')
plt.ylabel('Predicted Median House Value ($100,000s)')
plt.title('Linear Regression: Predicted vs Actual')
plt.legend()
plt.tight_layout()
plt.savefig('lr_predicted_vs_actual.png', dpi=120)
print("Plot saved.")Los puntos que caen sobre la línea roja discontinua son predicciones perfectas. La dispersión alrededor de la línea muestra el error. Una forma de abanico (mayor dispersión en valores más altos) indica heterocedasticidad — uno de los supuestos clave está siendo violado.
Canalización Completa (Todos los Pasos Juntos)
import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
# Load data
california = fetch_california_housing()
df = pd.DataFrame(california.data, columns=california.feature_names)
df['MedHouseVal'] = california.target
# Split
X = df[california.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)
# Train
model = LinearRegression()
model.fit(X_train, y_train)
# Evaluate
y_pred = model.predict(X_test)
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}")Cuándo Usar la Regresión Lineal
La regresión lineal es una buena primera opción cuando:
- La relación entre las entradas y la salida es aproximadamente lineal
- La interpretabilidad importa — necesitas explicar las predicciones a las partes interesadas
- El conjunto de datos es pequeño o mediano y la velocidad de entrenamiento es importante
- Quieres una línea base rápida antes de probar modelos más complejos
Considera alternativas cuando:
- Las características y el objetivo tienen relaciones fuertemente no lineales → prueba la regresión polinomial o los árboles de decisión
- Tienes muchas características que pueden ser irrelevantes → las variantes regularizadas (Ridge, Lasso) previenen el sobreajuste reduciendo los coeficientes
- El objetivo es una categoría, no un número → usa la regresión logística en su lugar
Errores Comunes
Olvidar escalar las características. Los coeficientes de la regresión lineal reflejan las unidades de cada característica. Si una característica está en miles y otra en fracciones, los tamaños brutos de los coeficientes no son comparables. Usa StandardScaler antes de comparar importancias de características. Consulta Feature Scaling para más detalles.
Multicolinealidad. Las características altamente correlacionadas hacen que los coeficientes individuales sean poco confiables — incluso pueden cambiar de signo. Verifica la matriz de correlación con df.corr() y elimina o combina las características correlacionadas.
Extrapolación. Un modelo lineal entrenado con datos en un cierto rango puede dar predicciones completamente erróneas fuera de ese rango. Verifica siempre que las nuevas entradas estén dentro de la distribución de entrenamiento.
Ignorar los gráficos de residuos. Siempre grafica los residuos después de ajustar el modelo. Los patrones en los residuos (curvas, abanicos, grupos de valores atípicos) indican que los supuestos del modelo están siendo violados y las predicciones no deben confiarse sin una investigación adicional.
Próximos Pasos
Una vez que tengas una línea base de regresión lineal funcionando, explora estos temas relacionados:
- Multiple Regression — profundización en el uso de múltiples características e interpretación de cada coeficiente
- Polynomial Regression — ajusta curvas en lugar de líneas agregando términos de características polinomiales
- Train/Test Split — entiende por qué y cómo evaluar correctamente el rendimiento del modelo
- Feature Scaling — estandariza las entradas para que los coeficientes y los solucionadores basados en gradiente funcionen correctamente
- Logistic Regression — predice categorías (sí/no, spam/no spam) en lugar de valores continuos