Dirección de Educación Continua.
En este cuadernillo exploraremos paso a paso cómo aplicar pruebas de hipótesis estadísticas en un contexto de marketing digital, particularmente para el análisis de una campaña de email marketing con pruebas A/B. Cubriremos tanto la teoría fundamental (hipótesis nula y alternativa, errores Tipo I y II, potencia, valor p, regiones críticas) como ejemplos prácticos aplicados a datos simulados de marketing (tasa de apertura, clics, conversiones, ticket medio o valor promedio de compra, etc.).
Usaremos un único conjunto de datos ficticio, coherente con un escenario realista de una campaña digital. Este dataset simula el flujo de conversión de usuarios: cuántos abren un email, hacen clic, convierten en una compra y cuánto gastan en promedio. Sobre este conjunto de datos desarrollaremos diversas pruebas de hipótesis, incluyendo:
Se utilizarán librerías de R como dplyr
,
readxl
y ggplot2
, explicando en cada caso los
parámetros y resultados de las funciones estadísticas involucradas. El
documento está organizado de forma progresiva: primero simularemos los
datos y presentaremos el escenario, luego repasaremos los conceptos
teóricos clave, y finalmente aplicaremos las pruebas con ejemplos
comentados, gráficos ilustrativos y ejercicios propuestos para
practicar.
Imaginemos que trabajamos en el departamento de marketing de una empresa que está llevando a cabo una campaña de email para promocionar un producto. Se envió un email promocional a una lista de clientes, y se está realizando una prueba A/B con dos variantes del correo electrónico:
Cada usuario recibe un único email (A o B) y puede o no realizar las siguientes acciones en secuencia:
Vamos a simular un conjunto de datos que refleje este flujo. Supongamos que en total se enviaron 20,000 correos (10,000 usuarios al Grupo A y 10,000 al Grupo B). Definiremos algunas tasas probables basadas en la experiencia:
Supondremos que el ticket medio (monto de compra) para ambas variantes ronda los $50 con una variabilidad (desviación estándar) de unos $20. Usaremos estas probabilidades para generar datos aleatorios coherentes. Cada fila del dataset representará un usuario con columnas indicando su grupo (A/B), si abrió el correo, si hizo clic, si convirtió, y cuánto gastó (si convirtió, en caso contrario el gasto será 0). Procedamos a crear este dataset sintético utilizando R.
# Instalar y cargar los paquetes necesarios
# install.packages(c("dplyr", "writexl"))
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(writexl)
# Fijamos una semilla para reproducibilidad (equivalente a np.random.seed(42))
set.seed(42)
N_A <- 10000 # usuarios en grupo A
N_B <- 10000 # usuarios en grupo B
N_total <- N_A + N_B
# Probabilidades definidas para cada grupo
p_open_A <- 0.25
p_click_given_open_A <- 0.20
p_conv_given_click_A <- 0.08
p_open_B <- 0.30
p_click_given_open_B <- 0.22
p_conv_given_click_B <- 0.12
mean_order <- 50 # media del ticket medio en ambos grupos
std_order <- 20 # desviación estándar del ticket medio
# Asignamos cada usuario a su grupo
groups <- c(rep('A', N_A), rep('B', N_B))
df <- data.frame(grupo = groups)
# Simular apertura (equivalente a np.random.rand y np.where)
random_open <- runif(N_total)
prob_open <- ifelse(df$grupo == 'A', p_open_A, p_open_B)
df$abierto <- as.integer(random_open < prob_open)
# Simular clic (solo puede ocurrir si 'abierto' es 1)
random_click <- runif(N_total)
prob_click <- ifelse(df$grupo == 'A', p_click_given_open_A, p_click_given_open_B)
df$click <- as.integer((random_click < prob_click) & (df$abierto == 1))
# Simular conversión (solo puede ocurrir si 'click' es 1)
random_conv <- runif(N_total)
prob_conv <- ifelse(df$grupo == 'A', p_conv_given_click_A, p_conv_given_click_B)
df$convertido <- as.integer((random_conv < prob_conv) & (df$click == 1))
# Simular monto de compra para los que convirtieron
monto <- numeric(N_total)
# Grupo A
conv_indices_A <- (df$grupo == 'A') & (df$convertido == 1)
n_conv_A <- sum(conv_indices_A)
monto_A <- rnorm(n_conv_A, mean = mean_order, sd = std_order)
monto_A[monto_A < 0] <- 0 # reemplazar valores negativos por 0
monto[conv_indices_A] <- monto_A
# Grupo B
conv_indices_B <- (df$grupo == 'B') & (df$convertido == 1)
n_conv_B <- sum(conv_indices_B)
monto_B <- rnorm(n_conv_B, mean = mean_order, sd = std_order)
monto_B[monto_B < 0] <- 0
monto[conv_indices_B] <- monto_B
df$monto <- monto
# Veamos las primeras filas del DataFrame resultante
head(df)
## grupo abierto click convertido monto
## 1 A 0 0 0 0
## 2 A 0 0 0 0
## 3 A 0 0 0 0
## 4 A 0 0 0 0
## 5 A 0 0 0 0
## 6 A 0 0 0 0
# Exportar a Excel (opcional, equivalente a df.to_excel)
write_xlsx(df, 'datos_simulados.xlsx')
Cada fila indica, por ejemplo, que el usuario 1 (índice 0) del grupo
A no abrió el correo (abierto=0, y por tanto click=0, convertido=0). El
usuario 2 (índice 1) del grupo A abrió el correo (abierto=1) pero no
hizo clic (click=0). El usuario 3 (índice 2) abrió y clicó, pero no
convirtió, etc. Si hubiera convertido, veríamos un monto positivo en la
columna monto
.
A continuación, vamos a resumir los resultados globales de la campaña simulada para cada grupo: cuántos usuarios abrieron, clicaron, convirtieron y el total recaudado, así como las tasas correspondientes (% de apertura, % de conversión, etc.):
# Resumen por grupo usando dplyr (equivalente a pandas groupby.agg)
resumen <- df %>%
group_by(grupo) %>%
summarise(
abierto = sum(abierto),
click = sum(click),
convertido = sum(convertido),
monto = sum(monto)
)
# Calcular métricas derivadas
resumen <- resumen %>%
mutate(
# tasa_apertura = abierto / ifelse(grupo == 'A', N_A, N_B),
# tasa_click = click / ifelse(grupo == 'A', N_A, N_B),
# tasa_conversion = convertido / ifelse(grupo == 'A', N_A, N_B),
ticket_medio = monto / convertido
)
print(select(resumen, grupo, ticket_medio))
## # A tibble: 2 × 2
## grupo ticket_medio
## <chr> <dbl>
## 1 A 50.8
## 2 B 53.3
Interpretación del escenario simulado: En el grupo A (control) se enviaron 10,000 emails y aproximadamente el 24.88% fueron abiertos (2488 aperturas). Un 4.94% del total de usuarios hicieron clic (494 clics), y finalmente 38 usuarios convirtieron en una compra, lo que es una tasa de conversión del 0.38% (38/10000). En el grupo B (email variante) también con 10,000 usuarios, la tasa de apertura fue mayor, ~30.20% (3020 aperturas), la tasa de clic del total 6.68% (668 clics), y 80 usuarios convirtieron (0.80% de conversión). Podemos ver que el grupo B superó al A en cada métrica: más aperturas, más clics y más del doble de conversiones. El ticket medio (valor promedio por compra) resultó similar en ambos grupos (unos $49.3 en A vs $50.1 en B).
Estos datos simulan una situación favorable para el Grupo B, sugiriendo que la nueva versión del email pudo haber mejorado la interacción de los usuarios, especialmente la probabilidad de conversión. Sin embargo, para tomar decisiones de negocio debemos realizar pruebas de hipótesis estadísticas que confirmen si las diferencias observadas son estadísticamente significativas o si podrían deberse al azar.
Antes de entrar en los análisis específicos (pruebas sobre medias, proporciones y el A/B test), repasemos los conceptos teóricos clave que necesitamos entender para interpretar correctamente los resultados.
Además de la intuición hemos añadido aquí otro modo de conocer; el que tiene lugar por deducción: por la cual entendemos todo aquello que se sigue necesariamente de otras cosas conocidas con certeza. […] Así pues, distinguimos aquí la intuición de la mente de la deducción en que ésta es concebida como un movimiento o sucesión, pero no ocurre de igual modo con aquélla; y además, porque para ésta no es necesaria una evidencia actual, como para la intuición, sino que más bien reciben en cierto modo de la memoria su certeza.
Vamos a aprender los pasos de la formulación de hipótesis estadísticas basados en una historia de amor.
La Ho es la base formal para examinar la significación estadística. Según la Ho, las diferencias observadas en las muestras son debidas únicamente al azar, es decir que las muestras provienen de una misma población. De este modo, la H1 y la Ho se excluyen mutuamente como explicaciones de los resultados de un mismo estudio.
La H1 establece que existen diferencias reales entre los grupos comparados; la relación entre las variables se puede formular de dos modos. La H1 bilateral o de 2 colas contempla la posibilidad de que la asociación entre variables se produzca en cualquier sentido; por ejemplo, el ejercicio físico puede modificar (aumentar o disminuir) la incidencia de infarto de miocardio.
La H1 unilateral o de una cola afirma la asociación en un solo sentido o dirección que puede ser de aumento o disminución; por ejemplo, el empleo de un nuevo tratamiento aumenta la supervivencia media de los pacientes respecto al tratamiento anterior.
El nivel de significación \((\alpha)\) se elige antes de aplicar las pruebas estadísticas y depende del nivel de confianza \((NC=1-\alpha)\) que desea el investigador para decidir si, finalmente, las diferencias halladas se atribuyen o no al azar.
Por consiguiente, antes de la prueba se establece un nivel de significación \((\alpha)\), y posteriormente se compara con el resultado (p) obtenido en la correspondiente prueba estadística. El valor p da argumentos al investigador para decidir el rechazo o mantenimiento de la Ho. Así se determina la probabilidad de que las diferencias observadas sean debidas al azar, siempre suponiendo que la Ho sea verdadera.
El nivel de significación \((\alpha)\) que permite rechazar a la Ho, suele fijarse en el 0,05, pero naturalmente el EI puede otorgarle otros valores (0,01; 0,001, entre otros) dependiendo de las consecuencias de la decisión a adoptar.
La prueba de significación es un procedimiento estadístico para valorar la verosimilitud de una hipótesis respecto a los datos empíricos. La prueba elegida depende de un conjunto de factores cuya valoración es esencial para aplicar la prueba más adecuada.
Basándose en la comparación de la p obtenida y la * preestablecida, se decide si se rechaza o no la Ho. Debe evitarse la expresión «se acepta la Ho», porque conduce a pensar que se ha demostrado que ésta es verdadera. Lo más que puede afirmarse es que los datos correspondientes a una de las posibles muestras no permiten rechazar la Ho.
Además de la intuición hemos añadido aquí otro modo de conocer; el que tiene lugar por deducción: por la cual entendemos todo aquello que se sigue necesariamente de otras cosas conocidas con certeza. […] Así pues, distinguimos aquí la intuición de la mente de la deducción en que ésta es concebida como un movimiento o sucesión, pero no ocurre de igual modo con aquélla; y además, porque para ésta no es necesaria una evidencia actual, como para la intuición, sino que más bien reciben en cierto modo de la memoria su certeza.
Vamos a aprender los pasos de la formulación de hipótesis estadísticas basados en una historia de amor.
La Ho es la base formal para examinar la significación estadística. Según la Ho, las diferencias observadas en las muestras son debidas únicamente al azar, es decir que las muestras provienen de una misma población. De este modo, la H1 y la Ho se excluyen mutuamente como explicaciones de los resultados de un mismo estudio.
La H1 establece que existen diferencias reales entre los grupos comparados; la relación entre las variables se puede formular de dos modos. La H1 bilateral o de 2 colas contempla la posibilidad de que la asociación entre variables se produzca en cualquier sentido; por ejemplo, el ejercicio físico puede modificar (aumentar o disminuir) la incidencia de infarto de miocardio.
La H1 unilateral o de una cola afirma la asociación en un solo sentido o dirección que puede ser de aumento o disminución; por ejemplo, el empleo de un nuevo tratamiento aumenta la supervivencia media de los pacientes respecto al tratamiento anterior.
El nivel de significación \((\alpha)\) se elige antes de aplicar las pruebas estadísticas y depende del nivel de confianza \((NC=1-\alpha)\) que desea el investigador para decidir si, finalmente, las diferencias halladas se atribuyen o no al azar.
Por consiguiente, antes de la prueba se establece un nivel de significación \((\alpha)\), y posteriormente se compara con el resultado (p) obtenido en la correspondiente prueba estadística. El valor p da argumentos al investigador para decidir el rechazo o mantenimiento de la Ho. Así se determina la probabilidad de que las diferencias observadas sean debidas al azar, siempre suponiendo que la Ho sea verdadera.
El nivel de significación \((\alpha)\) que permite rechazar a la Ho, suele fijarse en el 0,05, pero naturalmente el EI puede otorgarle otros valores (0,01; 0,001, entre otros) dependiendo de las consecuencias de la decisión a adoptar.
La prueba de significación es un procedimiento estadístico para valorar la verosimilitud de una hipótesis respecto a los datos empíricos. La prueba elegida depende de un conjunto de factores cuya valoración es esencial para aplicar la prueba más adecuada.
Basándose en la comparación de la p obtenida y la * preestablecida, se decide si se rechaza o no la Ho. Debe evitarse la expresión «se acepta la Ho», porque conduce a pensar que se ha demostrado que ésta es verdadera. Lo más que puede afirmarse es que los datos correspondientes a una de las posibles muestras no permiten rechazar la Ho.
Decisión estadística (a partir de la muestra) | ||
---|---|---|
Estado Real | No rechazar H0 | Rechazar H0 |
H0 es cierta | Decisión Correcta \((1-\alpha)\) | Error Tipo I (\(\alpha\)) |
H0 es falsa (H1 es cierta) | Error Tipo II (\(\beta\)) | Decisión Correcta (Potencia \(1-\beta\)) |
En nuestras pruebas más adelante, manejaremos cuidadosamente el nivel de significancia para limitar \(\alpha\) (típicamente a 0.05), e interpretaremos los resultados con precaución respecto a \(\beta\) (por ejemplo, si un resultado no es significativo, consideraremos el tamaño de muestra y posible falta de potencia).
Para decidir si rechazamos o no H0, calculamos un estadístico de prueba a partir de los datos muestrales. Este estadístico (por ejemplo, una Z o t) mide cuán lejos está nuestra estimación muestral del valor planteado por H0, en unidades de desviación estándar. En general, el estadístico de prueba tiene la forma: \[ \text{Estadístico} = \frac{\text{Estimación muestral} - \text{Valor bajo H0}}{\text{error estándar de la estimación}} \] Si H0 es verdadera, este estadístico seguirá aproximadamente una distribución conocida (normal estándar, t de Student, chi-cuadrado, etc., dependiendo del caso y supuestos).
Cuanto más extremo (grande en valor absoluto) sea el estadístico, más evidencia contra H0 tendremos.
Por ejemplo: * Para probar una media con varianza conocida, el estadístico sigue una distribución Z (Normal estándar). * Para una media con varianza desconocida (y muestra pequeña), sigue una distribución t de Student con los grados de libertad correspondientes. * Para proporciones (con n suficientemente grande), podemos usar la aproximación normal (Z). * Para comparar dos proporciones o dos medias, hay estadísticos específicos (Z para diferencia de proporciones, t para diferencia de medias, etc.).
Lo importante es conocer la distribución bajo H0, porque eso nos permite calcular probabilidades y decidir sobre la hipótesis.
Existen dos enfoques equivalentes para tomar la decisión en una prueba de hipótesis:
Al reportar pruebas, es común mencionar el valor p y la conclusión a cierto \(\alpha\). Por ejemplo: “obtenemos p=0.01, por lo que al 5% de significancia rechazamos H0 y concluimos…”. Con estos conceptos claros, pasemos a aplicar pruebas de hipótesis a nuestro escenario de marketing.
Prueba | Estadístico | Fórmula | Variables |
---|---|---|---|
z para la media (σ conocida) | \(Z_{\bar{x}}\) | \(Z = \frac{\bar{x} - \mu_0}{\sigma/\sqrt{n}}\) | \(\bar{x}\): media
muestral \(\mu_0\): media hipotética \(\sigma\): desviación típica poblacional conocida \(n\): tamaño de muestra |
z para una proporción | \(Z_p\) | \(Z = \frac{\hat{p} - p_0}{\sqrt{\frac{p_0(1-p_0)}{n}}}\) | \(\hat{p}\):
proporción muestral \(p_0\): proporción hipotética \(n\): tamaño de muestra |
t para la media (σ desconocida) | \(t_{\bar{x}}\) | \(t = \frac{\bar{x} - \mu_0}{s/\sqrt{n}}\) | \(\bar{x}\): media
muestral \(\mu_0\): media hipotética \(s\): desviación estándar muestral \(n-1\): grados de libertad |
En esta sección analizaremos hipótesis referentes a la media de una distribución, que en marketing podría relacionarse con métricas como el gasto medio por usuario, el valor medio de pedido, etc. Usaremos dos enfoques:
En la práctica, rara vez se conoce la varianza real, por lo que la prueba t es más común. Pero mostraremos ambos casos por aprendizaje.
Contexto: Supongamos que la empresa tiene como meta que el ticket medio de las compras sea de $50. Históricamente, además, conocen que el desvío estándar del monto de las compras es aproximadamente $20 (es decir, \(\sigma = 20\) se asume conocida por estudios previos). Queremos probar si con esta campaña el ticket medio es diferente de $50 o no.
Formulamos hipótesis: * H0: \(\mu = 50\) (el promedio de gasto por compra es 50 dólares). * H1: \(\mu \neq 50\) (el promedio es distinto de 50; usamos bilateral porque podría ser mayor o menor).
Tomaremos los datos de todos los usuarios que convirtieron (hicieron
una compra) en nuestra campaña combinada. En el DataFrame
df
, la columna monto
tiene el valor de la
compra o 0 si no compró; para analizar el ticket medio solo de los
convertidos, extraemos los registros donde convertido == 1
y miramos monto
.
\[ Z = \frac{\bar{x} - \mu_0}{\frac{\sigma}{\sqrt{n}}} \]
# install.packages(c("readxl", "BSDA"))
library(readxl)
library(BSDA)
# Cargar los datos. Asumimos que el archivo 'datos_simulados.xlsx' fue creado previamente.
# Si no, se puede descargar:
# download.file("https://github.com/jazaineam1/Diplomado_ucentral_ME/raw/main/Datos/datos_simulados.xlsx", "marketing.xlsx", mode = "wb")
df <- read_excel("marketing.xlsx")
# Filtrar montos de usuarios que convirtieron (monto > 0)
montos_convertidos <- df$monto[df$convertido == 1]
# Datos para la prueba Z
n <- length(montos_convertidos)
media_muestral <- mean(montos_convertidos)
sigma <- 20 # desviación estándar poblacional (supuesta conocida)
mu0 <- 50 # valor bajo H0
# Calcular estadístico Z manualmente
Z <- (media_muestral - mu0) / (sigma / sqrt(n))
# Calcular p-valor bilateral manualmente
# 2 * P(Z > |Z_obs|) que es 2 * (1 - P(Z < |Z_obs|))
p_value <- 2 * pnorm(abs(Z), lower.tail = FALSE)
cat(sprintf("Media muestral = %.2f, n = %d\n", media_muestral, n))
cat(sprintf("Estadístico Z = %.3f\n", Z))
cat(sprintf("p-valor bilateral = %.4f\n", p_value))
# Regla de decisión con región crítica (alpha = 0.05)
alpha <- 0.05
z_critico_inf <- qnorm(alpha / 2)
z_critico_sup <- qnorm(1 - alpha / 2)
cat(sprintf("\nRegión de no rechazo para Z (alpha=0.05): [%.3f, %.3f]\n", z_critico_inf, z_critico_sup))
if (Z < z_critico_inf || Z > z_critico_sup) {
cat("Conclusión: El estadístico Z cae en la región de rechazo. Rechazamos H0.\n")
} else {
cat("Conclusión: El estadístico Z no cae en la región de rechazo. No rechazamos H0.\n")
}
# --- Nota sobre la comparación con Python ---
# En Python, 'statsmodels.stats.weightstats.ztest' usa la desviación estándar de la muestra si sigma no se proporciona.
# La función z.test del paquete 'BSDA' en R permite especificar sigma.
# El cálculo manual anterior es el más fiel al ejemplo teórico.
# A continuación, mostramos cómo usar la función del paquete BSDA.
z_test_bsda <- z.test(x = montos_convertidos, mu = mu0, sigma.x = sigma, alternative = "two.sided")
cat("\n--- Resultados usando BSDA::z.test ---\n")
print(z_test_bsda)
Interpretación: La media muestral de los tickets es $43.83 con 118 compras observadas. El estadístico Z = -3.352 indica que la media observada está aproximadamente 3.352 errores estándar por debajo de la media hipotética de $50. El valor p asociado es 0.0008.
Con un nivel de significancia \(\alpha=0.05\), vemos que p = 0.0008 < 0.05, por lo que rechazamos H0. Esto significa que encontramos evidencia estadística suficiente para concluir que el ticket medio difiere significativamente de $50. La diferencia observada de $43.83 - $50 = -$6.17 es estadísticamente significativa.
En términos de negocio, esto sugiere que el valor promedio de las compras en la campaña es significativamente menor que la meta de $50.
Contexto: Ahora abordaremos un escenario más realista. En la práctica, rara vez conocemos la desviación estándar poblacional (\(\sigma\)). Por lo tanto, cuando \(\sigma\) es desconocida, la estimamos utilizando la desviación estándar de la muestra (\(s\)). En este caso, la prueba adecuada es la prueba t de Student.
Seguimos con el mismo objetivo: probar si el ticket medio de las compras en la campaña es diferente de $50.
Formulamos las hipótesis: * H0: \(\mu = 50\) (el promedio de gasto por compra es 50 dólares). * H1: \(\mu \neq 50\) (el promedio es distinto de 50; prueba bilateral).
Utilizaremos los mismos datos de montos_convertidos
.
Calcularemos la media muestral (\(\bar{x}\)), la desviación estándar muestral
(\(s\)), el tamaño de la muestra (\(n\)), y luego el estadístico t. Los grados
de freedom (gl) para esta prueba serán \(n-1\).
# --- Cálculo manual de la prueba t ---
# Reutilizamos las variables media_muestral, n, mu0
s_muestral <- sd(montos_convertidos) # sd() en R calcula la desviación estándar muestral (con n-1)
gl <- n - 1 # Grados de libertad
# Calcular el estadístico t manualmente
t_statistic_manual <- (media_muestral - mu0) / (s_muestral / sqrt(n))
# Calcular el p-valor bilateral manualmente
p_value_manual <- 2 * pt(abs(t_statistic_manual), df = gl, lower.tail = FALSE)
cat("--- Cálculo manual de la prueba t ---\n")
cat(sprintf("Media muestral = %.2f\n", media_muestral))
cat(sprintf("Desviación estándar muestral (s) = %.2f\n", s_muestral))
cat(sprintf("Tamaño de la muestra (n) = %d\n", n))
cat(sprintf("Grados de libertad (gl) = %d\n", gl))
cat(sprintf("Estadístico t (calculado manualmente) = %.3f\n", t_statistic_manual))
cat(sprintf("p-valor bilateral (calculado manualmente) = %.4f\n", p_value_manual))
cat("--------------------------------------------\n")
# --- Usando la función t.test() de R (equivalente a scipy.stats.ttest_1samp) ---
# Esta es la forma recomendada y más directa en R.
t_test_result <- t.test(x = montos_convertidos, mu = mu0, alternative = "two.sided")
cat("\n--- Resultados usando la función t.test() de R ---\n")
print(t_test_result)
Interpretación: La media muestral de los tickets de compra es de $43.83, con una desviación estándar muestral de $19.67, basada en 118 compras. El estadístico t calculado es -3.409. Este valor indica que la media muestral observada está aproximadamente 3.409 errores estándar (estimados a partir de la muestra) por debajo de la media hipotética de $50. El p-valor asociado es 0.0009 (0.09%).
Decisión: Con un nivel de significancia \(\alpha = 0.05\), comparamos el p-valor con \(\alpha\): \(p-valor (0.0009) < \alpha (0.05)\)
Dado que el p-valor es menor que el nivel de significancia, rechazamos la hipótesis nula (H0).
Conclusión: Existe evidencia estadística suficiente para concluir que el ticket medio de las compras en la campaña es significativamente diferente de $50. Específicamente, la media observada de $43.83 es significativamente menor que la meta de $50.
Este resultado es consistente con el obtenido en la prueba Z (Ejemplo 1). La principal diferencia es que la prueba t utiliza la desviación estándar muestral, lo cual es más apropiado cuando la desviación estándar poblacional es desconocida. Con un tamaño de muestra de n=118, los resultados de la prueba t y la prueba Z tienden a ser muy similares, ya que la distribución t se aproxima a la distribución normal a medida que aumentan los grados de libertad.
Ahora nos enfocaremos en probar hipótesis sobre una proporción poblacional, como la tasa de apertura de emails, la tasa de clics o la tasa de conversión. Usaremos la aproximación normal (prueba Z) para proporciones, que es válida cuando el tamaño de la muestra es suficientemente grande (generalmente, cuando \(np_0 \ge 10\) y \(n(1-p_0) \ge 10\), donde \(n\) es el tamaño de la muestra y \(p_0\) es la proporción bajo H0).
Contexto: La empresa tiene un objetivo histórico o de referencia para la tasa de apertura de sus campañas de email del 25%. Queremos verificar si la tasa de apertura global de la campaña actual (combinando Grupo A y B) es significativamente diferente de este 25%.
Formulamos las hipótesis: * H0: \(p = 0.25\) (la proporción poblacional de emails abiertos es 25%). * H1: \(p \neq 0.25\) (la proporción poblacional de emails abiertos es distinta del 25%; prueba bilateral).
Calcularemos la proporción muestral de emails abiertos (\(\hat{p}\)) del total de emails enviados en la campaña. Luego, calcularemos el estadístico Z para proporciones y su p-valor. El estadístico Z para una proporción se calcula como: \[ Z = \frac{\hat{p} - p_0}{\sqrt{\frac{p_0(1-p_0)}{n}}} \] Donde: * \(\hat{p}\) es la proporción muestral. * \(p_0\) es la proporción hipotética bajo H0. * \(n\) es el tamaño total de la muestra (total de emails enviados).
# Datos de la campaña global
total_enviados <- 20000
total_abiertos <- sum(df$abierto)
# Proporción muestral (tasa de apertura observada)
p_hat <- total_abiertos / total_enviados
# Parámetros de la prueba
p0 <- 0.25 # Proporción hipotética bajo H0
n_total_sample <- total_enviados
# --- Cálculo manual ---
se_prop <- sqrt((p0 * (1 - p0)) / n_total_sample)
Z_prop <- (p_hat - p0) / se_prop
p_value_prop <- 2 * pnorm(abs(Z_prop), lower.tail = FALSE)
cat("--- Resultados del cálculo manual ---\n")
cat(sprintf("Total de emails enviados (n): %d\n", n_total_sample))
cat(sprintf("Total de emails abiertos: %d\n", total_abiertos))
cat(sprintf("Tasa de apertura observada (p_hat): %.4f\n", p_hat))
cat(sprintf("Proporción bajo H0 (p0): %.2f\n", p0))
cat(sprintf("Estadístico Z para la proporción: %.3f\n", Z_prop))
cat(sprintf("p-valor bilateral: %.4g\n", p_value_prop)) # Usamos %g para notación científica si es necesario
cat("---------------------------------------------\n")
# --- Usando la función prop.test() de R ---
# Nota: prop.test por defecto usa la corrección de continuidad de Yates.
# Para una comparación más directa con la fórmula Z, la desactivamos con correct = FALSE.
# La función de Python 'proportions_ztest' no aplica esta corrección por defecto.
prop_test_result <- prop.test(
x = total_abiertos, # número de éxitos
n = n_total_sample, # número de observaciones
p = p0, # valor bajo H0
alternative = "two.sided",
correct = FALSE # Sin corrección de continuidad
)
cat("\n--- Resultados usando la función prop.test() de R (sin corrección) ---\n")
print(prop_test_result)
Interpretación de los resultados (Ejemplo 3):
La tasa de apertura observada en la campaña global (combinando Grupo
A y B) fue de \(\hat{p} = 0.2740\) (o
27.4%), calculada a partir de total_abiertos
(5480) emails
abiertos de un total de total_enviados
(20000) emails. Se
planteó la hipótesis nula (H0) de que la tasa de apertura poblacional
era igual al objetivo del 25% (\(p_0 =
0.25\)), contra la hipótesis alternativa (H1) de que era
diferente.
El estadístico de prueba (que se muestra como X-squared en la salida
de prop.test
, pero es conceptualmente \(Z^2\)) tiene un valor de 61.442, lo que
corresponde a un Z de \(\sqrt{61.442} \approx
7.838\). Este valor tan alto indica que la tasa de apertura
observada (27.4%) está muy alejada de la tasa hipotética (25%) en
términos de errores estándar.
El p-valor asociado es extremadamente pequeño (mostrado como
< 2.2e-16
).
Decisión: Utilizando un nivel de significancia \(\alpha = 0.05\): Dado que el \(p-valor (\\approx 0) < \\alpha (0.05)\), rechazamos la hipótesis nula (H0).
Conclusión: Existe evidencia estadística muy fuerte para concluir que la tasa de apertura de la campaña actual es significativamente diferente del 25%. Dado que la tasa observada (27.4%) es mayor que el 25%, podemos inferir que la campaña tuvo una tasa de apertura significativamente superior al objetivo o benchmark histórico. Esto sugiere un rendimiento positivo de la campaña en términos de captar la atención inicial de los destinatarios para que abran el correo.
Software de apoyo:
R.
# En R, las funciones para pruebas t y otras estadísticas básicas
# vienen en el paquete base `stats`, que se carga por defecto.
# Para la manipulación de datos y gráficos, usaremos los paquetes del 'tidyverse'.
library(dplyr)
library(ggplot2)
library(knitr)
# Establecer un estilo de gráfico similar a "darkgrid" de seaborn
theme_set(theme_bw())
# URL base para los datos
url_base <- "https://raw.githubusercontent.com/lacamposm/Fundamentos_Analitica/main/data/"
Problemas claves en el análisis de información es lograr determinar si un patrón que se observa es lo suficientemente significativo como para justificar una mayor investigación. Una herramienta fundamental para abordar este problema es llamada prueba de hipótesis estadística.
Deseamos dejar interiorizado:
Contexto comercial. Usted es parte de una organización de la sociedad civil que realiza un seguimiento de las métricas ambientales relacionadas con la deforestación y la calidad de los bosques en los Estados Unidos. El equipo de análisis de datos tiene la tarea de realizar una evaluación de las posibles estrategias de conservación para un bosque protegido en el estado de California. Como parte del proyecto de investigación, necesitan establecer algunas métricas descriptivas de la estratificación vertical del bosque (qué especies de árboles pertenecen al dosel y cuáles al sotobosque), diversidad de especies, biomasa, etc. Esto es importante porque si los árboles en este lugar específico exhibe características físicas diferentes a las de los árboles en el resto de California, es posible que sea necesario ajustar las estrategias para conservarlos para tener en cuenta estas particularidades.
Problema comercial. Su trabajo es determinar qué especies de árboles en el bosque protegido tienen alturas que difieren sustancialmente de las alturas promedio de esas especies en todo el estado de California. A partir de esto, otros miembros del equipo procederán a realizar estudios específicos de especies para investigar más a fondo las condiciones ecológicas de los lugares donde se encuentran estos árboles.
Contexto analítico. Se le proporcionó un conjunto de datos de la encuesta que contiene datos de 18 especies del bosque protegido. La muestra contiene 100 árboles por especie.
La tabla con la que estaremos trabajando tiene las siguientes features:
En la reserva hay 390.955 árboles de los que disponemos de datos censales. La altura media de todos esos árboles es de 57,35 pies (17,5 metros). Por lo tanto, decimos que la población consta de 390.955 árboles, y que la media poblacional de la altura de los árboles es de 57,35 pies (es decir, la media de la altura de todos los árboles de la población es de 57,35 pies). Denotaremos la media de la población como la letra griega \(\mu\).
censo <- read.csv(paste0(url_base, "censo.csv"),
col.names = c("ID", "CN", "HT"),
header = TRUE,
colClasses = c("NULL", "numeric", "numeric")) # Solo leemos CN y HT
kable(head(censo), caption = "Primeras filas del censo de árboles")
CN | HT |
---|---|
2.485871e+14 | 35 |
8.888777e+12 | 37 |
4.495602e+14 | 51 |
4.495582e+14 | 45 |
2.322019e+13 | 39 |
7.287400e+11 | 113 |
cat(paste("\nTamaño de la población:", nrow(censo), "\n"))
##
## Tamaño de la población: 390955
# En R, str() o glimpse() son similares a .info()
str(censo)
## 'data.frame': 390955 obs. of 2 variables:
## $ CN: num 2.49e+14 8.89e+12 4.50e+14 4.50e+14 2.32e+13 ...
## $ HT: num 35 37 51 45 39 113 30 24 115 80 ...
media <- mean(censo$HT, na.rm = TRUE)
std <- sd(censo$HT, na.rm = TRUE)
sprintf("La media y desviación poblacional son respectivamente: %.2f pies y %.2f pies.", media, std)
## [1] "La media y desviación poblacional son respectivamente: 57.35 pies y 39.62 pies."
Aquí está la distribución de las alturas de los árboles en la población, con \(\mu=57.35\) representado como una línea vertical en rojo:
media_poblacional <- mean(censo$HT, na.rm = TRUE)
ggplot(censo, aes(x = HT)) +
geom_histogram(aes(y = ..count..), fill = "green", color = "white", alpha = 0.7, bins = 50) +
geom_vline(xintercept = media_poblacional, color = "red", size = 1) +
annotate("text",
x = media_poblacional + 15,
y = 10000,
label = paste("μ =", round(media_poblacional, 2)),
color = "red",
size = 5) +
labs(title = "Distribución de la altura de los árboles (en pies).", x = "Altura (HT)", y = "Frecuencia")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: Removed 33769 rows containing non-finite outside the scale range
## (`stat_bin()`).
En muchos escenarios del mundo real, no tenemos acceso a toda la población de datos, en cambio, tenemos muestras. Esto crea incertidumbre porque es muy poco probable que la media de una muestra determinada sea exactamente igual a la media de la población de la que se extrae, incluso si la muestra es grande y se tomó al azar.
Debido a esto, vamos a analizar las distribuciones muestrales. La distribución muestral de la media muestral debe construirse utilizando muchos valores. La distribución muestral de la media muestral es la distribución de las medias de muchas muestras extraídas al azar de la población.
Por ejemplo, sabemos que la reserva tiene 390.955 árboles y que \(\mu=57,35\). Podemos tomar muestras de 20 árboles a la vez y calcular sus medias muestrales así:
sample(censo$HT, 20)
## [1] 69 43 NA NA 90 146 53 15 21 82 97 72 55 35 26 31 59 90 11
## [20] 48
set.seed(1) # Semilla para replicar los resultados.
# Tomamos 10 muestras de tamaño 20 y calculamos sus medias
medias_muestrales <- replicate(10, mean(sample(censo$HT, 20, replace = TRUE), na.rm = TRUE))
names(medias_muestrales) <- paste("Muestra", 1:10)
# Lo mostramos como una tabla
kable(t(as.data.frame(medias_muestrales)), caption = "Medias de 10 muestras")
Muestra 1 | Muestra 2 | Muestra 3 | Muestra 4 | Muestra 5 | Muestra 6 | Muestra 7 | Muestra 8 | Muestra 9 | Muestra 10 | |
---|---|---|---|---|---|---|---|---|---|---|
medias_muestrales | 63.63158 | 50.11111 | 60.125 | 60.47368 | 55.27778 | 42.88889 | 64.77778 | 73.78947 | 50.78947 | 57.68421 |
Podemos crear una tabla de frecuencia con todas estas medias muestrales y eso constituiría nuestra distribución muestral de la media muestral. Como vemos, estas medias de muestra están bastante cerca de \(\mu\), pero ninguna es exactamente igual a \(\mu\). Esta variación se due al hecho de que nuestro tamaño de muestra es más pequeño que el tamaño de la población. Sin embargo, aún podemos obtener una muy buena estimación de \(\mu\) al estudiar la distribución muestral de la media muestral.
La función de la celda de abajo muestra la distribución muestral de la media muestral para diferentes tamaños de muestra \(n\) en nuestro conjunto de datos del censo de la reserva. Cambie los valores de los parámetros. Por ejemplo, si establece \(n=50\) y el número de muestras en \(m=100\), entonces la función tomará 100 muestras de 50 árboles cada una de la población, encontrará la media de cada muestra y trazará la distribución muestral de todas las medias muestrales.
A partir de esto, calculamos la media de la distribución muestral y la imprimimos en azul. También damos como referencia la media poblacional (la sabemos del censo) en color rojo.
Experimente con diferentes valores de \(n\) y de \(m\) (número de muestras). ¿Qué observa acerca de la relación entre la media de la distribución muestral y la media de la población?
plot_media_muestral <- function(vector_datos, n = 1, m = 1) {
#' @description Dibuja la distribución muestral de la media.
#' @param vector_datos Vector numérico con los datos de la población.
#' @param n Tamaño de la muestra.
#' @param m Número de muestras a tomar.
# Quitar NAs para el muestreo
vector_datos <- na.omit(vector_datos)
media_poblacional <- mean(vector_datos)
# Generar m medias muestrales de tamaño n
info <- replicate(m, mean(sample(vector_datos, n, replace = TRUE)))
media_muestral_total <- mean(info)
# Crear un dataframe para ggplot
df_info <- data.frame(medias = info)
# Graficar
p <- ggplot(df_info, aes(x = medias)) +
geom_histogram(aes(y = ..density..), fill = "green", color = "white", alpha = 0.7, bins = 20) +
geom_density(color = "darkgreen", size = 1) +
geom_vline(xintercept = media_poblacional, color = "red", size = 1.2) +
geom_vline(xintercept = media_muestral_total, color = "blue", size = 1.2, linetype = "dashed") +
annotate("text",
x = media_poblacional + 0.5,
y = 0.01,
label = paste("μ =", round(media_poblacional, 2)),
color = "red", size = 5, hjust = 0) +
annotate("text",
x = media_muestral_total - 0.5,
y = 0.02,
label = paste("media muestral =", round(media_muestral_total, 2)),
color = "blue", size = 5, hjust = 1) +
labs(title = paste0("Muestras de tamaño ", n, ". Total de muestras ", m),
x = "Media Muestral", y = "Densidad") +
theme(plot.title = element_text(size = 16, face = "italic")) +
coord_cartesian(xlim = c(20, 100))
print(p)
}
## 1000 muestras de tamaño n = 5
plot_media_muestral(censo$HT, 5, 1000)
## 500 muestras de tamaño n = 50
plot_media_muestral(censo$HT, 50, 500)
## 1000 muestras de tamaño n = 300
plot_media_muestral(censo$HT, 300, 1000)
## 1000 muestras de tamaño n = 500
plot_media_muestral(censo$HT, 500, 1000)
Respuesta. Debe haber observado alguno (o todos) de los siguientes comentarios.
Con muchas muestras, la media de las medias muestrales convergerá a \(\mu\). Esto será cierto incluso si los tamaños de muestra en sí son pequeños. (Ley de los grandes números)
La dispersión de la distribución depende del tamaño de la muestra. Cuanto menor sea el tamaño de la muestra, más amplia será la distribución. (Pensar en el TLC)
A medida que aumenta el tamaño de la muestra, suponiendo un gran número de muestras, la distribución muestral de la media muestral comienza a tener forma de campana (Teorema del límite central).
Otro concepto importante que necesitaremos para responder a la pregunta de investigación es el de los \(p\)-valores. Un \(p\)-valor indica la probabilidad de que obtenga un número determinado o mayor cuando toma una muestra al azar de una distribución dada.
Supongamos que tenemos dos medias muestrales \(A\) y \(B\) como se muestra a continuación:
mu <- mean(censo$HT, na.rm = TRUE)
S <- sd(censo$HT, na.rm = TRUE)
n <- 200
df <- n - 1
se <- S / sqrt(n) # Error estándar
# Para la gráfica, usaremos la distribución normal como aproximación (TLC)
x_vals <- seq(mu - 4*se, mu + 4*se, length.out = 1000)
pdf_vals <- dnorm(x_vals, mean = mu, sd = se)
plot_data <- data.frame(x = x_vals, pdf = pdf_vals)
ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 60, color = "grey") +
geom_vline(xintercept = 62, color = "cyan") +
annotate("text", x = 60.2, y = 0.04, label = "A", size = 5, color = "grey", hjust = 0) +
annotate("text", x = 62.2, y = 0.04, label = "B", size = 5, color = "cyan", hjust = 0) +
annotate("text", x = mu + 0.1, y = 0.04, label = "μ", size = 5, color = "red", hjust = 0) +
labs(title = "Distribución de muestreo de la media muestral.", x = "", y = "")
¿Es más probable observar \(A\) o un valor mayor, o \(B\) o un valor mayor, dada nuestra distribución de muestreo?
Respuesta. \(A\) o que sea mayor es más probable. Vea que \(A\) tiene una mayor densidad de probabilidad a su alrededor y, además, su \(p\)-valor es mayor que el de \(B\). Podemos decir que la media muestral \(B\) es más extrema que la media muestral \(A\), lo que hace que los valores \(x_{i} \ge B\) sean menos probables de observar bajo la distribución muestral.
Ahora compare la media muestral \(B\) con una tercera media muestral \(C\). ¿Es plausible observar \(C\) como media muestral? ¿Puede decir algo sobre la población de la que se tomó la muestra \(C\)?
ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 62, color = "cyan") +
geom_vline(xintercept = 69, color = "green") +
annotate("text", x = 62.2, y = 0.04, label = "B", size = 5, color = "cyan", hjust = 0) +
annotate("text", x = 69.2, y = 0.04, label = "C", size = 5, color = "green", hjust = 0) +
annotate("text", x = mu + 0.2, y = 0.04, label = "μ", size = 5, color = "red", hjust = 0) +
labs(title = "Distribución de muestreo de la media muestral.", x = "", y = "")
Respuesta. La muestra \(C\) tiene alguna probabilidad de ser de la misma población que la nuestra; sin embargo, esta probabilidad es muy baja. Esto podría interpretarse como una sugerencia de que \(C\) en realidad proviene de una población diferente.
En otras palabras, cuanto más lejos esté la media de una muestra de \(\mu\), menos probable es que la población de la que se tomó tenga una media poblacional de \(\mu\).
Que dos valores sean estadísticamente iguales es diferente a decir que son aritméticamente iguales. Supongamos que \(\bar{X}=56 \text{ pies}\), sabemos que \(\mu=57.35 \text{ ft}\). Claramente, esos dos son números muy diferentes, por lo que no son aritméticamente iguales. Sin embargo, podemos argumentar razonablemente que la muestra a partir de la cual se calculó \(\bar{X}\) provino de hecho de una población con una media de \(\mu_1=\mu\), y que la diferencia de \(1,35 \text{ft}\) se debió al hecho de que solo observamos una muestra, en lugar de toda la población. En otras palabras, el argumento es así:
“Hay una diferencia entre \(\bar{X}\) y \(\mu\), pero si aumenta el tamaño de su muestra para que sea toda la población, probablemente encontrará que \(\bar{X}= \mu_1=\mu=57,35\). Esperamos que la diferencia entre \(\bar{X}\) y \(\mu\) se reduzca a cero a medida que aumentamos el tamaño de la muestra. Por lo tanto, ajustada por la variabilidad normal del muestreo, la diferencia entre \(\bar{\mu_1}\) (estimado por \(\bar{X}\)) y \(\mu\) no es estadísticamente significativa.”
Podemos usar pruebas de hipótesis para determinar si la diferencia entre \(\mu\) y la media \(\mu_1\) de la población de la que se tomó la media muestral \(\bar{X}\) es estadísticamente significativa. Una hipótesis es simplemente una suposición informada que hacen los analistas de datos, y esta suposición puede o no tener evidencia que la respalde. Probamos nuestra conjetura reuniendo evidencia a favor o en contra, y evaluamos la solidez de esa evidencia para determinar la validez de nuestra hipótesis.
El primer paso en la prueba de hipótesis es definir la hipótesis nula (frecuentemente denotada como \(H_0\)). Para nosotros, la hipótesis nula siempre corresponderá a la afirmación más conservadora. Muchas veces, esta hipótesis conservadora será $ H_0: _1=$.
Realizamos pruebas de hipótesis para desafiar nuestras afirmaciones (hipótesis), usamos métodos conservadores para asegurarnos de no rechazarlas con demasiada facilidad. En ese sentido, la ciencia limita su velocidad de innovación para reducir el riesgo de llegar a resultados demasiado audaces y arriesgados. Una buena analogía es el principio que rige numerosos sistemas judiciales en todo el mundo: “Inocente hasta que se pruebe su culpabilidad”. En otras palabras, mantendremos la hipótesis nula a menos que encontremos pruebas sólidas en su contra.
Note que este enfoque, como es el caso con el sistema judicial, no es perfecto. Incluso si no encontramos suficiente evidencia en contra de la hipótesis nula, la hipótesis nula aún puede resultar incorrecta.
Para formalizar esto, definimos una hipótesis alternativa (a menudo indicada con \(H_1\) o \(H_a\)) que desafía la hipótesis consevadora. Hay tres formas diferentes de definir una hipótesis alternativa:
\(H_a: \mu_1\neq \mu\) (prueba bilateral)
\(H_a: \mu_1 < \mu\) (prueba unilateral)
\(H_a: \mu_1 > \mu\) (prueba unilateral)
Definamos nuestra hipótesis alternativa como \(H_a: \mu_1 > \mu\) (la tercera opción) por ahora (veremos las otras más adelante). Cuestionamos la suposición de que las medias de las dos poblaciones son estadísticamente iguales y queremos demostrar que la media de la población desconocida de la que se tomó nuestra muestra es mayor que la media \(\mu\) de la población conocida.
Test de hipótesis
\[ H_0: \mu_1=57.35\] \[VS.\] \[H_a: \mu_1 > 57.35\]
Nosotros conocemos que la media poblacional es \(\mu=57.35\).
TLC: Sea \(X_1,X_2,X_3, \dots , X_n\) un conjunto de variables aleatorias independientes e identicamente distribuidas, cada una de ellas con función de distribución \(F\), y supongamos que \(E(X_k)=\mu\) y \(Var(X_k)=\sigma^2\). Si \[\bar{X}=\frac{X_1+X_2+X_3+\dots X_n}{n}\] entonces \[\bar{X} \longrightarrow N\left(\mu, \frac{\sigma^2}{n}\right)\]
Al tomar una muestra “grande” podemos hacer uso del TLC para pensar en la distribución muestral de la media muestral. PROBLEMA: En las situaciones reales no conocemos \(\mu\) (valor esperado) ni \(\sigma^{2}\) (varianza).
Al realizar la prueba de hipótesis, suponemos que \(H_0\) es verdadera, en cuyo caso ya no desconocemos a \(\mu\), quien sigue siendo desconocido es \(\sigma^{2}\).
El problema del desconocimiento de \(\sigma^{2}\) se soluciona tomando a: \[T = \frac{\bar{X}-\mu}{S/\sqrt{n}} \] Quien distribuye \(T\sim t_{n-1}\), donde \(S\) es la desviación estandar de la muestra.
Repasemos el diagrama del ejercicio anterior:
# Reutilizamos el gráfico anterior
ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 62, color = "cyan") +
geom_vline(xintercept = 69, color = "green") +
annotate("text", x = 62.2, y = 0.04, label = "B", size = 5, color = "cyan", hjust = 0) +
annotate("text", x = 69.2, y = 0.04, label = "C", size = 5, color = "green", hjust = 0) +
annotate("text", x = mu + 0.2, y = 0.04, label = "μ", size = 5, color = "red", hjust = 0) +
labs(title = "Distribución de muestreo de la media muestral.", x = "", y = "")
Supongamos que cree que la media de la población de la que se extrajo la media muestral \(B\) es estadísticamente igual a \(57.35\), mientras que la media de la población de la que se extrajo la media muestral \(C\) no lo es. Quiere convencer que este es el caso. Piense en un criterio más objetivo para determinar si una media poblacional inferida es estadísticamente diferente de \(57.35\) o no.
Respuesta. Una forma razonable de hacer que el proceso sea menos subjetivo (aunque no lo hace completamente objetivo) es definir un umbral en el eje \(x\) más allá del cual los valores se considerarán significativamente diferentes de la media de la población.
Podemos definir un punto de corte en nuestra distribución, de modo que siempre que la media de una muestra caiga más allá de ese punto, podemos decir con confianza que su media poblacional inferida es estadísticamente diferente de \(\mu\). Estos puntos de corte se denominan valores críticos. Por ejemplo, digamos que nuestro valor crítico es 65 pies:
ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 62, color = "cyan") +
geom_vline(xintercept = 69, color = "green") +
annotate("text", x = 62.1, y = 0.04, label = "B", size = 5, color = "cyan", hjust = 1) +
annotate("text", x = 69.1, y = 0.04, label = "C", size = 5, color = "green", hjust = 1) +
annotate("text", x = mu + 0.1, y = 0.04, label = "μ", size = 5, color = "red", hjust = 0) +
geom_point(aes(x = 65, y = 0), color = "red", size = 8, shape = 1) +
labs(title = "Distribución de muestreo de la media muestral", x = "", y = "")
## Warning in geom_point(aes(x = 65, y = 0), color = "red", size = 8, shape = 1): All aesthetics have length 1, but the data has 1000 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
Por lo tanto:
Como \(B < 65\), decimos que la media poblacional inferida de \(B\) no es estadísticamente diferente de \(\mu\). No podemos probarlo, pero tampoco podemos refutarlo, y como estamos siendo conservadores, nos atenemos a la hipótesis nula (aunque no podemos decir que sea 100% correcta) y decimos que no logramos rechazar la nula hipótesis.
Como \(C > 65\), decimos que la media poblacional inferida de \(C\) es estadísticamente diferente de \(\mu\). En otras palabras, rechazamos la hipótesis nula. (Todavía hay alguna probabilidad de que \(C\) no sea estadísticamente diferente de \(\mu\), pero esa probabilidad en este caso es suficientemente pequeña).
El problema con los valores críticos es que tienen que ser redefinidos en cada situación o prueba de hipótesis. Por ejemplo, si nuestro conjunto de datos tuviera medidas del diámetro del tronco en pulgadas, entonces nuestro punto de corte tendría que ajustarse para que esté en pulgadas y toda la comunidad científica tendría que ponerse de acuerdo sobre qué valor crítico tendría más sentido: ¿4 pulgadas? ¿6 pulgadas? ¿1 pulgada?
La forma de resolver este problema es definir nuestros valores críticos indirectamente, usando algo llamado niveles de significancia. Un nivel de significancia es simplemente el \(p\)-valor que corresponde a un valor crítico dado. Por ejemplo, en nuestra distribución (con \(n=200\)), el valor \(p\) para el valor crítico a 65 pies es 0,003886. Para evitar confusiones entre el \(p\)-valor de la media de una muestra y el \(p\)-valor de un valor crítico, usamos la letra griega \(\alpha\) para representar el nivel de significancia.
Luego, los científicos pueden ponerse de acuerdo sobre niveles de significancia razonables (que son independientes de la unidad, ya que son probabilidades) y dejar que los valores críticos se ajusten por sí solos en cada contexto individual. En las ciencias sociales, un nivel de significancia común es \(\alpha=0.05\), y en las ciencias naturales, un estándar popular es \(\alpha=0.01\).
Cambie los valores de \(\alpha\) en la función de abajo. ¿Observa algo con la hipótesis a medida que cambia los valores de \(\alpha\)?
Estas son las 2 hipótesis nulas (una para cada muestra):
Comente.
p_valor_plot <- function(alpha) {
# Usaremos los mismos datos de la gráfica anterior
percentil <- qnorm(1 - alpha, mean = mu, sd = se)
# Datos para la región de rechazo
x_alpha <- plot_data %>% filter(x >= percentil)
p <- ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_ribbon(data = x_alpha, aes(x = x, ymin = 0, ymax = pdf), fill = "pink") +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 62, color = "cyan") +
geom_vline(xintercept = 69, color = "green") +
annotate("text", x = 61.6, y = 0.15, label = "B=62", size = 4, color = "cyan") +
annotate("text", x = 68.6, y = 0.15, label = "C=69", size = 4, color = "green") +
annotate("text", x = mu - 2.5, y = 0.15, label = paste("Media poblacional: μ =", round(mu, 2)), size = 4, color = "red") +
labs(x="", y="")
print(p)
cat(paste0('El valor crítico para α=', sprintf("%.2f", alpha), ' es ', sprintf("%.3f", percentil), ' pies\n'))
if (percentil < 62) {
cat("La hipótesis nula para la muestra B: RECHAZADA.\n")
} else {
cat("La hipótesis nula para la muestra B: NO RECHAZADA.\n")
}
if (percentil < 69) {
cat("La hipótesis nula para la muestra C: RECHAZADA.\n")
} else {
cat("La hipótesis nula para la muestra C: NO RECHAZADA.\n")
}
}
p_valor_plot(0.01)
## El valor crítico para α=0.01 es 63.867 pies
## La hipótesis nula para la muestra B: NO RECHAZADA.
## La hipótesis nula para la muestra C: RECHAZADA.
## Celda para probar
p_valor_plot(0.04)
## El valor crítico para α=0.04 es 62.254 pies
## La hipótesis nula para la muestra B: NO RECHAZADA.
## La hipótesis nula para la muestra C: RECHAZADA.
## Celda para probar
p_valor_plot(0.05)
## El valor crítico para α=0.05 es 61.957 pies
## La hipótesis nula para la muestra B: RECHAZADA.
## La hipótesis nula para la muestra C: RECHAZADA.
## Celda para probar
p_valor_plot(0.10)
## El valor crítico para α=0.10 es 60.939 pies
## La hipótesis nula para la muestra B: RECHAZADA.
## La hipótesis nula para la muestra C: RECHAZADA.
# Graficar el p-valor para la muestra A (valor = 60)
x_alpha <- plot_data %>% filter(x >= 60)
ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color = "blue") +
geom_ribbon(data = x_alpha, aes(x = x, ymin = 0, ymax = pdf), fill = rgb(1, 0.27, 0.5, 0.5)) +
geom_vline(xintercept = mu, color = "red") +
geom_vline(xintercept = 60, color = "grey") +
geom_vline(xintercept = 62, color = "cyan") +
annotate("text", x = 60.2, y = 0.04, label = "A", size = 5, color = "grey", hjust = 0) +
annotate("text", x = 62.2, y = 0.04, label = "B", size = 5, color = "cyan", hjust = 0) +
annotate("text", x = mu + 0.1, y = 0.04, label = "μ", size = 5, color = "red", hjust = 0) +
labs(title = "Distribución de muestreo de la media muestral.", x = "", y = "")
Complete el espacio en blanco: “Cuanto ________ el \(\alpha\), más conservadora será su prueba y, por lo tanto, más difícil será rechazar la hipótesis nula”.
Respuesta. Mientras menor sea \(\alpha\), más conservadora será la prueba y, por lo tanto, más difícil será rechazar la hipótesis nula.
Puede pensarlo de esta manera: cuanto menor sea \(\alpha\), más lejos estará el valor crítico de \(57.35\), lo que reduce las posibilidades de que la media de su muestra caiga más allá del valor crítico. Esto efectivamente hace que la prueba sea más estricta.
Estando ya familiarizado con el significado de los valores \(\alpha\) y \(p\), tenemos la siguiente regla que permite interpretar resultados de una prueba de hipótesis. > Si \(p\)-valor\(< \alpha\), rechazar \(H_0\) a favor de \(H_a\). De lo contrario, no rechace \(H_0\).
Para ver gráficamente por qué funciona esta regla, podemos comparar el siguiente gráfico de una prueba \(t\) que nos lleva a rechazar el valor nulo:
# Visualización de Rechazo: p-valor < alpha
# Supongamos alpha en 60 y p-valor en 62
alpha_area <- plot_data %>% filter(x >= 60)
pval_area <- plot_data %>% filter(x >= 62)
ggplot(plot_data, aes(x=x, y=pdf)) +
geom_line() +
geom_ribbon(data = alpha_area, aes(x=x, ymin=0, ymax=pdf), fill="magenta") +
geom_ribbon(data = pval_area, aes(x=x, ymin=0, ymax=pdf), fill="green") +
labs(title = "Rechazar la hipótesis nula\nEl valor está más allá del valor crítico, por lo que se considera lo suficientemente extremo.") +
annotate("text", x=62.6, y=0.008, label="p-valor", size=6) +
annotate("text", x=60.6, y=0.04, label="α", size=6) +
annotate("text", x=66, y=0.08, label="p-valor < α", size=6)
con una prueba que NO nos permite rechazarla:
# Visualización de No Rechazo: p-valor > alpha
# Supongamos alpha en 62 y p-valor en 60
alpha_area <- plot_data %>% filter(x >= 62)
pval_area <- plot_data %>% filter(x >= 60)
ggplot(plot_data, aes(x=x, y=pdf)) +
geom_line() +
geom_ribbon(data = alpha_area, aes(x=x, ymin=0, ymax=pdf), fill="magenta") +
geom_ribbon(data = pval_area, aes(x=x, ymin=0, ymax=pdf), fill=rgb(1,1,0,0.5)) +
labs(title = "No se puede rechazar la hipótesis nula\nEl valor no es lo suficientemente extremo.") +
annotate("text", x=62.6, y=0.008, label="α", size=6) +
annotate("text", x=60.6, y=0.04, label="p-valor", size=6) +
annotate("text", x=66, y=0.08, label="p-valor > α", size=6)
Por lo tanto, siempre tenga en cuenta que un \(p\)-valor menor que su nivel de significancia puede rechazar la hipótesis nula.
Suponga que realizó una prueba \(t\) - con un nivel de significancia de \(\alpha=0.01\). El \(p\)-valor resultante fue 0,02. ¿Rechaza la hipótesis nula o no la rechaza?
Respuesta: No se rechaza la hipótesis nula, porque el p-valor (0.02) es mayor que el nivel de significancia \(\alpha\) (0.01).
Hasta acá, se ha trabajado en los casos donde la media muestral es mayor que la media poblacional. Vamos a construir una prueba \(t\) (prueba para la hipótesis alternativa opuesta) de la forma \(H_a: \mu_1 < 57.35\).
El razonamiento es similar que el anterior, cambiando solo que el \(p\)-valor será definido como la probabilidad de obtener un valor menor o igual a \(\bar{X}\). El valor crítico se desplazaría entonces hacia la otra cola de la distribución:
# Prueba de cola izquierda
pval_area_left <- plot_data %>% filter(x <= 54)
ggplot(plot_data, aes(x=x, y=pdf)) +
geom_line() +
geom_ribbon(data = pval_area_left, aes(x=x, ymin=0, ymax=pdf), fill="orange") +
labs(title = "Una prueba de cola izquierda\nCuanto más a la izquierda el valor, más extremo es.") +
annotate("text", x=52.9, y=0.02, label="p-valor", size=6)
Finalmente, se puede tener una prueba \(t\) a dos colas. En este caso, la hipótesis alternativa sería que \(\mu_1\) es mayor o menor que \(\mu\), es decir, \(H_a: \mu_1 \neq \mu\) y por lo tanto su \(\alpha\) se dividiría entre las dos colas:
# Prueba de dos colas
library(gridExtra)
# Datos para el p-valor
pval_left <- plot_data %>% filter(x <= (mu - 3.5))
pval_right <- plot_data %>% filter(x >= (mu + 3.5))
p1 <- ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color="blue") +
geom_ribbon(data = pval_left, aes(ymin=0, ymax=pdf), fill="cyan") +
geom_ribbon(data = pval_right, aes(ymin=0, ymax=pdf), fill="cyan") +
labs(title="P-valor a dos colas") +
annotate("text", x=52.1, y=0.01, label="p/2", size=6) +
annotate("text", x=60.9, y=0.01, label="p/2", size=6)
# Datos para alpha
alpha_left <- plot_data %>% filter(x <= (mu - 3.0))
alpha_right <- plot_data %>% filter(x >= (mu + 3.0))
p2 <- ggplot(plot_data, aes(x = x, y = pdf)) +
geom_line(color="blue") +
geom_ribbon(data = alpha_left, aes(ymin=0, ymax=pdf), fill="magenta") +
geom_ribbon(data = alpha_right, aes(ymin=0, ymax=pdf), fill="magenta") +
labs(title="Alpha (α) a dos colas") +
annotate("text", x=52.1, y=0.01, label="α/2", size=6) +
annotate("text", x=60.9, y=0.01, label="α/2", size=6)
grid.arrange(p1, p2, ncol=2, top="Una prueba de dos colas: Cuanto más lejos de la media, más extremo")
Luego, si una prueba \(t\) de una cola
tuviera un \(\alpha\) de 0.05, en la
versión de dos colas todavía tendría un \(\alpha\) total de 0.05. Si la media de la
muestra \(\bar{X}\) cae más allá de
cualquiera de los dos valores críticos (uno a la izquierda y
otro a la derecha), entonces la prueba indicará que se debe rechazar la
hipótesis nula.
Ahora que hemos explorado la situación detrás de las pruebas \(t\), seguimos con el problema de negocios inicial. Ahora debe ser mucho más fácil de solucionar.
A continuación tenemos una muestra de la encuesta que realizó el equipo en el bosque protegido de California:
## df: DataFrame donde tenemos la encuesta.
df <- read.csv(paste0(url_base, "forest_survey.csv"), header = TRUE,
col.names = c("CN", "HT", "SITREE", "common_name", "scientific_name"))
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## header and 'col.names' are of different lengths
kable(head(df), caption = "Primeras filas de la encuesta del bosque")
CN | HT | SITREE | common_name | scientific_name | |
---|---|---|---|---|---|
208659 | 1.545833e+13 | 90 | 52 | white fir | Abies concolor |
203043 | 1.537584e+13 | 44 | 50 | white fir | Abies concolor |
201091 | 1.538457e+13 | 37 | 45 | white fir | Abies concolor |
195762 | 1.533756e+13 | 120 | 85 | white fir | Abies concolor |
199488 | 1.535878e+13 | 53 | 60 | white fir | Abies concolor |
200202 | 1.536651e+13 | 27 | 74 | white fir | Abies concolor |
str(df)
## 'data.frame': 1800 obs. of 5 variables:
## $ CN : num 1.55e+13 1.54e+13 1.54e+13 1.53e+13 1.54e+13 ...
## $ HT : num 90 44 37 120 53 27 73 86 114 52 ...
## $ SITREE : num 52 50 45 85 60 74 59 69 52 43 ...
## $ common_name : chr "white fir" "white fir" "white fir" "white fir" ...
## $ scientific_name: chr "Abies concolor" "Abies concolor" "Abies concolor" "Abies concolor" ...
kable(summary(df), caption = "Resumen de los datos de la encuesta")
CN | HT | SITREE | common_name | scientific_name | |
---|---|---|---|---|---|
Min. :1.529e+13 | Min. : 6.00 | Min. : 17.00 | Length:1800 | Length:1800 | |
1st Qu.:1.531e+13 | 1st Qu.: 28.75 | 1st Qu.: 51.00 | Class :character | Class :character | |
Median :1.534e+13 | Median : 44.00 | Median : 65.00 | Mode :character | Mode :character | |
Mean :1.566e+13 | Mean : 56.41 | Mean : 68.73 | NA | NA | |
3rd Qu.:1.536e+13 | 3rd Qu.: 77.00 | 3rd Qu.: 86.00 | NA | NA | |
Max. :4.872e+13 | Max. :295.00 | Max. :160.00 | NA | NA |
n_especies <- length(unique(df$common_name))
cat(paste("Número de especies únicas:", n_especies, "\n"))
## Número de especies únicas: 18
print(unique(df$common_name))
## [1] "white fir" "California red fir" "Shasta red fir"
## [4] "Pacific madrone" "incense-cedar" "tanoak"
## [7] "whitebark pine" "lodgepole pine" "Jeffrey pine"
## [10] "sugar pine" "western white pine" "ponderosa pine"
## [13] "Douglas-fir" "canyon live oak" "blue oak"
## [16] "California black oak" "interior live oak" "redwood"
Para este problema usaremos la métrica site index
(SITREE
), que es la altura del árbol corregida por la edad
(entre más antiguo el árbol se tiene mayor altura). Podemos considerar
la altura normalizada por edad en pies de una especie determinada en un
lugar particular. Por lo general, varía entre ubicaciones según las
condiciones del suelo, el clima, el grado de intervención humana, etc.
Queremos comparar nuestros índices de sitios forestales con los índices
de sitios promedio conocidos en California para 18 especies.
Vamos a realizar múltiples pruebas \(t\), una prueba por cada especie. Vamos a contrastar las hipótesis:
donde \(\mu_{forest}\) es la media poblacional desconocida de los árboles del bosque según se deduce de la media muestral, y \(\mu_{california}\) es la media poblacional conocida de los árboles en todo el estado de California (esta media se calcula utilizando la base de datos de la encuesta Forest Inventory and Analysis). Por supuesto, \(\mu_{california}\) varía según la especie. La idea es que si terminamos rechazando la hipótesis nula, entonces este árbol en particular tiene características ecológicas que son diferentes a las del resto del estado de California, y que estas características pueden estar detrás de las diferencias en el crecimiento de especies particulares.
## df_means_population: DataFrame con las medias poblacionales.
df_means_population <- read.csv(paste0(url_base, "means_california.csv"))
kable(df_means_population, caption = "Medias poblacionales (California)")
scientific_name | SITREE |
---|---|
Abies concolor | 57.03358 |
Abies magnifica | 54.53857 |
Abies shastensis | 44.73362 |
Arbutus menziesii | 86.98315 |
Calocedrus decurrens | 57.78532 |
Lithocarpus densiflorus | 90.30475 |
Pinus albicaulis | 32.17610 |
Pinus contorta | 57.26495 |
Pinus jeffreyi | 59.11414 |
Pinus lambertiana | 58.48408 |
Pinus monticola | 50.19872 |
Pinus ponderosa | 75.47277 |
Pseudotsuga menziesii | 77.40075 |
Quercus chrysolepis | 73.20047 |
Quercus douglasii | 94.10839 |
Quercus kelloggii | 77.50191 |
Quercus wislizeni | 91.75527 |
Sequoia sempervirens | 101.32927 |
Tenemos las medias de la muestra por cada especie.
## df_means_sample: DataFrame con las medias de las especies en la encuesta.
df_means_sample <- df %>%
group_by(scientific_name) %>%
summarise(SITREE_sample = mean(SITREE, na.rm = TRUE))
kable(df_means_sample, caption = "Medias de la muestra (Bosque protegido)")
scientific_name | SITREE_sample |
---|---|
Abies concolor | 55.88 |
Abies magnifica | 53.80 |
Abies shastensis | 45.83 |
Arbutus menziesii | 86.09 |
Calocedrus decurrens | 58.94 |
Lithocarpus densiflorus | 87.39 |
Pinus albicaulis | 32.38 |
Pinus contorta | 56.97 |
Pinus jeffreyi | 57.70 |
Pinus lambertiana | 59.68 |
Pinus monticola | 49.79 |
Pinus ponderosa | 75.89 |
Pseudotsuga menziesii | 80.33 |
Quercus chrysolepis | 75.43 |
Quercus douglasii | 93.38 |
Quercus kelloggii | 79.94 |
Quercus wislizeni | 92.18 |
Sequoia sempervirens | 95.49 |
## DataFrame con las medias poblaciones y las de la encuesta.
df_comparacion <- inner_join(df_means_population, df_means_sample, by = "scientific_name") %>%
rename(SITREE_population = SITREE)
kable(df_comparacion, caption = "Comparación de medias poblacionales y muestrales")
scientific_name | SITREE_population | SITREE_sample |
---|---|---|
Abies concolor | 57.03358 | 55.88 |
Abies magnifica | 54.53857 | 53.80 |
Abies shastensis | 44.73362 | 45.83 |
Arbutus menziesii | 86.98315 | 86.09 |
Calocedrus decurrens | 57.78532 | 58.94 |
Lithocarpus densiflorus | 90.30475 | 87.39 |
Pinus albicaulis | 32.17610 | 32.38 |
Pinus contorta | 57.26495 | 56.97 |
Pinus jeffreyi | 59.11414 | 57.70 |
Pinus lambertiana | 58.48408 | 59.68 |
Pinus monticola | 50.19872 | 49.79 |
Pinus ponderosa | 75.47277 | 75.89 |
Pseudotsuga menziesii | 77.40075 | 80.33 |
Quercus chrysolepis | 73.20047 | 75.43 |
Quercus douglasii | 94.10839 | 93.38 |
Quercus kelloggii | 77.50191 | 79.94 |
Quercus wislizeni | 91.75527 | 92.18 |
Sequoia sempervirens | 101.32927 | 95.49 |
Realización de una prueba de hipótesis:
El estadístico de prueba es en este caso:
\[t=\frac{\bar{x}-\mu_{california}}{s/\sqrt n}\]
Y el correspondiente \(p\)-valor, es:
\[p\text{ -valor} = 2P(t_{n-1}\leq t)\]
## datos del árbol "Abies concolor" en la encuesta (muestra!!! OJO... PUES...).
x <- df %>%
filter(scientific_name == "Abies concolor") %>%
pull(SITREE)
head(x)
## [1] 52 50 45 85 60 74
x_barra <- mean(x, na.rm = TRUE)
s <- sd(x, na.rm = TRUE)
n <- length(na.omit(x))
cat(paste("Media (x̄):", round(x_barra, 2),
"| Desv. Est. (s):", round(s, 2),
"| Tamaño (n):", n, "\n"))
## Media (x̄): 55.88 | Desv. Est. (s): 13.02 | Tamaño (n): 100
## Suponemos la hipótesis nula verdadera.
mu_california <- df_means_population %>%
filter(scientific_name == "Abies concolor") %>%
pull(SITREE)
cat(paste("μ de California para Abies concolor:", mu_california, "\n"))
## μ de California para Abies concolor: 57.0335837384004
## Estadístico de prueba t.
t_value <- (x_barra - mu_california) / (s / sqrt(n))
cat(paste("Estadístico t:", round(t_value, 4), "\n"))
## Estadístico t: -0.8863
## p-valor correspondiente para una prueba a dos colas
# Como t_value es negativo, calculamos 2 * P(T <= t_value)
p_valor <- 2 * pt(t_value, df = n - 1)
sprintf("El p-valor para la prueba es: %.4f", p_valor)
## [1] "El p-valor para la prueba es: 0.3776"
Considerando \(\alpha = 0.05\), observamos que no encontramos diferencias significativas entre la media de la encuesta y la media poblacional para la especie de arból Abies concolor.
R
.Vamos a hacer uso de la función t.test()
del paquete
base stats
para realizar la misma prueba anterior.
# El paquete `broom` es útil para obtener una salida limpia de los tests
library(broom)
# Realizamos la prueba t para una muestra
test_result <- t.test(x, mu = mu_california, alternative = "two.sided")
# Usamos tidy para un formato de tabla
kable(tidy(test_result), caption = "Resultado de t.test para Abies concolor")
estimate | statistic | p.value | parameter | conf.low | conf.high | method | alternative |
---|---|---|---|---|---|---|---|
55.88 | -0.8863249 | 0.3775904 | 99 | 53.29747 | 58.46253 | One Sample t-test | two.sided |
Realice todas las pruebas \(t\) (una por cada especie). ¿Qué especies muestran una diferencia estadísticamente significativa a un nivel de significancia de 0.05?
# Unimos los datos de la encuesta con las medias poblacionales
df_full <- inner_join(df, df_means_population, by = "scientific_name")
# Agrupamos por especie y realizamos la prueba t para cada una
resultados_tests <- df_full %>%
group_by(scientific_name, SITREE_population = SITREE.y) %>% # SITREE.y es la media poblacional
summarise(
test_result = list(t.test(SITREE.x, mu = first(SITREE_population))),
.groups = 'drop'
) %>%
mutate(tidied = purrr::map(test_result, tidy)) %>%
tidyr::unnest(tidied) %>%
select(scientific_name, estimate, statistic, p.value, conf.low, conf.high)
kable(resultados_tests, caption = "Resultados de las pruebas t para todas las especies")
scientific_name | estimate | statistic | p.value | conf.low | conf.high |
---|---|---|---|---|---|
Abies concolor | 55.88 | -0.8863249 | 0.3775904 | 53.29747 | 58.46253 |
Abies magnifica | 53.80 | -0.3549628 | 0.7233725 | 49.67145 | 57.92855 |
Abies shastensis | 45.83 | 1.0454438 | 0.2983638 | 43.74912 | 47.91088 |
Arbutus menziesii | 86.09 | -0.3690819 | 0.7128549 | 81.28837 | 90.89163 |
Calocedrus decurrens | 58.94 | 0.7672673 | 0.4447486 | 55.95389 | 61.92611 |
Lithocarpus densiflorus | 87.39 | -1.3569560 | 0.1778811 | 83.12790 | 91.65210 |
Pinus albicaulis | 32.38 | 0.1369744 | 0.8913292 | 29.42630 | 35.33370 |
Pinus contorta | 56.97 | -0.2168607 | 0.8287632 | 54.27133 | 59.66867 |
Pinus jeffreyi | 57.70 | -0.7427684 | 0.4593808 | 53.92230 | 61.47770 |
Pinus lambertiana | 59.68 | 0.6668204 | 0.5064380 | 56.12136 | 63.23864 |
Pinus monticola | 49.79 | -0.3000404 | 0.7647754 | 47.08708 | 52.49292 |
Pinus ponderosa | 75.89 | 0.1368966 | 0.8913905 | 69.84251 | 81.93749 |
Pseudotsuga menziesii | 80.33 | 1.1811003 | 0.2403925 | 75.40893 | 85.25107 |
Quercus chrysolepis | 75.43 | 1.0039901 | 0.3178310 | 71.02371 | 79.83629 |
Quercus douglasii | 93.38 | -0.4951037 | 0.6216240 | 90.46084 | 96.29916 |
Quercus kelloggii | 79.94 | 1.0290978 | 0.3059414 | 75.23908 | 84.64092 |
Quercus wislizeni | 92.18 | 0.2565259 | 0.7980771 | 88.89476 | 95.46524 |
Sequoia sempervirens | 95.49 | -2.5660027 | 0.0117864 | 90.97466 | 100.00534 |
# Filtramos para encontrar las especies con diferencias significativas
resultados_significativos <- resultados_tests %>%
filter(p.value < 0.05)
kable(resultados_significativos, caption = "Especies con diferencias estadísticamente significativas (α = 0.05)")
scientific_name | estimate | statistic | p.value | conf.low | conf.high |
---|---|---|---|---|---|
Sequoia sempervirens | 95.49 | -2.566003 | 0.0117864 | 90.97466 | 100.0053 |
Si observa detenidamente, el \(p\)-valor para Sequoia sempervirens es pequeño. Sin embargo, la media muestral para esta especie en este bosque es \(\bar{X}=95,49 \text{ ft}\), mientras que la media en todo California es \(\mu_{california}=101,33 \text{ ft}\). Esta diferencia es ligeramente mayor de 5 pies, lo que no parece mucho dado que las secuoyas se encuentran entre los árboles más altos del mundo.
Resumiendo:
Se explicó el concepto de prueba de hipótesis. Esta herramienta que ayudará con problemas que involucran la detección de diferencias entre poblaciones.
Comprendió la importancia de reconocer cuándo los cambios en nuestros datos representan una variabilidad normal o no, y cómo la prueba de hipótesis puede ayudarnos con este problema.
Aprendió a interpretar el resultado de una prueba de hipótesis usando los \(p\)-valores en el contexto de distribuciones muestrales y sus aproximaciones con la distribución \(t\). El concepto de valores \(p\) aparece en muchos modelos que se utilizan en la ciencia de datos y también los veremos en varios casos futuros.
Notas de Julio Zainea
“Giant sequoias in Sequoia National Park 02 2013”, Sep 15, 2013, Tuxyso (Wikimedia Commons), CC BY-SA 3.0, https://commons.wikimedia.org/wiki/File:Giant_sequoias_in_Sequoia_National_Park_02_2013.jpg
“FIA Datamart”, 2021, U.S. Department of Agriculture, Forest Service, Public Domain, https://apps.fs.usda.gov/fia/datamart/CSV/datamart_csv.html.