Calcule un intervalo de confianza a partir de datos de muestra

109

Tengo datos de muestra para los que me gustaría calcular un intervalo de confianza, asumiendo una distribución normal.

Encontré e instalé los paquetes numpy y scipy y obtuve numpy para devolver una desviación media y estándar (numpy.mean (datos) con datos como una lista). Cualquier consejo sobre cómo obtener un intervalo de confianza de muestra sería muy apreciado.

Bmayer0122
fuente
1
Creo que seguro que especificas si quieres calcular el IC para la media de la muestra o la media de la población. Eso determinaría si desea utilizar la distribución normal ot para calcular la puntuación z. Y la respuesta principal a continuación es para la media de la muestra, por lo que se usa una distribución.
Jake

Respuestas:

162
import numpy as np
import scipy.stats


def mean_confidence_interval(data, confidence=0.95):
    a = 1.0 * np.array(data)
    n = len(a)
    m, se = np.mean(a), scipy.stats.sem(a)
    h = se * scipy.stats.t.ppf((1 + confidence) / 2., n-1)
    return m, m-h, m+h

se puede calcular así.

Shasan
fuente
1
sp.stats.stderr está obsoleto. ¡Sustituí sp.stats.sem y funcionó muy bien!
Bmayer0122
1
La importación scipyno necesariamente importa todos los subpaquetes automáticamente. Es mejor importar el subpaquete de forma scipy.statsexplícita.
Vikram
31
Cuidado con el uso "privado" de sp.stats.t._ppf. No me siento tan cómodo con eso sin más explicaciones. Es mejor usarlo sp.stats.t.ppfdirectamente, a menos que esté seguro de saber lo que está haciendo. En una inspección rápida de la fuente, hay una buena cantidad de código omitido _ppf. ¿Posiblemente benigno, pero también posiblemente un intento de optimización inseguro?
Russ
Me gusta porque puede agregarlo *ss.t._ppf((1+conf)/2.,n-1) al .semmétodo de marco de datos de pandas incorporado para que no tenga que preocuparseapply
TNT
1
Solo quiero aclarar que este cálculo es para la media de la muestra, por lo que se usa una distribución. Si las preguntas son para calcular la media de la población, se debe usar una distribución normal y el intervalo de confianza será menor para el mismo nivel de confianza.
Jake
133

Aquí una versión abreviada del código de shasan, calculando el intervalo de confianza del 95% de la media de la matriz a:

import numpy as np, scipy.stats as st

st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))

Pero usar StatsModels ' tconfint_meanes posiblemente incluso mejor:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

Las suposiciones subyacentes para ambos son que la muestra (matriz a) se extrajo independientemente de una distribución normal con una desviación estándar desconocida (consulte MathWorld o Wikipedia ).

Para un tamaño de muestra grande n, la media de la muestra se distribuye normalmente y se puede calcular su intervalo de confianza usando st.norm.interval()(como se sugiere en el comentario de Jaime). Pero las soluciones anteriores son correctas también para n pequeña, donde st.norm.interval()da intervalos de confianza que son demasiado estrechos (es decir, "confianza falsa"). Mira mi respuesta a una pregunta similar para obtener más detalles (y uno de los comentarios de Russ aquí).

Aquí un ejemplo donde las opciones correctas dan (esencialmente) intervalos de confianza idénticos:

In [9]: a = range(10,14)

In [10]: mean_confidence_interval(a)
Out[10]: (11.5, 9.4457397432391215, 13.554260256760879)

In [11]: st.t.interval(0.95, len(a)-1, loc=np.mean(a), scale=st.sem(a))
Out[11]: (9.4457397432391215, 13.554260256760879)

In [12]: sms.DescrStatsW(a).tconfint_mean()
Out[12]: (9.4457397432391197, 13.55426025676088)

Y finalmente, el resultado incorrecto usando st.norm.interval():

In [13]: st.norm.interval(0.95, loc=np.mean(a), scale=st.sem(a))
Out[13]: (10.23484868811834, 12.76515131188166)
Ulrich Stern
fuente
1
Creo que debería llamar st.t.interval(0.05)para obtener el intervalo de confianza del 95%.
Scimonster
5
No, st.t.interval(0.95)es correcto para el intervalo de confianza del 95%, ver los documentos para scipy.stats.t. Sin embargo, el nombre de SciPy al argumento alphaparece menos que ideal.
Ulrich Stern
Si tengo dos matrices de datos y luego calculé la diferencia de su media. ¿Hay alguna forma de obtener un IC del 95% para esta diferencia de medias? ¿Podrías pensar en alguna manera fácil de hacerlo como la que proporcionas aquí usando StatsModelsl?
steven
@steven, resulta que respondí una pregunta sobre esto. :)
Ulrich Stern
16

Comience buscando el valor z para su intervalo de confianza deseado en una tabla de búsqueda . Entonces mean +/- z*sigma, el intervalo de confianza es , donde sigmaes la desviación estándar estimada de la media de la muestra, dada por sigma = s / sqrt(n), donde ses la desviación estándar calculada a partir de los datos de la muestra y nes el tamaño de la muestra.

bogatron
fuente
29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime
4
El autor de la pregunta original indicó que se suponía una distribución normal, pero vale la pena señalar que, para poblaciones de muestra pequeñas (N <100 aproximadamente), es mejor buscar z en la distribución t de Student en lugar de en la distribución normal . La respuesta de Shasan ya hace esto.
Russ
3
@bogatron, sobre el cálculo sugerido para el intervalo de confianza, ¿no sería la media +/- z * sigma / sqrt (n) , donde n es el tamaño de la muestra?
David
3
@David, tienes razón. Expresé mal el significado de sigma. sigmaen mi respuesta debería ser la desviación estándar estimada de la media muestral, no la desviación estándar estimada de la distribución. Actualicé la respuesta para aclarar eso. Gracias por señalar eso.
bogatron
15

Comenzando Python 3.8, la biblioteca estándar proporciona el NormalDistobjeto como parte del statisticsmódulo:

from statistics import NormalDist

def confidence_interval(data, confidence=0.95):
  dist = NormalDist.from_samples(data)
  z = NormalDist().inv_cdf((1 + confidence) / 2.)
  h = dist.stdev * z / ((len(data) - 1) ** .5)
  return dist.mean - h, dist.mean + h

Esta:

  • Crea un NormalDistobjeto a partir de la muestra de datos ( NormalDist.from_samples(data), que nos da acceso a la desviación estándar y media de la muestra mediante NormalDist.meany NormalDist.stdev.

  • Calcule el Z-scorebasado en la distribución normal estándar (representada por NormalDist()) para la confianza dada usando el inverso de la función de distribución acumulativa ( inv_cdf).

  • Produce el intervalo de confianza basado en la desviación estándar y la media de la muestra.


Esto supone que el tamaño de la muestra es lo suficientemente grande (digamos más de ~ 100 puntos) para usar la distribución normal estándar en lugar de la distribución t de estudiante para calcular el zvalor.

Xavier Guihot
fuente