DEV Community

Jesus Oviedo Riquelme
Jesus Oviedo Riquelme

Posted on

MLZC25-11. Regresión Lineal: El ABC del Machine Learning

🎯 Objetivo del Post: Dominarás la regresión lineal, el algoritmo más fundamental del Machine Learning, desde conceptos básicos hasta implementación práctica con código.

📈 ¿Qué es la Regresión Lineal?

Imagina que tienes un conjunto de puntos en una hoja de papel y quieres dibujar la línea recta que mejor los atraviese. Esa línea representa una relación entre dos variables. La regresión lineal hace exactamente eso, pero con matemáticas precisas y datos reales.

La regresión lineal es un método estadístico que:

  • 🎯 Encuentra la línea recta que mejor se ajusta a un conjunto de datos
  • 🔮 Permite predecir valores futuros basándose en esta relación
  • 🧮 Utiliza matemáticas simples pero poderosas
  • 🚀 Es la base de algoritmos más complejos

🚀 ¿Por qué Empezar con Regresión Lineal?

  1. 🧠 Simplicidad: Es fácil de entender e implementar (perfecto para principiantes)
  2. 💬 Interpretabilidad: Los resultados son fáciles de explicar a cualquier audiencia
  3. 🏗️ Base sólida: Muchos algoritmos avanzados se basan en estos conceptos
  4. 🎯 Efectividad: A menudo funciona mejor de lo esperado en problemas reales
  5. ⚡ Velocidad: Es computacionalmente eficiente (milisegundos vs. minutos)

Regresión Lineal Simple: Una Variable

El Concepto Básico

En regresión lineal simple, tenemos:

  • Variable independiente (X): La característica que usamos para predecir
  • Variable dependiente (y): Lo que queremos predecir
  • Relación lineal: y = mx + b

Para nuestro proyecto de autos:

  • X: Año del auto
  • y: Precio del auto
  • Relación: Precio = m × Año + b

La Ecuación de la Línea

y = mx + b
Enter fullscreen mode Exit fullscreen mode

Donde:

  • m: Pendiente (slope) - cuánto cambia y por cada unidad de x
  • b: Intercepto (intercept) - valor de y cuando x = 0
  • x: Variable independiente
  • y: Variable dependiente

Ejemplo Práctico

Si tenemos la ecuación: Precio = 1000 × Año + 5000

  • Un auto del 2020: Precio = 1000 × 2020 + 5000 = $2,025,000
  • Un auto del 2015: Precio = 1000 × 2015 + 5000 = $2,020,000
  • Un auto del 2010: Precio = 1000 × 2010 + 5000 = $2,015,000

Interpretación:

  • La pendiente (1000) significa que por cada año más nuevo, el precio aumenta $1,000
  • El intercepto (5000) sería el precio teórico de un auto del año 0 (no tiene sentido práctico)

Regresión Lineal Múltiple: Varias Variables

¿Por qué Necesitamos Múltiples Variables?

En la vida real, el precio de un auto no depende solo del año. También importan:

  • Kilometraje
  • Marca
  • Modelo
  • Tipo de transmisión
  • Estado del vehículo

La Ecuación Múltiple

y = b₀ + b₁x₁ + b₂x₂ + b₃x₃ + ... + bₙxₙ
Enter fullscreen mode Exit fullscreen mode

Para nuestro proyecto de autos:

Precio = b₀ + b₁×Año + b₂×Kilometraje + b₃×Edad + b₄×Marca_BMW + b₅×Marca_Toyota + ...
Enter fullscreen mode Exit fullscreen mode

Donde:

  • b₀: Intercepto (precio base)
  • b₁, b₂, b₃...: Coeficientes para cada variable
  • x₁, x₂, x₃...: Valores de cada característica

Forma Vectorial: Matemáticas Elegantes

¿Por qué Forma Vectorial?

La forma vectorial nos permite:

  1. Escribir ecuaciones de manera compacta
  2. Usar operaciones matriciales eficientes
  3. Implementar algoritmos de manera elegante
  4. Escalar a millones de datos

Representación Vectorial

En lugar de escribir:

y = b₀ + b₁x₁ + b₂x₂ + b₃x₃ + ... + bₙxₙ
Enter fullscreen mode Exit fullscreen mode

Escribimos:

y = Xw
Enter fullscreen mode Exit fullscreen mode

Donde:

  • X: Matriz de características (m × n)
  • w: Vector de pesos (n × 1)
  • y: Vector de predicciones (m × 1)

Ejemplo Concreto

Si tenemos 3 autos y 2 características (año, kilometraje):

X = [[2020, 25000],     # Auto 1: año 2020, 25,000 km
     [2019, 30000],     # Auto 2: año 2019, 30,000 km
     [2021, 20000]]     # Auto 3: año 2021, 20,000 km

w = [1000, -0.5]        # Pesos: año=1000, kilometraje=-0.5

y = Xw = [2020×1000 + 25000×(-0.5),   # = 2007500
          2019×1000 + 30000×(-0.5),   # = 2004000
          2021×1000 + 20000×(-0.5)]   # = 2011000
Enter fullscreen mode Exit fullscreen mode

Implementación Práctica

Paso 1: Preparar los Datos

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler

# Cargar datos
df = pd.read_csv('car_data_limpio.csv')

# Preparar características numéricas
features = ['año', 'kilometraje', 'edad_auto']
X = df[features]
y = df['precio']

print("Forma de X:", X.shape)
print("Forma de y:", y.shape)
print("\nPrimeras 5 filas de X:")
print(X.head())
Enter fullscreen mode Exit fullscreen mode

Paso 2: Implementación Manual de Regresión Lineal

class LinearRegressionManual:
    def __init__(self):
        self.weights = None
        self.bias = None

    def fit(self, X, y):
        """Entrenar el modelo usando la ecuación normal"""
        # Agregar columna de unos para el bias
        X_with_bias = np.column_stack([np.ones(X.shape[0]), X])

        # Calcular pesos usando ecuación normal: w = (X^T X)^-1 X^T y
        XtX = np.dot(X_with_bias.T, X_with_bias)
        XtX_inv = np.linalg.inv(XtX)
        Xty = np.dot(X_with_bias.T, y)

        weights_with_bias = np.dot(XtX_inv, Xty)

        # Separar bias y pesos
        self.bias = weights_with_bias[0]
        self.weights = weights_with_bias[1:]

        return self

    def predict(self, X):
        """Hacer predicciones"""
        return np.dot(X, self.weights) + self.bias

# Usar nuestro modelo manual
modelo_manual = LinearRegressionManual()
modelo_manual.fit(X, y)

print("Pesos aprendidos:")
for i, feature in enumerate(features):
    print(f"{feature}: {modelo_manual.weights[i]:.2f}")
print(f"Bias: {modelo_manual.bias:.2f}")
Enter fullscreen mode Exit fullscreen mode

Paso 3: Usando scikit-learn

# Usar la implementación de scikit-learn
modelo_sklearn = LinearRegression()
modelo_sklearn.fit(X, y)

print("Pesos de scikit-learn:")
for i, feature in enumerate(features):
    print(f"{feature}: {modelo_sklearn.coef_[i]:.2f}")
print(f"Intercepto: {modelo_sklearn.intercept_:.2f}")

# Verificar que son iguales
print(f"\n¿Son iguales? {np.allclose(modelo_manual.weights, modelo_sklearn.coef_)}")
Enter fullscreen mode Exit fullscreen mode

La Ecuación Normal: La Matemática Detrás

¿Qué es la Ecuación Normal?

La ecuación normal es una fórmula matemática que nos da la solución exacta para encontrar los mejores pesos en regresión lineal.

Fórmula: w = (X^T X)^(-1) X^T y

Donde:

  • X: Matriz de características
  • X^T: Transpuesta de X
  • y: Vector de valores objetivo
  • w: Vector de pesos óptimos

¿Por qué Funciona?

La ecuación normal encuentra los pesos que minimizan la suma de errores cuadrados:

SSE = Σ(y_i - ŷ_i)² = Σ(y_i - (w₀ + w₁x₁ + w₂x₂ + ...))²
Enter fullscreen mode Exit fullscreen mode

Ventajas y Desventajas

Ventajas:

  • Solución exacta: No necesita iteraciones
  • Matemáticamente elegante: Una sola fórmula
  • Determinística: Siempre da el mismo resultado

Desventajas:

  • Computacionalmente costosa: O(n³) para matrices grandes
  • Problemas numéricos: Con matrices mal condicionadas
  • No escalable: Para datasets muy grandes

Visualización de Resultados

Paso 1: Predicciones vs Valores Reales

import matplotlib.pyplot as plt

# Hacer predicciones
y_pred = modelo_sklearn.predict(X)

# Crear gráfico de dispersión
plt.figure(figsize=(10, 6))
plt.scatter(y, y_pred, alpha=0.5, color='blue')
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'r--', lw=2)
plt.xlabel('Precio Real ($)')
plt.ylabel('Precio Predicho ($)')
plt.title('Precio Real vs Predicho')
plt.grid(True, alpha=0.3)

# Calcular R²
from sklearn.metrics import r2_score
r2 = r2_score(y, y_pred)
plt.text(0.05, 0.95, f'R² = {r2:.3f}', transform=plt.gca().transAxes, 
         bbox=dict(boxstyle='round', facecolor='white', alpha=0.8))
plt.show()
Enter fullscreen mode Exit fullscreen mode

Paso 2: Residuos (Errores)

# Calcular residuos
residuos = y - y_pred

# Gráfico de residuos
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(y_pred, residuos, alpha=0.5, color='green')
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('Precio Predicho ($)')
plt.ylabel('Residuos ($)')
plt.title('Gráfico de Residuos')
plt.grid(True, alpha=0.3)

plt.subplot(1, 2, 2)
plt.hist(residuos, bins=30, alpha=0.7, color='orange')
plt.xlabel('Residuos ($)')
plt.ylabel('Frecuencia')
plt.title('Distribución de Residuos')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

Interpretación de Resultados

Coeficientes y su Significado

# Crear DataFrame con coeficientes
coef_df = pd.DataFrame({
    'Característica': features,
    'Coeficiente': modelo_sklearn.coef_,
    'Significado': [
        'Por cada año más nuevo, el precio aumenta $' + f'{modelo_sklearn.coef_[0]:,.0f}',
        'Por cada km adicional, el precio disminuye $' + f'{abs(modelo_sklearn.coef_[1]):.2f}',
        'Por cada año de edad, el precio disminuye $' + f'{abs(modelo_sklearn.coef_[2]):,.0f}'
    ]
})

print("Interpretación de Coeficientes:")
print(coef_df)
Enter fullscreen mode Exit fullscreen mode

Ejemplo de Predicción

# Ejemplo: Predecir precio de un auto específico
auto_ejemplo = {
    'año': 2020,
    'kilometraje': 25000,
    'edad_auto': 4
}

# Convertir a array
X_ejemplo = np.array([list(auto_ejemplo.values())])

# Hacer predicción
precio_predicho = modelo_sklearn.predict(X_ejemplo)[0]

print(f"\nEjemplo de Predicción:")
print(f"Auto: Año {auto_ejemplo['año']}, {auto_ejemplo['kilometraje']:,} km")
print(f"Precio predicho: ${precio_predicho:,.2f}")

# Mostrar contribución de cada característica
contribuciones = modelo_sklearn.coef_ * X_ejemplo[0]
print(f"\nContribuciones:")
for i, feature in enumerate(features):
    print(f"{feature}: ${contribuciones[i]:,.2f}")
print(f"Intercepto: ${modelo_sklearn.intercept_:,.2f}")
print(f"Total: ${modelo_sklearn.intercept_ + contribuciones.sum():,.2f}")
Enter fullscreen mode Exit fullscreen mode

Limitaciones de la Regresión Lineal

1. Asume Relación Lineal

  • No puede capturar relaciones no lineales
  • Ejemplo: La depreciación de autos no es lineal

2. Sensible a Outliers

  • Un auto muy caro puede sesgar toda la línea
  • Necesita detección y manejo de outliers

3. Multicolinealidad

  • Si dos características están muy correlacionadas, los coeficientes pueden ser inestables
  • Ejemplo: Año y edad del auto están perfectamente correlacionadas

4. No Maneja Variables Categóricas Directamente

  • Necesita codificación (one-hot encoding)
  • Ejemplo: Marca = ["Toyota", "BMW", "Honda"]

Mejores Prácticas

1. Verificar Supuestos

# Verificar linealidad
plt.figure(figsize=(15, 5))
for i, feature in enumerate(features):
    plt.subplot(1, 3, i+1)
    plt.scatter(X[feature], y, alpha=0.5)
    plt.xlabel(feature)
    plt.ylabel('Precio')
    plt.title(f'Precio vs {feature}')
plt.tight_layout()
plt.show()
Enter fullscreen mode Exit fullscreen mode

2. Normalizar Variables

# Normalizar características
scaler = StandardScaler()
X_normalizado = scaler.fit_transform(X)

# Entrenar modelo con datos normalizados
modelo_normalizado = LinearRegression()
modelo_normalizado.fit(X_normalizado, y)

print("Coeficientes normalizados:")
print(modelo_normalizado.coef_)
Enter fullscreen mode Exit fullscreen mode

3. Validación Cruzada

from sklearn.model_selection import cross_val_score

# Validación cruzada
scores = cross_val_score(modelo_sklearn, X, y, cv=5, scoring='r2')
print(f"R² promedio: {scores.mean():.3f} (+/- {scores.std() * 2:.3f})")
Enter fullscreen mode Exit fullscreen mode

Conclusión

La regresión lineal es el fundamento de muchos algoritmos de Machine Learning. Aunque simple, es poderosa y nos enseña conceptos importantes:

  • Interpretabilidad: Cada coeficiente tiene significado
  • Eficiencia: Rápida de entrenar y predecir
  • Base sólida: Para algoritmos más complejos

Puntos clave:

  • La forma vectorial hace el código más elegante
  • La ecuación normal da la solución exacta
  • Los coeficientes son interpretables
  • Siempre verifica los supuestos del modelo

En el siguiente post, exploraremos cómo evaluar qué tan bien funciona nuestro modelo usando métricas como RMSE y cómo crear un modelo baseline para comparar.


¿Has usado regresión lineal antes? ¿Qué variables crees que serían más importantes para predecir el precio de un auto?

Top comments (0)