提示:本文是基于Python对多元线性回归模型的问题处理
目录
一、检验异方差性
方法一:残差图分析法
方法二:等级相关系数法
二、解决方法
第一种:一元加权最小二乘法
第二种:多元加权最小二乘法
总结:
多元线性回归模型你和完成后一般会出现很多问题,如异方差性和自相关性等问题,如果出现这些问题,我们该如何解决呢?下面就讲讲异方差问题的处理方式。
一、检验异方差性
方法一:残差图分析法
,正常的残差图一般随机分布在y=0的上下,不会呈现出任何趋势的,没有任何规律,如果出现残差图呈现一定的趋势,如增长趋势或者下降趋势,则存在异方差性。
#建模
result = smf.ols('y~x',data=df).fit()
para = result.params
#打印模型的参数
print(result.summary())
#计算残差
eres = result.resid
#print(eres)
#残差图
fig, ax = plt.subplots(figsize=(8,6))
ax.plot(eres, 'o', label='resid')
ax.plot([0, 53], [0, 0], c='black', linestyle='-',alpha = 0.4)
方法二:等级相关系数法
原理是使用spearmanr函数求解出x变量与残差的等级相关系数,然后再对等级相关系数进行t检验,如果pvalue的值为0,则无异方差性,如果pvalue的值不为0,则存在异方差性。
#残差取绝对值
abse = abs(eres)
#spearman相关系数检验
cortest1 = scipy.stats.spearmanr(df['x'],abse)
print(cortest1)
二、解决方法
一元加权最小二乘法
这种方法是对变量x加一个权重来消除异方差性的影响。
#加权最小二乘法
loglik_list = []
result_list = []
#遍历取不同的值(即权重)
for i in np.arange(-2, 4, 0.5):
w = df['x']**(-i)
resultw = smf.wls('y~x',data=df,weights=w).fit()
loglik_list.append(resultw.llf)
result_list.append(resultw.summary())
logresult = pd.Series(loglik_list)
#打印出每种情况下的对数极大似然统计量的值,值越大越好,最大的值对应的i值就是变量的权重
print(logresult)
print(result_list[logresult.idxmax()])
#确定最优的权重,然后从新建模
w = df['x']**(最优权重)
resultw = smf.wls('y~x1+x2',data=df,weights=w).fit()
举个例子,如下图就是打印出来的部分结果:
这里打印出-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3,3.5,4这几个i字对应的对数极大似然估计值,比较得到第8个数最大,对应的i值为2,所以就确定权重为2。
多元加权最小二乘法
多元回归中,变量太多,只需要对一个变量进行加权就可以。计算出每个变量与残差的等级相关系数,选取最大的等级系数进行最小二乘法的加权确定权重就可以了,在权重确定这一步的方法和一元的方法相同。
#等级系数计算和spearman相关系数检验,有几个因变量,
#我们就计算几次,然后比较选最大的等级相关系数的变量进行权重的确定
cortest1 = scipy.stats.spearmanr(df['x1'],abse)
print(cortest1)
cortest1 = scipy.stats.spearmanr(df['x2'],abse)
print(cortest1)
#这里我们假设x1的等级相关系数最大,故选取x1进行权重的确定
#加权最小二乘法
loglik_list = []
result_list = []
for i in np.arange(-2, 4, 0.5):
w = df['x']**(-i)
resultw = smf.wls('y~x',data=df,weights=w).fit()
loglik_list.append(resultw.llf)
result_list.append(resultw.summary())
logresult = pd.Series(loglik_list)
print(logresult)
print(result_list[logresult.idxmax()])
w = df['x']**(最优的权重)
resultw = smf.wls('y~x',data=df,weights=w).fit()
总结:
以上就是本次的内容,有错误的地方和疑问,可以评论区交流交流,一起学习学习!