使用PYOMO构建线性规划时约束函数报错:KeyError: 0
问题分析与修复方案
核心错误点
- DataFrame行访问错误:
y[i-1]试图用整数索引访问DataFrame的列,但y是单列DataFrame,列名为y而非整数,直接触发KeyError: 0,需改用行索引访问方式。 - Beta变量索引错误:
model.beta = pyo.Var(features)错误地将DataFrame的行作为变量索引,实际Beta应对应每个特征列,需用特征列名作为索引。 - 求和循环对象错误:循环
features(DataFrame)而非特征列名,导致计算时无法正确匹配特征与Beta系数。 - 截距列类型错误:
data['intercept'] = '1.0'设置为字符串类型,会导致后续数值计算异常,需改为浮点型。
修复后的完整代码
数据预处理部分
import pandas as pd import numpy as np data = pd.read_csv(r'Data\prostate.csv') data['y'] = data['lpsa'] # 复制lpsa列并重命名为y y = data[['y']] # 提取y为单独DataFrame del data['lpsa'] # 删除原lpsa列 data['intercept'] = 1.0 # 添加数值型截距列 features = data[['lcavol', 'lweight', 'age', 'lbph', 'svi', 'lcp', 'gleason', 'pgg45', 'intercept']] # 提取特征列
Pyomo建模部分
import pyomo.environ as pyo model = pyo.ConcreteModel() # 样本索引:从1到len(data)(覆盖所有样本) N = list(range(1, len(data)+1)) # 特征列名集合 feature_names = features.columns # 定义变量:r_pos、r_neg对应每个样本,beta对应每个特征 model.r_pos = pyo.Var(N, domain=pyo.NonNegativeReals) model.r_neg = pyo.Var(N, domain=pyo.NonNegativeReals) model.beta = pyo.Var(feature_names) def abs_rule(model, i): # 获取第i个样本的实际值(行索引为i-1) y_val = y.iloc[i-1, 0] # 计算特征与beta的线性组合 linear_comb = sum(data.loc[i-1, feat] * model.beta[feat] for feat in feature_names) # 返回约束表达式 return y_val - linear_comb == model.r_pos[i] - model.r_neg[i] model.abs = pyo.Constraint(N, rule=abs_rule) # L1目标函数:最小化r_pos与r_neg的和 model.L1_objective = pyo.Objective(expr=sum(model.r_pos[i] + model.r_neg[i] for i in N), sense=pyo.minimize)
额外说明
- 修复了样本索引范围:原
range(1, len(data))会漏掉最后一个样本,改为range(1, len(data)+1)确保覆盖所有样本。 - 显式指定目标函数的
sense=pyo.minimize,逻辑更清晰(Pyomo默认最小化,显式声明可避免歧义)。 - 统一使用浮点型数值参与计算,避免字符串类型导致的运算异常。
内容的提问来源于stack exchange,提问作者guanp175
相关产品推荐
相关产品推荐

