Berechnen Sie ein Konfidenzintervall aus Beispieldaten

108

Ich habe Beispieldaten, für die ich unter der Annahme einer Normalverteilung ein Konfidenzintervall berechnen möchte.

Ich habe die numpy- und scipy-Pakete gefunden und installiert und habe numpy erhalten, um einen Mittelwert und eine Standardabweichung zurückzugeben (numpy.mean (Daten), wobei Daten eine Liste sind). Jeder Rat zum Erhalten eines Stichproben-Konfidenzintervalls wäre sehr dankbar.

Bmayer0122
quelle
1
Ich denke, Sie geben sicher an, ob Sie den CI für den Stichprobenmittelwert oder den Populationsmittelwert berechnen möchten. Dies würde bestimmen, ob Sie die Normal- oder t-Verteilung verwenden möchten, um den Z-Score zu berechnen. Die oberste Antwort unten bezieht sich auf den Stichprobenmittelwert, sodass bei der Verteilung verwendet wird.
Jake

Antworten:

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

Sie können so rechnen.

shasan
quelle
1
sp.stats.stderr ist veraltet. Ich habe sp.stats.sem ersetzt und es hat super funktioniert!
Bmayer0122
1
Beim Importieren werden scipynicht unbedingt alle Unterpakete automatisch importiert. Es ist besser, das Unterpaket scipy.statsexplizit zu importieren .
Vikram
31
Vorsicht beim "privaten" Gebrauch von sp.stats.t._ppf. Ich fühle mich dort ohne weitere Erklärung nicht so wohl. Besser sp.stats.t.ppfdirekt verwenden, es sei denn, Sie sind sicher, dass Sie wissen, was Sie tun. Bei einer schnellen Überprüfung der Quelle wird eine ganze Menge Code übersprungen _ppf. Möglicherweise harmlos, aber möglicherweise auch ein unsicherer Optimierungsversuch?
Russ
Ich mag es, weil Sie einfach *ss.t._ppf((1+conf)/2.,n-1) die integrierte Pandas-Datenrahmenmethode hinzufügen können .sem, damit Sie sich keine Sorgen machen müssenapply
TNT
1
Ich möchte nur klarstellen, dass diese Berechnung für den Stichprobenmittelwert gilt, also wird bei der Verteilung verwendet. Wenn es um die Berechnung des Populationsmittelwerts geht, sollte eine Normalverteilung verwendet werden und das Konfidenzintervall wird bei gleichem Konfidenzniveau kleiner.
Jake
131

Hier eine verkürzte Version von Shasans Code, die das 95% -Konfidenzintervall des Mittelwerts des Arrays berechnet 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))

Aber die Verwendung von StatsModels tconfint_meanist wohl noch schöner:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

Die zugrunde liegenden Annahmen für beide sind, dass die Stichprobe (Array a) unabhängig von einer Normalverteilung mit unbekannter Standardabweichung gezogen wurde (siehe MathWorld oder Wikipedia ).

Für eine große Stichprobengröße n ist der Stichprobenmittelwert normal verteilt, und man kann sein Konfidenzintervall mit berechnen st.norm.interval()(wie in Jaimes Kommentar vorgeschlagen). Die obigen Lösungen sind jedoch auch für kleine n korrekt, bei denen st.norm.interval()zu enge Konfidenzintervalle angegeben werden (dh "falsches Vertrauen"). Siehe meine Antwort auf eine ähnliche Frage für weitere Details (und einen von Russ 'Kommentaren hier).

Hier ein Beispiel, bei dem die richtigen Optionen (im Wesentlichen) identische Konfidenzintervalle ergeben:

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)

Und schließlich das falsche Ergebnis mit 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
quelle
1
Ich glaube, Sie sollten anrufen st.t.interval(0.05), um das 95% -Konfidenzintervall zu erhalten.
Scimonster
5
Nein, st.t.interval(0.95)ist für das 95% -Konfidenzintervall korrekt, siehe Dokumentation für scipy.stats.t. Die Benennung des Arguments durch SciPy alphascheint jedoch nicht ideal.
Ulrich Stern
Wenn ich zwei Datenfelder habe und dann die Differenz ihres Mittelwerts berechnet habe. Gibt es eine Möglichkeit, einen 95% -KI für diesen mittleren Unterschied zu erhalten? Könnten Sie sich eine einfache Möglichkeit vorstellen, dies wie die hier mit StatsModelsl bereitgestellte zu tun?
Steven
@steven, stellte sich heraus, ich beantwortete eine Frage dazu. :)
Ulrich Stern
16

Beginnen Sie mit dem Nachschlagen des Z-Werts für Ihr gewünschtes Konfidenzintervall aus einer Nachschlagetabelle . Das Konfidenzintervall ist dann mean +/- z*sigma, wo sigmaist die geschätzte Standardabweichung Ihres Stichprobenmittelwerts, gegeben durch sigma = s / sqrt(n), wo sist die aus Ihren Stichprobendaten berechnete Standardabweichung und nist Ihre Stichprobengröße.

Bogatron
quelle
29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime
4
Der ursprüngliche Fragesteller gab an, dass eine Normalverteilung anzunehmen sei, es sei jedoch darauf hingewiesen, dass es für kleine Stichprobenpopulationen (N <100 oder so) besser ist, z in der Verteilung von Student t nachzuschlagen, als in der Normalverteilung . Shasans Antwort tut dies bereits.
Russ
3
@bogatron, über den vorgeschlagenen Kalkül für das Konfidenzintervall, wäre nicht Mittelwert +/- z * Sigma / sqrt (n) , wobei n die Stichprobengröße ist?
David
3
@ David, du bist richtig. Ich habe die Bedeutung von falsch angegeben sigma. sigmaIn meiner Antwort sollte die geschätzte Standardabweichung des Stichprobenmittelwerts sein, nicht die geschätzte Standardabweichung der Verteilung. Ich habe die Antwort aktualisiert, um dies zu verdeutlichen. Vielen Dank für den Hinweis.
Bogatron
14

Ab Python 3.8dem Start stellt die Standardbibliothek das NormalDistObjekt als Teil des statisticsModuls bereit :

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

Dies:

  • Erstellt ein NormalDistObjekt aus der Datenstichprobe ( NormalDist.from_samples(data)wodurch wir über NormalDist.meanund auf den Mittelwert und die Standardabweichung der Stichprobe zugreifen können NormalDist.stdev.

  • Berechnen Sie die Z-scorebasierend auf der Standardnormalverteilung (dargestellt durch NormalDist()) für das gegebene Vertrauen unter Verwendung der Umkehrung der kumulativen Verteilungsfunktion ( inv_cdf).

  • Erzeugt das Konfidenzintervall basierend auf der Standardabweichung und dem Mittelwert der Stichprobe.


Dies setzt voraus, dass die Stichprobengröße groß genug ist (sagen wir mehr als ~ 100 Punkte), um die Standardnormalverteilung anstelle der t-Verteilung des Schülers zur Berechnung des zWerts zu verwenden.

Xavier Guihot
quelle