Правильный способ получения доверительного интервала с помощью 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 ответ что их догадки говорят нам о желейных бобах.