废话不多说,直接看题
题自潘承毅《概率论与数理统计》
读完一遍题以后,大家应该对置信区间有了初步的了解。
我们作如下总结:
1. 置信区间是干嘛的
我们有一个变量(糖果的平均重量),我们去估计它,我们直接说它是多少多少,不够严谨。
别人要挑刺了,你这原始数据能代表全部吗,谁给你的自信?
哎,怕了怕了,我们不莽了,谦虚点谦虚点
说:我不确定这个平均值是多少,但我敢肯定,它在什么什么范围内?
别人又要挑刺儿了,你这个范围太小了!你有多少把握自己的话没有错误呢?
哎,95%吧(杠回去)
总体来看,置信区间就是干了这么个事,回答一个问题,目标对象是平均重量会落在哪个区间内。
2.适用范围
上图所示当然是最简单的情况,在教科书里,置信区间的估计有以下分类:
变量个数:单个变量、多个变量
是否已知平均值、方差
变量服从的分布:正态分布和0-1分布
估计对象:平均值、方差
每一种类别都有很成熟的解法,我们只需要按图索骥即可。
比如,遇到了上图所示的问题,我们上图所示(5.4)即可。下图是书上的总结:
作为非统计专业的同学,关于置信区间,我们只要会查表就行!
怎么查呢?
- 明确是否为正态分布(一般都是)
- 明确待估参数(一般都是平均值)
- 变量分布的其他参数是否已知(一般未知)
- 选好以上三点,就可以参照上表或者教科书,套公式,解决问题了。
3. 案例
写这篇文章的原因是昨晚看到一段代码,手动画出了置信区间上下界曲线。
没看懂,放到这里,大家一起看一下。
原链接
下面是原文的代码
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
np.random.seed(8)
def fit_plot_line(x=[], y=[], ci=95):
alpha = 1 - ci / 100
n = len(x)
Sxx = np.sum(x**2) - np.sum(x)**2 / n
Sxy = np.sum(x * y) - np.sum(x)*np.sum(y) / n
mean_x = np.mean(x)
mean_y = np.mean(y)
# Linefit
b = Sxy / Sxx
a = mean_y - b * mean_x
# Residuals
def fit(xx):
return a + b * xx
residuals = y - fit(x)
var_res = np.sum(residuals**2) / (n - 2)
sd_res = np.sqrt(var_res)
# Confidence intervals
se_b = sd_res / np.sqrt(Sxx)
se_a = sd_res * np.sqrt(np.sum(x**2)/(n * Sxx))
df = n-2 # degrees of freedom
tval = stats.t.isf(alpha/2., df) # appropriate t value
ci_a = a + tval * se_a * np.array([-1, 1])
ci_b = b + tval * se_b * np.array([-1, 1])
# create series of new test x-values to predict for
npts = 100
px = np.linspace(np.min(x), np.max(x), num=npts)
def se_fit(x):
return sd_res * np.sqrt(1. / n + (x - mean_x)**2 / Sxx)
# Plot the data
plt.figure()
plt.plot(px, fit(px), 'k', label='Regression line')
plt.plot(x, y, 'k.')
x.sort()
limit = (1 - alpha) * 100
plt.plot(x, fit(x) + tval * se_fit(x), 'r--', lw=2,
label='Confidence limit ({0:.1f}%)'.format(limit))
plt.plot(x, fit(x) - tval * se_fit(x), 'r--', lw=2)
plt.xlabel('X values')
plt.ylabel('Y values')
plt.title('Linear regression and confidence limits')
plt.legend(loc='best')
plt.show()
# generate data
mean, cov = [4, 6], [(1.5, .7), (.7, 1)]
x, y = np.random.multivariate_normal(mean, cov, 80).T
# fit line and plot figure
fit_plot_line(x=x, y=y, ci=95)
下图是代码效果:
最让我困惑的是,散点大部分都落在了红线区域外,这还能称作95%的置信区间?
翻完课本,现在来看一下实现细节。
# generate data
mean, cov = [4, 6], [(1.5, .7), (.7, 1)]
x, y = np.random.multivariate_normal(mean, cov, 80).T
首选是产生了随机数据,产生方式是规定了方差和平均值,因此样本分布可以定为正态分布。
# Plot the data
plt.figure()
plt.plot(px, fit(px), 'k', label='Regression line')
plt.plot(x, y, 'k.')
# Linefit
b = Sxy / Sxx
a = mean_y - b * mean_x
# Residuals
def fit(xx):
return a + b * xx
套用一元回归模型画出了回归线和散点
对比书上这个例题,我们可以发现,该问题是两个独立的变量,只不过求解对象不是样本均值差。
但我们可以确定①正态分布②两样本独立,只有测得的平均值和标准差,符合t分布③研究对象是一元线性回归模型
百度 一元线性回归模型的置信区间,很快啊,翻到了公式:
链接
显然两条红线的绘制参考了式(2.5.7),采用了t分布,一切都符合预期。
4. 写在最后
到这里可以回答最初的问题了。
那么多散点落在了红线外边,怎么还就95%了呢?
首先,95%指的是回归直线是95%的正确率。
回归直线本身就应该通过散点图的正中心,代表分布趋势。
所以,置信区间不是越大,囊括越多点,越好(当然,囊括点越多,置信度越高),我们要搞清楚研究对象是什么。
重要的不是“置信区间的细节”,而是,它能做什么,怎么套公式,去哪里找公式。