Calculer un intervalle de confiance à partir d'échantillons de données

109

J'ai des exemples de données pour lesquels je voudrais calculer un intervalle de confiance, en supposant une distribution normale.

J'ai trouvé et installé les packages numpy et scipy et j'ai obtenu numpy pour renvoyer une moyenne et un écart type (numpy.mean (données) avec les données étant une liste). Tout conseil sur l'obtention d'un échantillon d'intervalle de confiance serait très apprécié.

Bmayer0122
la source
1
Je pense que vous spécifiez bien si vous souhaitez calculer l'IC pour la moyenne de l'échantillon ou la moyenne de la population. Cela déterminerait si vous souhaitez utiliser une distribution normale ou t pour calculer le score z. Et la première réponse ci-dessous est pour la moyenne de l'échantillon, donc à la distribution est utilisée.
Jake

Réponses:

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

vous pouvez calculer de cette façon.

shasan
la source
1
sp.stats.stderr est obsolète. J'ai remplacé sp.stats.sem et cela a très bien fonctionné!
Bmayer0122
1
L' scipyimportation n'importera pas nécessairement tous les sous-packages automatiquement. Mieux vaut importer le sous-package scipy.statsexplicitement.
Vikram
31
Attention à l'utilisation "privée" de sp.stats.t._ppf. Je ne suis pas très à l'aise avec cela sans plus d'explications. Mieux vaut utiliser sp.stats.t.ppfdirectement, sauf si vous êtes sûr de savoir ce que vous faites. Lors d'une inspection rapide de la source , une bonne quantité de code est ignorée _ppf. Peut-être bénigne, mais peut-être aussi une tentative d'optimisation dangereuse?
Russ
Je l'aime parce que vous pouvez simplement ajouter *ss.t._ppf((1+conf)/2.,n-1) à la .semméthode de cadre de données pandas intégrée pour que vous n'ayez pas à vous soucier deapply
TNT
1
Je veux juste clarifier ce calcul est pour la moyenne de l'échantillon, donc à la distribution est utilisé. Si les questions portent sur le calcul de la moyenne de la population, une distribution normale doit être utilisée et l'intervalle de confiance sera plus petit pour le même niveau de confiance.
Jake
133

Voici une version abrégée du code de shasan, calculant l'intervalle de confiance à 95% de la moyenne du tableau 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))

Mais utiliser StatsModels tconfint_meanest sans doute encore plus agréable:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

Les hypothèses sous-jacentes pour les deux sont que l'échantillon (tableau a) a été dessiné indépendamment d'une distribution normale avec un écart type inconnu (voir MathWorld ou Wikipedia ).

Pour une grande taille d'échantillon n, la moyenne de l'échantillon est normalement distribuée, et on peut calculer son intervalle de confiance en utilisant st.norm.interval()(comme suggéré dans le commentaire de Jaime). Mais les solutions ci-dessus sont correctes aussi pour un petit n, où st.norm.interval()donne des intervalles de confiance trop étroits (c'est-à-dire «fausse confiance»). Voir ma réponse à une question similaire pour plus de détails (et l'un des commentaires de Russ ici).

Voici un exemple où les options correctes donnent (essentiellement) des intervalles de confiance identiques:

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)

Et enfin, le résultat incorrect en utilisant 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
la source
1
Je pense que vous devriez appeler st.t.interval(0.05)pour obtenir l'intervalle de confiance de 95%.
Scimonster
5
Non, st.t.interval(0.95)est correct pour l'intervalle de confiance à 95%, voir la documentation pour scipy.stats.t. Cependant, la dénomination de l'argument par SciPy alphasemble loin d'être idéale.
Ulrich Stern
Si j'ai deux tableaux de données et ensuite calculé la différence de leur moyenne. Existe-t-il un moyen d'obtenir un IC à 95% pour cette différence moyenne? Pourriez-vous penser à un moyen simple de le faire comme celui que vous fournissez ici en utilisant StatsModelsl?
steven
@steven, il s'avère que j'ai répondu à une question à ce sujet. :)
Ulrich Stern
16

Commencez par rechercher la valeur z de l' intervalle de confiance souhaité à partir d'une table de consultation . L'intervalle de confiance est alors mean +/- z*sigma, où sigmaest l'écart type estimé de la moyenne de votre échantillon, donné par sigma = s / sqrt(n), où sest l'écart type calculé à partir de vos données d'échantillon et nest la taille de votre échantillon.

Bogatron
la source
29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime
4
Le demandeur initial a indiqué qu'une distribution normale devait être supposée, mais il convient de souligner que, pour les petits échantillons de populations (N <100 environ), il est préférable de rechercher z dans la distribution de Student t plutôt que dans la distribution normale . La réponse de shasan le fait déjà.
Russ
3
@bogatron, à propos du calcul suggéré pour l'intervalle de confiance, ne serait pas une moyenne +/- z * sigma / sqrt (n) , où n est la taille de l'échantillon?
David
3
@David, vous avez raison. J'ai mal exprimé le sens de sigma. sigmadans ma réponse devrait être l'écart type estimé de la moyenne de l'échantillon, et non l'écart type estimé de la distribution. J'ai mis à jour la réponse pour clarifier cela. Merci d'avoir fait remarquer cela.
bogatron
15

Au départ Python 3.8, la bibliothèque standard fournit l' NormalDistobjet dans le cadre du statisticsmodule:

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

Ce:

  • Crée un NormalDistobjet à partir de l'échantillon de données ( NormalDist.from_samples(data), ce qui nous donne accès à la moyenne et à l'écart type de l'échantillon via NormalDist.meanet NormalDist.stdev.

  • Calculez le Z-scorebasé sur la distribution normale standard (représentée par NormalDist()) pour la confiance donnée en utilisant l'inverse de la fonction de distribution cumulative ( inv_cdf).

  • Produit l'intervalle de confiance basé sur l'écart type et la moyenne de l'échantillon.


Cela suppose que la taille de l'échantillon est suffisamment grande (disons plus de ~ 100 points) pour utiliser la distribution normale standard plutôt que la distribution t de l'étudiant pour calculer la zvaleur.

Xavier Guihot
la source