如何在 Python 中系统地删除共线变量(熊猫列)?

机器算法验证 Python 多重共线性 scikit-学习
2022-01-19 10:06:35

到目前为止,我已经通过查看相关表并消除了高于某个阈值的变量来删除共线变量作为数据准备过程的一部分。有没有更可接受的方式来做到这一点?此外,我知道一次只查看 2 个变量之间的相关性并不理想,像 VIF 之类的测量考虑了多个变量之间的潜在相关性。如何系统地选择不表现出多重共线性的变量组合?

我在熊猫数据框中有我的数据,并且正在使用 sklearn 的模型。

3个回答

谢谢 SpanishBoy - 这是一段很好的代码。@ilanman:这会检查 VIF 值,然后删除 VIF 大于 5 的变量。我认为“性能”是指运行时间。上面的代码花了我大约 3 个小时来运行大约 300 个变量,5000 行。

顺便说一句,我已经对其进行了修改以删除一些额外的循环。此外,我已经使它更干净一些,并返回带有减少变量的数据框。这个版本将我的运行时间减少了一半!我的代码在下面-希望它有所帮助。

from statsmodels.stats.outliers_influence import variance_inflation_factor    

def calculate_vif_(X, thresh=5.0):
    variables = list(range(X.shape[1]))
    dropped = True
    while dropped:
        dropped = False
        vif = [variance_inflation_factor(X.iloc[:, variables].values, ix)
               for ix in range(X.iloc[:, variables].shape[1])]

        maxloc = vif.index(max(vif))
        if max(vif) > thresh:
            print('dropping \'' + X.iloc[:, variables].columns[maxloc] +
                  '\' at index: ' + str(maxloc))
            del variables[maxloc]
            dropped = True

    print('Remaining variables:')
    print(X.columns[variables])
    return X.iloc[:, variables]

您可以尝试使用以下代码:

from statsmodels.stats.outliers_influence import variance_inflation_factor

def calculate_vif_(X):

    '''X - pandas dataframe'''
    thresh = 5.0
    variables = range(X.shape[1])

    for i in np.arange(0, len(variables)):
        vif = [variance_inflation_factor(X[variables].values, ix) for ix in range(X[variables].shape[1])]
        print(vif)
        maxloc = vif.index(max(vif))
        if max(vif) > thresh:
            print('dropping \'' + X[variables].columns[maxloc] + '\' at index: ' + str(maxloc))
            del variables[maxloc]

    print('Remaining variables:')
    print(X.columns[variables])
    return X

它有效,但我不喜欢这种方法的表现

我尝试了 SpanishBoy 的答案,并在为数据框运行它时发现了薮错误。这是一个经过调试的解决方案。

from statsmodels.stats.outliers_influence import variance_inflation_factor    

def calculate_vif_(X, thresh=100):
cols = X.columns
variables = np.arange(X.shape[1])
dropped=True
while dropped:
    dropped=False
    c = X[cols[variables]].values
    vif = [variance_inflation_factor(c, ix) for ix in np.arange(c.shape[1])]

    maxloc = vif.index(max(vif))
    if max(vif) > thresh:
        print('dropping \'' + X[cols[variables]].columns[maxloc] + '\' at index: ' + str(maxloc))
        variables = np.delete(variables, maxloc)
        dropped=True

print('Remaining variables:')
print(X.columns[variables])
return X[cols[variables]]

我的性能也没有问题,但没有进行广泛的测试。