Calcola un intervallo di confidenza dai dati di esempio


109

Ho dei dati di esempio per i quali vorrei calcolare un intervallo di confidenza, assumendo una distribuzione normale.

Ho trovato e installato i pacchetti numpy e scipy e ho ottenuto numpy per restituire una media e una deviazione standard (numpy.mean (dati) con i dati come elenco). Qualche consiglio su come ottenere un intervallo di confidenza campione sarebbe molto apprezzato.


1
Penso che tu specifichi sicuramente se vuoi calcolare l'IC per la media campionaria o la media della popolazione. Ciò determinerà se si desidera utilizzare la distribuzione normale o t per calcolare il punteggio z. E la risposta più in alto sotto è per la media del campione, quindi viene utilizzata la distribuzione.
Jake

Risposte:


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

puoi calcolare in questo modo.


1
sp.stats.stderr è deprecato. Ho sostituito sp.stats.sem e ha funzionato benissimo!
Bmayer0122

1
L'importazione scipynon importa necessariamente tutti i sottopacchetti automaticamente. Meglio importare scipy.statsesplicitamente il sottopacchetto.
Vikram

31
Attento all'uso "privato" di sp.stats.t._ppf. Non sono così a mio agio con quello lì senza ulteriori spiegazioni. Meglio usare sp.stats.t.ppfdirettamente, a meno che tu non sia sicuro di sapere cosa stai facendo. Ad una rapida ispezione della fonte viene saltata una discreta quantità di codice _ppf. Forse benigno, ma forse anche un tentativo di ottimizzazione non sicuro?
Russ

Mi piace perché puoi semplicemente aggiungere *ss.t._ppf((1+conf)/2.,n-1) al .semmetodo dataframe dei panda integrato in modo da non doverti preoccupareapply
TNT

1
Voglio solo chiarire che questo calcolo è per la media campionaria, quindi viene utilizzata la distribuzione. Se le domande riguardano il calcolo della media della popolazione, deve essere utilizzata una distribuzione normale e l'intervallo di confidenza sarà più piccolo per lo stesso livello di confidenza.
Jake

133

Ecco una versione abbreviata del codice di shasan, calcolando l'intervallo di confidenza del 95% della media dell'array 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))

Ma usare StatsModels tconfint_meanè probabilmente ancora più bello:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

Le ipotesi sottostanti per entrambi sono che il campione (array a) sia stato disegnato indipendentemente da una distribuzione normale con deviazione standard sconosciuta (vedere MathWorld o Wikipedia ).

Per campioni di grandi dimensioni n, la media campionaria è normalmente distribuita e si può calcolare il suo intervallo di confidenza usando st.norm.interval()(come suggerito nel commento di Jaime). Ma le soluzioni di cui sopra sono corrette anche per n piccolo, dove st.norm.interval()fornisce intervalli di confidenza troppo stretti (cioè, "fiducia falsa"). Vedi la mia risposta a una domanda simile per maggiori dettagli (e uno dei commenti di Russ qui).

Ecco un esempio in cui le opzioni corrette danno intervalli di confidenza (essenzialmente) identici:

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)

E infine, il risultato errato utilizzando st.norm.interval():

In [13]: st.norm.interval(0.95, loc=np.mean(a), scale=st.sem(a))
Out[13]: (10.23484868811834, 12.76515131188166)

1
Credo che dovresti chiamare st.t.interval(0.05)per ottenere l'intervallo di confidenza del 95%.
Scimonster

5
No, st.t.interval(0.95)è corretto per l'intervallo di confidenza del 95%, vedere la documentazione per scipy.stats.t. Tuttavia, il nome dell'argomento da parte di SciPy alphasembra tutt'altro che ideale.
Ulrich Stern,

Se ho due matrici di dati e poi ho calcolato la differenza della loro media. C'è un modo per ottenere un CI del 95% per questa differenza media? Potresti pensare a un modo semplice per farlo come quello che fornisci qui usando StatsModelsl?
Steven

@steven, risulta, ho risposto a una domanda su questo. :)
Ulrich Stern

16

Inizia cercando il valore z per l'intervallo di confidenza desiderato da una tabella di ricerca . L'intervallo di confidenza è quindi mean +/- z*sigma, dove sigmaè la deviazione standard stimata della media campionaria, data da sigma = s / sqrt(n), dove sè la deviazione standard calcolata dai dati del campione ed nè la dimensione del campione.


29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime

4
Il richiedente originario ha indicato che si doveva assumere una distribuzione normale, ma vale la pena sottolineare che, per piccole popolazioni campione (N <100 o giù di lì), è meglio cercare z nella distribuzione t di Student invece che nella distribuzione normale . la risposta di shasan lo fa già.
Russ

3
@bogatron, riguardo al calcolo suggerito per l'intervallo di confidenza, non sarebbe medio +/- z * sigma / sqrt (n) , dove n è la dimensione del campione?
David,

3
@David, hai ragione. Ho espresso male il significato di sigma. sigmanella mia risposta dovrebbe essere la deviazione standard stimata della media campionaria, non la deviazione standard stimata della distribuzione. Ho aggiornato la risposta per chiarirlo. Grazie per la segnalazione.
bogatron

15

Iniziando Python 3.8, la libreria standard fornisce l' NormalDistoggetto come parte del statisticsmodulo:

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

Questo:

  • Crea un NormalDistoggetto dal campione di dati ( NormalDist.from_samples(data), che ci dà accesso alla media e alla deviazione standard del campione tramite NormalDist.meane NormalDist.stdev.

  • Calcola in Z-scorebase alla distribuzione normale standard (rappresentata da NormalDist()) per la confidenza data utilizzando l'inversa della funzione di distribuzione cumulativa ( inv_cdf).

  • Produce l'intervallo di confidenza in base alla deviazione standard e alla media del campione.


Ciò presuppone che la dimensione del campione sia abbastanza grande (diciamo più di ~ 100 punti) per poter utilizzare la distribuzione normale standard piuttosto che la distribuzione t di Student per calcolare il zvalore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.