01 · Punto de partida
La táctica decide el ruido
Dos formas de comparar Q = 100 vs 90 con igual N: con semillas comunes la diferencia sale 50 ± 5; con semillas distintas, 50 ± 20. Mismo costo, cuádruple precisión. La táctica es gratis y paga.
Táctico = cómo se corre: semillas, orden, bloques, versiones y logs. Estratégico (tema 32) = qué se pregunta.
- ¿Mismas semillas en todas las celdas?
- ¿En qué orden corro las celdas?
- ¿Qué versión de código y datos?
- ¿Qué log permite repetirlo?
02 · Definición
Cuatro reglas tácticas
Semillas
Lista explícita 1…R, mismas en cada celda. Nada de azar del sistema.
Orden
Aleatorizar el orden de celdas por bloque si hay estado externo. Si no, bloque prolijo.
Registro
Código + semillas + N + fecha + máquina. Repetible con un comando.
| Regla | Bien | Mal |
|---|---|---|
| Semillas | [1…10] en todas | Distintas por celda |
| Piloto | 500 por celda antes | Directo al final |
| Orden | Bloques o aleatorio anotado | Siempre A luego B |
| Log | CSV con (celda, semilla, N, media) | Solo la media final |
03 · Técnicas
- 1Números comunes.
Mismas semillas ⇒ diferencias con varianza (σ_A² + σ_B² − 2Cov)/n. Cov > 0 achica.
- 2Bloques completos.
Cada semilla recorre todas las celdas antes de pasar a la siguiente.
- 3Piloto y parada.
500 por celda, medir σ, proyectar N, correr final una vez.
- Cov positiva
- Las mismas demandas suben/bajan a ambas políticas juntas: la diferencia se estabiliza.
- Sincronizar sorteos
- El mismo U para la misma incertidumbre en cada política: no mezclar el orden de
random(). - Versionar
- Git +
requirements+ semilla = experimento repetible en otra máquina.
04 · Ejemplos
- 1Q 100 vs 90.
Comunes: dif 50 ± 5. Independientes: 50 ± 20. Misma N.
- 2Precio A/B.
Mismas demandas para ambos precios: la diferencia es mérito, no suerte.
- 3Orden.
Si la PC se calienta y baja reloj, alternar A/B evita favorecer al primero.
05 · Representación en Python
Comunes vs independientes, medido
Python en tu navegador. La diferencia es la táctica, no el modelo.
import random
import statistics
def media(Q, N, semilla):
random.seed(semilla)
tot = 0
for _ in range(N):
D = random.choices([80, 100, 120], weights=[30, 40, 30])[0]
tot += 5*min(Q, D) - 2*Q
return tot / N
N = 2000
comunes = [media(100, N, s) - media(90, N, s) for s in range(1, 11)]
indep = [media(100, N, 100+s) - media(90, N, 200+s) for s in range(1, 11)]
print("comunes s:", round(statistics.pstdev(comunes), 2))
print("indep s:", round(statistics.pstdev(indep), 2))
06 · Exploración
Laboratorio: la misma suerte para todos
Diferencia Q100 − Q90 ≈ 50 en 10 bloques. Verde: mismos U (apiñadas). Gris: U distintos (desparramadas). Mismo N, distinto ±.
Bloques que cancelan ruido
dif_s con y sin números comunes
Tocá «Comparar» para correr 10 bloques.
Cada punto es un bloque (semilla). Verdes juntos = la táctica paga. Grises sueltos = ruido evitable.
Preguntas para explorar
- ¿El factor ronda 4–16? ¿Cambia con n?
- ¿Por qué los verdes se apiñan si usan los mismos datos?
- ¿Cuándo NO convienen los números comunes?
Ver respuestas sugeridas
- Sí, estable: es correlación, no N. n achica ambos, el cociente queda.
- La misma demanda sube/baja a ambas Q: la resta cancela lo común.
- Si las políticas usan distinto n° de sorteos o modelos distintos: no se puede sincronizar.
07 · Comprensión
Confusiones frecuentes
«Semillas comunes sesgan»
No: cada política sigue insesgada; solo sus diferencias tienen menos varianza.
«Con N grande da igual»
El factor persiste a todo N: es correlación, no tamaño.
«El orden no importa en estática»
En el modelo no; en la máquina sí (caché, reloj, logs). Aleatorizar cuesta nada.
«Guardo solo la media final»
Guardá por (celda, semilla): sin bloques no hay diagnóstico ni re-análisis.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: medir el factor táctico
Calculá s de difs comunes vs independientes con n = 1 000.
import random
import statistics
def media(Q, N, s):
random.seed(s)
return sum(5*min(Q, random.choices([80,100,120], weights=[30,40,30])[0])-2*Q for _ in range(N))/N
com = [media(100, 1000, s)-media(90, 1000, s) for s in range(10)]
ind = [media(100, 1000, 100+s)-media(90, 1000, 200+s) for s in range(10)]
print(round(statistics.pstdev(com), 2), round(statistics.pstdev(ind), 2))
Ver solución razonada
~5 vs ~20: factor ~16. La táctica vale más que cuadruplicar N.
Ejercicio 2: log por bloques
Guardá la tabla (Q, semilla, media) como lista de dicts.
log = [{"Q": Q, "s": s, "m": None} for Q in [90, 100] for s in [1, 2, 3]]
print(log[:3], "... total", len(log))
Ver solución
6 filas auditables. Con N y medias completas, el experimento se repite y se grafica.
Ejercicio 3: sincronizar sorteos
Mostrá que un sorteo extra desincroniza: agregá un random() en una rama y mirá la correlación.
Ver una posible respuesta
import random
def media_extra(Q, N, s):
random.seed(s)
random.random() # sorteo fantasma: desincroniza
return sum(5*min(Q, random.choices([80,100,120], weights=[30,40,30])[0])-2*Q for _ in range(N))/N
print("Sin fantasma la correlación es alta; con fantasma cae. No tocar random() a ciegas.")
Moraleja: el consumo de azar es parte del protocolo. Versionarlo también.
09 · Síntesis
Ideas para recordar
- Mismas R semillas en todas las celdas: números comunes.
- Comparar dentro del bloque: dif_s, no medias sueltas.
- Sincronizar el consumo de U por política.
- Piloto, bloques, orden anotado y log por (celda, semilla).
- La táctica es gratis: factor 4–16 sin más N.
En el próximo tema subiremos un nivel: el planteo estratégico de experimentos.