首先,我必须承认我的统计学知识非常生疏:即便在刚开始学习时,我也并不是特别喜欢这门学科,这意味着我很难理解它。
尽管如此,我仍然查看了 barplot 图中误差线的计算方式,惊讶地发现使用了“置信区间”(CI)来取代更为普遍的标准偏差。进一步调查 CI ,我找到了这篇 维基百科文章 ,该文章似乎表明,CI 的计算方式如下:
或者,用伪代码表示:
def ci_wp(a):
"""calculate confidence interval using Wikipedia's formula"""
m = np.mean(a)
s = 1.96*np.std(a)/np.sqrt(len(a))
return m - s, m + s
但是我们在seaborn/utils.py中发现的是:
def ci(a, which=95, axis=None):
"""Return a percentile range from an array of values."""
p = 50 - which / 2, 50 + which / 2
return percentiles(a, p, axis)
现在也许我完全错了,但这似乎是一个与维基百科提出的完全不同的计算。有人能解释一下这个差异吗?
再举个例子,从评论中可以看出,为什么我们在以下两种情况下得到的结果如此不同:
>>> sb.utils.ci(np.arange(100))
array([ 2.475, 96.525])
>>> ci_wp(np.arange(100))
[43.842250270646467,55.157749729353533]
与其他统计工具进行比较:
def ci_std(a):
"""calculate margin of error using standard deviation"""
m = np.mean(a)
s = np.std(a)
return m-s, m+s
def ci_sem(a):
"""calculate margin of error using standard error of the mean"""
m = np.mean(a)
s = sp.stats.sem(a)
return m-s, m+s
这给我们带来了:
>>> ci_sem(np.arange(100))
(46.598850802411796, 52.401149197588204)
>>> ci_std(np.arange(100))
(20.633929952277882, 78.366070047722118)
或者使用随机样本:
rng = np.random.RandomState(10)
a = rng.normal(size=100)
print sb.utils.ci(a)
print ci_wp(a)
print ci_sem(a)
print ci_std(a)
... 得到的结果为:
[-1.9667006 2.19502303]
(-0.1101230745774124, 0.26895640045116026)
(-0.017774461397903049, 0.17660778727165088)
(-0.88762281417683186, 1.0464561400505796)
为什么 Seaborn 的结果与其他结果差异如此之大?
sb.ci(np.arange(100))
的结果是array([ 2.475, 96.525])
,而直接计算np.mean(np.arange(100))-np.arange(100).std()*1.96/10
的结果是[43.842250270646467,55.157749729353533]
。 - DYZmean +/- std
得到的结果是:(20.633929952277882, 78.366070047722118)
。 - anarcat