Unidad I. Variables, distribuciones y pruebas de hipótesis.

Prueba de Hipótesis. Verificación estadística de hipótesis estadística.

  • Prueba de bondad de ajuste a una distribución.
    • Procedimientos no paramétricos chi cuadrado y Kolmogorov–Smirnov
  • Comparación de dos poblaciones.
    • Test de Student y Fischer para comparar variables independientes con distribución normal. Test de Student para comparar variables apareadas.
    • Alternativas no paramétricas de comparación transversal y longitudinal. Los tests de Mann Whitney y Wicolxon.
    • Otras pruebas de comparación no paramétricas: El test de Kolmogorov-Smirnov y de la Mediana. Test de los signos y de McNemar.

Estadística inferencial

La estadística inferencial trata de inferir información acerca de la distribución de probabilidad de una población, partiendo de la información de una muestra. Se diferencia de la estadística descriptiva en que en lugar de simplemente describir la muestra, trata de describir algo acerca de la población. Uno puede realizar diferentes estimaciones acerca de la población, la cual normalmente se conduce haciendo uso de la estadística frecuentista:

Test de hipótesis.

Una prueba de hipótesis es análoga a una demostración matemática por contradicción (en particular es un tipo de reductio ad absurdum), aunque no debe considerarse en ningún caso una demostración matemática. Ambos métodos, parten de considerar una declaración verdadera, en el caso del test de hipótesis, la hipótesis nula ó H₀. En ambos métodos se trata de llegar a una contradicción, dado que una implicación solo puede ser falsa si partiendo de una premisa verdadera llegamos a una conclusión falsa (tabla de verdad):

p q p → q
true true true
true false false
false true true
false false true

Acá es donde ambos métodos divergen, dado que la demostración matemática lo hace siguiendo reglas lógicas determinadas y procedimientos matemáticos permitidos, llegando a un resultado determinado no azaroso. Finalmente, si se llega a una contradicción, se concluye que la declaración original es falsa, aceptando la negación de dicha declaración. En el caso de la prueba de hipótesis, rechazar H₀ implica aceptar la hipótesis alternativa Hₐ. Sin embargo, no rechazar H₀ no implica aceptarla, decimos simplemente que no hay evidencia suficiente para rechazar la hipótesis nula. En cualquier caso, una prueba de hipótesis no demuestra una hipótesis, sólo la soporta con un cierto grado de confianza. Acumular evidencia a favor de una hipótesis (razonamiento inductivo) no es suficiente para demostrarla, la evidencia acumulada solo puede soportar dicha hipótesis.
Las pruebas de hipótesis fueron propuestas para solucionar el problema de la inducción e incluir el análisis estadístico dentro de un modelo hipotético deductivo (Kaplan 2019, capítulo 13).
Existen dos tipos de errores que podemos cometer (Neyman & Pearson, 1933):

H₀ es cierta Hₐ es cierta
Se escogió Hₐ Error de tipo I Decisión correcta
Se escogió H₀ Decisión correcta Error de tipo II

El riesgo o probabilidad de caer en un error del tipo I se conoce como nivel de significación estadistica, normalmente indicado con la letra griega $\alpha$. La probabilidad de caer en un error del tipo II normalmente se anota con la letra griega $\beta$. Siendo $1-\beta$ la potencia o poder del test.

$$P(escoger H_a | H_0 cierta) = \alpha$$

$$P(escoger H_0 | H_a cierta) = \beta$$

$$P(escoger H_a | H_a cierta) = 1 - \beta$$

Se habla de errores de tipo III cuando se da la respuesta correcta (rechazar una hipótesis nula) para una pregunta incorrecta o errónea.

Referencias
  • Kaplan, D. (2009). Statistical modeling: A fresh approach.
  • Neyman, J., & Pearson, E. S. (1992). On the problem of the most efficient tests of statistical hypotheses (pp. 73-108). Springer New York.
  • Lehmann, E. L. (2012). The Fisher, Neyman-Peerson Theories of Testing Hypotheses: One Theory or Two?. In Selected Works of EL Lehmann (pp. 201-208). Springer US.
  • Biau, D. J., Jolles, B. M., & Porcher, R. (2010). P value and the theory of hypothesis testing: an explanation for new researchers. Clinical Orthopaedics and Related Research®, 468(3), 885-892.
  • Nickerson, R. S. (2000). Null hypothesis significance testing: a review of an old and continuing controversy. Psychological methods, 5(2), 241.

Valor P

El valor P (p value) es la probabilidad de observar un determinado valor (o uno más extremo) dado que H₀ es correcta. En ningún caso debe interpretarse como una probabilidad de la hipótesis nula. Un valor P bajo indica que los datos son inconsistentes con la hipótesis nula, permitiéndonos rechazar la hipótesis nula ante esa observación. Para decidir que es un valor bajo, uno puede recurrir al valor de significación α.

$$P(escoger H_a | H_0 cierta) = P(p \le \alpha | H_0 cierta) = \alpha$$

T de Student para una muestra

La prueba de T de Student para una muestra permite probar si la media de una muestra es diferente de una media $\mu_0$. Algo que tenemos que tener en cuenta, es que no podemos testear que la media poblacional sea un determinado valor. Ésto se debe a que no podemos saber cuál es la media poblacional sin analizar toda la población. Es decir, no podemos saber dónde se encuentra localizada la distribución T Student correspondiente a la media poblacional. Para determinar probabilidades necesitamos un parámetro de ubicación exacto. Es por esto que la hipótesis nula será la ubicación de la media poblacional en un lugar determinado. De hecho, las hipótesis nulas se caracterizan normalmente por tener igualdades (uno supone una distribución con parámetros determinados).

$$H_0 : \mu = \mu_0$$

Si para una muestra de tamaño $n$ se cumplen las supuestos del test:

  • Distribución normal de la variable (continua) en la población
  • Muestreo al azar (cada observación es independiente)

Entonces el estadístico $t$ sigue una distribución T de Student con $n - 1$ grados de libertad.

$$ t = \frac{ \bar{x} - \mu }{ \frac{s}{\sqrt{n}} }$$

Supongamos una variable aleatoria $X$ que en la población se distribuye con una distribución Normal(0.1,0.1). Y supongamos que estamos interesados en demostrar que la media de esa variable $X$ en la población es mayor a 0. Es decir:

$$H_0 : \mu = 0$$

$$H_a : \mu > 0$$

Otras dos hipótesis alternativas son posibles; $H_a \ne 0$ ó $H_a < 0$. Podemos elegir cualquiera de éstas dependiendo de nuestro hipótesis de trabajo, determinando si el test será a una o dos colas. En este caso el test será a una cola y el p value para un valor observado $T$ será:

$$P(t \ge T|H_0)$$

In [1]:
using Distributions

μ = 0.1
población = Normal(μ,0.1)

n = 5
muestra   = rand(población, n)


Out[1]:
5-element Array{Float64,1}:
  0.133009 
 -0.0209208
 -0.046207 
  0.051295 
  0.096264 

In [2]:
# H₀
μ₀ = 0 
H₀ = TDist(n-1)


Out[2]:
Distributions.TDist{Float64}(ν=4.0)

In [3]:
 = mean(muestra)


Out[3]:
0.042688016494693275

In [4]:
s = std(muestra)


Out[4]:
0.07591236375417096

In [5]:
T = (-μ₀)/(s/sqrt(n))


Out[5]:
1.257414497273138

In [6]:
p = ccdf(H₀,T)


Out[6]:
0.138505654299523

Obtenemos el mismo resultado que utilizando OneSampleTTest de la biblioteca HypothesisTests de Julia:


In [7]:
using HypothesisTests

In [8]:
ttest = OneSampleTTest(muestra, 0)


Out[8]:
One sample t-test
-----------------
Population details:
    parameter of interest:   Mean
    value under h_0:         0
    point estimate:          0.042688016494693275
    95% confidence interval: (-0.05156963259740913,0.1369456655867957)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.277011308599046 (not significant)

Details:
    number of observations:   5
    t-statistic:              1.257414497273138
    degrees of freedom:       4
    empirical standard error: 0.03394904113740348

In [9]:
pvalue(ttest, tail=:right)


Out[9]:
0.138505654299523

El p value depende de si el test es a una o dos colas, en este caso, como la distribución es simétrica alrededor del 0, es obvio que el p value para el test a dos colas es el doble del p value que obtuvimos. Pero calcular el p value a dos colas no es trivial, principalmente puede ser un problema para distribuciones asimétricas (Kulinskaya, 2008; Agresti & Kateri, 2011). Pero en general se toma la idea de doblar el valor del P value menor al testear las dos opciones a una cola (es como si hiciéramos una corrección de Bonferroni al haber realizado dos pruebas).

Kulinskaya, Elena. "On two-sided p-values for non-symmetric distributions." arXiv preprint arXiv:0810.2124 (2008).
Agresti, Alan, and Maria Kateri. Categorical data analysis. Springer Berlin Heidelberg, 2011.

En particular, para una variable aleatoria $X$, que sigue una determinada distribución si $H_0$ es cierta, dado un estimador $x_0$, el p value es:

$P(X \geq x|H_0)$ prueba de una cola hacia la derecha (right-tail event)


In [10]:
p_right = pvalue(ttest, tail=:right)


Out[10]:
0.138505654299523

In [11]:
using Plots
pyplot(size=(400,200))

PDF = plot(t -> pdf(H₀,t), -10, T, legend=false)
plot!(PDF, t -> pdf(H₀,t), T, 10, fill=0)

CCDF = plot(t -> ccdf(H₀,t), -10, 10, legend=false)
scatter!(CCDF, [T], [p_right])

plot(PDF, CCDF)


Out[11]:

$P(X \leq x|H_0)$ prueba de una cola hacia la izquierda (left-tail event)


In [12]:
p_left = pvalue(ttest, tail=:left)


Out[12]:
0.861494345700477

In [13]:
PDF = plot(t -> pdf(H₀,t),   T, 10, legend=false)
plot!(PDF, t -> pdf(H₀,t), -10,  T, fill=0)

CDF = plot(t -> cdf(H₀,t), -10, 10, legend=false)
scatter!(CDF, [T], [p_left])

plot(PDF, CDF)


Out[13]:

$2 min{P(X \leq x|H_0), P(X \geq x|H_0)}$ para el test a dos colas (double-tailed event)


In [14]:
pvalue(ttest, tail=:both)


Out[14]:
0.277011308599046

In [15]:
2*min(p_left,p_right)


Out[15]:
0.277011308599046

In [16]:
PDF = plot(t -> pdf(H₀,t), -T,  T, legend=false)
plot!(PDF, t -> pdf(H₀,t), -10, -T, fill=0)
plot!(PDF, t -> pdf(H₀,t),  T,  10, fill=0)

CCDF = plot(t -> ccdf(H₀,t), -10, 10, legend=false)
scatter!(CCDF, [-T, T], [p_left,p_right])

plot(PDF, CCDF)


Out[16]:

Para facilitar ésto, la biblioteca HypothesisTests define la función pvalue para tomar directamente una distribución de probabilidad (no solamente un test estadístico), y calcular el p value para un determinado estadístico.


In [17]:
pvalue(TDist(n-1), T, tail=:right)


Out[17]:
0.138505654299523

Intervalo de confianza

El intervalo de confianza es un tipo de estimador por intervalo para un parámetro de la población. Se calcula a partir de una o más muestras de la población, y posee un nivel de confianza que determina qué tan frecuentemente una serie de intervalos estimados de la misma manera contiene al parámetro poblacional. Es importante notar que el intervalo de confianza calculado a partir de una única muestra puede no contener al parámetro a estimar, pero aún así es una buena estimación intervalar del mismo. Así un intervalo con una confianza del 95%, significa que de un número N de intervalos calculados, 0.95N contendrán al parámetro a estimar. No debe interpretarse nunca como un intervalo con una probabilidad del 95% de contener el parámetro.

El intervalo para una media se calcula utilizando el valor crítico de $t$ si la desviación estándar proviene de la muestra o $Z$ si se conoce la desviación estándar de la población. Los valores críticos son aquellos valores de $t$ o $Z$ que dejan un área de $\frac{\alpha}{2}$ hacia la izquierda del menor valor crítico, y el mismo hacia la derecha (dejando un área $1-\alpha$ en el intervalo).

Así el valor crítico, utilizando la distribución T de Student con $n-1$ grados de libertad, para una confianza del 95% ($\alpha = 5%$) puede calcularse con la función quantile de Distributions


In [18]:
t_left = quantile(TDist(n-1),0.05/2)


Out[18]:
-2.7764451051977943

In [19]:
t_right = quantile(TDist(n-1),1-0.05/2)


Out[19]:
2.7764451051977934

Los valores son iguales en módulo dada la simetría de la distribución T de Student. Siendo $t$ ese módulo, el intervalo de confianza para la media de la población sería:

$$(\bar{x}-t\frac{s}{\sqrt{n}} , \bar{x}+t\frac{s}{\sqrt{n}})$$

In [20]:
t  = abs(t_left)

se = s/sqrt(n) # Error estándar de la media


Out[20]:
0.03394904113740348

In [21]:
(  - t*se,  + t*se )


Out[21]:
(-0.05156963259740916,0.13694566558679572)

Para facilitar ésto, la biblioteca HypothesisTests define la función ci.


In [22]:
confint(ttest) # usando ci de HypothesisTests sobre el T test


Out[22]:
(-0.05156963259740913,0.1369456655867957)

Nivel de confianza


In [23]:
n_experimentos = 50

intervalos = map(1:n_experimentos) do N
    
    muestra = rand(población, n)
    
    t_test  = OneSampleTTest(muestra)
    intervalo = confint(t_test, 0.1) # α = 0.1
    
    [intervalo[1], intervalo[2]] # retorno un vector [inicio, fin]
end


Out[23]:
50-element Array{Array{Float64,1},1}:
 [0.10444,0.167928]   
 [0.00226236,0.24267] 
 [0.033861,0.20915]   
 [0.120587,0.280967]  
 [-0.0323041,0.239351]
 [0.0760238,0.256807] 
 [0.0232045,0.18654]  
 [0.0113195,0.221061] 
 [-0.0151557,0.160663]
 [-0.0181343,0.208701]
 [-0.0215792,0.207693]
 [0.056575,0.175543]  
 [0.0961303,0.254531] 
 ⋮                    
 [-0.0166307,0.10352] 
 [0.060759,0.244057]  
 [-0.00596191,0.19468]
 [0.00354181,0.16571] 
 [0.0096855,0.23366]  
 [-0.0694735,0.241097]
 [-0.017344,0.146808] 
 [0.0652223,0.227261] 
 [0.0645839,0.223697] 
 [0.0886298,0.217953] 
 [0.0385181,0.130664] 
 [-0.0133689,0.263237]

In [24]:
intervalos = hcat(intervalos...)


Out[24]:
2×50 Array{Float64,2}:
 0.10444   0.00226236  0.033861  …  0.0886298  0.0385181  -0.0133689
 0.167928  0.24267     0.20915      0.217953   0.130664    0.263237 

In [25]:
y = hcat(map(N -> [N,N],1:n_experimentos)...)


Out[25]:
2×50 Array{Int64,2}:
 1  2  3  4  5  6  7  8  9  10  11  12  …  42  43  44  45  46  47  48  49  50
 1  2  3  4  5  6  7  8  9  10  11  12     42  43  44  45  46  47  48  49  50

In [30]:
plot(intervalos, y, size=(600,600), legend=false, linecolor=:darkgrey, ylim=(-1,51), grid=false)
vline!([μ])


Out[30]:

In [31]:
contiene_μ = [ intervalos[1,i]  μ  intervalos[2,i] for i in 1:n_experimentos ]


Out[31]:
50-element Array{Bool,1}:
 false
  true
  true
 false
  true
  true
  true
  true
  true
  true
  true
  true
  true
     ⋮
  true
  true
  true
  true
  true
  true
  true
  true
  true
  true
  true
  true

In [32]:
mean(contiene_μ) # ~ 90% ( α = 0.1, confianza = 1 - α = 0.9 )


Out[32]:
0.92

Bootstrap

**Bootstrap** nos permite obtener estimaciones puntuales o por intervalos, en particular, intervalos de confianza, para parámetros poblacionales sin necesidad de conocer la distribución subyacente.
Básicamente la técnica de bootstrap se basa en hacer un muestreo aleatorio con reemplazo de nuestra muestra (remuestreo), calculando el parámetro de interés en cada muestra. La muestra de la que se parte debe ser una muestra representativa, en particular debe complir con ser una muestra de valores independientes e idénticamente distribuidos (iid). Si bien la distribución de la variable de interés en la población no forma parte de los supuestos del método, una implementación naïve puede generar resultados incorrectos con distribuciones con colas pesadas. Bootstrap también puede presentar problemas con distribuciones discretas y poco densas.


In [33]:
# Se hacen muchos remuestreos
medias = map(1:10_000) do i

    # Se toma una muestra al azar (con reemplazo) del mismo tamaño que la muestra
    resampling = sample(muestra, replace=true, n)
    
    # Se calcula el estadístico de interés
    mean(resampling)    
    
end

# Bootstrap distribution of the statistic
histogram(medias, legend=false)


Out[33]:

In [47]:
quantile(medias,[0.05,0.95]) # α = 0.05 + 0.95 = 0.1, confianza = 1 - α = 0.9


Out[47]:
2-element Array{Float64,1}:
 -0.00759833
  0.0929744 

In [48]:
median(medias)


Out[48]:
0.04268801649469327

A pesar de que ésta implementación naïve es super sencilla, la biblioteca Bootstrap de Julia ofrece herramientas para facilitar el proceso de bootstraping, así como implementaciones más complejas para reducir el error en algunas situaciones. Herramientas similares son ofrecidas por la biblioteca boot de R.


In [49]:
using Bootstrap

In [50]:
bootstrapped_mean = bootstrap(muestra, mean, BasicSampling(10_000))


Out[50]:
Bootstrap Sampling
  Estimates:
    │ Var │ Estimate │ Bias         │ StdError  │
    ├─────┼──────────┼──────────────┼───────────┤
    │ 1   │ 0.042688 │ -0.000532175 │ 0.0303866 │
  Sampling: BasicSampling
  Samples:  10000
  Data:     Array{Float64,1}: { 5 }

In [51]:
Bootstrap.ci(bootstrapped_mean, BasicConfInt(0.9)) # α = 0.1, confianza = 0.9


Out[51]:
((0.042688016494693275,-0.007598328498678794,0.09297436148806536),)

Una ventaja de hacerlo con estas bibliotecas es que podemos tener intervalos de confianza con corrección del sesgo, BCa:


In [52]:
Bootstrap.ci(bootstrapped_mean, BCaConfInt(0.9)) # Bias-Corrected and accelerated (BCa)


Out[52]:
((0.042688016494693275,-0.007598328498678803,0.09297436148806534),)
Referencias
  • Efron, B. (1992). Bootstrap methods: another look at the jackknife. In Breakthroughs in Statistics (pp. 569-593). Springer New York. link
  • Gleason, J. R. (1988). Algorithms for balanced bootstrap simulations. The American Statistician, 42(4), 263-266.
  • Carpenter, J., & Bithell, J. (2000). Bootstrap con" dence intervals: when, which, what? A practical guide for medical statisticians. link
  • Singh, K., & Xie, M. (2008). Bootstrap: a statistical method. Unpublished manuscript, Rutgers University, USA. link

Prueba de bondad de ajuste a una distribución.

Muchas veces es necesario saber cuando los datos de una muestra se ajustan a una determinada distribución. En ese sentido uno se puede preguntar si la distribución observada (en general, para una muestra) es igual, o no, a una distribución esperada (en general, para la población). Para testear ésto, disponemos de las siguientes pruebas:

Prueba χ²

La prueba χ² se puede utilizar para testear la bondad de ajuste de cualquier distribución univariada para la cual se pueda calcular la CDF. Dado que requiere datos en grupos, por lo que puede utilizarse para testear distribución para datos categóricos (a diferencia de KS). Para poder utilizar el test en una distribución de probabilidad para datos continuos, debemos discretizar/agrupar los datos de la misma manera en que lo hacemos al calcular un histograma. Debemos tener en cuenta q el test es sensible a la elección de los bins. Una desventaja de este test es que requiere de un tamaño muestral de al menos 1000 para que la aproximación χ² sea válida.


In [53]:
población = Binomial(100, 0.055)
expected  = Binomial(100, 0.05 ) # H₀: expected == observed


Out[53]:
Distributions.Binomial{Float64}(n=100, p=0.05)

In [54]:
observed = rand(población, 1000) # muestra

histogram(observed, legend=false, bins=-0.5:1:maximum(observed))


Out[54]:

In [55]:
using StatsBase
cdf_observed = ecdf(observed)

scatter( 0:1:maximum(observed),      cdf_observed,     alpha=0.7, label="observed")
scatter!(0:1:maximum(observed), x -> cdf(expected, x), alpha=0.7, label="expected")


Out[55]:

Dadas $k$ categorías, para la categoría $i$, $O_i$ representa la frecuencia observada para esa categoría, mientras $E_i$ representa la frecuencia esperada (nuestra hipótesis nula).

$$ χ^{2} = \sum_{i=1}^{k}{\frac{(O_i - E_i)^{2}}{E_i}} $$

Ésta última, en el caso de haber generado bins para una variable continua, la calculamos usando la CDF evaluada en el extremo superior bin, menos su valor en el extremo inferior del bin. N es el tamaño de la muestra.

$$Ei=N(CDF(X_f)−CDF(X_i))$$

In [56]:
N  = length(observed)
Oᵢ = Float64[ sum(observed .== x) for x in 0:1:100 ]
Eᵢ = Float64[ pdf(expected,x) for x in 0:1:100 ] .* N


Out[56]:
101-element Array{Float64,1}:
   5.92053     
  31.1607      
  81.1818      
 139.576       
 178.143       
 180.018       
 150.015       
 106.026       
  64.8709      
  34.9013      
  16.7159      
   7.19823     
   2.80983     
   ⋮           
   1.3015e-99  
   8.37223e-102
   4.84224e-104
   2.49314e-106
   1.12876e-108
   4.42402e-111
   1.47059e-113
   4.03122e-116
   8.74926e-119
   1.40965e-121
   1.49884e-124
   7.88861e-128

In [57]:
χ² = sum( ( (Oᵢ .- Eᵢ) .^ 2 ) ./ Eᵢ )


Out[57]:
51.31857616265398

In [58]:
k = 101 # Número de bins/categorías
c = 2 + 1 # Parámetros estimados para la distribución más uno
# k - c grados de libertad
# Se testea a una cola, a la derecha χ²
pvalue(Chisq(k-c), χ², tail=:right)


Out[58]:
0.9999731212168578

In [59]:
H₀ = Chisq(k-c)

PDF = plot(x -> pdf(H₀,x),  0, χ², legend=false)
plot!(PDF, x -> pdf(H₀,x), χ², χ²+100, fill=0)


Out[59]:

In [61]:
ChisqTest(convert(Vector{Int}, Oᵢ), Eᵢ./sum(Eᵢ))


Out[61]:
Pearson's Chi-square Test
-------------------------
Population details:
    parameter of interest:   Multinomial Probabilities
    value under h_0:         [0.00592053,0.0311607,0.0811818,0.139576,0.178143,0.180018,0.150015,0.106026,0.0648709,0.0349013,0.0167159,0.00719823,0.00280983,0.00100107,0.000327419,9.88002e-5,2.7625e-5,7.18422e-6,1.74354e-6,3.96039e-7,8.44189e-8,1.69261e-8,3.19895e-9,5.7098e-10,9.64155e-11,1.54265e-11,2.34208e-12,3.37843e-13,4.63582e-14,6.0577e-15,7.54555e-16,8.96755e-17,1.0177e-17,1.10372e-18,1.14473e-19,1.13612e-20,1.07965e-21,9.82895e-23,8.57651e-24,7.17603e-25,5.7597e-26,4.43623e-27,3.27992e-28,2.32846e-29,1.58759e-30,1.03982e-31,6.54351e-33,3.95688e-34,2.2995e-35,1.28436e-36,6.895e-38,3.55779e-39,1.76449e-40,8.41069e-42,3.85285e-43,1.69599e-44,7.17289e-46,2.9142e-47,1.13712e-48,4.26039e-50,1.53224e-51,5.28816e-53,1.75075e-54,5.55794e-56,1.69115e-57,4.92966e-59,1.3759e-60,3.67484e-62,9.3862e-64,2.29106e-65,5.34007e-67,1.18756e-68,2.51749e-70,5.08218e-72,9.75951e-74,1.78068e-75,3.0829e-77,5.05739e-79,7.84885e-81,1.1504e-82,1.58937e-84,2.06545e-86,2.51884e-88,2.87503e-90,3.06237e-92,3.03393e-94,2.78513e-96,2.35885e-98,1.83403e-100,1.3015e-102,8.37223e-105,4.84224e-107,2.49314e-109,1.12876e-111,4.42402e-114,1.47059e-116,4.03122e-119,8.74926e-122,1.40965e-124,1.49884e-127,7.88861e-131]
    point estimate:          [0.004,0.02,0.06,0.108,0.165,0.176,0.158,0.133,0.088,0.045,0.021,0.015,0.004,0.003,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
    95% confidence interval: Tuple{Float64,Float64}[(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.045,1.0),(0.056,1.0),(0.038,1.0),(0.013,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0),(0.0,1.0)]

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.9999864623721593 (not significant)

Details:
    Sample size:        1000
    statistic:          51.31857616265393
    degrees of freedom: 100
    residuals:          [-0.789297,-1.99934,-2.35089,-2.67269,-0.984688,-0.299456,0.651952,2.61968,2.87167,1.7094,1.04784,2.90791,0.710014,1.99785,-0.572206,-0.314325,-0.166208,-0.0847598,-0.0417557,-0.0199007,-0.00918798,-0.00411413,-0.00178856,-0.000755632,-0.000310508,-0.000124203,-4.8395e-5,-1.83805e-5,-6.80869e-6,-2.46124e-6,-8.68651e-7,-2.99459e-7,-1.00881e-7,-3.32223e-8,-1.06992e-8,-3.37064e-9,-1.03906e-9,-3.13512e-10,-9.26094e-11,-2.67881e-11,-7.58927e-12,-2.10624e-12,-5.72706e-13,-1.52593e-13,-3.98445e-14,-1.01972e-14,-2.55803e-15,-6.29038e-16,-1.51641e-16,-3.5838e-17,-8.30361e-18,-1.88621e-18,-4.20059e-19,-9.17098e-20,-1.96287e-20,-4.11824e-21,-8.46929e-22,-1.7071e-22,-3.37212e-23,-6.52717e-24,-1.23784e-24,-2.2996e-25,-4.1842e-26,-7.45516e-27,-1.30044e-27,-2.22028e-28,-3.70932e-29,-6.06204e-30,-9.68824e-31,-1.51363e-31,-2.31086e-32,-3.4461e-33,-5.01746e-34,-7.12894e-35,-9.87903e-36,-1.33442e-36,-1.75582e-37,-2.24886e-38,-2.80158e-39,-3.39175e-40,-3.98668e-41,-4.54472e-42,-5.01881e-43,-5.36193e-44,-5.53387e-45,-5.50811e-46,-5.27743e-47,-4.8568e-48,-4.28256e-49,-3.60763e-50,-2.89348e-51,-2.20051e-52,-1.57897e-53,-1.06243e-54,-6.65133e-56,-3.83483e-57,-2.00779e-58,-9.35375e-60,-3.75454e-61,-1.22427e-62,-2.80867e-64]
    std. residuals:     [-0.791644,-2.03124,-2.45255,-2.88132,-1.08618,-0.330698,0.707147,2.77067,2.9696,1.74004,1.05671,2.91843,0.711014,1.99885,-0.572299,-0.31434,-0.16621,-0.0847601,-0.0417557,-0.0199007,-0.00918798,-0.00411413,-0.00178856,-0.000755632,-0.000310508,-0.000124203,-4.8395e-5,-1.83805e-5,-6.80869e-6,-2.46124e-6,-8.68651e-7,-2.99459e-7,-1.00881e-7,-3.32223e-8,-1.06992e-8,-3.37064e-9,-1.03906e-9,-3.13512e-10,-9.26094e-11,-2.67881e-11,-7.58927e-12,-2.10624e-12,-5.72706e-13,-1.52593e-13,-3.98445e-14,-1.01972e-14,-2.55803e-15,-6.29038e-16,-1.51641e-16,-3.5838e-17,-8.30361e-18,-1.88621e-18,-4.20059e-19,-9.17098e-20,-1.96287e-20,-4.11824e-21,-8.46929e-22,-1.7071e-22,-3.37212e-23,-6.52717e-24,-1.23784e-24,-2.2996e-25,-4.1842e-26,-7.45516e-27,-1.30044e-27,-2.22028e-28,-3.70932e-29,-6.06204e-30,-9.68824e-31,-1.51363e-31,-2.31086e-32,-3.4461e-33,-5.01746e-34,-7.12894e-35,-9.87903e-36,-1.33442e-36,-1.75582e-37,-2.24886e-38,-2.80158e-39,-3.39175e-40,-3.98668e-41,-4.54472e-42,-5.01881e-43,-5.36193e-44,-5.53387e-45,-5.50811e-46,-5.27743e-47,-4.8568e-48,-4.28256e-49,-3.60763e-50,-2.89348e-51,-2.20051e-52,-1.57897e-53,-1.06243e-54,-6.65133e-56,-3.83483e-57,-2.00779e-58,-9.35375e-60,-3.75454e-61,-1.22427e-62,-2.80867e-64]

Prueba de Kolmogórov-Smirnov

La prueba de Kolmogorov-Smirnov es otra prueba de ajuste a una distribución que usa la función de densidad acumulada (CDF). En particular, su estadístico, $D$ mide la distancia entre la CDF de la distribución, que suponemos correcta en la hipótesis nula, y la ECDF de la muestra. En particular, el estadístico $D$ es el valor máximo de las diferencias. Si la función de densidad acumulada empírica es igual a la función de densidad de nuestra distribución a ajustar, el estadístico $D$ será 0 ($H_0$: $D = 0$).
Éste es un test paramétrico, por lo que hace pocas supuestos, pero debe tenerse en cuenta que la distribución que suponemos en nuestra $H_0$ no puede tener parámetros libres, debe estar completamente determinada y debe ser continua. Es sensible tanto a cambios en la ubicación como en la forma de la distribución, pero no tiene gran poder, por lo que puede requerir un tamaño muestral grande para rechazar correctamente la hipótesis nula.


In [62]:
población = Binomial(100, 0.05)
muestra   = rand(población, 10)

ExactOneSampleKSTest(muestra, población)


WARNING: This test is inaccurate with ties
Out[62]:
Exact one sample Kolmogorov-Smirnov test
----------------------------------------
Population details:
    parameter of interest:   Supremum of CDF differences
    value under h_0:         0.0
    point estimate:          0.25783865911601617

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.44548344820197927 (not significant)

Details:
    number of observations:   10

Comparación de dos poblaciones.

sleep dataset

Data which show the effect of two soporific drugs (increase in hours of sleep compared to control) on 10 patients.

  • Extra: increase in hours of sleep
  • Group: drug given
  • ID: patient ID

In [63]:
using RDatasets
sleep_long = dataset("datasets","sleep")


Out[63]:
ExtraGroupID
10.711
2-1.612
3-0.213
4-1.214
5-0.115
63.416
73.717
80.818
90.019
102.0110
111.921
120.822
131.123
140.124
15-0.125
164.426
175.527
181.628
194.629
203.4210

In [66]:
?DataFrames.unstack


Out[66]:

Unstacks a DataFrame; convert from a long to wide format

unstack(df::AbstractDataFrame, rowkey, colkey, value)
unstack(df::AbstractDataFrame, colkey, value)
unstack(df::AbstractDataFrame)

Arguments

  • df : the AbstractDataFrame to be unstacked
  • rowkey : the column with a unique key for each row, if not given, find a key by grouping on anything not a colkey or value
  • colkey : the column holding the column names in wide format, defaults to :variable
  • value : the value column, defaults to :value

Result

  • ::DataFrame : the wide-format dataframe

Examples

wide = DataFrame(id = 1:12,
                 a  = repeat([1:3;], inner = [4]),
                 b  = repeat([1:4;], inner = [3]),
                 c  = randn(12),
                 d  = randn(12))

long = stack(wide)
wide0 = unstack(long)
wide1 = unstack(long, :variable, :value)
wide2 = unstack(long, :id, :variable, :value)

Note that there are some differences between the widened results above.


In [67]:
sleep_wide = unstack(sleep_long, :ID, :Group, :Extra)


Out[67]:
ID12
110.71.9
22-1.60.8
33-0.21.1
44-1.20.1
55-0.1-0.1
663.44.4
773.75.5
880.81.6
990.04.6
10102.03.4

In [68]:
names!(sleep_wide, [:ID,:G1,:G2])


Out[68]:
IDG1G2
110.71.9
22-1.60.8
33-0.21.1
44-1.20.1
55-0.1-0.1
663.44.4
773.75.5
880.81.6
990.04.6
10102.03.4

¿Son variables independientes con distribución normal?


In [70]:
using RCall 

by(sleep_long, :Group) do df
    
    extra = df[:Extra]
    
    DataFrame(
    
        P_AD = pvalue(OneSampleADTest(extra, Normal())),
    
        P_Shapiro = rcopy(R"shapiro.test($extra)")[Symbol("p.value")]
    )
end


Out[70]:
GroupP_ADP_Shapiro
110.40192781951420050.40792879642998914
220.37847072243625640.35113468540765047

¿Hay igualdad de varianza?


In [73]:
using StatPlots
boxplot(sleep_long, :Group, :Extra, legend=false)


Out[73]:

In [74]:
by(sleep_long, :Group) do df
    var( df[:Extra] )
end


Out[74]:
Groupx1
113.200555555555556
224.0089999999999995

Todos los test de igualdad de varianza tienen como hipótesis nula que las varianzas son iguales.

El test F de igualdad de varianzas tiene como supuesto que las distribuciones son normales.


In [75]:
R"var.test(Extra ~ Group, $sleep_long)"


Out[75]:
RCall.RObject{RCall.VecSxp}

	F test to compare two variances

data:  Extra by Group
F = 0.79834, num df = 9, denom df = 9, p-value = 0.7427
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
 0.198297 3.214123
sample estimates:
ratio of variances 
         0.7983426 

El test de Bartlett es sensible a las desviaciones de la normalidad, por lo que no es recomendable usarlo con distribuciones no normales.


In [76]:
R"bartlett.test(Extra ~ Group, $sleep_long)"


Out[76]:
RCall.RObject{RCall.VecSxp}

	Bartlett test of homogeneity of variances

data:  Extra by Group
Bartlett's K-squared = 0.10789, df = 1, p-value = 0.7426

El test de Levene es robusto ante distribuciones no normales.


In [79]:
# install.packages("car")

R"""
library(car)
leveneTest(Extra ~ Group, $sleep_long)
"""


WARNING: RCall.jl: Warning in leveneTest.default(y = y, group = group, ...) :
  group coerced to factor.
Out[79]:
RCall.RObject{RCall.VecSxp}
Levene's Test for Homogeneity of Variance (center = median)
      Df F value Pr(>F)
group  1  0.2482 0.6244
      18               

In [80]:
EqualVarianceTTest(sleep_wide[:G1], sleep_wide[:G2])


Out[80]:
Two sample t-test (equal variance)
----------------------------------
Population details:
    parameter of interest:   Mean difference
    value under h_0:         0
    point estimate:          -1.5799999999999996
    95% confidence interval: (-3.363874032287598,0.2038740322875987)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.07918671421593818 (not significant)

Details:
    number of observations:   [10,10]
    t-statistic:              -1.8608134674868528
    degrees of freedom:       18
    empirical standard error: 0.8490910172387619

In [81]:
UnequalVarianceTTest(sleep_wide[:G1], sleep_wide[:G2]) # Welch’s t-test


Out[81]:
Two sample t-test (unequal variance)
------------------------------------
Population details:
    parameter of interest:   Mean difference
    value under h_0:         0
    point estimate:          -1.5799999999999996
    95% confidence interval: (-3.3654832307117104,0.20548323071171093)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.07939414018735824 (not significant)

Details:
    number of observations:   [10,10]
    t-statistic:              -1.8608134674868526
    degrees of freedom:       17.776473516178495
    empirical standard error: 0.849091017238762

In [82]:
OneSampleTTest(
    convert(Vector{Float64}, sleep_wide[:G1]), 
    convert(Vector{Float64}, sleep_wide[:G2])
) # H₀: mean(x) - mean(y) = 0


Out[82]:
One sample t-test
-----------------
Population details:
    parameter of interest:   Mean
    value under h_0:         0
    point estimate:          -1.58
    95% confidence interval: (-2.4598857632769824,-0.7001142367230176)

Test summary:
    outcome with 95% confidence: reject h_0
    two-sided p-value:           0.00283289019738427 (very significant)

Details:
    number of observations:   10
    t-statistic:              -4.062127683382037
    degrees of freedom:       9
    empirical standard error: 0.3889587238883952

Alternativas no paramétricas


In [83]:
MannWhitneyUTest(sleep_wide[:G1], sleep_wide[:G2]) # H₀: P(x > y) = P(y > x)


Out[83]:
Approximate Mann-Whitney U test
-------------------------------
Population details:
    parameter of interest:   Location parameter (pseudomedian)
    value under h_0:         0
    point estimate:          -1.4

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.06932757543362658 (not significant)

Details:
    number of observations in each group: [10,10]
    Mann-Whitney-U statistic:             25.5
    rank sums:                            [80.5,129.5]
    adjustment for ties:                  18.0
    normal approximation (μ, σ):          (-24.5,13.213828482233858)

In [84]:
SignedRankTest(
    convert(Vector{Float64}, sleep_wide[:G1]), 
    convert(Vector{Float64}, sleep_wide[:G2])
) # H₀:  median(x - y) = 0


Out[84]:
Exact Wilcoxon signed rank test
-------------------------------
Population details:
    parameter of interest:   Location parameter (pseudomedian)
    value under h_0:         0
    point estimate:          -1.3
    95% confidence interval: (-2.6999999999999997,-0.8999999999999999)

Test summary:
    outcome with 95% confidence: reject h_0
    two-sided p-value:           0.00390625 (very significant)

Details:
    number of observations:      10
    Wilcoxon rank-sum statistic: 0.0
    rank sums:                   [0.0,45.0]
    adjustment for ties:         6.0
Kolmogorov-Smirnov

In [85]:
ApproximateTwoSampleKSTest(sleep_wide[:G1], sleep_wide[:G2]) # H₀: x e y provienen de la misma distribución


WARNING: This test is inaccurate with ties
Out[85]:
Approximate two sample Kolmogorov-Smirnov test
----------------------------------------------
Population details:
    parameter of interest:   Supremum of CDF differences
    value under h_0:         0.0
    point estimate:          0.5

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.1640791977266521 (not significant)

Details:
    number of observations:   [10,10]
    KS-statistic:              1.118033988749895

Then let W be the number of pairs for which yi − xi > 0. Assuming that H0 is true, then W follows a binomial distribution W ~ b(m, 0.5).

$m$ es el número de pares que muestran diferencias.


In [86]:
SignTest(sleep_wide[:G1], sleep_wide[:G2]) # H₀: P(x > y) = 0.5


Out[86]:
Sign Test
---------
Population details:
    parameter of interest:   Median
    value under h_0:         0.0
    point estimate:          -1.3
    95% confidence interval: (-1.7999999999999998,-1.0000000000000004)

Test summary:
    outcome with 95% confidence: reject h_0
    two-sided p-value:           0.0039062500000000035 (very significant)

Details:
    number of observations:       9
    observations larger than 0.0: 0

Es un caso especial de la prueba de chi-cuadrado. Esta prueba posee poco poder.
Se calcula la mediana para todos los datos ($x$ e $y$), estableciéndose dos grupos (por encima o por debajo de ésta). Luego se arma una tabla de contingencia con esta nueva variable versus las dos variables anteriores ($x$ e $y$).


In [87]:
median_xy = median(sleep_long[:Extra])


Out[87]:
0.9500000000000001

In [88]:
sleep_long[:Side] = sleep_long[:Extra] .<= median_xy


Out[88]:
20-element DataArrays.DataArray{Bool,1}:
  true
  true
  true
  true
  true
 false
 false
  true
  true
 false
 false
  true
 false
  true
  true
 false
 false
 false
 false
 false

In [90]:
using FreqTables

In [91]:
tabla = freqtable(sleep_long, :Side, :Group)


Out[91]:
2×2 Named Array{Int64,2}
Side ╲ Group │ 1  2
─────────────┼─────
false        │ 3  7
true         │ 7  3

In [92]:
ChisqTest(tabla)


Out[92]:
Pearson's Chi-square Test
-------------------------
Population details:
    parameter of interest:   Multinomial Probabilities
    value under h_0:         [0.25,0.25,0.25,0.25]
    point estimate:          [0.15,0.35,0.35,0.15]
    95% confidence interval: Tuple{Float64,Float64}[(0.0,0.449679),(0.0,0.649679),(0.0,0.649679),(0.0,0.449679)]

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.07363827012030282 (not significant)

Details:
    Sample size:        20
    statistic:          3.1999999999999984
    degrees of freedom: 1
    residuals:          [-0.894427,0.894427,0.894427,-0.894427]
    std. residuals:     [-1.78885,1.78885,1.78885,-1.78885]

Comparar frecuencias

Use Fisher's exact test when you have two nominal variables. You want to know whether the proportions for one variable are different among values of the other variable.


In [93]:
FisherExactTest(tabla...)


Out[93]:
Fisher's exact test
-------------------
Population details:
    parameter of interest:   Odds ratio
    value under h_0:         1.0
    point estimate:          0.20204490697560082
    95% confidence interval: (0.017989281978933312,1.6833921322245327)

Test summary:
    outcome with 95% confidence: fail to reject h_0
    two-sided p-value:           0.1788954079975756 (not significant)

Details:
    contingency table:
        3  7
        7  3

Se utiliza para tablas de contingencia 2x2 de variables dicotómicas en medidas pareadas.

X / Y true false
true a b
false c d
$$H0: Pb = Pc$$$$Ha: Pb \neq Pc$$$$Q = \frac{(b-c)^{2}}{b+c}$$

Q sigue una distribución χ²con 1 grado de libertad para muestras grandes, es posible hacer una corrección por continuidad para conseguir una mejor aproximación a χ²:

$$Q_{c} = \frac{(|b-c|-1)^{2}}{b+c}$$

In [125]:
X = rand(Binomial(1,0.6),100)
Y = rand(Binomial(1,0.4),100)

tabla = freqtable(X, Y)


Out[125]:
2×2 Named Array{Int64,2}
Dim1 ╲ Dim2 │  0   1
────────────┼───────
0           │ 20  15
1           │ 39  26

In [127]:
b = tabla[0,1]


Out[127]:
15

In [128]:
c = tabla[1,0]


Out[128]:
39

In [129]:
Q = ((b-c)^2)/(b+c)


Out[129]:
10.666666666666666

In [130]:
Qc = ((abs(b-c)-1)^2)/(b+c)


Out[130]:
9.796296296296296

In [131]:
pvalue(Chisq(1), Q, tail=:right)


Out[131]:
0.0010908351761252978

In [132]:
pvalue(Chisq(1), Qc, tail=:right)


Out[132]:
0.001748637004975699

In [133]:
NamedArrays.setnames!(tabla, [1,2], 1)
NamedArrays.setnames!(tabla, [1,2], 2)


Out[133]:
(DataStructures.OrderedDict(1=>1,2=>2),DataStructures.OrderedDict(1=>1,2=>2))

In [134]:
R"mcnemar.test($tabla)"


Out[134]:
RCall.RObject{RCall.VecSxp}

	McNemar's Chi-squared test with continuity correction

data:  `#JL`$tabla
McNemar's chi-squared = 9.7963, df = 1, p-value = 0.001749