我试图用python计算一个简单数据集中每一列的方差通胀因子(VIF):
a b c d
1 2 4 4
1 2 6 3
2 3 7 4
3 2 8 5
4 1 9 4
我已经在R中使用了usdm library中的vif函数完成了这项工作,它给出了以下结果:
a <- c(1, 1, 2, 3, 4)
b <- c(2, 2, 3, 2, 1)
c <- c(4, 6, 7, 8, 9)
d <- c(4, 3, 4, 5, 4)
df <- data.frame(a, b, c, d)
vif_df <- vif(df)
print(vif_df)
Variables VIF
a 22.95
b 3.00
c 12.95
d 3.00
但是,当我在python中使用statsmodel vif function执行相同操作时,我的结果是:
a = [1, 1, 2, 3, 4]
b = [2, 2, 3, 2, 1]
c = [4, 6, 7, 8, 9]
d = [4, 3, 4, 5, 4]
ck = np.column_stack([a, b, c, d])
vif = [variance_inflation_factor(ck, i) for i in range(ck.shape[1])]
print(vif)
Variables VIF
a 47.136986301369774
b 28.931506849315081
c 80.31506849315096
d 40.438356164383549
尽管输入是相同的,但结果却大不相同。一般来说,statsmodel VIF函数的结果似乎是错误的,但我不确定这是否是因为我调用它的方式,或者这是否是函数本身的问题。
我希望有人能帮我弄清楚我是在错误地调用statsmodel函数还是解释结果中的差异。如果这是函数的问题,那么python中是否有VIF的替代方案?
我认为这是由于Python的OLS不同造成的。OLS用于python方差通胀因子计算,默认情况下不添加截距。不过,你肯定想在里面拦截。
你要做的是在矩阵ck中再加一列,用它们来表示一个常数。这就是方程的截距项。完成后,您的值应该正确匹配。
编辑:将0替换为1
正如其他人和Josef perktell在this post中所提到的,函数的作者
variance_inflation_factor
期望解释变量矩阵中存在常量。可以使用statsmodels中的add_constant
将所需常量添加到数据帧,然后再将其值传递给函数。我相信您还可以使用
assign
将常量添加到数据帧最右边的列:源代码本身相当简洁:
修改代码以将所有vif作为一个系列返回也相当简单:
对于这条线索的未来参与者(如我):
此代码给出
[编辑]
作为对注释的响应,我试图尽可能多地使用
DataFrame
(需要numpy
来反转矩阵)。代码给出了
对角线元素提供VIF。
相关问题 更多 >
编程相关推荐