En la lección anterior dibujamos el histograma de los importes de pedido de MercaFresh y hablamos de su "forma": una masa central y una cola a la derecha. Las distribuciones de probabilidad son los modelos matemáticos de esas formas: describen cómo se reparten los valores que puede tomar una variable aleatoria. Entenderlas es imprescindible en Machine Learning porque muchos algoritmos asumen que los datos siguen ciertas distribuciones, y porque comparar los datos reales con una distribución esperada es la base de la detección de anomalías. En esta lección conocerás las distribuciones discretas y continuas más importantes, estudiarás la normal en profundidad y aprenderás a generarlas y visualizarlas con NumPy y scipy.
Contenido
- Variable aleatoria y función de probabilidad
- Distribuciones discretas: Bernoulli, binomial y Poisson
- Distribuciones continuas: uniforme, normal y exponencial
- La distribución normal en detalle: regla 68-95-99.7 y z-scores
- Por qué importan las distribuciones en Machine Learning
- Generación y visualización con NumPy y scipy
Variable aleatoria y función de probabilidad
Una variable aleatoria es una variable cuyo valor depende del azar: no sabemos qué valdrá en la próxima observación, pero sí podemos describir con qué probabilidad tomará cada valor posible.
Ejemplos en MercaFresh:
- X = "¿el próximo cliente abandona el carrito?" → toma valores 0 o 1.
- Y = "número de pedidos que llegarán en la próxima hora" → 0, 1, 2, 3...
- Z = "importe del próximo pedido" → cualquier valor real positivo.
La forma de describir esas probabilidades depende del tipo de variable (¿recuerdas la clasificación de 02-01?):
| Variable discreta | Variable continua | |
|---|---|---|
| Función | Función de masa de probabilidad (PMF): P(X = k) | Función de densidad de probabilidad (PDF): f(x) |
| Interpretación | Probabilidad exacta de cada valor | Densidad; la probabilidad es el área bajo la curva en un intervalo |
| P(X = valor exacto) | Puede ser > 0 | Siempre 0 (un punto no tiene área) |
| Suma/integral total | Σ P(X=k) = 1 | ∫ f(x) dx = 1 |
Un matiz que confunde al principio: para una variable continua, la pregunta "¿cuál es la probabilidad de que el pedido valga exactamente 50,00 €?" tiene respuesta 0. Lo que sí tiene respuesta es "¿cuál es la probabilidad de que valga entre 45 y 55 €?": el área bajo la curva de densidad en ese intervalo. Para calcular áreas acumuladas se usa la función de distribución acumulada (CDF): F(x) = P(X ≤ x), que scipy nos da hecha.
Distribuciones discretas: Bernoulli, binomial y Poisson
Bernoulli: un experimento de sí/no
Modela un único ensayo con dos resultados: éxito (1) con probabilidad p, fracaso (0) con probabilidad 1−p.
- MercaFresh: "un cliente concreto hace churn este mes" con p = 0,08.
- Es el ladrillo básico: la binomial y muchos modelos de clasificación (como la regresión logística del módulo 4) se construyen sobre ella.
Binomial: contar éxitos en n ensayos
Si repetimos n ensayos Bernoulli independientes con la misma p, el número total de éxitos sigue una binomial B(n, p).
- MercaFresh: de 500 clientes con p = 0,08 de churn cada uno, ¿cuántos harán churn este mes? → B(500, 0,08), con media n·p = 40 clientes.
from scipy import stats
# ¿Probabilidad de que hagan churn exactamente 40 de 500 clientes?
print(stats.binom.pmf(k=40, n=500, p=0.08).round(4)) # 0.0657
# ¿Probabilidad de que hagan churn 50 o más? (1 - P(X <= 49))
print(1 - stats.binom.cdf(k=49, n=500, p=0.08)) # ~0.064stats.binom.pmf(k, n, p)devuelve P(X = k): la probabilidad de exactamente k éxitos.stats.binom.cdf(k, n, p)devuelve P(X ≤ k); restarla de 1 da la probabilidad de la cola superior. Este patrón1 - cdfse usa constantemente.
Lectura de negocio: aunque "lo esperado" son 40 bajas, hay más de un 6 % de meses en los que habrá 50 o más solo por azar. Saber cuánta variación es normal evita alarmas injustificadas.
Poisson: contar eventos por unidad de tiempo
Modela el número de eventos en un intervalo fijo cuando ocurren de forma independiente a un ritmo medio λ (lambda).
- MercaFresh: si llegan de media λ = 12 pedidos por hora, ¿qué probabilidad hay de recibir 20 o más en una hora (y saturar el reparto)?
| Distribución | Modela | Parámetros | Ejemplo MercaFresh |
|---|---|---|---|
| Bernoulli | Un ensayo sí/no | p | ¿Este cliente hace churn? |
| Binomial | Nº de éxitos en n ensayos | n, p | Bajas entre 500 clientes |
| Poisson | Nº de eventos por intervalo | λ | Pedidos por hora |
Regla mnemotécnica: Bernoulli = una moneda, binomial = n monedas, Poisson = "cuántas veces suena el timbre en una hora".
Distribuciones continuas: uniforme, normal y exponencial
Uniforme
Todos los valores de un intervalo [a, b] son igual de probables; su densidad es una meseta plana. Aparece poco en datos reales, pero es la base de la simulación (los generadores aleatorios producen uniformes y de ahí derivan todo lo demás) y un modelo honesto de "no sé nada dentro de este rango".
Normal (gaussiana)
La campana simétrica definida por su media μ (centro) y su desviación estándar σ (anchura). Es la reina de las distribuciones por el teorema central del límite (adelanto: sumas y medias de muchos efectos pequeños e independientes tienden a ser normales; lo demostraremos con una simulación en la lección 02-04). Por eso tantas magnitudes agregadas —errores de medición, medias de muestras— tienen forma de campana.
- MercaFresh: el tiempo de preparación de un pedido en almacén ronda una normal con μ = 18 min y σ = 4 min.
Exponencial
Modela el tiempo entre eventos de un proceso de Poisson. Si llegan λ = 12 pedidos/hora, el tiempo entre dos pedidos consecutivos sigue una exponencial con media 1/λ = 5 minutos. Es asimétrica con cola derecha y "sin memoria": la probabilidad de esperar 5 minutos más no depende de cuánto llevas esperando.
# Si llegan 12 pedidos/hora, ¿probabilidad de estar más de 15 min sin pedidos?
scale = 60 / 12 # media: 5 minutos entre pedidos
print(1 - stats.expon.cdf(15, scale=scale)) # ~0.05Fíjate en la pareja Poisson/exponencial: cuentan lo mismo desde dos ángulos (cuántos eventos por intervalo vs. cuánto tiempo entre eventos).
| Distribución | Forma | Parámetros | Ejemplo MercaFresh |
|---|---|---|---|
| Uniforme | Meseta plana | a, b | Simulaciones; descuento aleatorio entre 5 y 15 % |
| Normal | Campana simétrica | μ, σ | Tiempo de preparación en almacén |
| Exponencial | Decae desde 0, cola derecha | λ (o su inversa, la media) | Minutos entre pedidos consecutivos |
La distribución normal en detalle
La regla 68-95-99.7
Si X sigue una normal con media μ y desviación estándar σ:
- El 68,3 % de los valores cae en μ ± 1σ.
- El 95,4 % cae en μ ± 2σ.
- El 99,7 % cae en μ ± 3σ.
Para el tiempo de preparación de MercaFresh (μ = 18, σ = 4):
- 68 % de los pedidos se preparan entre 14 y 22 minutos.
- 95 % entre 10 y 26 minutos.
- 99,7 % entre 6 y 30 minutos. Un pedido que tarda 35 minutos en prepararse está a más de 4σ: algo raro ha pasado.
Z-scores: medir en "número de desviaciones estándar"
El z-score de un valor x es:
z = (x − μ) / σ
Responde a: ¿a cuántas desviaciones estándar de la media está este valor? Es una regla universal de "rareza" que no depende de las unidades:
import numpy as np
mu, sigma = 18, 4
x = 31 # un pedido tardó 31 min en prepararse
z = (x - mu) / sigma
print(z) # 3.25 -> muy atípico
# ¿Qué proporción de pedidos tarda más de 31 min?
print(1 - stats.norm.cdf(x, loc=mu, scale=sigma)) # ~0.0006- Un |z| < 2 es terreno normal; |z| > 3 es un candidato serio a anomalía.
stats.norm.cdf(x, loc=mu, scale=sigma)da P(X ≤ x) para la normal de medialocy desviaciónscale; su complemento dice que solo un 0,06 % de pedidos tardaría tanto por puro azar.
Aquí usamos el z-score como detector de rarezas. En el módulo 3 (lección 03-05) reaparecerá con otro papel: estandarizar variables como paso de preprocesamiento para los modelos. Misma fórmula, propósito distinto.
Por qué importan las distribuciones en Machine Learning
- Supuestos de los modelos. Varios algoritmos funcionan mejor (o solo tienen garantías) bajo ciertas distribuciones: la regresión lineal (04-01) asume errores normales, Naive Bayes gaussiano (04-06) asume normalidad por clase, K-means (05-01) rinde mejor con grupos "redondos" de tipo gaussiano. Conocer la distribución real de tus datos te dice si esos supuestos son razonables.
- Detección de anomalías. El planteamiento clásico es: modela la distribución de lo normal y marca como anómalo lo que sea muy improbable bajo ella. Para MercaFresh: si los importes de pedido de un cliente siguen aproximadamente una distribución conocida, un pedido con probabilidad bajísima (z-score enorme, cola de la Poisson, etc.) merece revisión antes de aceptarse: puede ser un error o un fraude.
- Datos sintéticos y simulación. Generar datos con distribuciones controladas (como hicimos en 02-01) permite probar pipelines y modelos antes de tener datos reales.
- Colas y transformaciones. Reconocer una cola derecha (importes, tiempos) anticipa que quizá convenga transformar la variable (p. ej., con logaritmos), técnica que se desarrolla en la lección 03-03.
Generación y visualización con NumPy y scipy
División del trabajo entre librerías:
- NumPy (
np.random.default_rng()): generar muestras aleatorias. - scipy.stats: calcular PMF/PDF, CDF, cuantiles y ajustar distribuciones.
- matplotlib: visualizar y comparar muestra vs. curva teórica.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
rng = np.random.default_rng(7)
fig, axes = plt.subplots(2, 2, figsize=(11, 7))
# 1) Binomial: bajas mensuales entre 500 clientes (p=0.08)
bajas = rng.binomial(n=500, p=0.08, size=2000)
axes[0, 0].hist(bajas, bins=range(20, 65), color="steelblue", edgecolor="white")
axes[0, 0].set_title("Binomial: bajas/mes entre 500 clientes")
# 2) Poisson: pedidos por hora (lambda=12)
pedidos_hora = rng.poisson(lam=12, size=2000)
axes[0, 1].hist(pedidos_hora, bins=range(0, 30), color="darkorange", edgecolor="white")
axes[0, 1].set_title("Poisson: pedidos por hora")
# 3) Normal: tiempo de preparación, muestra vs. densidad teórica
prep = rng.normal(loc=18, scale=4, size=2000)
axes[1, 0].hist(prep, bins=40, density=True, color="seagreen",
edgecolor="white", alpha=0.7)
x = np.linspace(4, 32, 300)
axes[1, 0].plot(x, stats.norm.pdf(x, loc=18, scale=4), "k--", label="PDF teórica")
axes[1, 0].set_title("Normal: minutos de preparación")
axes[1, 0].legend()
# 4) Exponencial: minutos entre pedidos (media = 5)
entre_pedidos = rng.exponential(scale=5, size=2000)
axes[1, 1].hist(entre_pedidos, bins=40, density=True, color="indianred",
edgecolor="white", alpha=0.7)
x = np.linspace(0, 30, 300)
axes[1, 1].plot(x, stats.expon.pdf(x, scale=5), "k--", label="PDF teórica")
axes[1, 1].set_title("Exponencial: minutos entre pedidos")
axes[1, 1].legend()
plt.tight_layout()
plt.show()Claves del código:
rng.binomial,rng.poisson,rng.normal,rng.exponentialgeneran muestras de cada distribución;size=2000pide 2.000 observaciones simuladas.density=Trueen el histograma normaliza el eje Y para que el área total sea 1, y así el histograma sea comparable con la curva de densidad teórica que dibujamos encima constats.<dist>.pdf.- Superponer muestra e histograma con la PDF teórica es el chequeo visual más simple de "¿mis datos se parecen a esta distribución?". En la lección 02-04 veremos contrastes formales para responder con números.
- Observa las formas: binomial y Poisson son campanas discretas casi simétricas (con estos parámetros), la normal es la campana continua perfecta y la exponencial decae desde cero con cola derecha, como los tiempos entre pedidos reales.
Errores Comunes y Consejos
- Interpretar la densidad como probabilidad. f(x) puede valer más de 1 (por ejemplo, en una uniforme estrecha); la probabilidad es el área bajo la curva en un intervalo, no la altura.
- Asumir normalidad porque sí. Importes y tiempos suelen tener cola derecha (asimetría); aplicar la regla 68-95-99.7 a datos no normales da conclusiones erróneas. Dibuja el histograma primero.
- Confundir los parámetros de scipy.
scaleenstats.expones la media (1/λ), no λ. Ystats.normrecibe la desviación estándar (scale), no la varianza. Consulta siempre la parametrización en la documentación. - Olvidar la independencia. La binomial exige ensayos independientes con la misma p. Si el churn de un cliente arrastra al de sus vecinos (efecto boca a boca), el modelo binomial se queda corto.
- Usar z-scores con distribuciones muy asimétricas. Un z-score de 3 en una exponencial no es tan raro como en una normal. La regla |z| > 3 presupone campana.
- Consejo: memoriza las parejas "fenómeno → distribución" de las tablas de esta lección; reconocer el patrón correcto en un problema nuevo es el 80 % del trabajo.
Ejercicios
Ejercicio 1
MercaFresh envía una campaña de email a 200 clientes con una probabilidad de conversión del 5 % cada uno. (a) ¿Qué distribución sigue el número de conversiones y con qué parámetros? (b) Calcula con scipy la probabilidad de conseguir exactamente 10 conversiones y (c) la de conseguir 15 o más.
Ejercicio 2
El tiempo de preparación de pedidos sigue una normal con μ = 18 min y σ = 4 min. Usando solo la regla 68-95-99.7 (sin código): (a) ¿entre qué valores está el 95 % central de los pedidos? (b) ¿Qué porcentaje aproximado tarda más de 26 minutos? (c) Un pedido tardó 6 minutos: ¿cuál es su z-score y cómo lo interpretas?
Ejercicio 3
Al centro logístico de MercaFresh llegan de media 12 pedidos por hora. Simula con NumPy 10.000 horas de actividad y estima empíricamente la probabilidad de recibir 20 o más pedidos en una hora. Compara el resultado con el valor exacto de 1 - stats.poisson.cdf(19, mu=12).
Soluciones
Solución 1
(a) Binomial B(n=200, p=0,05): 200 ensayos Bernoulli independientes. Su media es n·p = 10 conversiones.
from scipy import stats
print(stats.binom.pmf(10, n=200, p=0.05).round(4)) # (b) ~0.1288
print((1 - stats.binom.cdf(14, n=200, p=0.05)).round(4)) # (c) ~0.0744(b) Un 12,9 % de probabilidad de exactamente 10. (c) Un 7,4 % de conseguir 15 o más. Nota: para la cola "15 o más" se resta la CDF en 14, no en 15.
Solución 2
- (a) μ ± 2σ = 18 ± 8 → entre 10 y 26 minutos.
- (b) Fuera de μ ± 2σ queda el 5 % repartido en dos colas; solo la superior: ≈ 2,5 % de los pedidos tarda más de 26 min.
- (c) z = (6 − 18) / 4 = −3. Está a tres desviaciones estándar por debajo de la media: un pedido preparado sospechosamente rápido (¿se registró mal el tiempo?, ¿pedido de un solo artículo?). Las anomalías también existen por la izquierda.
Solución 3
import numpy as np
from scipy import stats
rng = np.random.default_rng(0)
horas = rng.poisson(lam=12, size=10_000)
print((horas >= 20).mean()) # ~0.0210 (varía con la semilla)
print(1 - stats.poisson.cdf(19, mu=12)) # 0.0213 (exacto)(horas >= 20) crea un array de booleanos y .mean() calcula la proporción de True: la frecuencia con que ocurre el evento en la simulación. Con 10.000 repeticiones, la estimación empírica (~2,1 %) coincide casi exactamente con la teórica. Este patrón "simular y contar" es una herramienta potentísima cuando la fórmula exacta no existe o no la recuerdas.
Conclusión
Ya sabes qué es una variable aleatoria y conoces las seis distribuciones de trabajo del día a día: Bernoulli, binomial y Poisson para contar; uniforme, normal y exponencial para medir. Has profundizado en la normal —la regla 68-95-99.7 y los z-scores— y has visto por qué las distribuciones importan en ML: sustentan los supuestos de los modelos y la detección de anomalías en los pedidos de MercaFresh, además de permitir simulaciones con NumPy y cálculos exactos con scipy. Hasta ahora hemos mirado cada variable por separado; el siguiente paso es estudiar cómo se relacionan entre sí: en la próxima lección, covarianza y correlación nos dirán qué variables de MercaFresh se mueven juntas y cuáles avisan del churn.
Curso de Machine Learning
Módulo 1: Introducción al Machine Learning
- ¿Qué es el Machine Learning?
- Historia y evolución del Machine Learning
- Tipos de Machine Learning
- Aplicaciones del Machine Learning
- El flujo de trabajo de un proyecto de Machine Learning
Módulo 2: Fundamentos de Estadística y Probabilidad
- Conceptos básicos de estadística
- Distribuciones de probabilidad
- Correlación y covarianza
- Inferencia estadística
- Teorema de Bayes
Módulo 3: Preprocesamiento de Datos
- Limpieza de datos
- Manejo de datos faltantes
- Transformación de datos
- Codificación de variables categóricas
- Normalización y estandarización
- Ingeniería de características
Módulo 4: Algoritmos de Machine Learning Supervisado
- Regresión lineal
- Regresión logística
- Árboles de decisión
- Máquinas de soporte vectorial (SVM)
- K-Vecinos más cercanos (K-NN)
- Naive Bayes
- Redes neuronales
Módulo 5: Algoritmos de Machine Learning No Supervisado
- Clustering: K-means
- Clustering jerárquico
- Análisis de componentes principales (PCA)
- Análisis de agrupamiento DBSCAN
- Visualización de datos con t-SNE y UMAP
Módulo 6: Evaluación y Validación de Modelos
- División de datos: entrenamiento, validación y prueba
- Métricas de evaluación
- Validación cruzada
- Curva ROC y AUC
- Overfitting y underfitting
Módulo 7: Técnicas Avanzadas y Optimización
- Regularización: Ridge, Lasso y Elastic Net
- Ensemble Learning
- Gradient Boosting
- Redes neuronales profundas (Deep Learning)
- Optimización de hiperparámetros
Módulo 8: Implementación y Despliegue de Modelos
- Frameworks y bibliotecas populares
- Implementación de modelos en producción
- Mantenimiento y monitoreo de modelos
- Consideraciones éticas y de privacidad
Módulo 9: Proyectos Prácticos
- Proyecto 1: Predicción de precios de viviendas
- Proyecto 2: Clasificación de imágenes
- Proyecto 3: Análisis de sentimientos en redes sociales
- Proyecto 4: Detección de fraudes
- Proyecto 5: Segmentación de clientes
