Probabilidad y Estadística · Tema 06

Probabilidad condicional

Actualizar la chance cuando sabemos algo más: qué cambia al condicionar, cómo se calcula P(A|B) y cómo se usa en filtros, embudos y ramas del simulador.

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

P(A|B)

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.

1000 clientes: B = «usó caja rápida», A = «esperó menos de 5 min».
A (rápido)Aᶜ (lento)Total
B (caja rápida)280120400
Bᶜ (normal)180420600
Total4605401000

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

Sé B→Filtra NB→P(A|B)
  1. 1
    Cola.

    P(espera menor a 5 | caja rápida) = 0,7 vs 0,3 en normal. Refuerza abrir la rápida en picos.

  2. 2
    Ventas.

    P(compra | vio oferta) vs P(compra | no vio). Mide el efecto real de la oferta.

  3. 3
    Soporte.

    P(resuelve al primer contacto | cliente nuevo) segmenta capacitación.

  4. 4
    Máquinas.

    P(falla | pasó mantenimiento) vs P(falla | no pasó). Justifica el mantenimiento.

  5. 5
    Juego.

    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₀.

EXPERIMENTO 06

Condicional y total

P(A) = q·p₁ + (1−q)·p₀

Los resultados numéricos aparecen debajo.
P̂(A|B) rápida0,000
P̂(A|Bᶜ) normal0,000
P̂(A) total0,000
Total teórico0,000

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

  1. Igualá p₁ = p₀ = 0,5. ¿Qué pasa con la diferencia entre ramas? ¿Qué significa?
  2. Poné q = 0,1. ¿La estimación de P(A|B) salta más o menos? ¿Por qué?
  3. 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
  1. Se igualan: la condición B no informa nada sobre A. Saber la caja no cambia la chance.
  2. Salta más: hay pocos casos B (10 % de 3000 ≈ 300) y la condicional se estima con menos datos.
  3. 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.