Empieza la segunda mitad del libro 🎬
Hasta ahora describíamos lo que teníamos delante. A partir de aquí vamos a afirmar cosas sobre lo que no medimos, y para eso hace falta un poco de probabilidad.
Poca, te lo prometo. Nada de urnas con bolas ni de barajas. Tres ideas, y las tres se calculan con la misma tabla de ventas de siempre.
import pandas as pd import numpy as np URL = 'https://missyera.com/static/datasets/ventas-miss-yera.csv' def carga_limpia(url): """La misma del capítulo 2.""" v = pd.read_csv(url).drop_duplicates() v['ciudad'] = (v['ciudad'].str.strip().str.lower() .str.normalize('NFKD') .str.encode('ascii', 'ignore').str.decode('utf-8')) v['monto'] = pd.to_numeric(v['monto'].str.replace(',', '.')) for col in ['fecha', 'fecha_ultima_compra']: f = pd.to_datetime(v[col], format='%Y-%m-%d', errors='coerce') falta = f.isna() & v[col].notna() f[falta] = pd.to_datetime(v.loc[falta, col], format='%d/%m/%Y', errors='coerce') v[col] = f return v v = carga_limpia(URL) print('P(compra) = %.4f' % v['compro'].mean()) print('P(mayorista) = %.4f' % (v['segmento'] == 'Mayorista').mean())
P(compra) = 0.5777 P(mayorista) = 0.2500
Ahí tienes la única definición de probabilidad que vas a necesitar: la proporción de veces que pasa algo. Y ya sabes calcularla desde el capítulo 2, porque es la media de una columna de ceros y unos 😌
Y dime: ¿te has creído alguna vez un resultado de laboratorio sin preguntar cuánta gente tiene esa enfermedad? Es el mismo error que vamos a ver acá, y cuesta mucho más caro en datos 🎲
Regla 1: la suma, con su descuento
¿Cuál es la probabilidad de que una venta sea de un mayorista o venga por WhatsApp?
La tentación es sumar. Vamos a ver:
mayorista = v['segmento'] == 'Mayorista' whatsapp = v['canal'] == 'WhatsApp' print('P(mayorista) = %.4f' % mayorista.mean()) print('P(whatsapp) = %.4f' % whatsapp.mean()) print('sumando los dos = %.4f' % (mayorista.mean() + whatsapp.mean())) print('P(mayorista O whatsapp) = %.4f' % (mayorista | whatsapp).mean()) print('lo que sobra = %.4f' % (mayorista & whatsapp).mean())
P(mayorista) = 0.2500 P(whatsapp) = 0.2397 sumando los dos = 0.4897 P(mayorista O whatsapp) = 0.4327 lo que sobra = 0.0570
Sumando sale 0,4897 y la verdad es 0,4327. Sobran exactamente 0,0570, que es la proporción de ventas que son las dos cosas a la vez: un mayorista que compró por WhatsApp.
Al sumar las contaste dos veces. Por eso la regla es restar la intersección 🧮
sumas las dos probabilidades y le restas lo que contaste dos veces
Regla 2: la condicional, que es la que se usa de verdad
"Dado que ya sé algo, ¿qué probabilidad hay de lo otro". En pandas esto es simplemente filtrar antes de promediar:
de todo lo que cumple B, qué parte cumple también A
print('P(compra) = %.4f' % v['compro'].mean()) print('P(compra | mayorista) = %.4f' % v.loc[mayorista, 'compro'].mean()) print('P(compra | whatsapp) = %.4f' % v.loc[whatsapp, 'compro'].mean()) print('P(compra | marketplace) = %.4f' % v.loc[v['canal'] == 'Marketplace', 'compro'].mean())
P(compra) = 0.5777 P(compra | mayorista) = 0.7240 P(compra | whatsapp) = 0.6551 P(compra | marketplace) = 0.4613
Saber quién es el cliente cambia la probabilidad: de 0,5777 sube a 0,7240 si es mayorista y baja a 0,4613 si viene por Marketplace 📈
Y eso es, literalmente, de qué va el análisis de datos: buscar el dato que, al conocerlo, cambia lo que esperas 🔮
Regla 3: independencia
Dos cosas son independientes si saber una no te dice nada de la otra. La prueba es esta: si son independientes, la probabilidad de que pasen las dos es el producto de las dos por separado.
Probemos con ciudad, que llevamos seis capítulos sospechando que no sirve para nada:
for c in ['lima', 'arequipa', 'trujillo']: es_ciudad = v['ciudad'] == c juntas = (es_ciudad & (v['compro'] == 1)).mean() producto = es_ciudad.mean() * v['compro'].mean() print('%-9s juntas %.4f | producto %.4f | diferencia %+.4f' % (c, juntas, producto, juntas - producto))
lima juntas 0.0917 | producto 0.0907 | diferencia +0.0010 arequipa juntas 0.1047 | producto 0.1051 | diferencia -0.0005 trujillo juntas 0.0930 | producto 0.0907 | diferencia +0.0023
Prácticamente idénticas. Ciudad y compra son independientes: saber de qué ciudad es una venta no te dice nada sobre si se va a cerrar ✅
Y ahora el contraste, con segmento:
juntas = (mayorista & (v['compro'] == 1)).mean() producto = mayorista.mean() * v['compro'].mean() print('juntas %.4f' % juntas) print('producto %.4f' % producto) print('la realidad es %.1f%% mayor de lo que serIa si fueran independientes' % (100 * (juntas / producto - 1)))
juntas 0.1810 producto 0.1444 la realidad es 25.3% mayor de lo que serIa si fueran independientes
Un 25,3% por encima. Aquí no hay independencia ninguna: ser mayorista y comprar van juntos 🤝
Guarda este cálculo porque es exactamente el que hace la prueba ji cuadrado del capítulo 13. Lo único que añade la prueba es decirte cuánta diferencia hace falta para que no sea casualidad.
El error que cuesta campañas
Este es el importante del capítulo, y lo he visto en presentaciones de verdad 😖
print('P(compra | mayorista) = %.4f' % v.loc[mayorista, 'compro'].mean()) print('P(mayorista | compra) = %.4f' % (v.loc[v['compro'] == 1, 'segmento'] == 'Mayorista').mean())
P(compra | mayorista) = 0.7240 P(mayorista | compra) = 0.3133
0,7240 y 0,3133. Son dos números completamente distintos, y en castellano se parecen tanto que se confunden todo el rato:
- ✅ "El 72,40% de los mayoristas compra". Verdad.
- ✅ "El 31,33% de los que compran son mayoristas". Verdad.
- ❌ "El 72,40% de los que compran son mayoristas". Falso, y es lo que la gente entiende.
Y la consecuencia es de plata. Si crees que el 72% de tus compradores son mayoristas, concentras el equipo comercial ahí y abandonas a los demás. Pero resulta que casi siete de cada diez ventas cerradas vienen de otros segmentos 💸
La regla mnemotécnica: P(A dado B) no es P(B dado A). Cuando leas un porcentaje, pregúntate siempre sobre qué total está calculado.
Bayes, que es la fórmula para darle la vuelta
El teorema de Bayes es justo eso: cómo pasar de una a la otra sin equivocarse.
para darle la vuelta a una condicional multiplicas por la tasa base y divides por la del otro suceso
Vamos a comprobar que funciona:
p_may = mayorista.mean() p_compra = v['compro'].mean() p_compra_dado_may = v.loc[mayorista, 'compro'].mean() bayes = p_compra_dado_may * p_may / p_compra print('con Bayes: %.4f' % bayes) print('contando: %.4f' % (v.loc[v['compro'] == 1, 'segmento'] == 'Mayorista').mean())
con Bayes: 0.3133 contando: 0.3133
Clavado 🎯
Fíjate en la pieza que hace todo el trabajo: P(A), la proporción de mayoristas, que es 0,25. Como solo una de cada cuatro ventas es de un mayorista, por muy alta que sea su tasa de compra no pueden ser la mayoría de los cierres.
A esa P(A) se le llama tasa base, y olvidarla es el error más famoso de toda la probabilidad.
La tasa base, con las 21 negativas
Imagina que alguien de sistemas te ofrece un detector de ventas rotas. Dice que acierta el 99%: si la venta está rota la detecta el 99% de las veces, y si está bien solo se equivoca el 1%.
Suena excelente. Vamos a ver qué pasa cuando lo sueltas sobre estas ventas, donde ya sabemos que hay 21 rotas de 3.000:
tasa_base = (v['monto'] < 0).mean() sensibilidad = 0.99 falsa_alarma = 0.01 alarmas_buenas = sensibilidad * tasa_base alarmas_falsas = falsa_alarma * (1 - tasa_base) print('proporcion de ventas rotas: %.5f' % tasa_base) print('alarmas correctas por venta: %.5f' % alarmas_buenas) print('alarmas falsas por venta: %.5f' % alarmas_falsas) print() print('P(rota | suena la alarma) = %.4f' % (alarmas_buenas / (alarmas_buenas + alarmas_falsas)))
proporcion de ventas rotas: 0.00700 alarmas correctas por venta: 0.00693 alarmas falsas por venta: 0.00993 P(rota | suena la alarma) = 0.4110
El 41,10%. O sea que cuando el detector del 99% suena, se equivoca más veces de las que acierta 😵
Y no es que el detector sea malo: es buenísimo. El problema es que hay 2.979 ventas sanas y solo 21 rotas. El 1% de errores sobre 2.979 son 29,79 alarmas falsas, más que las 20,79 correctas que salen del 99% sobre 21.
Esto es lo que pasa con todos los detectores de cosas raras: fraude, enfermedades poco frecuentes, fallos de máquina. Cuando lo que buscas es raro, la mayoría de las alarmas son falsas aunque el detector sea buenísimo 🚨
Es también la razón por la que el libro de machine learning tiene un capítulo entero sobre clases raras: el mismo problema, con modelos.
El error del capítulo
v.groupby('segmento')['compro'].mean()['Mayoristas']
KeyError: 'Mayoristas'
Una ese de más 🤦 En el archivo el segmento se llama Mayorista,
en singular.
Parece tonto, y lo pongo aquí porque este error tiene una versión hermana que no da error y que es de las que más daño hacen:
print('mal escrito: %.4f' % v.loc[v['segmento'] == 'Mayoristas', 'compro'].mean()) print('bien escrito: %.4f' % v.loc[v['segmento'] == 'Mayorista', 'compro'].mean()) print('cuantas filas trae el mal escrito:', (v['segmento'] == 'Mayoristas').sum())
mal escrito: nan bien escrito: 0.7240 cuantas filas trae el mal escrito: 0
Con groupby te avisa. Con un filtro, no: te
devuelve cero filas y un nan, tan tranquilo 😶
Y si en vez de una media hubieras pedido un sum(), te habría
devuelto 0,0, que parece un número de verdad y se cuela en cualquier informe.
La defensa es la de siempre y cuesta un segundo: después de filtrar, mira cuántas filas quedaron.
Y dos más, y los dos son la regla número uno
np.random.default_rng(7).choice(['si', 'no'], p=[0.7, 0.5])
ValueError: Probabilities do not sum to 1. See Notes section of docstring for more information.
Ahí está el axioma en un mensaje de error: las probabilidades de todo lo que puede pasar suman 1. Un 70% y un 50% suman 120%, y no hay mundo donde eso signifique algo.
np.random.default_rng(7).binomial(10, 1.3)
ValueError: p < 0, p > 1 or p is NaN
Y el otro lado de lo mismo: una probabilidad sola tampoco puede pasar de 1. Suele salir de haber guardado un porcentaje sin dividir entre cien, que es de los descuidos más caros que hay porque a veces no revienta y te deja el número mal 🎲
Practica 💪
1. La probabilidad de compra por canal, ordenada
Calcula P(compra | canal) para los cuatro canales y ordénalos. ¿Cuánto separa al mejor del peor?
por_canal = v.groupby('canal')['compro'].agg(['mean', 'count']).sort_values('mean') por_canal.columns = ['P(compra)', 'ventas'] print(por_canal.round(4)) print() print('el mejor supera al peor en %.1f puntos' % (100 * (por_canal['P(compra)'].max() - por_canal['P(compra)'].min())))
P(compra) ventas canal Marketplace 0.4613 763 Web 0.5808 792 Tienda 0.6198 726 WhatsApp 0.6551 719 el mejor supera al peor en 19.4 puntos
19,4 puntos entre WhatsApp y Marketplace 📱
Y ahí hay una decisión de negocio esperando. Pero cuidado con el salto fácil: esto no dice que mover a la gente a WhatsApp vaya a subir las ventas.
Puede que WhatsApp cierre más porque por ahí escriben los clientes que ya estaban decididos, y Marketplace reciba a los que están mirando precios. En ese caso el canal no causa nada, solo refleja quién ya venía convencido.
Distinguir eso es el capítulo 15, y es el problema más difícil de todo el libro 🧩
2. Un test de independencia casero
Escribe algo que, dada una columna categórica, te diga
cuánto se aleja de la independencia respecto a compro.
def cuanto_depende(df, columna): p_compra = df['compro'].mean() peor = 0.0 for valor in df[columna].unique(): es = df[columna] == valor juntas = (es & (df['compro'] == 1)).mean() producto = es.mean() * p_compra peor = max(peor, abs(juntas / producto - 1)) return peor for col in ['ciudad', 'categoria', 'canal', 'segmento']: print('%-11s se desvia hasta %5.1f%% de la independencia' % (col, 100 * cuanto_depende(v, col)))
ciudad se desvia hasta 2.5% de la independencia categoria se desvia hasta 3.2% de la independencia canal se desvia hasta 20.1% de la independencia segmento se desvia hasta 35.1% de la independencia
Ahí está el ranking del archivo entero, en cuatro líneas 🏆
Segmento manda con un 35,1%, canal le sigue con 20,1%, y ciudad y categoría se quedan por debajo del 4%, o sea que son ruido.
Es exactamente lo mismo que veníamos diciendo a ojo desde el capítulo 1, pero ahora con un número que se puede comparar entre columnas.
Lo que este cálculo no te dice es si un 3,4% es poco porque no hay relación o poco porque no hay datos suficientes. Para eso hace falta el capítulo 13 🔬
3. Dale la vuelta tú
Sabemos que P(compra | WhatsApp) es 0,6551. Calcula P(WhatsApp | compra) con Bayes y compruébalo contando.
p_wa = whatsapp.mean() p_compra = v['compro'].mean() p_compra_dado_wa = v.loc[whatsapp, 'compro'].mean() print('P(whatsapp | compra) con Bayes: %.4f' % (p_compra_dado_wa * p_wa / p_compra)) print('contando: %.4f' % (v.loc[v['compro'] == 1, 'canal'] == 'WhatsApp').mean())
P(whatsapp | compra) con Bayes: 0.2718 contando: 0.2718
El 65,51% de los que llegan por WhatsApp compran, y solo el 27,18% de las compras llegan por WhatsApp 🔁
Otra vez la tasa base haciendo su trabajo: WhatsApp es solo el 23,97% de las ventas, así que por muy bien que convierta no puede aportar la mayoría de los cierres.
Y de aquí sale una idea de negocio que sí es defendible: si WhatsApp convierte mucho mejor y solo trae una cuarta parte del tráfico, hay margen para mandarle más. Eso es una hipótesis para probar, no una conclusión, pero es del tipo bueno 🌱
4. Un detector con datos de verdad
Usa la satisfacción baja (1 o 2) como alarma de "esta venta no se va a cerrar" y calcula si sirve.
con_dato = v.dropna(subset=['satisfaccion']) alarma = con_dato['satisfaccion'] <= 2 no_cerro = con_dato['compro'] == 0 print('filas con satisfaccion: %d' % len(con_dato)) print('P(alarma) = %.4f' % alarma.mean()) print('P(no cerro) = %.4f' % no_cerro.mean()) print() print('P(alarma | no cerro) = %.4f' % alarma[no_cerro].mean()) print('P(alarma | si cerro) = %.4f' % alarma[~no_cerro].mean()) print('P(no cerro | alarma) = %.4f' % no_cerro[alarma].mean())
filas con satisfaccion: 2769 P(alarma) = 0.3962 P(no cerro) = 0.4258 P(alarma | no cerro) = 0.4724 P(alarma | si cerro) = 0.3396 P(no cerro | alarma) = 0.5077
Vamos a leerlo como se lee un detector 🕵️
Caza el 47,24% de las ventas que no se cierran, y se equivoca avisando en el 33,96% de las que sí se cierran. O sea que distingue algo, pero poco: la diferencia entre las dos es de 13 puntos.
Y el número que decide es el último: cuando la alarma suena, acierta el 50,77% de las veces. Prácticamente una moneda al aire 🪙
Compáralo con la tasa base: sin ningún detector, si dijeras "no se va a cerrar" a todo, acertarías el 42,58%. La alarma te sube al 50,77%. Mejora ocho puntos, que no es nada despreciable, pero está lejísimos de "esta venta se cae seguro".
Esa comparación contra la tasa base es lo que hay que exigirle a cualquier alerta antes de montar un proceso encima 📋
5. Fabrica dos cosas independientes
Añade una columna con un número al azar y comprueba que es independiente de la compra. Sirve para ver qué pinta tiene la independencia de verdad.
generador = np.random.default_rng(7) v['moneda'] = generador.integers(0, 2, size=len(v)) cara = v['moneda'] == 1 juntas = (cara & (v['compro'] == 1)).mean() producto = cara.mean() * v['compro'].mean() print('P(cara) = %.4f' % cara.mean()) print('P(compra | cara) = %.4f' % v.loc[cara, 'compro'].mean()) print('P(compra) = %.4f' % v['compro'].mean()) print() print('juntas %.4f | producto %.4f | se desvia %.2f%%' % (juntas, producto, 100 * (juntas / producto - 1)))
P(cara) = 0.5033 P(compra | cara) = 0.5755 P(compra) = 0.5777 juntas 0.2897 | producto 0.2908 | se desvia -0.38%
0,38% de desviación 🎲
Y esto es lo valioso del ejercicio: ahora sabes cuánto se desvía algo que es independiente de verdad. Con 3.000 filas, el azar puro produce desviaciones de medio punto porcentual.
Así que cuando ciudad se desvía 2,5%, ya tienes con qué compararlo: es unas seis veces el ruido de una moneda, pero catorce veces menos que segmento.
Fabricar una columna de basura a propósito y medir cuánto se desvía es uno de los trucos más útiles que conozco. Te da la vara de medir del ruido con tus propios datos, sin teoría 📏
6. Probabilidad de dos filtros a la vez
¿Qué probabilidad hay de que una venta sea de un mayorista Y venga por WhatsApp Y se cierre? Calcúlalo directo y con la cadena de condicionales.
directo = (mayorista & whatsapp & (v['compro'] == 1)).mean() cadena = (mayorista.mean() * whatsapp[mayorista].mean() * v.loc[mayorista & whatsapp, 'compro'].mean()) print('directo: %.6f' % directo) print('cadena: %.6f' % cadena) print() print('son %d ventas de %d' % ((mayorista & whatsapp & (v['compro'] == 1)).sum(), len(v)))
directo: 0.046667 cadena: 0.046667 son 140 ventas de 3000
Las dos formas dan lo mismo, como tenía que ser ✅
La cadena se lee de izquierda a derecha: la probabilidad de ser mayorista, por la de venir por WhatsApp dado que eres mayorista, por la de cerrar dado que eres las dos cosas.
Parece un rodeo cuando puedes contar directo, y lo es aquí. Pero es la forma en que se construyen los cálculos cuando no tienes la tabla entera, solo trozos, y es la base de cómo funcionan los modelos que estiman probabilidades.
Mira también el número de filas: 140. Ese es el aviso de verdad de este ejercicio. Cada condición que añades parte la muestra, y con 140 filas cualquier porcentaje que calcules ya tiene un margen de error gordo. Cuánto de gordo es el capítulo 10 📉
7. La probabilidad de cerrar, por segmento
Calcula qué porcentaje cierra en cada segmento y ordénalos.
tabla = pd.crosstab(v['segmento'], v['compro'], normalize='index') print((tabla * 100).round(1).to_string()) print() print('cierra mas seguido: %s' % tabla[1].idxmax()) print('cierra menos: %s' % tabla[1].idxmin())
compro 0 1 segmento Bodega 62.5 37.5 Horeca 36.8 63.2 Mayorista 27.6 72.4 Minimarket 43.1 56.9 cierra mas seguido: Mayorista cierra menos: Bodega
Eso es una probabilidad condicional, aunque no lo parezca 🧮
El 72,4% del mayorista es P(cierra | es mayorista), escrito como lo escribiría cualquiera. Y la diferencia con el 37,5% de la bodega es enorme: casi el doble.
Fíjate en el normalize='index', que es lo único que hay que entender de la línea: dice que cada fila sume 100, o sea que condicionas por segmento. Si pusieras 'columns' estarías contestando la pregunta al revés, que es exactamente el error que este capítulo persigue 🔄
8. ¿Son independientes el canal y el cierre?
Comprueba si P(Web y cierra) es igual a P(Web) por P(cierra).
p_web = (v['canal'] == 'Web').mean() p_cierra = v['compro'].mean() juntas_real = ((v['canal'] == 'Web') & (v['compro'] == 1)).mean() print('P(Web) = %.4f' % p_web) print('P(cierra) = %.4f' % p_cierra) print('si fueran independientes, P(las dos) = %.4f' % (p_web * p_cierra)) print('P(las dos) de verdad = %.4f' % juntas_real)
P(Web) = 0.2640 P(cierra) = 0.5777 si fueran independientes, P(las dos) = 0.1525 P(las dos) de verdad = 0.1533
0,1525 contra 0,1533. Prácticamente iguales 💚
O sea que el canal Web y cerrar la venta son casi independientes: saber que un pedido vino por Web no te dice casi nada sobre si va a cerrar. Compáralo con el ejercicio anterior, donde el segmento cambiaba la probabilidad del 37% al 72%.
Esta comparación de dos números es la definición de independencia ejecutada, y es la comprobación que hay que hacer antes de multiplicar probabilidades. Multiplicar cosas que no son independientes es el error del capítulo 🔗
Dos porcentajes del mismo canal que no dicen lo mismo
Antes de cerrar, la trampa. Los dos números están bien calculados y la conclusión que sale de mezclarlos está muy mal 🔀
La trampa
Quieres saber cuántos mayoristas van a comprar el mes que viene. Tienes las dos probabilidades por separado, así que las multiplicas.
p_compra = (v['compro'] == 1).mean() # 0.5777 p_mayor = (v['segmento'] == 'Mayorista').mean() # 0.2500 print(round(p_compra * p_mayor * 3000)) # 433 real = ((v['compro'] == 1) & (v['segmento'] == 'Mayorista')).mean() print(round(real * 3000)) # 543
Qué está mal
Ciento diez clientes de diferencia, un 25% por debajo 🤝
Multiplicar dos probabilidades solo vale si los dos sucesos son independientes, o sea si saber uno no te dice nada del otro. Y aquí sí te dice: los mayoristas compran más que la media, así que "ser mayorista" y "comprar" van juntos.
Lo que hay que usar es la condicional: la proporción de compra dentro de los mayoristas, no la del archivo entero. Con tres condiciones a la vez el error crece: multiplicando salen 104 clientes y de verdad son 140.
La independencia no se supone, se comprueba. Y en datos de negocio casi nunca se cumple, porque todo está relacionado con todo: la ciudad con el canal, el canal con el segmento y el segmento con lo que compra. Si multiplicas, di en voz alta por qué crees que son independientes, y verás lo rápido que se te cae.
Comprueba que lo tienes
El 72,40% de los mayoristas compra. ¿Qué porcentaje de las compras son de mayoristas?
- El 31,33%, porque los mayoristas son solo una cuarta parte de las ventas
- También el 72,40%
- No se puede saber con esa información
- Más del 72,40%, porque compran más
Lo que te llevas
- 🎲 Una probabilidad es la proporción de veces que pasa algo, o sea la media de una columna de ceros y unos.
- ➕ P(A o B) no es P(A) + P(B). Hay que restar lo que se cuenta dos veces: aquí 0,4897 contra 0,4327 de verdad.
- 🔍 La condicional es filtrar antes de promediar. P(compra) es 0,5777 y P(compra|mayorista) es 0,7240.
- 🔀 P(A|B) no es P(B|A). El 72,40% de los mayoristas compra, pero solo el 31,33% de las compras son de mayoristas.
- ⚖️ Bayes es la fórmula para darle la vuelta, y la pieza que manda es la tasa base.
- 🚨 Un detector con 99% de acierto sobre algo que pasa el 0,70% de las veces acierta el 41,11% de sus alarmas.
- 👻 Un filtro mal escrito no da error: devuelve cero filas y un
nan. Cuenta las filas después de filtrar.
Y si de todo el capítulo te llevas una sola frase, que sea esta:
Todo porcentaje contesta a un "dado qué". Si no sabes cuál, no sabes qué te están diciendo.
Y esto de darle la vuelta a una condicional es exactamente lo que hace que un modelo con 99% de acierto sea inútil en un problema raro. Está contado en el libro de machine learning 🤖
Qué viene ahora
En el capítulo 8 vemos las tres distribuciones que de verdad se usan (binomial, Poisson y normal) y el teorema que explica por qué la campana aparece por todas partes aunque tus datos no sean campana 🔔
Preguntas frecuentes
¿Qué es el teorema de Bayes?
La regla que te deja dar vuelta una probabilidad condicional: si sabes la probabilidad de B dado A, te da la de A dado B. Es cómo se pasa de "el test da positivo cuando hay enfermedad" a lo que de verdad quieres saber, que es "hay enfermedad cuando el test da positivo".
¿Cuál es la fórmula del teorema de Bayes?
La probabilidad de A dado B es igual a la probabilidad de B dado A, por la probabilidad de A, dividido entre la probabilidad de B.
¿Un ejemplo del teorema de Bayes?
Un test que acierta el 99% suena infalible hasta que la enfermedad la tiene una persona de cada diez mil. Ahí la mayoría de los positivos son falsos, y el teorema es lo que lo demuestra con números. Está resuelto en este capítulo.
¿Qué es la probabilidad condicional?
La probabilidad de algo cuando ya sabes que pasó otra cosa. Cambia el resultado más de lo que la intuición espera, y es la pieza que necesita Bayes.
¿Cómo se calcula la probabilidad condicional?
Se divide la probabilidad de que pasen las dos cosas entre la probabilidad de la que ya sabes que pasó. Dicho fácil: te quedas solo con los casos donde pasó la primera y cuentas dentro de esos.
¿Qué es el teorema de la probabilidad total?
La forma de calcular la probabilidad de algo sumando por partes: se parte el mundo en casos que no se pisan, se calcula dentro de cada uno y se suma pesando por lo que pesa cada caso. Es el denominador de Bayes.
¿Cuáles son las fórmulas de probabilidad que hacen falta?
Tres: la de la unión, la de la intersección y la condicional. Con esas tres y el teorema de Bayes está cubierto casi todo lo que un analista necesita.
Practica este capítulo 📓
Todo el código de arriba en un cuaderno que corre de principio a fin, y los ejercicios con una celda vacía para que los hagas tú. Se abre en Google Colab de un clic y no hay que instalar nada. Donde veas %%revisa, escribe tu respuesta y el cuaderno te dice si te salió.
¿Prefieres trabajar en tu máquina? Bájate el cuaderno de práctica o el de soluciones. Todos están también en github.com/soymissyera/MissYeraEjercicios.