Capitulo 00
Fundamentos para Machine Learning
Python, SQL y formulacion de problemas: antes del modelo viene la pregunta correcta
Repaso integrado de Python, SQL y definicion de problemas de datos para llegar a Machine Learning con bases solidas.
Machine Learning no comienza con fit(). Comienza cuando puedes describir el problema, localizar los datos, entender su estructura y definir como sabras si una solucion funciona. Este modulo conecta esas cuatro decisiones.
0.1 El mapa de trabajo
Un proyecto de datos recorre este camino:
Pregunta de negocio
↓
Problema de datos medible
↓
Datos extraidos y entendidos
↓
Datos limpios y preparados
↓
Modelo o analisis
↓
Decision, medicion y mejora
Si saltas directamente al modelo, no sabes si estas resolviendo el problema correcto. Por eso este repaso tiene tres bloques:
- Python: manipular valores, estructuras y logica.
- SQL: consultar el dato donde vive.
- Definicion del problema: convertir una necesidad ambigua en una pregunta testeable.
💡 Piensa en la decision que el negocio necesita tomar.
Como estudiar este mapa
No intentes memorizar los nombres como una lista aislada. Para cada paso responde tres preguntas:
| Pregunta | Ejemplo |
|---|---|
| ¿Que entrada recibe? | Una tabla de ventas sin transformar. |
| ¿Que transformacion realiza? | Filtrar, validar o crear una feature. |
| ¿Que salida entrega? | Un dataset listo para analizar o entrenar. |
Esta forma de pensar convierte una herramienta en una pieza de un sistema. Python no es solamente sintaxis, SQL no es solamente consultas y Machine Learning no es solamente elegir un algoritmo.
Pipeline de datos
M0Secuencia reproducible de pasos que extrae, transforma, valida y entrega datos a un analisis o modelo.
Ej: CSV o base de datos → limpieza → features → entrenamiento → metrica.
0.2 Python: los atomos del analisis
Variables y tipos
Una variable es un nombre que referencia un valor. Python tiene tipado dinamico: el interprete infiere el tipo a partir del valor asignado.
producto = "Auriculares Bluetooth" # str: texto
precio = 2499.99 # float: decimal
stock = 35 # int: entero
disponible = True # bool: verdadero o falso
print(f"{producto} | ${precio:.2f} | stock: {stock} | disponible: {disponible}")
El formato :.2f muestra dos decimales. El valor no cambia: cambia su presentacion.
Tipo de dato y decision de negocio
El tipo tecnico importa porque limita las operaciones validas y cambia la interpretacion del dato:
cantidad = "35" # str: parece un numero, pero concatena como texto
cantidad_real = int(cantidad)
precio = float("19.90")
print(cantidad + " unidades") # 35 unidades
print(cantidad_real * 2) # 70
print(precio * cantidad_real) # 696.5
En un dataset real, una columna puede llegar como texto aunque represente numeros. Antes de modelar debes distinguir:
- Tipo almacenado: como llega el valor (
str,int,float). - Tipo semantico: que significa (
precio,cantidad,fecha,categoria). - Regla de validacion: que valores son aceptables (precio no negativo, cantidad entera positiva).
int("35") funciona, pero int("35 unidades") falla. Convertir tipos es una transformacion, no una reparacion magica. Primero registra los valores invalidos y decide si deben corregirse, excluirse o enviarse a una cola de calidad.
f-string
M0Cadena formateada que permite insertar variables y expresiones dentro de llaves.
Ej: f"Promedio: {promedio:.2f}"
Estructuras de datos
| Estructura | Ordenada | Mutable | Uso frecuente |
|---|---|---|---|
list | Sí | Sí | Secuencias de valores. |
tuple | Sí | No | Coordenadas o valores que no deben cambiar. |
dict | Por inserción | Sí | Registros clave-valor, JSON y configuraciones. |
set | No garantizado | Sí | Valores únicos y pertenencia. |
precios = [150.2, 151.0, 149.5]
cliente = {"id": 101, "nombre": "Ana", "compras": [15.5, 20.0]}
posicion = (10.450, -66.900)
categorias = set(["Ropa", "Hogar", "Ropa"])
print(precios[0])
print(cliente.get("nombre"))
print(categorias)
La lista se indexa desde cero. El diccionario se consulta por clave. .get() evita que una clave ausente rompa el programa con KeyError.
Condicionales, bucles y funciones
score = 0.85
if score > 0.9:
print("Modelo excelente")
elif score > 0.7:
print("Modelo aceptable")
else:
print("Reentrenar modelo")
Un for repite una accion sobre cada elemento:
precios = [100, 200, 300]
precios_con_descuento = []
for precio in precios:
precios_con_descuento.append(precio * 0.9)
print(precios_con_descuento)
Una funcion encapsula una responsabilidad. El caso borde debe resolverse antes de la logica principal:
def resumen_estadistico(valores):
"""Devuelve suma, promedio y cantidad de una lista numerica."""
if not valores:
return {"suma": 0, "promedio": 0, "cantidad": 0}
suma = sum(valores)
cantidad = len(valores)
return {
"suma": suma,
"promedio": suma / cantidad,
"cantidad": cantidad,
}
print(resumen_estadistico([1200, 1500, 1100]))
La formula del promedio es:
promedio = suma de valores / cantidad de valores
La guard clause evita dividir por cero cuando valores esta vacia.
Una funcion de datos debe tener contrato
Una funcion reutilizable se entiende por su contrato:
Entrada valida → transformacion → salida esperada
↓
error explicito si no se cumple
En resumen_estadistico:
- La entrada esperada es una coleccion numerica.
- La salida es un diccionario con tres claves conocidas.
- Una lista vacia tiene un resultado definido.
- Un dato de tipo incorrecto debe producir un error visible, no un numero silenciosamente incorrecto.
Esta disciplina prepara el camino para funciones de limpieza, transformadores de scikit-learn y pipelines reproducibles.
0.3 SQL: consultar antes de modelar
Modelo relacional
Una tabla representa una entidad, cada fila es un registro y cada columna es un atributo.
ventas_tecnologia
├── id_venta ← identificador
├── producto ← atributo descriptivo
├── categoria ← puede ser NULL
├── precio_unitario ← medida numerica
├── cantidad ← medida numerica
├── fecha ← dimension temporal
└── pais ← dimension geografica
NULL significa desconocido o ausente. No es cero ni una cadena vacia.
Consulta y filtro
SELECT
producto,
precio_unitario
FROM ventas_tecnologia
WHERE pais = 'Colombia'
AND precio_unitario > 500
ORDER BY precio_unitario DESC;
La consulta se lee como una pregunta: selecciona estas columnas, desde esta tabla, donde se cumplen estas condiciones y ordena el resultado.
Para nulos se usa IS NULL:
SELECT producto, pais
FROM ventas_tecnologia
WHERE categoria IS NULL;
Agregacion y orden de ejecucion
SELECT
categoria,
SUM(precio_unitario * cantidad) AS ingresos_totales,
COUNT(*) AS numero_ventas
FROM ventas_tecnologia
GROUP BY categoria
HAVING SUM(precio_unitario * cantidad) > 10000
ORDER BY ingresos_totales DESC;
| Etapa logica | Funcion |
|---|---|
FROM | Localiza la tabla. |
WHERE | Filtra filas individuales. |
GROUP BY | Construye grupos. |
HAVING | Filtra grupos agregados. |
SELECT | Proyecta columnas y aliases. |
ORDER BY | Ordena el resultado final. |
WHERE se aplica antes de agrupar. HAVING se aplica despues de agrupar. Si la condicion usa SUM, COUNT o AVG, normalmente necesitas HAVING.
NULL y la logica de tres valores
SQL no trabaja solo con TRUE y FALSE. Una comparacion con NULL produce UNKNOWN:
-- No encuentra los nulos: NULL = NULL no es TRUE
SELECT * FROM ventas_tecnologia
WHERE categoria = NULL;
-- Forma correcta
SELECT * FROM ventas_tecnologia
WHERE categoria IS NULL;
La consecuencia practica es importante: una fila con NULL puede no pasar un filtro aunque parezca que la condicion deberia ser cierta. Por eso el tratamiento de faltantes debe ser una decision explicita del pipeline.
Pregunta, query y evidencia
Una consulta profesional deja trazable la relacion entre negocio y resultado:
Pregunta: ¿Que categorias superan $10,000 de ingresos?
Query: GROUP BY categoria + HAVING SUM(...) > 10000
Evidencia: tabla resultante + fecha de ejecucion + fuente de datos
Decision: priorizar inventario de Laptops y Smartphones
Sin esa cadena, una tabla puede ser correcta sintacticamente y aun asi no servir para decidir.
Una consulta correcta no es la que devuelve filas: es la que responde una pregunta verificable.
— Principio de trabajo en datos
0.4 Definir problemas de datos
Pregunta de negocio vs pregunta de datos
| Nivel | Ejemplo |
|---|---|
| Pregunta de negocio | ¿Como reducimos las cancelaciones de clientes? |
| Pregunta de datos | ¿Podemos estimar la probabilidad de cancelacion en los proximos 30 dias usando el historial del cliente? |
| Resultado operativo | Priorizar clientes para una accion de retencion. |
Un problem statement correcto debe especificar:
- Contexto y decision que se quiere mejorar.
- Variable objetivo o
target. - Unidad de observacion: cliente, venta, sesion o producto.
- Horizonte temporal.
- Features disponibles y datos faltantes.
- Metrica de modelo y metrica de negocio.
- Restricciones tecnicas, legales y eticas.
Target
M0Variable objetivo que el modelo intenta predecir. Debe tener una definicion operativa, una unidad de observacion y un horizonte temporal.
Ej: cancelara_en_30_dias = True o False para cada cliente activo al cierre del mes.
Elegir el tipo de problema
| Pregunta | Tipo |
|---|---|
| ¿El cliente cancelara? | Clasificacion binaria. |
| ¿Cuanto venderemos? | Regresion. |
| ¿Que grupos naturales existen? | Clustering. |
| ¿Que comportamiento se aparta de lo normal? | Deteccion de anomalias. |
| ¿Que valor esperamos la proxima semana? | Serie temporal. |
No se elige un algoritmo por moda. Primero se define la decision, luego el target y finalmente la tecnica adecuada.
Metricas
Clasificacion:
precision = TP / (TP + FP)
recall = TP / (TP + FN)
F1 = 2 * precision * recall / (precision + recall)
Regresion:
MAE = promedio(|valor_real - prediccion|)
RMSE = raiz(promedio((valor_real - prediccion)^2))
Si perder un caso real es costoso, prioriza recall. Si una falsa alarma es costosa, prioriza precision. La metrica se decide antes de entrenar para no mover el objetivo despues de ver el resultado.
Baseline antes del modelo
Un baseline es una solucion sencilla que establece el punto de comparacion. Ejemplos:
- Clasificacion: predecir siempre la clase mas frecuente.
- Regresion: predecir siempre la mediana del target.
- Forecasting: usar el valor del periodo anterior.
Si un modelo sofisticado no supera el baseline con una metrica de negocio relevante, su complejidad no esta justificada.
Definicion SMART del problema
Una pregunta util debe ser:
| Criterio | Aplicacion |
|---|---|
| Especifica | Define cliente, producto o evento. |
| Medible | Tiene target y metrica. |
| Alcanzable | Los datos existen y tienen suficiente calidad. |
| Relevante | Cambia una decision concreta. |
| Temporal | Declara horizonte y fecha de corte. |
Ejemplo debil: “Quiero predecir ventas”.
Ejemplo operativo: “Estimar las unidades vendidas por categoria para los proximos 30 dias, usando ventas historicas cerradas al ultimo dia del mes, y evaluar MAE contra el baseline de la mediana mensual.”
0.5 Mini-proyecto integrador
Objetivo
Usar el dataset ventas_tecnologia para pasar de una pregunta a una respuesta reproducible.
Entregables
- Un
README.mdcon el contexto de negocio. - Un notebook que cargue los datos y ejecute consultas SQL.
- Una funcion Python que valide valores faltantes y tipos.
- Una tabla de ingresos por categoria.
- Un problem statement con target, features, horizonte y metricas.
import pandas as pd
ventas = pd.read_csv("ventas_tecnologia.csv")
reporte_calidad = {
"filas": len(ventas),
"columnas": list(ventas.columns),
"nulos_por_columna": ventas.isna().sum().to_dict(),
}
print(reporte_calidad)
La salida no es todavia un modelo. Es evidencia de que entiendes el dato con el que eventualmente trabajaras.
- Explica por que una lista vacia rompe el promedio.
- Explica por que
HAVINGes necesario para filtrar ingresos agregados. - Define un target para predecir si una categoria superara $10,000 el proximo mes.
- Escribe una metrica de negocio que indique si la prediccion ayudo a decidir mejor.
Primero entiende el dato, despues escribe la transformacion, luego valida el resultado y recien entonces piensa en el modelo. El algoritmo no corrige una pregunta mal definida.
0.6 Preguntas de entrevista
Q: ¿Por que no empezarias entrenando un modelo?
Porque primero debo confirmar la decision, el target, la calidad de los datos, el horizonte y la metrica. Un modelo optimizado sobre una pregunta equivocada sigue siendo una mala solucion.
🪤 Responder solamente que hay que limpiar los datos, sin hablar del problema de negocio.Q: ¿Cuando usarias WHERE y cuando HAVING?
WHERE filtra filas antes de la agregacion; HAVING filtra grupos despues de GROUP BY. Una condicion sobre SUM o COUNT requiere HAVING.
🪤 Decir que HAVING es simplemente un segundo WHERE.💡 Busca palabras que no puedan medirse.