Tres módulos preparando los datos de MercaFresh y por fin llega la recompensa: entrenar un modelo. Empezamos por la regresión lineal, el algoritmo supervisado más antiguo y más simple — y precisamente por eso el mejor lugar para entender, sin cajas negras, qué significa que una máquina aprenda. En esta lección construirás la intuición geométrica (una recta que atraviesa una nube de puntos), verás qué error minimiza y cómo lo minimiza (mínimos cuadrados y descenso de gradiente), aprenderás a leer los coeficientes como afirmaciones de negocio, y entrenarás tu primer modelo real: predecir el gasto mensual de los clientes de MercaFresh.

Contenido

  1. La intuición geométrica: la recta que mejor ajusta
  2. La ecuación: regresión simple y múltiple
  3. Mínimos cuadrados: qué significa "mejor ajuste"
  4. Descenso de gradiente: cómo se encuentra el mínimo
  5. Implementación con scikit-learn: gasto mensual en MercaFresh
  6. Interpretación de los coeficientes
  7. Supuestos del modelo en la práctica
  8. Limitaciones y cuándo desconfiar

La intuición geométrica: la recta que mejor ajusta

Imagina un gráfico de dispersión con los clientes de MercaFresh: en el eje X, sus pedidos por mes; en el eje Y, su gasto mensual en euros. La nube de puntos sube hacia la derecha — más pedidos, más gasto — pero no forma una línea perfecta: hay clientes de muchos pedidos pequeños y clientes de pocos pedidos enormes.

La regresión lineal responde a una pregunta muy concreta: de todas las rectas posibles que podrían atravesar esa nube, ¿cuál pasa "más cerca" de todos los puntos a la vez? Esa recta es el modelo. Una vez la tienes, predecir es trivial: para un cliente nuevo con 6 pedidos/mes, subes verticalmente desde x=6 hasta la recta y lees el gasto estimado.

Fíjate en que esto encaja exactamente con la definición de Mitchell del módulo 1:

  • Tarea T: predecir el gasto mensual de un cliente.
  • Experiencia E: los clientes históricos con su gasto conocido.
  • Medida P: cuánto se equivocan las predicciones (lo formalizamos en dos apartados).

"Aprender" es, literalmente, mover la recta hasta que la medida P sea lo mejor posible sobre la experiencia E.

La ecuación: regresión simple y múltiple

Regresión simple (una variable)

La recta de toda la vida:

$$\hat{y} = w_0 + w_1 x$$

Símbolo Nombre Lectura en MercaFresh
$\hat{y}$ Predicción Gasto mensual estimado (el sombrero indica "estimado", no real)
$x$ Feature Pedidos por mes del cliente
$w_1$ Pendiente (coeficiente) Euros adicionales de gasto por cada pedido mensual extra
$w_0$ Intercepto (sesgo) Gasto base estimado cuando x = 0

Los parámetros que el modelo aprende son solo dos números: $w_0$ y $w_1$. Nada más. Todo el "conocimiento" del modelo cabe en ellos.

Regresión múltiple (varias variables)

En la práctica nunca predices con una sola feature. El gasto de un cliente depende de sus pedidos, su recencia, su plan... La ecuación se generaliza sumando un término por feature:

$$\hat{y} = w_0 + w_1 x_1 + w_2 x_2 + \dots + w_n x_n$$

Geométricamente ya no es una recta sino un hiperplano: con 2 features es un plano en 3D; con las features del dataset de MercaFresh, un hiperplano en un espacio que no podemos dibujar pero que funciona con la misma lógica. Cada $w_i$ sigue siendo "cuánto cambia la predicción cuando $x_i$ sube una unidad, manteniendo el resto constante" — esa coletilla final será clave al interpretar.

Mínimos cuadrados: qué significa "mejor ajuste"

"La recta que pasa más cerca de todos los puntos" suena bien pero es ambiguo. Hay que definir cerca con una fórmula. La definición clásica:

  1. Para cada cliente $i$, calcula el residuo: $e_i = y_i - \hat{y}_i$ (gasto real menos gasto predicho). Es la distancia vertical del punto a la recta.
  2. Eleva cada residuo al cuadrado: $e_i^2$. Así los errores positivos y negativos no se cancelan, y los errores grandes pesan desproporcionadamente más (equivocarse por 20 € cuenta 4 veces más que equivocarse por 10 €).
  3. Promedia: eso es el error cuadrático medio (MSE), la función de coste.

$$MSE(w) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$

La recta de mínimos cuadrados es la que hace este número lo más pequeño posible. Ahora "aprender" tiene una definición operativa exacta: encontrar los valores de $w_0, \dots, w_n$ que minimizan el MSE sobre los datos de entrenamiento. En el módulo 6 (06-02) veremos el MSE y sus parientes como métricas de evaluación con detalle; aquí nos basta su papel como función de coste — el objetivo que el algoritmo persigue.

Un detalle que conviene saber: para la regresión lineal existe una fórmula cerrada (la "ecuación normal") que da los pesos óptimos de un plumazo, y es lo que scikit-learn usa por debajo. Pero merece la pena entender el método general, porque casi ningún otro modelo del curso tiene fórmula cerrada.

Descenso de gradiente: cómo se encuentra el mínimo

El descenso de gradiente es el método iterativo universal para minimizar funciones de coste, y reaparecerá en la regresión logística (04-02) y en las redes neuronales (04-07). La intuición:

Imagina el MSE como un paisaje: cada punto del terreno es una combinación de pesos $(w_0, w_1)$, y la altura en ese punto es el error que produce esa combinación. Para la regresión lineal, ese paisaje es un valle con forma de cuenco, con un único fondo. Estás en la ladera, con niebla, y quieres llegar abajo:

  1. Empieza en cualquier sitio: pesos aleatorios.
  2. Mira la pendiente bajo tus pies: el gradiente indica hacia dónde sube más el error.
  3. Da un paso en la dirección contraria, de tamaño proporcional a la tasa de aprendizaje (learning rate).
  4. Repite hasta que el terreno sea llano: has llegado al mínimo.
flowchart TD
    A["Pesos iniciales aleatorios<br/>w0, w1"] --> B["Calcular predicciones<br/>y el MSE actual"]
    B --> C["Calcular el gradiente:<br/>en que direccion crece el error"]
    C --> D["Actualizar pesos:<br/>paso en direccion contraria<br/>w = w - tasa * gradiente"]
    D --> E{"El error ya<br/>casi no baja?"}
    E -- "No" --> B
    E -- "Si" --> F["Pesos finales:<br/>modelo entrenado"]

La tasa de aprendizaje es el compromiso central: pasos demasiado pequeños tardan una eternidad; pasos demasiado grandes saltan de una ladera a la opuesta sin bajar nunca. Es el primer hiperparámetro que ves en el curso — un número que tú fijas antes de entrenar, no algo que el modelo aprende (su optimización sistemática llega en 07-05).

Implementación con scikit-learn: gasto mensual en MercaFresh

Objetivo de negocio: MercaFresh quiere estimar el gasto mensual futuro de cada cliente para dimensionar campañas y stock. Es una regresión: la etiqueta es un número continuo. Usamos features derivadas de la tabla RFM que construimos en 03-06:

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

rng = np.random.default_rng(42)
n = 500

# Simulamos la tabla de clientes de MercaFresh (features de 03-06)
clientes = pd.DataFrame({
    "pedidos_por_mes":   rng.gamma(3, 1.2, n).round(1),
    "gasto_medio_pedido": rng.gamma(9, 5, n).round(2),
    "recencia_dias":     rng.integers(1, 120, n),
    "antiguedad_meses":  rng.integers(3, 60, n),
})

# Gasto mensual real: pedidos x ticket, penalizado por inactividad, mas ruido
clientes["gasto_mensual"] = (
    clientes["pedidos_por_mes"] * clientes["gasto_medio_pedido"]
    - 0.8 * clientes["recencia_dias"]
    + rng.normal(0, 15, n)
).clip(lower=0).round(2)

X = clientes[["pedidos_por_mes", "gasto_medio_pedido",
              "recencia_dias", "antiguedad_meses"]]
y = clientes["gasto_mensual"]

# División train/test: entrenamos con el 80% y comprobamos con el 20%
# que el modelo nunca vio (el porqué en profundidad, en 06-01)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42)

modelo = LinearRegression()
modelo.fit(X_train, y_train)          # aqui ocurre el "aprendizaje"

predicciones = modelo.predict(X_test)
mse = mean_squared_error(y_test, predicciones)
print(f"MSE en test: {mse:.1f}")
print(f"Error tipico: ~{np.sqrt(mse):.1f} EUR")

Explicación paso a paso para quien entrena por primera vez:

  • train_test_split: aparta un 20% de clientes que el modelo no verá durante el entrenamiento, para medir el error sobre datos nuevos — la misma disciplina fit-en-train que aplicamos al escalado en 03-05. El módulo 6 desarrolla esta idea a fondo.
  • modelo.fit(X_train, y_train): la línea donde sucede todo. scikit-learn calcula los pesos que minimizan el MSE sobre el entrenamiento. Es la misma interfaz fit que usabas en SimpleImputer o StandardScaler: ajustar parámetros a partir de datos.
  • modelo.predict(X_test): aplica la ecuación $\hat{y} = w_0 + w_1 x_1 + \dots$ a cada cliente de test.
  • mean_squared_error: el MSE del apartado 3, ahora como juez. Su raíz cuadrada devuelve el error a euros, la unidad original: "nos equivocamos típicamente en unos 15 €".

Nota práctica que retoma 03-05: LinearRegression funciona sin escalar las features (la solución exacta no depende de la escala), pero si entrenaras con descenso de gradiente o añadieras regularización (07-01), escalar sería imprescindible. Escalar por defecto, como hace nuestro preprocesador del módulo 3, nunca estorba.

Interpretación de los coeficientes

La gran virtud de la regresión lineal es que el modelo entrenado se puede leer:

coefs = pd.Series(modelo.coef_, index=X.columns).round(3)
print(coefs)
print(f"Intercepto: {modelo.intercept_:.2f}")

Salida típica (tus números variarán ligeramente):

Feature Coeficiente Lectura de negocio
pedidos_por_mes +44.1 Cada pedido mensual adicional suma ~44 € de gasto estimado, a igualdad del resto
gasto_medio_pedido +3.6 Cada euro extra de ticket medio suma ~3.6 € al mes
recencia_dias −0.81 Cada día sin comprar resta ~0.81 € de gasto mensual esperado
antiguedad_meses ~0.0 La antigüedad apenas aporta una vez conocidas las demás

Tres advertencias de oficio:

  • "A igualdad del resto" no es una coletilla decorativa: el coeficiente de recencia_dias compara clientes con los mismos pedidos y ticket pero distinta recencia. Si las features están correlacionadas entre sí (y las de RFM lo están, como vimos en el heatmap de 02-03), los coeficientes individuales se vuelven inestables y hay que leerlos con cautela.
  • Las unidades importan: un coeficiente de 44 sobre "pedidos" y uno de 3.6 sobre "euros de ticket" no son comparables directamente — miden cosas en unidades distintas. Para comparar importancias, entrena sobre features estandarizadas (03-05).
  • Correlación no es causalidad (02-03): el modelo dice que recencia alta acompaña a gasto bajo, no que forzar una compra vaya a rejuvenecer al cliente.

Supuestos del modelo en la práctica

La regresión lineal asume cosas sobre los datos. No hace falta la formalidad estadística completa; sí saber comprobar las dos que más duelen en la práctica:

  • Linealidad: la relación real entre features y objetivo debe ser aproximadamente una suma de efectos lineales. Comprobación: gráfico de dispersión de cada feature contra el objetivo. Si ves una curva (rendimientos decrecientes del gasto con la frecuencia, por ejemplo), la recta se quedará corta — las transformaciones log de 03-03 o las interacciones de 03-06 pueden linealizar la relación.
  • Residuos sin estructura: los errores del modelo deberían parecer ruido — centrados en cero, sin patrón, con varianza estable. La comprobación es un gráfico de residuos contra predicciones:
import matplotlib.pyplot as plt

residuos = y_test - predicciones
plt.scatter(predicciones, residuos, alpha=0.5)
plt.axhline(0, color="red", linestyle="--")
plt.xlabel("Gasto predicho (EUR)")
plt.ylabel("Residuo (real - predicho)")
plt.show()

Cómo leerlo: una nube horizontal y amorfa alrededor de cero es buena señal. Una forma de U dice "hay no linealidad que no estoy capturando"; un embudo (residuos que crecen con la predicción) dice "predigo mucho peor a los clientes grandes" — el histograma y el boxplot de 02-01 aplicados a los residuos completan el diagnóstico.

Limitaciones y cuándo desconfiar

Limitación Por qué ocurre Mitigación
No captura relaciones no lineales El modelo es un hiperplano Transformar features (03-03), interacciones (03-06), o modelos no lineales (04-03 en adelante)
Sensible a outliers El cuadrado del residuo hace que un punto extremo tire de la recta con muchísima fuerza La limpieza de outliers de 03-01 antes de entrenar
Coeficientes inestables con features correlacionadas Varias features "compiten" por explicar lo mismo Filtro de correlación de 03-06; la regularización Ridge/Lasso (07-01) extiende la regresión lineal penalizando pesos grandes y estabiliza justo este problema
Extrapola alegremente La recta sigue recta fuera del rango de entrenamiento Desconfiar de predicciones para clientes muy distintos de los vistos

La primera limitación es la más importante conceptualmente: hay problemas donde ninguna recta funciona. El más notorio: predecir una categoría (¿este cliente abandonará, sí o no?). Ahí la regresión lineal fracasa por diseño — y ese fracaso es exactamente donde empieza la siguiente lección.

Errores Comunes y Consejos

  • Usar regresión lineal para clasificar (churn sí/no codificado como 0/1 y a correr). Produce predicciones absurdas como "probabilidad 1.4". La herramienta correcta llega en 04-02.
  • Interpretar coeficientes de features correlacionadas como verdades aisladas. Con pedidos_por_mes y gasto_total a la vez en el modelo, sus coeficientes se reparten el efecto de forma arbitraria. Revisa el heatmap de correlaciones (02-03) antes de leer coeficientes.
  • Olvidar mirar los residuos. Un MSE aceptable puede esconder un modelo que falla sistemáticamente en un segmento (por ejemplo, todos los clientes premium). El gráfico de residuos tarda tres líneas y lo revela.
  • Ajustar el modelo con outliers sin depurar. Un solo cliente corporativo con gasto de 10 000 €/mes desplaza la recta para todos. Retoma el tratamiento IQR/z-score de 03-01.
  • Consejo: empieza siempre por la regresión lineal aunque planees usar modelos complejos. Es la línea base: barata, interpretable, y si un modelo sofisticado no la supera claramente, no paga su complejidad.

Ejercicios

Ejercicio 1. Con el modelo entrenado en la lección, calcula a mano (sin predict) el gasto mensual estimado de un cliente con 4 pedidos/mes, ticket medio de 30 €, recencia de 10 días y 24 meses de antigüedad. Usa modelo.intercept_ y modelo.coef_. Comprueba después con modelo.predict.

Ejercicio 2. Añade al dataset una feature nueva, interaccion = pedidos_por_mes * gasto_medio_pedido (la interacción elegida a mano, como en 03-06), reentrena y compara el MSE en test. ¿Por qué esta interacción ayuda tanto en este dataset concreto?

Ejercicio 3. Introduce artificialmente un outlier: un cliente con gasto_mensual = 50000 en el conjunto de entrenamiento. Reentrena y compara los coeficientes con los originales. ¿Qué coeficiente cambia más y por qué?

Soluciones

Ejercicio 1

cliente = np.array([4, 30, 10, 24])
prediccion_manual = modelo.intercept_ + np.dot(modelo.coef_, cliente)
print(f"A mano: {prediccion_manual:.2f} EUR")

cliente_df = pd.DataFrame([[4, 30, 10, 24]], columns=X.columns)
print(f"Con predict: {modelo.predict(cliente_df)[0]:.2f} EUR")

Ambos valores coinciden exactamente: predict no hace nada más que la ecuación del hiperplano. Interiorizar esto desmitifica el modelo — toda la "inteligencia" son cinco números.

Ejercicio 2

X2 = X.copy()
X2["interaccion"] = X2["pedidos_por_mes"] * X2["gasto_medio_pedido"]
X2_train, X2_test, y_train, y_test = train_test_split(
    X2, y, test_size=0.2, random_state=42)

modelo2 = LinearRegression().fit(X2_train, y_train)
mse2 = mean_squared_error(y_test, modelo2.predict(X2_test))
print(f"MSE sin interaccion: {mse:.1f} | con interaccion: {mse2:.1f}")

El MSE cae drásticamente porque el gasto real se generó como pedidos × ticket: una relación multiplicativa que ningún hiperplano de features sueltas puede expresar, pero que se vuelve lineal en cuanto la interacción existe como columna. Moraleja: la ingeniería de características (03-06) puede convertir un problema no lineal en uno lineal.

Ejercicio 3

X_out, y_out = X_train.copy(), y_train.copy()
y_out.iloc[0] = 50000
modelo3 = LinearRegression().fit(X_out, y_out)
print(pd.DataFrame({"original": modelo.coef_, "con_outlier": modelo3.coef_},
                   index=X.columns).round(2))

Los coeficientes de las features donde ese cliente tiene valores altos se disparan: el residuo de 50 000 € al cuadrado domina la función de coste, y al modelo le compensa desajustar a los otros 399 clientes con tal de acercarse un poco a ese uno. Es la sensibilidad a outliers en acción — y el argumento definitivo para la limpieza de 03-01.

Conclusión

Ya has entrenado tu primer modelo de verdad: sabes que la regresión lineal busca el hiperplano que minimiza el MSE, que el descenso de gradiente es el método general para encontrar ese mínimo (y volverá una y otra vez en el curso), que los coeficientes se leen como afirmaciones de negocio — con las cautelas de la correlación entre features —, y que los residuos son el chivato de los supuestos rotos. También has visto sus límites: no linealidad, outliers, y sobre todo su incapacidad para responder preguntas de sí o no.

Y esa última limitación es la puerta de la siguiente lección: MercaFresh no solo quiere saber cuánto gastará un cliente, sino si va a abandonar. Para eso necesitamos doblar la recta en una curva en forma de S que hable el idioma de las probabilidades: la regresión logística.

Curso de Machine Learning

Módulo 1: Introducción al Machine Learning

Módulo 2: Fundamentos de Estadística y Probabilidad

Módulo 3: Preprocesamiento de Datos

Módulo 4: Algoritmos de Machine Learning Supervisado

Módulo 5: Algoritmos de Machine Learning No Supervisado

Módulo 6: Evaluación y Validación de Modelos

Módulo 7: Técnicas Avanzadas y Optimización

Módulo 8: Implementación y Despliegue de Modelos

Módulo 9: Proyectos Prácticos

Módulo 10: Recursos Adicionales

© Copyright 2026. Todos los derechos reservados