Вычислить доверительный интервал из выборочных данных

109

У меня есть образцы данных, для которых я хотел бы вычислить доверительный интервал, предполагая нормальное распределение.

Я нашел и установил пакеты numpy и scipy и получил numpy для возврата среднего и стандартного отклонения (numpy.mean (data) с данными в виде списка). Мы будем очень благодарны за любые советы по получению выборочного доверительного интервала.

Bmayer0122
источник
1
я думаю, вы обязательно укажете, хотите ли вы вычислить CI для выборочного среднего или для среднего значения генеральной совокупности. Это определит, хотите ли вы использовать нормальное или t-распределение для расчета z-оценки. И верхний ответ ниже предназначен для выборочного среднего, поэтому используется при распределении.
Джейк

Ответы:

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

вы можете рассчитать таким образом.

шасан
источник
1
sp.stats.stderr устарел. Я заменил sp.stats.sem, и он отлично заработал!
Bmayer0122
1
При scipyимпорте не обязательно автоматически импортировать все подпакеты. Лучше scipy.statsявно импортировать подпакет.
Vikram
31
Осторожно с "частным" использованием sp.stats.t._ppf. Мне это не нравится без дальнейших объяснений. Лучше использовать sp.stats.t.ppfнапрямую, если вы не уверены, что знаете, что делаете. При быстром просмотре источника обнаруживается, что изрядное количество кода пропущено _ppf. Возможно, безобидная, но, возможно, и небезопасная попытка оптимизации?
Russ
Мне это нравится, потому что вы можете просто добавить *ss.t._ppf((1+conf)/2.,n-1) к встроенному .semметоду фрейма данных pandas, чтобы вам не о чем беспокоитьсяapply
TNT
1
Просто хочу уточнить, что этот расчет предназначен для выборочного среднего, поэтому используется распределение. Если вопрос заключается в вычислении среднего значения для генеральной совокупности, следует использовать нормальное распределение, а доверительный интервал будет меньше для того же уровня достоверности.
Джейк
133

Вот сокращенная версия кода шасана, вычисляющая 95% доверительный интервал среднего значения массива 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))

Но использование StatsModels, tconfint_meanвозможно, даже лучше:

import statsmodels.stats.api as sms

sms.DescrStatsW(a).tconfint_mean()

В основе обоих лежит предположение, что выборка (массив a) была построена независимо от нормального распределения с неизвестным стандартным отклонением (см. MathWorld или Википедию ).

Для большого размера выборки n среднее значение выборки имеет нормальное распределение, и его доверительный интервал можно рассчитать, используя st.norm.interval()(как предлагается в комментарии Хайме). Но приведенные выше решения верны также для малых n, что st.norm.interval()дает слишком узкие доверительные интервалы (т. Е. «Ложная уверенность»). См. Мой ответ на аналогичный вопрос для получения более подробной информации (и один из комментариев Русса здесь).

Вот пример, в котором правильные параметры дают (по существу) одинаковые доверительные интервалы:

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)

И, наконец, неверный результат с использованием 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
Я считаю, что вам следует позвонить, st.t.interval(0.05)чтобы получить 95% доверительный интервал.
Scimonster
5
Нет, st.t.interval(0.95)подходит для 95% доверительного интервала, см. Документацию для scipy.stats.t. Однако то, что SciPy называет аргумент, alphaкажется далеко не идеальным.
Ulrich Stern
Если у меня есть два массива данных, а затем вычисляется разница их среднего значения. Есть ли способ получить 95% ДИ для этой средней разницы? Не могли бы вы придумать какой-нибудь простой способ сделать это, подобный тому, который вы здесь предлагаете, с помощью StatsModelsl?
Стивен
@steven, оказывается, я ответил на вопрос по этому поводу. :)
Ульрих Стерн
16

Начните с поиска z-значения для желаемого доверительного интервала в справочной таблице . Тогда доверительный интервал равен mean +/- z*sigma, где sigma- оценочное стандартное отклонение среднего значения выборки, выраженное формулой sigma = s / sqrt(n), где s- стандартное отклонение, вычисленное на основе данных выборки, и n- размер вашей выборки.

богатрон
источник
29
scipy.stats.norm.interval(confidence, loc=mean, scale=sigma)
Jaime
4
Первоначальный автор вопроса указал, что предполагалось нормальное распределение, но стоит отметить, что для небольших выборок (N <100 или около того) лучше искать z в распределении Стьюдента, а не в нормальном распределении. . Ответ Шасана уже делает это.
Russ
3
@bogatron, о предлагаемом исчислении для доверительного интервала, не будет означать +/- z * sigma / sqrt (n) , где n - размер выборки?
Дэвид
3
@ Дэвид, ты прав. Я исказил значение sigma. sigmaв моем ответе должно быть оценочное стандартное отклонение выборочного среднего, а не оценочное стандартное отклонение распределения. Я обновил ответ, чтобы прояснить это. Спасибо что подметил это.
bogatron
15

Начиная Python 3.8, стандартная библиотека предоставляет NormalDistобъект как часть statisticsмодуля:

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

Это:

  • Создает NormalDistобъект из выборки данных ( NormalDist.from_samples(data), который дает нам доступ к среднему и стандартному отклонению выборки с помощью NormalDist.meanи NormalDist.stdev.

  • Вычислить на Z-scoreоснове стандартного нормального распределения (представленного NormalDist()) для заданной достоверности, используя обратную функцию кумулятивного распределения ( inv_cdf).

  • Выдает доверительный интервал на основе стандартного отклонения и среднего значения выборки.


Это предполагает, что размер выборки достаточно велик (скажем, более ~ 100 точек), чтобы использовать стандартное нормальное распределение, а не распределение Стьюдента для вычисления zзначения.

Ксавье Гихот
источник