Правильный способ получения доверительного интервала с помощью scipy

у меня есть 1-мерный массив данных:

a = np.array([1,2,3,4,4,4,5,5,5,5,4,4,4,6,7,8])

для которого я хочу получить доверительный интервал 68% (т. е.:1 Сигма).

первый комментарий в ответ заявляет, что это может быть достигнуто с помощью scipy.stats.norm.interval С scipy.статистика.норма!--9-- функция>, через:

from scipy import stats
import numpy as np
mean, sigma = np.mean(a), np.std(a)

conf_int = stats.norm.interval(0.68, loc=mean, scale=sigma)

но комментарий этот пост указано, что фактический правильный способ получения доверия интервал:

conf_int = stats.norm.interval(0.68, loc=mean, scale=sigma / np.sqrt(len(a)))

то есть a 1/np.sqrt(len(a)) фактор используется на Сигма.

вопрос в том, какая версия является правильной?

3 ответов


доверительный интервал 68% для единственная ничья из нормального распределения среднее Mu и std отклонение Сигма

stats.norm.interval(0.68, loc=mu, scale=sigma)

доверительный интервал 68% для среднее значение N рисует из нормального распределения со средним отклонением mu и std Сигма

stats.norm.interval(0.68, loc=mu, scale=sigma/sqrt(N))

интуитивно эти формулы имеют смысл, так как, если вы держите банку желейных бобов и попросите большое количество людей угадать количество желейных бобов, каждый индивид может быть выключен на много - то же отклонение std sigma -- но среднее из догадок сделает замечательно тонкую работу по оценке фактического числа, и это отражается стандартным отклонением среднего сокращения в коэффициент 1/sqrt(N).


если один розыгрыш имеет дисперсию sigma**2, потом формула Bienaymé, сумма N некоррелированных ничья имеет дисперсию N*sigma**2.

средняя равна сумма делится на N. Когда вы умножаете случайную величину (например, сумму) на константу, дисперсия умножается на постоянную в квадрате. Это

Var(cX) = c**2 * Var(X)

таким образом, дисперсия среднего равна

(variance of the sum)/N**2 = N * sigma**2 / N**2 = sigma**2 / N

и поэтому стандартное отклонение среднего (которое является квадратным корнем дисперсии) равно

sigma/sqrt(N).

это происхождение sqrt(N) в знаменателе.


вот пример кода, основанный на коде Тома, что демонстрирует утверждения, сделанные выше:

import numpy as np
from scipy import stats

N = 10000
a = np.random.normal(0, 1, N)
mean, sigma = a.mean(), a.std(ddof=1)
conf_int_a = stats.norm.interval(0.68, loc=mean, scale=sigma)

print('{:0.2%} of the single draws are in conf_int_a'
      .format(((a >= conf_int_a[0]) & (a < conf_int_a[1])).sum() / float(N)))

M = 1000
b = np.random.normal(0, 1, (N, M)).mean(axis=1)
conf_int_b = stats.norm.interval(0.68, loc=0, scale=1 / np.sqrt(M))
print('{:0.2%} of the means are in conf_int_b'
      .format(((b >= conf_int_b[0]) & (b < conf_int_b[1])).sum() / float(N)))

печать

68.03% of the single draws are in conf_int_a
67.78% of the means are in conf_int_b

будьте осторожны, если вы определяете conf_int_b с оценками для mean и sigma на основе образца a, значит, возможно, не падать в conf_int_b с желаемым частота.


если взять пример из распределения и вычислить среднее значение выборки и отклонение std,

mean, sigma = a.mean(), a.std()

будьте осторожны, чтобы отметить, что нет никакой гарантии, что эта воля равный население среднее и стандартное отклонение, и что мы предполагая, что население распределено нормально - это не автоматические данности!

если вы берете образец и хотите оценка среднее и стандартное население отклонение, вы должны использовать

mean, sigma = a.mean(), a.std(ddof=1)

так как это значение для Сигмы-это несмещенная оценка для стандартного отклонения населения.


Я только что проверил, как R и GraphPad вычисляют доверительные интервалы, и они увеличивают интервал в случае небольшого размера выборки (n). Например, более чем в 6 раз при n=2 по сравнению с большим n. Этот код (основанный на ответ) соответствует их доверительные интервалы:

import numpy as np, scipy.stats as st

# returns confidence interval of mean
def confIntMean(a, conf=0.95):
  mean, sem, m = np.mean(a), st.sem(a), st.t.ppf((1+conf)/2., len(a)-1)
  return mean - m*sem, mean + m*sem

для R я сверился с t.испытание (a). Программ graphpad это доверительный интервал среднего страница содержит информацию "уровень пользователя" о зависимости размера выборки.

выход например, Габриэль:--7-->
In [2]: a = np.array([1,2,3,4,4,4,5,5,5,5,4,4,4,6,7,8])

In [3]: confIntMean(a, 0.68)
Out[3]: (3.9974214366806184, 4.877578563319382)

In [4]: st.norm.interval(0.68, loc=np.mean(a), scale=st.sem(a))
Out[4]: (4.0120010966037407, 4.8629989033962593)

обратите внимание, что разница между confIntMean() и st.norm.interval() интервалы здесь относительно малы; len (a) == 16 не слишком мал.


я протестировал ваши методы, используя массив с известным доверительным интервалом. и NumPy.случайность.normal (mu,std,size) возвращает массив с центром в mu со стандартным отклонением std (in документы определяется как Standard deviation (spread or “width”) of the distribution.).

from scipy import stats
import numpy as np
from numpy import random
a = random.normal(0,1,10000)
mean, sigma = np.mean(a), np.std(a)
conf_int_a = stats.norm.interval(0.68, loc=mean, scale=sigma)
conf_int_b = stats.norm.interval(0.68, loc=mean, scale=sigma / np.sqrt(len(a)))


conf_int_a
(-1.0011149125527312, 1.0059797764202412)
conf_int_b
(-0.0076030415111100983, 0.012467905378619625)

поскольку значение Сигмы должно быть от -1 до 1,/ np.sqrt(len(a)) метод кажется неправильным.

редактировать

поскольку у меня нет репутации, чтобы прокомментировать выше, я поясню, как этот ответ связан с unutbu исчерпывающий ответ. Если вы заполняете случайный массив с нормальным распределением, 68% от общего числа будет находиться в пределах 1-σ от среднего. В приведенном выше случае, если вы проверите, что видите

b = a[np.where((a>-1)&(a <1))]
len(a)
> 6781

или 68% населения попадает в 1σ. Ну, около 68%. При использовании все большего и большего массива вы приблизитесь к 68% (в пробной версии 10, 9 были между -1 и 1). Это потому, что 1-σ является неотъемлемым распределением данных, и чем больше данных у вас есть, тем лучше вы можете его решить.

в основном, моя интерпретация вашего вопроса была если у меня есть образец данных, который я хочу использовать для описания распределения, из которого они были взяты, каков метод поиска стандартного отклонения этих данных? в то время как unutbu представляется более каков интервал, на который я могу поместить среднее значение с уверенностью 68%?. Что означало бы, что для желейных бобов я ответил как они догадываются и unutbu ответ что их догадки говорят нам о желейных бобах.