执行共线性分析遇KeyError:Int64Index不在列中求助
解决VIF计算中的KeyError问题
首先,直接帮你定位核心问题:你遇到的KeyError根本原因不是分隔符,也不是np.arange的冲突,而是用位置整数索引直接访问DataFrame列名导致的。
为什么会报错?
你的代码里variables = range(X.shape[1])生成的是列的位置索引(0、1、2、3),但当你用X[variables]时,pandas会默认按列名去查找,而你的DataFrame列名是Year、Age这类字符串,根本不存在名为0/1/2/3的列,自然会抛出KeyError。另外,range对象是不可变的,del variables[maxloc]这行代码本身也会报错,你能运行到KeyError说明可能手动把range改成了列表,但存储的还是位置索引,问题依然存在。
先排除分隔符疑虑
从你打印的training_set结果来看,列名和数据都正确加载了,说明sep=";"的设置没问题,这个猜测可以排除。
修正后的VIF函数
下面是修复后的代码,我调整了变量索引的方式,改用列名列表来操作:
from statsmodels.stats.outliers_influence import variance_inflation_factor import pandas as pd import numpy as np # 读取数据(你的这部分代码没问题) read_training_set = pd.read_csv('C:\\Users\\rapha\\Desktop\\New test\\Classeur1.csv', sep=";") training_set = pd.DataFrame(read_training_set) print(training_set) def calculate_vif_(X): thresh = 5.0 # 初始化为列名列表,而非位置索引 variables = list(X.columns) # 用while循环动态处理变量删除,避免for循环的固定次数问题 while len(variables) > 1: # 针对当前变量子集计算VIF vif_values = [variance_inflation_factor(X[variables].values, ix) for ix in range(len(variables))] print(f"当前VIF值: {vif_values}") max_vif = max(vif_values) maxloc = vif_values.index(max_vif) if max_vif > thresh: dropped_var = variables[maxloc] print(f'删除变量 \'{dropped_var}\',其VIF值为: {max_vif}') del variables[maxloc] else: # 所有变量VIF都低于阈值,停止循环 break print('剩余变量:') print(variables) # 返回筛选后的DataFrame return X[variables] X = training_set X2 = calculate_vif_(X)
关键修改点说明
- 用列名列表代替位置索引:
variables = list(X.columns)直接存储列名,这样X[variables]能正确选取对应的列,不会触发KeyError。 - 改用while循环:因为每次删除变量后,剩余变量数量会减少,while循环可以动态判断何时停止,比固定次数的for循环更合理。
- 明确返回筛选结果:原函数返回的是原始X,修正后返回
X[variables],即筛选后的变量子集。
针对你的数据的额外说明
你的DataFrame中所有变量都是完全线性相关的(Year每增加1,Age、Weight、Size也同步+1),所以计算出的VIF会是无穷大,函数会逐步删除变量,直到剩下最后一个符合阈值要求的变量。
内容的提问来源于stack exchange,提问作者Raphaël Ambit
相关产品推荐
相关产品推荐

