# machine-learning-clasico-con-python
Machine Learning con scikit-learn y XGBoost
Volver a la portada del cursoPreparación de un problema de ML
Sección 1 · Fundamentos: qué es ML y el flujo de scikit-learn
Preparación de un problema de ML
La mayoría de los proyectos de machine learning que fallan no fallan por el algoritmo: fallan antes, al plantear mal la pregunta. Un modelo responde con precisión justo lo que le preguntas, aunque no sea lo que necesitas. En esta lección preparas el problema de PyRitmo, una app de streaming de música ficticia con datos simulados, antes de entrenar nada en serio. El notebook preparacion-del-problema recorre cada paso con el resultado a la vista.
1. De la pregunta de negocio a un objetivo medible
El equipo de PyRitmo dice: «queremos saber qué canciones van a pegar». Eso todavía no es un problema de ML. Hay que convertirlo en una columna que el modelo pueda predecir y que alguien pueda comprobar después:
- Clasificación:
top50vale 1 si la canción entró al Top 50 en su primer mes y 0 si no. - Regresión:
popularidad, un número de 0 a 100 (media 48.39).
Las dos son medibles y las dos aparecerán en el curso. Para preparar el problema usarás top50. De las 1500 canciones, 412 entraron al Top 50: el 27.5 %. Esa cifra importa más de lo que parece, como verás en el paso 5.
2. La unidad de análisis: una fila, una canción
Antes de elegir columnas, decide qué representa cada fila. En PyRitmo cada fila es una canción, con sus rasgos de audio (energia, bailabilidad, acustica, tempo_bpm, duracion_seg), datos del artista (seguidores_miles) y del lanzamiento (colaboracion, explicita, en_playlist, genero). Si quisieras predecir por artista, la tabla sería otra: la pregunta define la fila.
3. Solo lo que se sabe ANTES de predecir
Esta es la regla que más modelos rompe. PyRitmo quiere la predicción antes de lanzar la canción, así que en X solo puede haber columnas disponibles en ese momento. La tabla trae reproducciones_mes1, las reproducciones del primer mes: un dato que se conoce después del lanzamiento. Usarla es una fuga de datos (data leakage): el modelo ve una pista de la respuesta que nunca tendrá en la vida real.
El notebook entrena la misma regresión logística con y sin esa columna y mide sobre el conjunto de prueba:
- Con fuga: accuracy 0.904 y AUC 0.96.
- Sin fuga: accuracy 0.811 y AUC 0.846.
El primer resultado se ve mejor, pero es falso: el día del lanzamiento esa columna no existe. No sorprende que sea la columna más correlacionada con top50 (0.581): la mediana de reproducciones es 1257.4 mil en las canciones que no entraron y 10368.0 mil en las que sí. Una regla práctica: si una columna parece demasiado buena, pregunta cuándo se conoce.
4. Elegir la métrica antes de ver resultados
La métrica traduce «funciona bien» a un número, y conviene fijarla antes de probar modelos para no escoger la que más te favorece. Por ahora basta con dos:
- Accuracy: proporción de aciertos. Fácil de explicar, pero engañosa cuando una clase domina.
- AUC: mide qué tan bien ordena el modelo las canciones por probabilidad de entrar al Top 50. Vale 0.5 si ordena al azar y 1.0 si ordena perfecto.
En la sección de clasificación verás precision, recall y la matriz de confusión, que ayudan a decidir cuál error sale más caro.
5. Partir en train y test con stratify
El modelo aprende con un conjunto (train) y se califica con otro que nunca vio (test). Así simulas canciones futuras. Con stratify=y ambos conjuntos conservan la misma proporción de éxitos:
from sklearn.model_selection import train_test_split
X = df[NUMERICAS + CATEGORICAS]
y = df["top50"]
X_tr, X_te, y_tr, y_te = train_test_split(
X, y, test_size=0.25, stratify=y, random_state=42)
print(X_tr.shape, X_te.shape)
print(round(y_tr.mean(), 3), round(y_te.mean(), 3))
Resultado: (1125, 10) (375, 10) y 0.275 0.275. Son 10 columnas: las 9 numéricas y genero. Ni top50, ni popularidad, ni reproducciones_mes1 están en X. El test tiene 103 canciones del Top 50 y 272 que no entraron. random_state=42 hace que la partición sea la misma cada vez que ejecutes.
6. Una línea base: el modelo tonto
¿0.811 es bueno? Depende de contra qué lo compares. DummyClassifier ignora las columnas y siempre predice la clase más frecuente:
from sklearn.dummy import DummyClassifier
dummy = DummyClassifier().fit(X_tr, y_tr)
print(dummy.score(X_te, y_te)) # 0.725
Dice «no entra» para las 375 canciones de test y acierta 272: 0.725 de accuracy sin aprender nada, con AUC de 0.5. Por eso el 27.5 % del paso 1 importa: con clases desbalanceadas, una accuracy alta puede no significar nada. Cualquier modelo de este curso tiene que superar esa línea base; la regresión logística sin fuga lo hace (0.811 contra 0.725).
Trampas comunes
- Columnas del futuro. Cualquier dato que se registra después del momento de predecir es fuga, aunque mejore las métricas.
- Partir sin
stratify. Con 27.5 % de positivos, un test con pocos éxitos puede dar cifras engañosas. - Mirar el test a cada rato. Si ajustas el modelo según el test, deja de ser una prueba independiente.
Checklist antes de entrenar
- La pregunta de negocio se volvió una columna objetivo medible.
- Sabes qué representa cada fila.
- Cada columna de
Xse conoce antes del momento de predecir. - Elegiste la métrica antes de comparar modelos.
- Partiste train y test con
stratifyy una semilla fija. - Tienes la cifra del modelo tonto para comparar.
Con estos seis puntos resueltos, el problema de PyRitmo queda listo para modelar.