01 · Punto de partida
Saber algo cambia la chance
La probabilidad de «esperar menos de 5 minutos» no es la misma a las 10 h que en hora pico. La probabilidad condicional P(A|B) responde: «si ya sé que ocurrió B, ¿cuál es la chance de A?». Es la herramienta para actualizar el modelo con información.
En simulación aparece en cada rama: si el cliente es prioritario, si la máquina pasó mantenimiento, si el visitante vio la oferta. Programar bien un if aleatorio es programar una condicional.
- ¿Qué información ya tengo antes de sortear?
- ¿Cómo cambia P(A) al saber B?
- ¿La condición filtra casos o cambia el mecanismo?
- ¿Cómo estimo P(A|B) contando solo los casos B?
02 · Definición
La fórmula y su lectura
Definición
P(A|B) = P(A ∩ B) / P(B), con P(B) mayor a 0. Casos donde ocurren ambos, sobre casos donde ocurre la condición.
Total
Ley de probabilidad total: P(A) = P(A|B)·P(B) + P(A|Bᶜ)·P(Bᶜ). El promedio ponderado de cada rama.
Actualización
Pasar de P(A) a P(A|B) es aprender de evidencia. Base del filtrado, el diagnóstico y la segmentación.
| A (rápido) | Aᶜ (lento) | Total | |
|---|---|---|---|
| B (caja rápida) | 280 | 120 | 400 |
| Bᶜ (normal) | 180 | 420 | 600 |
| Total | 460 | 540 | 1000 |
Leemos: P(A) = 460/1000 = 0,46. Pero P(A|B) = 280/400 = 0,70 y P(A|Bᶜ) = 180/600 = 0,30. Saber la caja actualiza la chance de 0,46 a 0,70 o 0,30.
03 · Ramas del simulador
Dónde condicionar en tu modelo
Condición que filtra
Segmentar lo simulado
«Dado que llegó en hora pico…», «dado que compró…». Se estima contando solo ese segmento. No cambia el sorteo, cambia el denominador.
Condición que ramifica
If aleatorio
«Si es prioritario, sortea con otra distribución». Se programa como rama con su propia probabilidad y parámetros.
- Tabla de contingencia
- Conteos cruzados A × B. De ella salen todas las condicionales dividiendo por fila o columna.
- Árbol
- Primero ramas B con P(B), luego A con P(A|B). Multiplicar ramas da la intersección.
- Total
- P(A) pondera cada rama: útil para verificar que la simulación ramificada cierra.
- Error típico
- Confundir P(A|B) con P(B|A). «P(rápido|prioridad)» no es «P(prioridad|rápido)».
04 · Ejemplos
Condicionales que deciden
- 1Cola.
P(espera menor a 5 | caja rápida) = 0,7 vs 0,3 en normal. Refuerza abrir la rápida en picos.
- 2Ventas.
P(compra | vio oferta) vs P(compra | no vio). Mide el efecto real de la oferta.
- 3Soporte.
P(resuelve al primer contacto | cliente nuevo) segmenta capacitación.
- 4Máquinas.
P(falla | pasó mantenimiento) vs P(falla | no pasó). Justifica el mantenimiento.
- 5Juego.
P(gana | tiene escudo) balancea objetos sin romper el juego base.
05 · Representación en Python
Contar dentro de la condición
La condicional se estima filtrando la lista: éxitos de A entre los casos B, no entre todos:
Python en tu navegador. Cambiá las probabilidades y verificá la ley del total.
import random
random.seed(9)
# B = caja rápida con P=0.4. P(A|B)=0.7, P(A|no B)=0.3
N = 5000
AyB = B = A = 0
for _ in range(N):
b = random.random() < 0.4
a = random.random() < (0.7 if b else 0.3)
B += b; A += a; AyB += (a and b)
print("P(A):", round(A / N, 3))
print("P(A|B):", round(AyB / B, 3))
print("total:", round(0.7*0.4 + 0.3*0.6, 3))
Consejo: el último número es la ley del total: 0,46. La simulación debe pegarse a él.
Tabla de contingencia en código
import random
random.seed(2)
# Contar los 4 casilleros y derivar condicionales
cas = {"AB": 0, "Ab": 0, "aB": 0, "ab": 0}
for _ in range(3000):
b = random.random() < 0.4
a = random.random() < (0.7 if b else 0.3)
clave = ("A" if a else "a") + ("B" if b else "b")
cas[clave] += 1
print(cas)
print("P(A|B):", round(cas["AB"] / (cas["AB"] + cas["aB"]), 3))
06 · Exploración
Laboratorio: ramas que se verifican con el total
Simulamos clientes: con prob. q van a caja rápida. La prob. de atención veloz es p₁ en rápida y p₀ en normal. Las barras claras son teoría; las sólidas, simulación. La tercera barra P(A) debe cerrar con q·p₁ + (1−q)·p₀.
Condicional y total
P(A) = q·p₁ + (1−q)·p₀
La barra total simulada debe pegarse a la teórica.
Tres grupos: P(A|B), P(A|Bᶜ) y P(A). N = 3000 fijo para que el error sea chico y se vea el cierre del total.
Preguntas para explorar
- Igualá p₁ = p₀ = 0,5. ¿Qué pasa con la diferencia entre ramas? ¿Qué significa?
- Poné q = 0,1. ¿La estimación de P(A|B) salta más o menos? ¿Por qué?
- Si P(A|B) = 0,9 y P(A|Bᶜ) = 0,2 con q = 0,5, ¿cuánto vale P(A)? Verificalo en el laboratorio.
Ver respuestas sugeridas
- Se igualan: la condición B no informa nada sobre A. Saber la caja no cambia la chance.
- Salta más: hay pocos casos B (10 % de 3000 ≈ 300) y la condicional se estima con menos datos.
- 0,55 = 0,5×0,9 + 0,5×0,2. La barra total debe marcar ~0,55 en teoría y simulación.
07 · Comprensión
Confusiones frecuentes
«P(A|B) es lo mismo que P(B|A)»
No: una filtra por B, la otra por A. P(veloz|rápida) = 0,7 no implica P(rápida|veloz) = 0,7. Son denominadores distintos.
«Condicionar siempre sube la probabilidad»
Puede subir o bajar: P(A|B) = 0,7 supera al total 0,46, pero P(A|Bᶜ) = 0,3 está por debajo. Actualizar es mover, no inflar.
«El total es el promedio simple de las ramas»
Es promedio ponderado por P(rama). Ignorar q es el error más común al combinar segmentos.
«Con pocos casos B ya estimo»
La condicional vive de NB. Con 30 casos B el error es grande aunque N total sea 5000.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: leer la tabla
Con la tabla de 1000 clientes de la sección 02, calculá P(B|A): de los veloces, ¿qué fracción usó caja rápida?
# Tabla: AB=280, aB=120, Ab=180, ab=420
AB, Ab = 280, 180
print("P(B|A):", round(AB / (AB + Ab), 3))
print("P(A|B):", round(AB / (AB + 120), 3))
Ver solución razonada
P(B|A) = 280/460 ≈ 0,609: el 61 % de los veloces pasó por rápida. Distinto de P(A|B) = 0,7. Mismo numerador, distinto denominador.
Ejercicio 2: verificar el total
Con q = 0,25, p₁ = 0,8, p₀ = 0,4, calculá el total exacto y verificalo con 8000 réplicas.
import random
random.seed(11)
q, p1, p0, N = 0.25, 0.8, 0.4, 8000
ex = sum(1 for _ in range(N) if random.random() < (p1 if random.random() < q else p0))
print("sim:", round(ex / N, 3), "| total:", round(q*p1 + (1-q)*p0, 3))
Ver solución
El total es 0,5. La simulación cae a ±0,01. Si tu código no cierra con el total, revisá el orden de los sorteos (primero rama, luego resultado).
Ejercicio 3: segmento chico, error grande
Con q = 0,05 estimá P(A|B) con N = 2000. Repetilo con 3 semillas y mirá el salto. ¿Qué harías?
Ver una posible respuesta
import random
def est(semilla, q=0.05, p1=0.7, N=2000):
random.seed(semilla)
b = a_y_b = 0
for _ in range(N):
if random.random() < q:
b += 1
if random.random() < p1:
a_y_b += 1
return a_y_b / b, b
for s in [1, 2, 3]:
print(s, [round(v, 3) if isinstance(v, float) else v for v in est(s)])
Con q = 0,05 hay ~100 casos B y la estimación salta ±0,05. Solución: más N, o juntar segmentos, o informar el intervalo (tema 33).
09 · Síntesis
Ideas para recordar
- P(A|B) filtra por B: éxitos de A entre casos B.
- El total pondera ramas: P(A) = Σ P(A|rama)·P(rama).
- P(A|B) ≠ P(B|A): el denominador manda.
- En Python: primero se sortea la rama, luego el resultado con su probabilidad.
- La precisión de la condicional depende de NB, no de N total.
En el próximo tema veremos cuándo la condición no cambia nada: independencia.