创建 Python 函数以迭代 List/DataFrame (VIF)

问题描述

我有一个数据集,我想选择 VIF(方差膨胀系数)小于某个阈值的变量子集。我的想法是计算每个变量的 VIF,然后取出最高值的变量(如果它高于某个阈值),重新计算每个剩余变量的 VIF 并重复该过程,直到没有高于阈值的 VIF .

这种方法没有什么新颖的想法,但我无法超越某个点来制作一个函数来在 Python 中自动化这个过程。

x 是删除了目标变量的数据集

import pandas as pd
import numpy as np
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

x_vif = add_constant(x)

vif = pd.DataFrame([variance_inflation_factor(x_vif.values,i) for i in range(x_vif.shape[1])],index=x_vif.columns)

vif 也可以是一个列表。那么,是否有任何软件包可以自动执行此操作,或者您能否告诉我如何创建此功能

我找到了一个可以自动执行此操作的 R 库 (thinXwithVIF),但我无法让 rpy2 与我需要使用的 Python 版本一起使用。

解决方法

也许有意义的是删除每一轮中具有最高 vif 的变量,对数据帧进行子集化并在所有变量低于您的阈值时停止。我不认为 vif 会是万能的,你真的必须查看数据来决定要包含什么等等。

import statsmodels.api as sm
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor

data = sm.datasets.get_rdataset('mtcars')

x_vif = data.data.iloc[:,1:]
y = data.data['mpg']

thres = 10

while True:
    Cols = range(x_vif.shape[1])
    
    vif = np.array([variance_inflation_factor(x_vif.values,i) for i in Cols])
    if all(vif < thres):
        break
    else:
        Cols = np.delete(Cols,np.argmax(vif))
        x_vif = x_vif.iloc[:,Cols]