最近在研究线性回归分析中如何评估一个模型能否较好的描述数据,除了正常评测预测值和观测值的总体偏差(也是我们优化方向),我们还会对预测值和观测值偏差分布进行分析。这里具体的原因是: 正常在进行回归分析时,我们都会设置一个系统噪声,我们一般会有一下假设[1]:
那么正常在得出我们模型的预测值和观测值偏差分布时,我们希望验证一下我们建立模型时的假设还是否成立,这时候我们将应用到单因素方差分析(One-way ANOVA), 这里的单因素是指单个影响因素,一般指自变量,既然有单因素,是不是有多因素?答案是有的(Two-Way ANOVA & MANOVA), 多因素已超本篇内容,感兴趣的同学可以自己查阅相关资料。这里单因素方差分析主要目的是为了验证不同自变量分类中的应变量偏差的均值是否相同, 普遍的假设是多组偏差分布的均值相同(与t-test 的差异在于,t-test 一般用来对比两组样本)。
以下内容将分为三个部分,第一部分是单因素分析的理论部分,第二部分为具体样例分析,第三部分为样例代码
既然单因素方差分析研究的是不同组内,因变量方差的均值是否相同,那么这里我们假设自变量( Ii ),即共有n组,每组中对应的应变量为( xij ), 该变量表示i组中j样本的值, 那么在单因素方差分析中,我们关心一下值:
当我们的significant值为 0.05时,我们有一个在自由度为(n, n* (m-1))下F的预期值 Fexpected , 和根据观测值计算的值 Fpractical , 当 Fexpected<Fpractical , 我们知道小概率时间放生,我们放弃原假设 null hypothesis
这个case来于wiki [1], 这里将他重新整理, 自变量组为3,每组内的观测值为6,具体值见下表
I1 | I2 | I3 |
6 | 8 | 13 |
8 | 12 | 9 |
4 | 9 | 11 |
5 | 11 | 8 |
3 | 6 | 7 |
4 | 8 | 12 |
组内均值
I1 | I2 | I3 |
5 | 9 | 10 |
上面是基于观测值计算的 Fratio , 接下来我们要基于观测值的自由度,计算对应的期望F 值,python 有对应的公开包可以计算(scipy.stats.f [2]), F(0.05,2,15)expected=3.68 , 观测值小于预期的F值,我们reject原假设
# -*- encoding: utf-8 -*-
import re
import sys
import numpy as np
from scipy.stats import f
def main(instance):
"""
"""
alpha = 0.05
group_num = len(instance)
ingroup_num = len(instance[0])
group_mean = [np.mean(ele) for ele in instance]
grand_mean = np.mean(group_mean)
bg_squared_difference = sum([ingroup_num * ((ele - grand_mean) ** 2) for ele in group_mean])
bg_degree = group_num - 1
bg_mean_square = bg_squared_difference / bg_degree
within_group_square = 0
for i in range(group_num):
for j in range(ingroup_num):
within_group_square += (instance[i][j] - group_mean[i]) ** 2
within_group_degree = group_num * (ingroup_num - 1)
within_group_difference = within_group_square / within_group_degree
F_practical = bg_mean_square / within_group_difference
F_expected = f.ppf(alpha, bg_degree, within_group_degree)
if F_practical > F_expected: return False
return True
if __name__ == "__main__":
reload(sys)
sys.setdefaultencoding("utf-8")
instance = [[6, 8, 4, 5, 3, 4],
[8, 12, 9, 11, 6, 8],
[13, 9, 11, 8, 7, 12]]
print main(instance)