假设分布未知,从样本数据计算置信区间
Posted
技术标签:
【中文标题】假设分布未知,从样本数据计算置信区间【英文标题】:Compute a confidence interval from sample data assuming unknown distribution 【发布时间】:2017-11-07 15:29:56 【问题描述】:假设分布不正常且未知,我想计算置信区间的样本数据。基本上,看起来分布是 Pareto 但我不确定。
正态分布的答案:
Compute a confidence interval from sample data
Correct way to obtain confidence interval with scipy
【问题讨论】:
【参考方案1】:如果您不知道底层分布,那么我的第一个想法是使用引导:https://en.wikipedia.org/wiki/Bootstrapping_(statistics)
在伪代码中,假设 x
是一个包含您的数据的 numpy 数组:
import numpy as np
N = 10000
mean_estimates = []
for _ in range(N):
re_sample_idx = np.random.randint(0, len(x), x.shape)
mean_estimates.append(np.mean(x[re_sample_idx]))
mean_estimates
现在是一个包含 10000 个分布均值估计值的列表。取这 10000 个值的第 2.5 和第 97.5 个百分位数,您就有一个围绕数据平均值的置信区间:
sorted_estimates = np.sort(np.array(mean_estimates))
conf_interval = [sorted_estimates[int(0.025 * N)], sorted_estimates[int(0.975 * N)]]
【讨论】:
我已经用真实数据进行了测试。看起来好像错了。我得到了 Conf Int: [22.78, 69.93] 。 (np.array(x) 【参考方案2】:从另一个答案的讨论中,我假设您想要总体均值的置信区间,是吗? (对于某个数量,您必须有一个置信区间,而不是分布本身。)
对于所有具有有限矩的分布,均值的抽样分布渐近趋于正态分布,均值等于总体均值,方差等于总体方差除以 n。所以如果你有很多数据,$\mu \pm \Phi^-1(p) \sigma / \sqrtn$ 应该是总体均值的 p 置信区间的一个很好的近似值,即使如果分布不正常。
【讨论】:
【参考方案3】:当前的解决方案不起作用,因为 randint 似乎已被弃用
np.random.seed(10)
point_estimates = [] # Make empty list to hold point estimates
for x in range(200): # Generate 200 samples
sample = np.random.choice(a= x, size=x.shape)
point_estimates.append( sample.mean() )
sorted_estimates = np.sort(np.array(point_estimates))
conf_interval = [sorted_estimates[int(0.025 * N)], sorted_estimates[int(0.975 * N)]]
print(conf_interval, conf_interval[1] - conf_interval[0])
pd.DataFrame(point_estimates).plot(kind="density", legend= False)
【讨论】:
【参考方案4】:您可以使用 bootstrap 来估算来自 UNKNOW 分布的每个数量
def bootstrap_ci(
data,
statfunction=np.average,
alpha = 0.05,
n_samples = 100):
"""inspired by https://github.com/cgevans/scikits-bootstrap"""
import warnings
def bootstrap_ids(data, n_samples=100):
for _ in range(n_samples):
yield np.random.randint(data.shape[0], size=(data.shape[0],))
alphas = np.array([alpha/2, 1 - alpha/2])
nvals = np.round((n_samples - 1) * alphas).astype(int)
if np.any(nvals < 10) or np.any(nvals >= n_samples-10):
warnings.warn("Some values used extremal samples; results are probably unstable. "
"Try to increase n_samples")
data = np.array(data)
if np.prod(data.shape) != max(data.shape):
raise ValueError("Data must be 1D")
data = data.ravel()
boot_indexes = bootstrap_ids(data, n_samples)
stat = np.asarray([statfunction(data[_ids]) for _ids in boot_indexes])
stat.sort(axis=0)
return stat[nvals]
模拟帕累托分布中的一些数据
np.random.seed(33)
data = np.random.pareto(a=1, size=111)
sample_mean = np.mean(data)
plt.hist(data, bins=25)
plt.axvline(sample_mean, c='red', label='sample mean'); plt.legend()
使用引导生成SAMPLE MEAN的置信区间
low_ci, up_ci = bootstrap_ci(data, np.mean, n_samples=1000)
绘制结果
plt.hist(data, bins=25)
plt.axvline(low_ci, c='orange', label='low_ci mean')
plt.axvline(up_ci, c='magenta', label='up_ci mean')
plt.axvline(sample_mean, c='red', label='sample mean'); plt.legend()
使用引导生成分布参数的置信区间
from scipy.stats import pareto
true_params = pareto.fit(data)
low_ci, up_ci = bootstrap_ci(data, pareto.fit, n_samples=1000)
low_ci[0]
和 up_ci[0]
是形状参数的置信区间
low_ci[0], true_params[0], up_ci[0] ---> (0.8786, 1.0983, 1.4599)
【讨论】:
以上是关于假设分布未知,从样本数据计算置信区间的主要内容,如果未能解决你的问题,请参考以下文章
显著水平|区间估计|假设检验|显著性|第一类错误|Ⅱ类错误|β错误|t检验|连续性矫正|二项分布的假设检验|样本百分率|
置信区间(Confidence Intervals)是什么?如何计算置信区间?置信区间的两种计算方法是什么?二值样本置信区间如何计算?如何基于bootstrap抽样进行置信区间计算?