Análisis estadístico experimental con Python
Al finalizar este tema
Podrá realizar una prueba t para comparar dos grupos, utilizar ANOVA para comparar tres o más grupos e interpretar correctamente el valor p.
¿Por qué son necesarias las pruebas estadísticas?
La tasa de supervivencia celular promedio en el grupo tratado con fármaco es del 80 % y en el grupo control es del 85 %. ¿Podemos concluir que "el fármaco es efectivo"?
Que las medias sean diferentes no implica necesariamente que haya una "diferencia real". Al repetir el experimento, se obtienen valores distintos cada vez; esto es la variación. Es necesario distinguir si una diferencia del 5 % se debe al efecto del fármaco o simplemente a un error experimental.
La herramienta para determinar esto es la prueba estadística, y su resultado es el valor p.
¿Qué es el valor p?
El valor p es la "probabilidad de que esta diferencia ocurra por azar, bajo la suposición de que no existe diferencia alguna".
p-value = 0.03 → "La probabilidad de que esta diferencia ocurra por casualidad si no hay diferencia es del 3%"
→ Difícil de considerar casualidad → Se decide que hay diferencia
p-value = 0.42 → "La probabilidad de que esta diferencia ocurra por casualidad si no hay diferencia es del 42%"
→ Podría ser suficientemente casual → Difícil afirmar que hay diferenciaPor convención, se considera que p < 0.05 es "estadísticamente significativo". Sin embargo, 0.05 no es un criterio absoluto, sino una convención.
Prueba t: comparación de dos grupos
Prueba t independiente — compara las medias de dos grupos independientes.
import numpy as npfrom scipy import stats
# Tasa de supervivencia celular del grupo tratado con fármaco (%)drug = np.array([78, 82, 75, 80, 77, 83, 79, 76])
# Tasa de supervivencia celular del grupo control (%)control = np.array([85, 88, 82, 86, 90, 84, 87, 89])
t_stat, p_value = stats.ttest_ind(drug, control)
print(f"Promedio del Grupo Control: {control.mean():.1f}%")print(f"Estadístico t: {t_stat:.3f}")print(f"t-statistic: {t_stat:.3f}")print(f"p-value: {p_value:.4f}")
if p_value < 0.05: print("→ Diferencia estadísticamente significativa (p < 0.05)")else: print("→ No hay diferencia significativa")
assert p_value < 0.05stats.ttest_ind() — prueba t para muestras independientes. Se utiliza cuando los dos grupos son muestras distintas.
Prueba t pareada: comparación antes y después en la misma muestra
Para comparar los resultados antes y después del tratamiento en el mismo paciente, se utiliza la prueba t pareada:
from scipy import statsimport numpy as np
before = np.array([120, 135, 128, 142, 138, 125])after = np.array([115, 128, 122, 130, 132, 118])
t_stat, p_value = stats.ttest_rel(before, after)
print(f"Promedio después del tratamiento: {after.mean():.1f}")print(f"p-value: {p_value:.4f}")print(f"p-value: {p_value:.4f}")ttest_rel() — prueba t relacionada. Compara los valores medidos antes y después en el mismo sujeto.
| Situación | Método de prueba | Función de scipy |
|---|---|---|
| Comparación de dos grupos distintos | Prueba t independiente | stats.ttest_ind() |
| Comparación antes/después en el mismo sujeto | Prueba t pareada | stats.ttest_rel() |
ANOVA: Comparación de tres o más grupos
¿Cómo comparar las tasas de proliferación celular en tres medios diferentes (DMEM, RPMI y MEM)? Dado que la prueba t solo puede comparar dos grupos, se utiliza ANOVA (Análisis de Varianza).
from scipy import statsimport numpy as np
dmem = np.array([1.2, 1.4, 1.3, 1.5, 1.1])rpmi = np.array([1.8, 1.7, 1.9, 2.0, 1.6])mem = np.array([1.0, 1.1, 0.9, 1.2, 1.0])
f_stat, p_value = stats.f_oneway(dmem, rpmi, mem)
print(f"DMEM promedio: {dmem.mean():.2f}")print(f"RPMI promedio: {rpmi.mean():.2f}")print(f"MEM promedio: {mem.mean():.2f}")print(f"F-statistic: {f_stat:.3f}")print(f"p-value: {p_value:.6f}")
assert p_value < 0.05Un p-valor significativo en el ANOVA significa que "al menos uno de los tres grupos es diferente". Para determinar qué grupo es el que difiere, se debe realizar una prueba post-hoc.
Visualización de resultados: diagrama de caja
Es difícil comprender la distribución utilizando solo números. Por ello, se visualiza mediante un diagrama de caja:
import matplotlib.pyplot as pltimport numpy as np
drug = np.array([78, 82, 75, 80, 77, 83, 79, 76])control = np.array([85, 88, 82, 86, 90, 84, 87, 89])
fig, ax = plt.subplots(figsize=(6, 4))ax.boxplot([drug, control], labels=["Drug", "Control"])ax.set_ylabel("Cell Viability (%)")ax.set_title("Drug vs Control")plt.tight_layout()plt.savefig("drug_vs_control.png", dpi=150)plt.show()El diagrama de caja y bigotes muestra de un vistazo la mediana, el rango intercuartílico y los valores atípicos. Es uno de los tipos de gráficos más comunes en las figuras de artículos científicos.
Precauciones: las trampas del valor p
Puntos a tener en cuenta al interpretar el valor p:
1. Que p < 0.05 no significa que la diferencia sea "importante"
La significancia estadística y la relevancia práctica son distintas. Si el tamaño de la muestra es muy grande, incluso una diferencia mínima puede resultar en un p < 0.05. Siempre pregúntese: "¿esta diferencia tiene relevancia biológica?".
2. Que p > 0.05 no significa que "no haya diferencia"
Significa que "no se encontró evidencia de una diferencia". Si el tamaño de la muestra es demasiado pequeño, es posible que no se detecte una diferencia real.
3. El problema de las comparaciones múltiples
Si se realizan pruebas simultáneas para 20.000 genes, 1.000 de ellos (el 5%) tendrán aleatoriamente un p < 0.05. En este caso, es necesario aplicar la corrección de Bonferroni o la corrección de la Tasa de Falso Descubrimiento (FDR).
Práctica directa (Ejemplo desvanecido)
Complete los espacios en blanco a continuación para realizar una prueba t entre dos grupos.
from import statsimport numpy as nptreated = np.array([4.2, 3.8, 4.5, 4.1, 3.9])control = np.array([5.1, 5.3, 4.9, 5.0, 5.2])t_stat, p_value = stats.ind(treated, control)print(f"p-value: {p_value:.4f}")if p_value < :print("Diferencia significativa")
Errores comunes y soluciones
Q: ModuleNotFoundError: No module named 'scipy'
Instálelo con pip install scipy. En Google Colab ya viene instalado.
Q: ¿Debo usar la prueba t o ANOVA?
Si compara 2 grupos, use la prueba t; si son 3 o más, use ANOVA. Si compara 3 grupos mediante tres pruebas t (A-B, A-C, B-C), surge el problema de comparaciones múltiples, por lo que debe usar ANOVA.
Q: ¿Qué hacer si los datos no siguen una distribución normal?
La prueba t y ANOVA asumen que los datos siguen aproximadamente una distribución normal. Si no es el caso, utilice pruebas no paramétricas: Mann-Whitney U test (stats.mannwhitneyu()), Kruskal-Wallis test (stats.kruskal()).
Q: nan aparece en los resultados
Es posible que los datos contengan valores faltantes (NaN). Utilice una función como np.nanmean(data) que ignore nan, o elimine los valores faltantes con df.dropna() en Pandas antes de realizar la prueba.