如何在 r 中使用 VIF?

Posted

技术标签:

【中文标题】如何在 r 中使用 VIF?【英文标题】:How to use VIF in r? 【发布时间】:2021-02-11 23:12:33 【问题描述】:

我是 R 新手,正在使用 caret 学习机器学习。我正在研究 UCI 银行营销响应数据,但这里使用了 iris 数据以实现可重复性。

问题是我在classification 模型上从car package 运行vif 得到error

library(tidyverse)
library(caret)
library(car)

iris

# to make it binary classification
iris_train <- iris %>% filter(Species %in% c("setosa","versicolor"))
iris_train$Species <- factor(iris_train$Species)

创建模型


model_iris3 <- train(Species ~ ., 
                      data = iris_train, 
                      method = "gbm",
                     verbose = FALSE
                      # tuneLength = 5,
                      # metric = "Spec", 
                      # trControl = fitCtrl
                      )

vif 中的错误

# vif
car::vif(model_iris3)

UseMethod("vcov") 中的错误:没有适用于 'vcov' 的方法应用于“c('train', 'train.formula')”类的对象

我通过这篇 SO 帖子了解了如何使用 finalModel 进行 vif:Variance inflation VIF for glm caret model in R

但还是报错

car::vif(model_iris3$finalModel)

UseMethod("vcov") 中的错误:没有适用于 'vcov' 的方法应用于“gbm”类的对象

adaboostearth 等出现同样的错误。

感谢任何解决此问题的帮助或建议。

更新

终于成功了(如果您仍然遇到错误,请参阅Answers 中的完整解决方案):

vif 不适用于classification 模型,因此将dependent 变量转换为numeric 并在其上运行linear regression,然后运行vif


model_iris4 <- train(as.numeric(Species) ~ ., 
                      data = iris_train, 
                      method = "lm",
                     verbose = FALSE
                      # tuneLength = 5,
                      # metric = "Spec", 
                      # trControl = fitCtrl
                      )

car::vif(model_iris4$finalModel)

######## output ##########

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    4.803414     2.594389    36.246326    25.421395 

【问题讨论】:

【参考方案1】:

终于成功了:

vif 不适用于classification 模型,因此将dependent 变量转换为numeric 并在其上运行linear regression,然后运行vif

model_iris4 <- train(as.numeric(Species) ~ ., 
                      data = iris_train, 
                      method = "lm",
                     verbose = FALSE
                      # tuneLength = 5,
                      # metric = "Spec", 
                      # trControl = fitCtrl
                      )

car::vif(model_iris4$finalModel)

######## output ##########

Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    4.803414     2.594389    36.246326    25.421395 

如果模型中有假人,很有可能仍然会出错。

例如:执行上述步骤后,我的原始 UCI 银行数据集出现新错误:Error in vif.default(model_vif_check$finalModel) : there are aliased coefficients in the model

要解决此错误,您可以尝试以下步骤

model 上运行alias(),其中predicted 变量为numeric

alias_res <- alias( 
  lm( as.numeric(y) ~ duration+nr.employed+euribor3m+pdays+emp.var.rate+poutcome.success+month.mar+cons.conf.idx+contact.telephone+contact.cellular+previous+age+cons.price.idx+month.jun+job.retired, data = train ) 
  )

alias_res
ld.vars <- attributes(alias_res$Complete)$dimnames[[1]]
ld.v

这将返回导致错误的别名,因此只需从模型中删除该预测器并再次运行 model(在我的情况下是 "contact.cellular"

model_vif_check_aliased <- train(as.numeric(pull(y)) ~ duration+nr.employed+euribor3m+pdays+emp.var.rate+poutcome.success+month.mar+cons.conf.idx+contact.telephone+previous+age+cons.price.idx+month.jun+job.retired, 
                      data = train, 
                      method = "lm"
                      )
model_vif_check_aliased

现在运行 vif

vif_values <- car::vif(model_vif_check_aliased$finalModel)
vif_values

duration nr.employed euribor3m pdays 1.016706 75.587546 80.930134 10.216410 emp.var.rate poutcome.success month.mar cons.conf.idx 64.542469 9.190354 1.077018 3.972748 contact.telephone 以前的年龄 cons.price.idx 2.091533 1.850089 1.185461 28.614339 月.君工作.退休 3.936681 1.198350

【讨论】:

干得好!您可以更改“最佳答案”标志并选择此答案而不是我的,因为这是正确的最佳答案。 :-) 谢谢@BrianLang :),据我说,我在两天内无法接受自己的答案。【参考方案2】:

car::vif 是一个函数,需要针对每种类型的模型进行适配。它适用于链接问题,因为 car::vif 已实施以应对 glm 模型。 car::vif 不支持您选择的模型类型:gbm

【讨论】:

感谢@BrianLang,我在互联网上寻找的更多,现在我认为car::vif 或一般vif 不适用于classification 模型。对于classification,我必须将因变量更改为数字,然后对其创建线性回归,然后运行vif。参考:researchgate.net/post/… 没错。 Crossvalidated has more information as well. 是的,我会在帖子中更新解决方案代码。再次感谢您的帮助:) 如果你找到了正确的方法,你总是可以回答你自己的问题!这样,当人们展望未来时,他们将拥有您新发现的知识! 好的,我也会在答案部分添加代码!!

以上是关于如何在 r 中使用 VIF?的主要内容,如果未能解决你的问题,请参考以下文章

看R语言建立回归分析,如何利用VIF查看共线性问题

如何使用scipy 1.0.0计算python 3.6中的VIF?

简单来说,为啥二元结果回归模型没有 VIF?

R vif() 以及 step()

R语言使用car包的vif函数计算方差膨胀因子,并基于方差膨胀因子开方后和阈值的判断来确认模型特征(预测变量)之间是否存在多重共线性(Multicollinearity)

R计算方差膨胀因子(VIF,Variance Inflation Factor)计算并解读VID与共线性(Multicollinearity)的关系实战