若在一项试验中,只考虑一个因素A的变化,其他因素保持不变,称这种试验为单因素试验。具体做法是:A取几个水平,在每个水平上作若干个试验,试验过程中除A外其他影响指标的因素都保持不变(只有随机因素存在),我们的任务是从试验结果推断,因素A对指标有无显著影响,即当A取不同水平时指标有无显著差别。A取某个水平下的指标可视为随机变量,判断A取不同水平时指标有无显著差异,相当于检验若干总体的均值是否相等。
用4种工艺A1、A2、A3、A4生产灯泡,从各种工艺制成的灯泡中各抽出了若干个测量其寿命,结果如表4.10所示,试推断这几种工艺制成的灯泡寿命是否有显著差异。
A1 | A2 | A3 | A4 |
---|---|---|---|
1620 | 1580 | 1460 | 1500 |
1670 | 1600 | 1540 | 1550 |
1700 | 1640 | 1620 | 1610 |
1750 | 1720 | 1680 | |
1800 |
该例中不同配料的灯丝称为因素或因子, 属单因素的试验, 灯丝的不同 配料方案称为水平, 共有 $A_{1}, A_{2}, A_{3}, A_{4}$ 四种水平。一般情况下, 单因素 $A$ 的 $r$ 种不同水平分别记为 $A_{1}, A_{2}, \cdots, A_{r}$ 。
例中在不同配料方案下各抽取若干样品作检验, 每一种方案生产出灯泡的寿命都构成一个总体, 为此要检验各种灯丝配料方案对灯泡寿命 是否有显著影响, 即是要检验四个总体的均值是否相等。由于在实际问题中通常遇到的是各总体都服从或近似服从正态分布的情形, 故可将这类问题 归结为如下的数学模型。
设有 $r$ 个正态总体 $X_{i} \sim N\left(\mu_{i}, \sigma^{2}\right)(i=1,2, \cdots, r)$, 且相互独立。对这 $r$ 个总 体作如下假设: $$ \boldsymbol{H}_{0}: \mu_{1}=\mu_{2}=\cdots=\mu_{r} . $$ 现独立地从各总体中随机抽取若干样品,如下表所列, 要求利用该 表中数据检验假设 $H_{0}$ 是否成立?
由假设检验的知识知道, 对于假设 $H_{0}$, 可以用 $t$ 检验法来检验任何两相邻总体均值是否相等就可以了, 但这样就需要检验 $r-1$ 次, 如果 $r$ 较大时会很繁琐, 为此我们采用离差分解法来分析。将每个总体中抽出来的样品组成 一组, 共有 $r$ 组, 记各组内的样本平均值为 $$ \bar{X}_{i}=\frac{1}{n_{i}} \sum_{j=1}^{n_{i}} X_{i j}, i=1,2, \cdots, r, $$
我们计算各样本值与总的平均值之间的离差平方和:
我们计算各样本值与总的平均值之间的离差平方和: $$ \boldsymbol{S}_{T}=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(\boldsymbol{X}_{i j}-\bar{X}\right)^{2}=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left[\left(\boldsymbol{X}_{i j}-\bar{X}_{i}\right)+\left(\bar{X}_{i}-\bar{X}\right)\right]^{2} $$ $$ \begin{aligned} =\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i}\right)^{2}+2 \sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i}\right)\left(\bar{X}_{i}-\bar{X}\right)+\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(\bar{X}_{i}-\bar{X}\right)^{2} \\ &=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i}\right)^{2}+\sum_{i=1}^{r} n_{i}\left(\bar{X}_{i}-\bar{X}\right)^{2} \end{aligned} $$
记 $$ \boldsymbol{S}_{E}=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}}\left(X_{i j}-\bar{X}_{i}\right)^{2}, S_{A}=\sum_{i=1}^{r} n_{i}\left(\bar{X}_{i}-\bar{X}\right)^{2}, $$ 则有 $$ S_{T}=S_{E}+S_{A}, $$ 该式称为离差平方和分解公式,
其中 $S_{E}$ 反映了各组内部 $X_{i j}$ 之间的差异 (即同一组内随机抽样产生的误 差), 称为组内离差平方和; $S_{A}$ 反映各组之间由于因素水平不同而引起的差 异 (不同水平下的差异即条件误差), 称为组间离差平方和。方差分析就是 通过对组内、组间离差平方和的比较来检验假设的。
在实际中, 为了简化计算步聚, 常按下面一组公式去计算 $S_{T}, S_{E}, S_{A}$ 。 $$ \begin{aligned} S_{T} &=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}} X_{i j}^{2}-\frac{1}{n}\left(\sum_{i=1}^{r} \sum_{j=1}^{n_{i}} X_{i j}\right)^{2} \\ S_{E} &=\sum_{i=1}^{r} \sum_{j=1}^{n_{i}} X_{i j}^{2}-\sum_{i=1}^{r} \frac{1}{n_{i}}\left(\sum_{j=1}^{n_{i}} X_{i j}\right)^{2} \\ S_{A} &=S_{T}-S_{E} \end{aligned} $$
定理 1
定理 2 当 $H_{0}: \mu_{1}=\mu_{2}=\cdots=\mu_{r}$ 成立时, 有
根据定理 2, 构造检验统计量 $$ F=\frac{S_{A} /(r-1)}{S_{E} /(n-r)}, $$ 当 $H_{0}$ 成立时, $F \sim F(r-1, n-r)$ 。于是, 在给定的显著性水平 $\alpha$ 下, 检验 假设 $$ \boldsymbol{H}_{0}: \mu_{1}=\mu_{2}=\cdots=\mu_{r} \text {, } $$ 若由实验数据算得结果有 $F>F_{\alpha}(r-1, n-r)$, 则拒绝 $H_{0}$, 即认为因素 $A$ 对试验结果有显著影响; 若 $F<F_{\alpha}(r-1, n-r)$, 则接受 $H_{0}$, 即认为因素 $A$ 对 试验结果没有显著影响。
在方差分析中, 还作如下规定:
将上述统计过程归纳为方差分析表 。最后一列给出 $F(r-1, n-r)$ 分布大于 $F$ 值的概率 $p$, 当 $p<\alpha$ 时拒绝原假设, 否则接受原假设。
下面使用 statsmodels 库中的 anova_Im 函数进行单因素方差分析, 输 出值 $F$ 是 $F$ 统计量的值, 输出值 $P R$ 是一个概率值, 当 $P R>\alpha ( \alpha$ 为显著性 水平) 时接受原假设, 即认为因素 $A$ 对指标无显著影响。
import numpy as np
import statsmodels.api as sm
y=np.array([1620, 1670, 1700, 1750, 1800, 1580, 1600, 1640, 1720,
1460, 1540, 1620, 1680, 1500, 1550, 1610])
x=np.hstack([np.ones(5), np.full(4,2), np.full(4,3), np.full(3,4)])
d= {'x':x,'y':y} #构造字典
model = sm.formula.ols("y~C(x)",d).fit() #构建模型
anovat = sm.stats.anova_lm(model) #进行单因素方差分析
print(anovat)
结果为:
df | sum_sq | mean_sq | F | PR(>F) | |
---|---|---|---|---|---|
C(x) | 3 | 60153.3 | 20051.1 | 3.72774 | 0.0420037 |
Residual | 12 | 64546.7 | 5378.89 | nan | nan |
参考文献
import numpy as np
import statsmodels.api as sm
y=np.array([1620, 1670, 1700, 1750, 1800, 1580, 1600, 1640, 1720,
1460, 1540, 1620, 1680, 1500, 1550, 1610])
x=np.hstack([np.ones(5), np.full(4,2), np.full(4,3), np.full(3,4)])
d= {'x':x,'y':y} #构造字典
model = sm.formula.ols("y~C(x)",d).fit() #构建模型
anovat = sm.stats.anova_lm(model) #进行单因素方差分析
print(anovat)
df sum_sq mean_sq F PR(>F) C(x) 3.0 60153.333333 20051.111111 3.727742 0.042004 Residual 12.0 64546.666667 5378.888889 NaN NaN
x
array([1., 1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3., 4., 4., 4.])
print(anovat.to_markdown())
| | df | sum_sq | mean_sq | F | PR(>F) | |:---------|-----:|---------:|----------:|----------:|------------:| | C(x) | 3 | 60153.3 | 20051.1 | 3.72774 | 0.0420037 | | Residual | 12 | 64546.7 | 5378.89 | nan | nan |