案例:
制作玩偶的数量和成本之间的关系
生产个数: xi
实际生产成本:yi
模型预测的成本:yi^
数学推导:
1.假设条件概率:
yi = axi + b + εi
其中,a,b是模型参数,分别表示生产一个玩偶的变动成本和固定成本;εi 被称为噪声项,服从期望为0,方差为σ2的正态分布,记为εi ~ N(0, σ2)。
注:这里假设{εi}之间相互独立,{εi} 和 {xi}之间相互独立。
如果给定一组参数a,b以及噪声项的方差为 σ2,由于xi表示玩偶个数,是个可控制的量,
那么,yi 和εi一样是一个随机变量,服从期望为axi + b,方差为σ2的正态分布,记为yi ~ N(axi + b, σ2)。
* yi 在已知a,b,xi,σ时的条件概率为N(axi + b, σ2),如下公式:
P(yi | a, b, xi, σ2) ~ N(axi + b, σ2)
2.参数估计:
2.1 因{yi}之间相互独立, 所以得到{yi}出现的联合概率(称为该模型的似然函数(likelihood function),通常记为L)如下:
P(Y | a, b, X, σ2) = ∏P(yi | a, b, xi, σ2)
ln P(Y | a, b, X, σ2) = -0.5nln(2πσ2) - (1/2σ2)Σi(yi - axi - b )2
2.2 对于不同的模型参数,{yi}出现的概率(即参数的似然函数)不同。
最大似然估计法(Maximum Likelihood Estimation, MLE)即找到使得这个概率最大的参数
(a^,b^) = argmaxa,bP(Y | a, b, X, σ2) = argmina,bΣi(yi - axi - b )2
σ2^ = argmaxa,bP(Y | a, b, X, σ2) = 1/nΣni=1(yi - axi - b )2
2.3 模型预测公式
yi^= ai^ + b^
3. 置信区间和假设检验:
3.1 在95%的情况下,参数a的真实值(生产一个玩偶的变动成本)会落在什么区间例?称为参数a的95%置信区间
3.2 在1%犯错误的情况下,是否能拒绝参数b的真实值其实等于0这个假设?称为参数b的99%显著性假设检验(参数b的真实值等于0的概率是否小于1%)
常用方法: f_test , 可做单个或多个变量的假设检验
t_test,只能做单个变量的假设检验
代码实现:
1 import statsmodels.api as sm 2 3 def linearModel(data): 4 """ 5 线性回归统计性分析步骤展示 6 参数: 7 -------------------- 8 data : DataFrame, 建模数据 9 """ 10 11 features = ["x"] 12 labels = ["y"] 13 Y = data[labels] 14 # 加入常量变量,目的是引入参数b 15 X = sm.add_constant(data[features]) 16 17 # 构建模型 18 re = trainModel(X, Y) 19 20 # 分析模型效果 21 modelSummary(re) 22 23 def trainModel(X, Y): 24 """ 25 训练模型 26 """ 27 28 model = sm.OLS(Y, X) 29 re = model.fit() 30 31 return re 32 33 def modelSummary(re): 34 """ 35 分析线性回归模型的统计性质 36 """ 37 38 # 整体统计分析结果 39 print( re.summary() ) 40 41 # 用 f test 检验x对应的系数a是否显著, "x=0"代表x的系数a,不是x 42 print( re.f_test("x = 0") ) 43 44 # 用 f test 检验常量b是否显著 45 print( re.f_test("const = 0") ) 46 47 # 用 f test 检验a = 1, b = 0 同时成立的显著性 48 print( re.f_test(["x = 1", "const = 0"]) )
上面的结果显示参数a显著, b不显著,因此去掉参数b,搭建新模型
1 from statsmodels.sandbox.regression.regression.predstd import wls_prediction_std 2 3 def linearModel(data): 4 #省去前面代码 5 # const并不显著,去掉常量变量 6 resNew = trainModel(data[features], Y) 7 8 # 输出新模型的分析结果 9 print(resNew.summary()) 10 11 # 将模型结果可视化 12 visualizeModel(resNew, data, features, labels) 13 14 def visualizeModel(res, data, features, labels) 15 """ 16 模型可视化 17 """ 18 19 # 计算预测结果的标准差, 预测下界, 预测上界 20 prstd, preLow, preUp = wla_prediction_std(res, alpha = 0.5) 21 22 #省去后面代码