首页 > 编程知识 正文

vif检验多重共线性,可解决多重共线性的回归算法

时间:2023-05-04 11:25:41 阅读:10872 作者:912

多元线性回归是我们在数据分析中常用的方法之一,很多人遇到多维数据时,基本上没有使用这个方法,使用多元线性回归后得到的结果并不完美,其问题实际上不是方法,而是数据。 随着与数据相关的维度的增长,我们很难保证维度之间的互相关,这些维度对结果有一定的影响,并且在一组维度或变量之间存在强相关的情况下,可以认为这违背了多元线性回归模型的基本假设。 今天介绍用VIF法解决多维数据中多重共线性问题的方法。

首先介绍多重共线性。

多元回归模型有一个基本假设,即要求设计矩阵x的秩rank(x )=p 1。 其中,p是维数,也就是说,要求x中列向量之间的线性无关。 全部存在非零p 1的个数c0、c1、c2、cp,如果c0 c1xi1 c2xi2 . cpxip=0,I=1、2、3、n,则在自变量x1、x2、xp之间存在多重共享笔者用实际的例子来告诉大家。

这个例子来自1994年的统计摘要,是中国民航客运量的回归模型,统计了1978-1993年各年的数据。 该模型以民航票价为因素变量y,国民收入、消费额、民航航线距离、来华旅游入境人数为影响客运量的因素。 其中y的单位为万人,x1为国民收入(亿元),x2为消费额),x3为铁路客运量(万人,x4为民航航线距离),x5为来华观光入境人数) ),该数据集如图1所示,全部为来华观光入境人数

图1 .数据集的屏幕捕获

使用此数据集创建多元线性回归模型,主要使用statsmodels。 代码如下。 首先是导入各种库。 importnumpyasnp

importpandasaspd

importstatsmodels.apiassm

fromstatsmodels.stats.outliers _ influenceimportvariance _ inflation _ factor

然后读取数据,生成自变量x和自变量y。 file=r ' c :usersdesktopdata.xlsx '

数据=PD.read _ excel (file )读取数据

y=data['y']#变量数据

X=data.loc[:' x1':]#自变量数据

然后生成多元回归模型,输出结果的结果如图2所示。 x=sm.add_constant(x ) #加上常数1就是回归模型的常数项

生成reg=sm.ols(y,x ) #回归模型

model=reg.fit(#拟合数据

model.summary生成结果

图2 .原始数据的多元回归模型结果

如果您不太清楚图2中的参数,请参考笔者以前在公众号上写的文章《详解用statsmodels进行回归分析》。 从图2可以看到,我们模型的回归方程是y=450.90.354 x1-0.561 x2-0.0073 x 321.578 x 40.435 x 5。 看这里,似乎很多人都理解了几个问题。 该回归模型表面上没有太大问题,但仔细分析实际意义,可以看出一些问题。 x2是消费额,从经济学角度分析,消费额与民航票价的关系应该是正相关的。 也就是说,x2之前的系数应该是正的,但这里是负值。 问题出在哪里? 这是由于变量之间的多重共线性。

多重共线性的影响就在这里。 在我们的模型结果中,每个参数都可以通过验证,模型整体线性也很好。 例如,在本例中,R-squared值为0.998,非常有效。 )但是,那个参数的实际意义的一部分违背了我们的常识。 这种情况下,很多人很难发现自己的模型在数学上没有任何问题,就这样使用着

那么如何诊断多重共线性呢? 今天介绍VIF的方法。 VIF全称是变异基础因子,即方差放大因子,以自变量x为中心标准化后,x为Xs,得到xs’xs=[ rij ],这就是自变量的相关矩阵。 如图3所示,式(1)中c的主对角线要素VIFj=cjj是自变量xj的方差放大因子,式)中的Rj^2是对自变量xj的剩下的p-1个自变量的复数决定系数,式)也是方差放大因子VIFj的定义,VIFj是

图3. VIF方法的一些公式

Rj^2测量了自变量xj与剩下的p-1个自变量的线性相关,这一相关越强,自变量之间的多重共线性越强,表示Rj^2越接近1,VIFj越大。 相反,xj和剩下的p-1自变量之间的线性相关性越弱,多重共线性越弱,Rj^2接近0,VIFj接近约1。 由此可见,VIFj的大小

小反映了自变量之间是否存在多重共线性,可由它来度量多重共线性的严重程度,那么VIFj多大才算是有严重的多重共线性呢?根据统计学中的使用经验,当VIFj大于等于10的时候,就说明自变量xj与其余自变量之间存在严重的多重共线性,且这种多重共线性会过度地影响最唠叨的冰淇淋乘估计值。

在了解了VIF的概念之后,我们就用代码来展示一下如何诊断并消除多重共线性。这里笔者依然使用前面的数据,但加入了VIF检测,同时给出消除多重共线性后的结果,全部代码如下。file = r'C:UsersDesktopdata.xlsx'

data = pd.read_excel(file)

y = data['y']

X = data.loc[:, 'x1':]

X = sm.add_constant(X)

def process(data, col):

data = data.loc[:, col] #读取对应列标数据

vif = [variance_inflation_factor(data.values, i) for i in range(data.shape[1])][1:]

if max(vif) >= 10:

index = np.argmax(vif)+1 #得到最大值的标号

del col[index] #删除vif值最大的一项

return process(data, col) #递归过程

else:

vif = [variance_inflation_factor(data.values, i) for i in range(data.shape[1])][1:]

return col, vif

cols = ['const', 'x1', 'x2', 'x3', 'x4', 'x5']

cols, vif = process(X, cols)

reg = sm.OLS(y, X[cols])

model = reg.fit()

model.summary()

这里我们从process这个函数开始讲起,process需要两个参数,一个是data,就是要输入的数据,另一个是col,就是数据的columns(即数据的列标题),我们这里默认使用的数据集是pandas.DataFrame格式的,所以数据都是有columns的。在process函数中,data = data.loc[:, col]就是读取只含有col列标的那些数据, vif = [variance_inflation_factor(data.values, i) for i in range(data.shape[1])][1:]这行代码就是计算vif的过程,variance_inflation_factor函数需要输入两个参数,分别是数据和每列数据的标号,这个标号也是从0开始的。而最终我们取得的vif结果是去掉第一项的,因为第一项对应数据集中const那一列,这一列因为都是1,所以在vif结果中要去掉,但在计算时要保留。而得到vif之后,我们要找出vif中数据最大的一项,判断其是否大于等于10。如果是,就找到其对应的标号,利用np.argmax即可,然后删除col中这一项,再把所得的结果带入到process函数中,形成递归;如果不是,则直接返回col和vif这两个结果。

最终我们得到的cols是['const', 'x3', 'x4', 'x5'],const就是前面X = sm.add_constant(X)中加入的常数项一列,这个const列标是自动添加的,我们在这里仍沿用这个叫法,这列数据在VIF方法中只参与计算,但其值不用于比较大小。我们可以看到这里的结果去掉了x1和x2这两列数据,消除多重共线性最好的方式就是把那些造成多重共线性的维度(自变量)直接去掉,vif是[1.9836946236748652, 6.6499090855830225, 8.513876170172715],vif中所有数值都在10以内,说明目前已经消除了多重共线性。

然后用剩下的这些数据进行建模,得到多元回归模型,其结果如图4所示。该模型为y = 591.9 - 0.0104x3 + 26.4358x4 + 0.3174x5,该模型无论从数学上还是经济意义上,都能合理有效地进行解释。

图4. 用VIF法处理后的模型结果

判断数据是否具有多重共线性实际上有多种方法,比如特征根判定法、直接判断法等,本文主要讲解如何用VIF法来诊断多重共线性,有兴趣的读者也可以把此方法和其他方法进行一下对比学习。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。