W3docs

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:

SupuestoQué verificar
LinealidadLa relación entre las características y el objetivo es aproximadamente lineal
IndependenciaLas observaciones son independientes entre sí
HomocedasticidadLa varianza de los residuos es aproximadamente constante en todas las predicciones
Normalidad de los residuosLos residuos siguen una distribución aproximadamente normal
Sin multicolinealidadLas 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 price

Los 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_score

Paso 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ísticaDescripción
MedIncIngreso mediano del 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 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)}")    # 4128

El 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.0233

Lectura 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 con AveRooms (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.434 y Latitude = -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.5758

Interpretació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 y que 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
Was this page helpful?