Tests de Hipotesis con SciPy
Tomando Decisiones Basadas en DatosLos tests de hipotesis son la base de la toma de decisiones en data science. Te permiten responder preguntas como: Es este cambio significativo? Hay diferencia real entre estos dos grupos? Este resultado es producto del azar?
Conceptos Clave
# Hipotesis nula (H0): No hay diferencia / No hay efecto
# Hipotesis alternativa (H1): SI hay diferencia / SI hay efecto
# p-valor: Probabilidad de obtener este resultado si H0 fuera verdadera
# Si p-valor < 0.05: Rechazamos H0 (resultado significativo)
# Si p-valor >= 0.05: No rechazamos H0
El Framework de Decision
| p-valor | Decision | Confianza |
|---|---|---|
| < 0.001 | Altamente significativo | 99.9% |
| < 0.01 | Muy significativo | 99% |
| < 0.05 | Significativo | 95% |
| >= 0.05 | No significativo | Insuficiente |
Test t de Student: Comparar Dos Grupos
Test t para dos muestras independientes
import numpy as np
from scipy import stats
import pandas as pd
np.random.seed(42)
# Ejemplo: Salarios de hombres vs mujeres
salarios_grupo_a = np.random.normal(72000, 15000, 100)
salarios_grupo_b = np.random.normal(68000, 14000, 100)
# Test t de dos muestras
t_stat, p_valor = stats.ttest_ind(salarios_grupo_a, salarios_grupo_b)
print("Test t: Comparacion de salarios entre grupos")
print(f"Grupo A: Media=${salarios_grupo_a.mean():,.0f}, n={len(salarios_grupo_a)}")
print(f"Grupo B: Media=${salarios_grupo_b.mean():,.0f}, n={len(salarios_grupo_b)}")
print(f"Diferencia: ${salarios_grupo_a.mean() - salarios_grupo_b.mean():,.0f}")
print(f"t-statistic: {t_stat:.4f}")
print(f"p-valor: {p_valor:.4f}")
print(f"Resultado: {'Diferencia SIGNIFICATIVA' if p_valor < 0.05 else 'Diferencia NO significativa'}")
Test t pareado (antes y despues)
# Ejemplo: Productividad antes y despues de una capacitacion
np.random.seed(42)
antes = np.random.normal(75, 12, 50)
mejora = np.random.normal(8, 5, 50) # Mejora promedio de 8 puntos
despues = antes + mejora
t_stat, p_valor = stats.ttest_rel(antes, despues)
print("\nTest t pareado: Antes vs Despues de capacitacion")
print(f"Antes: Media={antes.mean():.1f}")
print(f"Despues: Media={despues.mean():.1f}")
print(f"Mejora promedio: {(despues - antes).mean():.1f} puntos")
print(f"p-valor: {p_valor:.6f}")
print(f"La capacitacion tuvo efecto? {'SI' if p_valor < 0.05 else 'NO'}")
Test Chi-Cuadrado: Variables Categoricas
# Ejemplo: Preferencia de producto por region
datos = pd.DataFrame({
'region': ['Norte']*60 + ['Sur']*40 + ['Norte']*30 + ['Sur']*70,
'producto': ['A']*60 + ['A']*40 + ['B']*30 + ['B']*70
})
# Tabla de contingencia
tabla = pd.crosstab(datos['region'], datos['producto'])
print("Tabla de contingencia:")
print(tabla)
# Test Chi-cuadrado
chi2, p_valor, dof, expected = stats.chi2_contingency(tabla)
print(f"\nChi-cuadrado: {chi2:.4f}")
print(f"p-valor: {p_valor:.4f}")
print(f"Grados de libertad: {dof}")
print(f"La preferencia depende de la region? {'SI' if p_valor < 0.05 else 'NO'}")
ANOVA: Comparar 3+ Grupos
# Ejemplo: Salarios por departamento
np.random.seed(42)
marketing = np.random.normal(65000, 10000, 40)
ventas = np.random.normal(70000, 12000, 40)
it = np.random.normal(82000, 15000, 40)
rrhh = np.random.normal(60000, 8000, 40)
# ANOVA de una via
f_stat, p_valor = stats.f_oneway(marketing, ventas, it, rrhh)
print("ANOVA: Salarios por departamento")
print(f"Marketing: ${marketing.mean():,.0f}")
print(f"Ventas: ${ventas.mean():,.0f}")
print(f"IT: ${it.mean():,.0f}")
print(f"RRHH: ${rrhh.mean():,.0f}")
print(f"\nF-statistic: {f_stat:.4f}")
print(f"p-valor: {p_valor:.6f}")
print(f"Hay diferencias significativas entre departamentos? {'SI' if p_valor < 0.05 else 'NO'}")
# Post-hoc: Cual departamento es diferente?
from itertools import combinations
grupos = {'Marketing': marketing, 'Ventas': ventas, 'IT': it, 'RRHH': rrhh}
print("\nComparaciones por pares:")
for (n1, g1), (n2, g2) in combinations(grupos.items(), 2):
_, p = stats.ttest_ind(g1, g2)
sig = '*' if p < 0.05 else ''
print(f" {n1} vs {n2}: p={p:.4f} {sig}")
A/B Testing (Caso de Negocio)
# Ejemplo: Test A/B de una pagina web
# Version A: 1000 visitantes, 120 conversiones
# Version B: 1000 visitantes, 145 conversiones
n_a, conv_a = 1000, 120
n_b, conv_b = 1000, 145
tasa_a = conv_a / n_a
tasa_b = conv_b / n_b
mejora = (tasa_b - tasa_a) / tasa_a * 100
# Test de proporciones
z_stat, p_valor = stats.proportions_ztest(
[conv_a, conv_b],
[n_a, n_b],
alternative='two-sided'
)
print("A/B Test de Conversion")
print(f"Version A: {tasa_a:.1%} ({conv_a}/{n_a})")
print(f"Version B: {tasa_b:.1%} ({conv_b}/{n_b})")
print(f"Mejora relativa: +{mejora:.1f}%")
print(f"\nz-statistic: {z_stat:.4f}")
print(f"p-valor: {p_valor:.4f}")
print(f"Version B es significativamente mejor? {'SI' if p_valor < 0.05 else 'NO'}")
Video Recomendado
Tests de Hipotesis con Python - Guia Practica
Ejercicio Practico
Crea un notebook 14_tests_hipotesis.ipynb:
- Genera datos de dos grupos y aplica un test t para ver si hay diferencia significativa
- Simula un A/B test con tasas de conversion del 5% vs 6.5% y determina si es significativo
- Aplica ANOVA para comparar el rendimiento de 4 regiones de ventas
- Usa Chi-cuadrado para analizar si hay relacion entre genero y preferencia de producto
- Para cada test, escribe la hipotesis nula, alternativa e interpretacion del resultado
💡 Concepto Clave
Revisemos los puntos más importantes de esta lección antes de continuar.
Resumen
- Test t: Comparar medias de 2 grupos (independientes o pareados)
- ANOVA: Comparar medias de 3+ grupos
- Chi-cuadrado: Relacion entre variables categoricas
- Test de proporciones: Comparar tasas (A/B testing)
- p-valor < 0.05: Resultado estadisticamente significativo
- Siempre reporta el tamano del efecto, no solo la significancia
🧠 Pon a prueba tu conocimiento
¿Cuál es el aspecto más importante que aprendiste en esta lección?
- Comprendo el concepto principal y puedo explicarlo con mis palabras
- Entiendo cómo aplicarlo en mi situación específica
- Necesito repasar algunas partes antes de continuar
- Quiero ver más ejemplos prácticos del tema
✅ ¡Excelente! Continúa con la siguiente lección para profundizar más.