一、背景
1、多元回归的残差假定:
残差的期望为0;
残差对所有的x而言有同方差性;
残差是服从正态分布,且相互独立。
2、残差检验需要检验的部分
正态性检验
方差齐性检验
独立性(自相关性)检验
二、详细阐述
1、正态性检验
还有当模型的残差服从正态性假设时,才能保证模型偏回归系数对于的t值和模型的F值是有效的。
残差的正态性检验由两类方法:
定性的图形法(PP图和QQ图):当PP图和QQ图的点差不多集中在45度直线上时,则认为满足正态性;
定量的非参数法(Shapiro检验和K-S检验):如果p_value<0.05,则拒绝原假设,即不满足正态性假设。
解决措施:如果残差不服从正态分布的话,建议对Y变量进行box-cox变换处理(或者直接粗暴的做一个log变换,效果会好很多)。
知识点补充:
Q-Q图是一种散点图,对应于正态分布的Q-Q图,就是由标准正态分布的分位数为横坐标,样本值为纵坐标的散点图. 要利用QQ图鉴别样本数据是否近似于正态分布,只需看QQ图上的点是否近似地在一条直线附近,而且该直线的斜率为标准差,截距为均值。
P-P图是根据变量的累积比例与指定分布的累积比例之间的关系所绘制的图形。通过P-P图可以检验数据是否符合指定的分布。当数据符合指定分布时,P-P图中各点近似呈一条直线。如果P-P图中各点不呈直线,但有一定规律,可以对变量数据进行转换,使转换后的数据更接近指定分布。
#####下面的操作建立在已经建立了一个多元线性模型的基础上,暂称其为model
###图形法(QQ图,PP图)
sm.qqplot(model.resid,fit=True,line="45") #Q-Q 图
plt.title("Q-Q Plot")
plt.show()
sm.ProbPlot(model.resid).ppplot(line = '45') #P-P图
plt.title('P-P plot')
plt.show()
###非参检验
from scipy.stats import kstest
kstest(model.resid, 'norm') #ks检验,当p值<0.05时,拒绝原假设,即不满足正态性假设
from scipy import stats
stats.shapiro(model.resid) #这种检验方法比KS检验的P值略大,适合样本量在5000以内
##如果正态性检验未通过,考虑box-cox变换
import scipy.stats as stats
lamd = stats.boxcox_normmax(y, method = 'mle') # 找到box-cox变换的lambda系数
y = stats.boxcox(y, lamd) # 对Y进行变换
2、方差齐性检验
在线性回归建模中,如果模型表现的非常好的话,那么残差与拟合值之间不应该存在某些明显的关系或趋势。 如果模型的残差存在一定的异方差的话,会导致估计出来的偏回归系数不具备有效性,甚至导致模型的预测也不准确。
残差方差齐性检验的方法有两种:
图形法(残差与拟合值的散点图):如果残差在参考线(0值)两侧均匀分布,则意味着异方差性较弱;而如果呈现出明显的不均匀分布,则意味着存在明显的异方差性。
统计验证法:可以通过White检验和Breush-Pagan检验来完成定量化的异方差性检验,如果p_value<0.05,则拒绝原假设,即方差不满足齐性。
解决措施:如果模型的残差不服从齐性的话,可以考虑是模型变换法(log变换,box_cox变换)和加权最小二乘法。
####图形法
#拟合值与残差的图像
plt.plot(model.fittedvalues,model.resid,"o")
plt.xlabel("predicted_value")
plt.ylabel("residual")
plt.axhline(y=0,c="r")
plt.show()
####统计验证法
#这两种方法的均会返回四个值,其中第一个为拉格朗日乘数统计量,第二个为拉格朗日乘数测试的p值,第三个是误差方差不依赖于x的假设的f统计量,第四个是f统计量的p值。
#故可以参考输出的第二个值和第四个值
# White's Test
sm.stats.diagnostic.het_white(model.resid, exog = model.model.exog)
# Breusch-Pagan
sm.stats.diagnostic.het_breushpagan(model.resid, exog_het = model.model.exog)
3、残差独立性检验
两种检验方法:
DW检验:在模型的summary输出中,包含了残差的Durbin-Watson统计量值DW=2(1-p),如果该值越接近于2,则说明残差是独立。 (DW=0时,残差序列存在完全正自相关, DW=(0,2)时,残差序列存在正自相关, DW=2时,残差序列无自相关, DW=(2,4)时,残差序列存在负自相关, DW=4时,残差序列存在完全负自相关。 )
图形法:画残差与滞后一阶的散点图。如果图形呈现圆盘分布
###图形法
res1=model.resid[:-1]
res2=model.resid[1:]
plt.scatter(res1,res2)
plt.show()
三、回归中其它需要检验的部分
1、异常点检验
首先建立回归模型,关于异常点的检测方法,一般可以通过高杠杆值点(帽子矩阵)或DFFITS值、学生化残差、cook距离和covratio值来判断。
当高杠杆值点(或帽子矩阵)大于2(p+1)/n时,则认为该样本点可能存在异常(其中p为自变量的个数,n为观测的个数);
当DFFITS统计值大于2sqrt((p+1)/n)时 ,则认为该样本点可能存在异常;
当学生化残差的绝对值大于2,则认为该样本点可能存在异常;
对于cook距离来说,则没有明确的判断标准,一般来说,值越大则为异常点的可能性就越高;
对于covratio值来说,如果一个样本的covratio值离数值1越远,则认为该样本越可能是异常值。
对于异常值的处理,我们可以考虑下面几种办法:
当异常比例极低时(如5%以内),可以考虑直接删除;
当异常比例比较高时,可以考虑将异常值衍生为哑变量,即异常值对应到1,非异常值则对应到0;
将单独把异常值提取出来,另行建模;
####异常点检验
outliers = fit.get_influence() #影响点
leverage = outliers.hat_matrix_diag # 高杠杆值点(帽子矩阵)
dffits = outliers.dffits[0] # dffits值
resid_stu = outliers.resid_studentized_external # 学生化残差
cook = outliers.cooks_distance[0] # cook距离
covratio = outliers.cov_ratio # covratio值
# 将上面的几种异常值检验统计量与原始数据集合并
contat1 = pd.concat([pd.Series(leverage, name = 'leverage'),pd.Series(dffits, name = 'dffits'),
pd.Series(resid_stu,name = 'resid_stu'),pd.Series(cook, name = 'cook'),
pd.Series(covratio, name = 'covratio'),],axis = 1)
data_outliers = pd.concat([data,contat1], axis = 1)
data_outliers.head()
##计算异常点的比例
outliers_ratio = len(np.where(np.abs(data_outliers.resid_stu)>2)[0])/data_outliers.shape[0]
outliers_ratio
##删除异常点
data_outliers = data_outliers.loc[np.abs(data_outliers.resid_stu)<=2,] #这里根据的是学生化残差
2、共线性检验
如果VIF大于10,则说明变量存在多重共线性。如果发现变量之间存在多重共线性的话,可以考虑删除变量和重新选择模型。
X=sm.add_constant(X) #加上一列常数项,必须
vif = pd.DataFrame()
vif["VIF Factor"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])] #variance_inflation_factor(X.values, i) 表示计算第i个变量的VIF
vif["features"] = X.columns
vif