Lección 16 de 16 · Nivel 4: Experto

Machine learning con Python: tu primer modelo con scikit-learn

  • ⏱ 10 min de lectura
  • ❓ 3 preguntas de repaso
  • ✍️ Ejercicio con solución
En esta lección
  1. Qué problemas resuelve
  2. El caso: predecir las ventas diarias de una cafetería
  3. Paso 1: separar datos de entrenamiento y de prueba
  4. Paso 2: entrenar el modelo
  5. Paso 3: evaluar
  6. Paso 4: interpretar y predecir
  7. Sobreajuste: cuando el modelo memoriza
  8. Resumen
  9. Resumen del curso
Lo que lograrás en esta lección
  • Entender qué es el machine learning y qué tipo de problemas resuelve.
  • Entrenar un modelo de regresión con scikit-learn para predecir ventas.
  • Evaluarlo correctamente con datos de prueba, el MAE y el R², y compararlo con una línea base.
  • Reconocer el sobreajuste y saber cuál es el siguiente paso en tu aprendizaje.

El machine learning (aprendizaje automático) es la rama de la inteligencia artificial en la que un programa aprende patrones a partir de ejemplos, en lugar de seguir reglas escritas a mano. Detrás de las recomendaciones de una tienda en línea, la detección de fraude con tarjetas o la previsión de la demanda de un supermercado hay modelos como el que vas a entrenar hoy. En esta última lección del curso juntarás todo: pandas, funciones y buenas prácticas, con una biblioteca nueva, scikit-learn.

Qué problemas resuelve

TipoQué prediceEjemplos
RegresiónUn númeroVentas de mañana, precio de una vivienda, tiempo de entrega
ClasificaciónUna categoría¿Este cliente se dará de baja?, ¿este correo es spam?, ¿esta transacción es fraude?
Agrupamiento (no supervisado)Grupos parecidos, sin etiquetas previasSegmentos de clientes según su forma de comprar

En los dos primeros, el modelo aprende de ejemplos en los que ya conoces la respuesta (ventas pasadas, clientes que ya se fueron). Por eso se llaman problemas supervisados.

El caso: predecir las ventas diarias de una cafetería

pip install scikit-learn pandas

Para que obtengas exactamente los mismos números, generaremos un año de datos con una semilla fija. Las ventas dependen de la temperatura, de si es fin de semana y de si hubo promoción, más una parte aleatoria (como en la vida real):

import numpy as np
import pandas as pd

rng = np.random.default_rng(42)
fechas = pd.date_range("2025-01-01", periods=365, freq="D")
df = pd.DataFrame({
    "fecha": fechas,
    "temperatura": rng.uniform(12, 30, 365).round(1),
    "fin_de_semana": (fechas.dayofweek >= 5).astype(int),
    "promocion": rng.integers(0, 2, 365),
})
df["ventas"] = (200 + 8 * df["temperatura"] + 120 * df["fin_de_semana"]
                + 90 * df["promocion"] + rng.normal(0, 40, 365)).round()
print(df.head())
       fecha  temperatura  fin_de_semana  promocion  ventas
0 2025-01-01         25.9              0          1   502.0
1 2025-01-02         19.9              0          0   370.0
2 2025-01-03         27.5              0          1   573.0
3 2025-01-04         24.6              1          1   592.0
4 2025-01-05         13.7              1          0   392.0

En un proyecto real, cargarías tus datos desde un CSV o una base de datos (lecciones 11 y 13). Las columnas que usas para predecir se llaman variables o features (X), y lo que quieres predecir es el objetivo (y).

Paso 1: separar datos de entrenamiento y de prueba

La regla más importante del machine learning: nunca evalúes un modelo con los mismos datos con los que aprendió. Sería como tomar un examen con las preguntas que ya estudiaste de memoria. Se separa una parte de los datos que el modelo no verá hasta el final:

from sklearn.model_selection import train_test_split

X = df[["temperatura", "fin_de_semana", "promocion"]]
y = df["ventas"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
print(len(X_train), len(X_test))
292 73

El 80% de los días sirve para entrenar y el 20% para comprobar. random_state fija el reparto para que el resultado sea reproducible.

Paso 2: entrenar el modelo

En scikit-learn todos los modelos funcionan igual: se crean, se entrenan con fit y predicen con predict. Empezamos por el más sencillo e interpretable, la regresión lineal:

from sklearn.linear_model import LinearRegression

modelo = LinearRegression()
modelo.fit(X_train, y_train)          # aprende de los ejemplos
pred = modelo.predict(X_test)         # predice los días que no vio

Paso 3: evaluar

from sklearn.metrics import mean_absolute_error, r2_score

print("MAE:", round(mean_absolute_error(y_test, pred), 1))
print("R²:", round(r2_score(y_test, pred), 3))

# Línea base: predecir siempre el promedio
base = np.full(len(y_test), y_train.mean())
print("MAE base:", round(mean_absolute_error(y_test, base), 1))
MAE: 25.6
R²: 0.846
MAE base: 68.0
  • MAE (error absoluto medio): en promedio, el modelo se equivoca en unas 26 ventas por día. Se mide en las mismas unidades que lo que predices, por eso es fácil de explicar a cualquiera.
  • R²: qué parte de la variación de las ventas explica el modelo. 1 sería perfecto; 0, no mejor que el promedio. Aquí, un 84,6%.
  • Línea base: si predijeras siempre el promedio, te equivocarías en 68 ventas por día. El modelo reduce el error en más de la mitad. Sin línea base, no sabrías si un MAE de 25,6 es bueno o malo.

1. ¿Por qué se evalúa el modelo con X_test y no con X_train?

  • Porque X_test tiene más filas.
  • Porque hay que medir cómo predice datos que no vio al entrenar, que es lo que pasará en la realidad.
  • Porque scikit-learn no permite predecir con datos de entrenamiento.

Un modelo puede memorizar los datos de entrenamiento. Solo los datos de prueba, que no vio, muestran si aprendió un patrón útil.

Paso 4: interpretar y predecir

print("Intercepto:", round(modelo.intercept_, 1))
for col, coef in zip(X.columns, modelo.coef_):
    print(f"{col:<15}{coef:>8.1f}")

nuevo = pd.DataFrame({"temperatura": [27], "fin_de_semana": [1], "promocion": [1]})
print("Predicción:", round(modelo.predict(nuevo)[0]))
Intercepto: 196.5
temperatura         7.9
fin_de_semana     121.2
promocion          92.5
Predicción: 625

La regresión lineal se lee como una receta: cada grado más de temperatura suma unas 8 ventas, un fin de semana suma 121 y una promoción, 92. Fíjate que el modelo recuperó casi exactamente los valores con los que generamos los datos (8, 120 y 90) sin conocerlos: los aprendió de los ejemplos. Con datos reales no sabrás la verdad, pero los coeficientes te dirán qué factores pesan más, información valiosa para el negocio: ¿cuánto rinde de verdad una promoción?

2. Según el modelo, ¿cuántas ventas más se esperan un día con promoción respecto a uno igual sin promoción?

  • 7,9
  • Unas 92
  • 625

El coeficiente de promocion (92,5) es el efecto de pasar de 0 a 1 en esa variable, con las demás iguales.

Sobreajuste: cuando el modelo memoriza

Probemos un modelo más potente, un bosque aleatorio (random forest), que combina cientos de árboles de decisión:

from sklearn.ensemble import RandomForestRegressor

bosque = RandomForestRegressor(n_estimators=200, random_state=42)
bosque.fit(X_train, y_train)

print("Entrenamiento:", round(mean_absolute_error(y_train, bosque.predict(X_train)), 1))
print("Prueba:       ", round(mean_absolute_error(y_test, bosque.predict(X_test)), 1))
Entrenamiento: 17.5
Prueba:        34.6

El bosque acierta mucho en los datos que ya vio (17,5) y bastante peor en los nuevos (34,6), peor incluso que la regresión lineal (25,6). Eso es sobreajuste: aprendió también el ruido de los datos de entrenamiento. Moraleja: un modelo más complejo no es automáticamente mejor. Empieza siempre por el más simple, compara en los datos de prueba y quédate con el que generaliza mejor.

Cuidado con las conclusiones
  • Un modelo aprende de los datos del pasado: si las condiciones cambian (nuevo competidor, otra temporada), sus predicciones pueden fallar. Revísalo periódicamente.
  • Correlación no es causalidad: que dos cosas suban juntas no significa que una cause la otra.
  • Si los datos tienen sesgos (por ejemplo, solicitudes de crédito decididas con criterios injustos), el modelo los aprenderá y los repetirá.

3. Un modelo tiene un error de 5 en entrenamiento y de 60 en prueba. ¿Qué indica?

  • Que es excelente, porque el error de entrenamiento es muy bajo.
  • Que está sobreajustado: memorizó los datos de entrenamiento y no generaliza.
  • Que hay que usar los datos de prueba para entrenar.

Una gran diferencia entre el error de entrenamiento y el de prueba es la señal típica del sobreajuste. Un modelo más simple o más datos suelen ayudar.

Ejercicio práctico: ¿qué variables importan?

  1. Entrena una regresión lineal usando solo la temperatura y calcula su MAE y su R² en los datos de prueba. Compáralos con el modelo de tres variables.
  2. Con el modelo de tres variables, predice las ventas de un día laborable de 22 grados con promoción.
  3. Escribe una función evaluar(modelo, columnas) que entrene y devuelva el MAE de prueba, para comparar modelos con una sola línea.
Ver solución
m1 = LinearRegression().fit(X_train[["temperatura"]], y_train)
p1 = m1.predict(X_test[["temperatura"]])
print(round(mean_absolute_error(y_test, p1), 1), round(r2_score(y_test, p1), 3))
# 58.0 0.304  → mucho peor que con tres variables (25.6 y 0.846)

dia = pd.DataFrame({"temperatura": [22], "fin_de_semana": [0], "promocion": [1]})
print(round(modelo.predict(dia)[0]))
# 464

def evaluar(modelo, columnas):
    modelo.fit(X_train[columnas], y_train)
    return round(mean_absolute_error(y_test, modelo.predict(X_test[columnas])), 1)

print(evaluar(LinearRegression(), ["temperatura"]))                          # 58.0
print(evaluar(LinearRegression(), ["temperatura", "fin_de_semana", "promocion"]))  # 25.6

Con solo la temperatura, el modelo no puede distinguir fines de semana ni promociones, y su error se acerca al de la línea base. Elegir buenas variables suele mejorar un modelo mucho más que elegir un algoritmo sofisticado.

Resumen

  • El machine learning aprende patrones de ejemplos: regresión para números, clasificación para categorías.
  • Separa siempre entrenamiento y prueba, y evalúa solo con datos que el modelo no vio.
  • En scikit-learn todo modelo se usa igual: fit, predict y una métrica como MAE o R².
  • Compara con una línea base y empieza por modelos simples e interpretables.
  • Una gran diferencia entre el error de entrenamiento y el de prueba indica sobreajuste.

Resumen del curso

  • Nivel 1, básico: instalación, variables, cadenas de texto y condicionales.
  • Nivel 2, intermedio: bucles, estructuras de datos, funciones, archivos y manejo de errores.
  • Nivel 3, avanzado: clases, módulos y entornos, pandas, APIs y automatización.
  • Nivel 4, experto: bases de datos con SQL, gráficos con matplotlib, web scraping y machine learning.

¡Felicidades, terminaste el curso de Python! Ya puedes construir programas que guardan datos en una base, los analizan, los grafican, los obtienen de la web y hasta aprenden de ellos. Marca las lecciones como completadas para descargar tu certificado. Para seguir: profundiza en ciencia de datos con más modelos de scikit-learn, en desarrollo web con FastAPI o Django, o aprende a usar modelos de lenguaje desde Python en el curso de inteligencia artificial.

¡Llegaste al final del curso!

Esta es la última de las 16 lecciones de Curso de Python desde cero (gratis y en español). Si las recorriste todas, eso es constancia de verdad.

🎓 Guarda tu avance y obtén tu certificado gratis

Crea tu cuenta en 30 segundos, marca tus lecciones y descarga el certificado al terminar.

Inscribirme gratis