Juan Diego Andrés PRADA··RAMÍREZ Entrar
Lección 2 de 7

Fundamentos de Machine Learning

Antes de empezar: entorno y dependencias. Trabajaremos siempre dentro de un entorno virtual aislado para no contaminar tu Python del sistema.

python3 -m venv .venv # crea el entorno
source .venv/bin/activate # actívalo (Windows: .venv\Scripts\activate)
pip install --upgrade pip
pip install torch torchvision scikit-learn pandas

Verifica que PyTorch quedó instalado:

import torch
print(torch.__version__) # algo como 2.x.x

Cada vez que abras una terminal nueva para este curso, recuerda volver a ejecutar source .venv/bin/activate.

¿Qué es?

Machine Learning (ML) es enseñarle a un programa a aprender una función a partir de datos en lugar de escribir nosotros las reglas a mano. No le decimos "si las horas de estudio son > 5, aprueba"; le mostramos cientos de ejemplos (estudiantes y si aprobaron) y el algoritmo ajusta sus propios parámetros para que sus predicciones se parezcan a las respuestas reales.

¿Cómo funciona?

Todo aprendizaje supervisado tiene tres ingredientes:

  1. Datos: pares (X, y). X son las features (entradas) y y son las labels (lo que queremos predecir). Cada fila es un ejemplo.
  2. Un modelo con parámetros que transforma X en una predicción ŷ.
  3. Una medida de error (la loss) que compara ŷ con y. El entrenamiento es, literalmente, buscar los parámetros que minimizan esa loss.

Hay dos tipos de problema según cómo sea y:

  • Clasificación: y es categórico (¿aprueba o reprueba? ¿gato o perro?).
  • Regresión: y es numérico continuo (¿qué nota saca? ¿cuánto cuesta?).

¿Para qué sirve?

Para predecir lo que aún no ha pasado a partir de patrones del pasado: riesgo de deserción, precios, diagnósticos, recomendaciones, reconocimiento de imágenes. En este curso lo usaremos para un objetivo concreto.

La pieza del proyecto que construimos aquí

El proyecto final es "Entrena un modelo útil". Tomaremos el camino de riesgo académico con datos tabulares: predecir si un estudiante está en riesgo de reprobar. En este módulo construimos la base del proyecto: generar/cargar los datos, separarlos correctamente en train y test, y dejarlos listos como tensores.

Paso 1: los datos

import numpy as np
import pandas as pd

# Datos sintéticos: ¿el estudiante reprueba? (1 = en riesgo, 0 = a salvo)
rng = np.random.default_rng(42)
n = 800
horas_estudio = rng.uniform(0, 10, n)
asistencia = rng.uniform(0, 1, n)
ruido = rng.normal(0, 1.0, n)

# Regla "real" oculta que el modelo deberá descubrir
puntaje = 0.6 * horas_estudio + 4.0 * asistencia + ruido
en_riesgo = (puntaje < 3.5).astype(int) # baja nota -> riesgo

df = pd.DataFrame({
 "horas_estudio": horas_estudio,
 "asistencia": asistencia,
 "en_riesgo": en_riesgo,
})
print(df.head())
print("Proporción en riesgo:", df["en_riesgo"].mean().round(2))

Mira siempre la proporción de clases. Si el 95 % son de una sola clase, un modelo que "siempre dice no" acertaría el 95 % sin aprender nada.

Paso 2: separar train y test

from sklearn.model_selection import train_test_split

X = df[["horas_estudio", "asistencia"]].values
y = df["en_riesgo"].values

X_train, X_test, y_train, y_test = train_test_split(
 X, y, test_size=0.2, random_state=42, stratify=y
)
print(X_train.shape, X_test.shape) # (640, 2) (160, 2)

El error más caro del ML. Evaluar el modelo con los mismos datos con los que se entrenó. Memorizaría las respuestas y parecería perfecto, pero fallaría con datos nuevos: eso es sobreajuste (overfitting). El set de test solo se toca al final, para medir.

Paso 3: escalar y convertir a tensores

import torch
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler().fit(X_train) # se ajusta SOLO con train
X_train_s = scaler.transform(X_train)
X_test_s = scaler.transform(X_test) # al test se le aplica, no se reajusta

X_train_t = torch.tensor(X_train_s, dtype=torch.float32)
y_train_t = torch.tensor(y_train, dtype=torch.float32).unsqueeze(1)
X_test_t = torch.tensor(X_test_s, dtype=torch.float32)
y_test_t = torch.tensor(y_test, dtype=torch.float32).unsqueeze(1)

print(X_train_t.shape, y_train_t.shape) # torch.Size([640, 2]) torch.Size([640, 1])

Ajustar el StandardScaler con todo el dataset (train + test) es fuga de datos (data leakage): el modelo "ve" información del test durante el preprocesado. Ajusta siempre solo con train.

Tech English: features (entradas), labels (etiquetas), training/test split (separación), overfitting (sobreajuste), data leakage (fuga de datos), baseline (modelo de referencia mínimo).

Ejercicios

  1. Lee el baseline. Calcula qué accuracy obtendría un modelo trivial que siempre predice la clase mayoritaria (y_train más frecuente). Anótalo: es la barra mínima que tu futuro modelo deberá superar. ¿Por qué un accuracy alto no significa nada sin este número?
  2. Rompe la regla a propósito. Vuelve a entrenar el StandardScaler usando X completo (train + test) en lugar de solo X_train. Compara las medias de X_test_s en ambos casos. Explica con tus palabras por qué la diferencia, aunque pequeña, es trampa.
Tu progreso se guarda en este navegador. Inicia sesión para guardarlo en tu cuenta y verlo desde cualquier dispositivo.