Scipy 置信区间 returns 与手动计算的界限不同
Scipy confidence interval returns different bounds than manual calculation
我有来自 10 个不同人的以下数据。
df = pd.DataFrame({'id':range(1, 11),
'x':[.7,-1.6,-.2,-1.2,-.1,3.4,3.7,.8,0,2]})
print(df)
id x
0 1 0.7
1 2 -1.6
2 3 -0.2
3 4 -1.2
4 5 -0.1
5 6 3.4
6 7 3.7
7 8 0.8
8 9 0.0
9 10 2.0
我想计算总体均值 df[x]
的 95% 置信区间。
由于观测数量少,样本均值应服从自由度为 10 - 1 的 t 分布。我尝试了以下方法以计算出 95% C.I。使用 scipy
:
# Libraries
import numpy as np
from scipy import stats
# Number of observations
n_obs = 10
# Observed mean
m_obs = df['x'].mean()
# Observed variance (unbiased)
v_obs = df['x'].var(ddof=1) / n_obs
# Declare random variable with observed parameters
t = stats.t(df=n_obs - 1, loc=m_obs, scale=np.sqrt(v_obs))
# Calculate 95% CI
t.interval(alpha=0.95)
> (-0.5297804134938646, 2.0297804134938646) ### Correct interval
这个置信区间是正确的。但是,当我手动计算间隔时,我得到了完全不同的结果。这是什么原因造成的?
# T such that P(t < T) = 0.975
T = t.ppf(0.975)
# Manually compute interval
(m_obs - (T * np.sqrt(v_obs)), m_obs + (T * np.sqrt(v_obs)))
> (-0.3983168630668432, 1.8983168630668432) ### Incorrect interval
自从我在评论中发布答案已经两周了,但没有人相信它,所以这里是:
两个置信区间不同的原因是因为值T
在t
的概率分布下累积了97.5%的面积,t
的均值m_obs
和方差 v_obs
。也就是说,它 不是 标准 t 分布。
正确的区间可以通过简单地使T
累积标准t分布概率的0.975的值来正确计算:
# Number of observations (UNCHANGED)
n_obs = 10
# Observed mean (UNCHANGED)
m_obs = df['x'].mean()
# Observed variance (unbiased) (UNCHANGED)
v_obs = df['x'].var(ddof=1) / n_obs
# Declare *STANDARD* t distribution (CHANGED!!!)
t = stats.t(df=n_obs - 1, loc=0, scale=1)
# T such that P(x < T) = 0.975 (CHANGED!!!)
T = t.ppf(0.975)
# Manually compute interval (CORRECT ANSWER)
(m_obs - (T * np.sqrt(v_obs)), m_obs + (T * np.sqrt(v_obs)))
> (-0.5297804134938646, 2.0297804134938646)
这会得出正确答案。
我有来自 10 个不同人的以下数据。
df = pd.DataFrame({'id':range(1, 11),
'x':[.7,-1.6,-.2,-1.2,-.1,3.4,3.7,.8,0,2]})
print(df)
id x
0 1 0.7
1 2 -1.6
2 3 -0.2
3 4 -1.2
4 5 -0.1
5 6 3.4
6 7 3.7
7 8 0.8
8 9 0.0
9 10 2.0
我想计算总体均值 df[x]
的 95% 置信区间。
由于观测数量少,样本均值应服从自由度为 10 - 1 的 t 分布。我尝试了以下方法以计算出 95% C.I。使用 scipy
:
# Libraries
import numpy as np
from scipy import stats
# Number of observations
n_obs = 10
# Observed mean
m_obs = df['x'].mean()
# Observed variance (unbiased)
v_obs = df['x'].var(ddof=1) / n_obs
# Declare random variable with observed parameters
t = stats.t(df=n_obs - 1, loc=m_obs, scale=np.sqrt(v_obs))
# Calculate 95% CI
t.interval(alpha=0.95)
> (-0.5297804134938646, 2.0297804134938646) ### Correct interval
这个置信区间是正确的。但是,当我手动计算间隔时,我得到了完全不同的结果。这是什么原因造成的?
# T such that P(t < T) = 0.975
T = t.ppf(0.975)
# Manually compute interval
(m_obs - (T * np.sqrt(v_obs)), m_obs + (T * np.sqrt(v_obs)))
> (-0.3983168630668432, 1.8983168630668432) ### Incorrect interval
自从我在评论中发布答案已经两周了,但没有人相信它,所以这里是:
两个置信区间不同的原因是因为值T
在t
的概率分布下累积了97.5%的面积,t
的均值m_obs
和方差 v_obs
。也就是说,它 不是 标准 t 分布。
正确的区间可以通过简单地使T
累积标准t分布概率的0.975的值来正确计算:
# Number of observations (UNCHANGED)
n_obs = 10
# Observed mean (UNCHANGED)
m_obs = df['x'].mean()
# Observed variance (unbiased) (UNCHANGED)
v_obs = df['x'].var(ddof=1) / n_obs
# Declare *STANDARD* t distribution (CHANGED!!!)
t = stats.t(df=n_obs - 1, loc=0, scale=1)
# T such that P(x < T) = 0.975 (CHANGED!!!)
T = t.ppf(0.975)
# Manually compute interval (CORRECT ANSWER)
(m_obs - (T * np.sqrt(v_obs)), m_obs + (T * np.sqrt(v_obs)))
> (-0.5297804134938646, 2.0297804134938646)
这会得出正确答案。