带约束线性回归求解:基于DataFrame最小化MAE的模型实现求助
带约束的MAE线性回归实现(基于PuLP + Pandas)
核心思路
最小化MAE的线性回归可转化为线性规划问题:引入非负辅助变量e_i表示每个样本的预测误差绝对值,目标函数变为最小化所有e_i的总和,同时加入你指定的参数约束条件。
代码实现步骤
1. 导入依赖库
import pulp import pandas as pd
2. 加载你的DataFrame
直接替换成你实际的数据集即可,下面用模拟数据做示例:
# 模拟你的数据结构(实际使用时替换为你的真实DataFrame) data = { 'speed_20-40': [30, 25, 40, 35, 28], 'speed_40-50': [40, 50, 30, 35, 42], 'speed_50-60': [30, 25, 30, 30, 30], 'fuel efficiency': [2.5, 2.7, 2.3, 2.6, 2.4] } df = pd.DataFrame(data)
3. 构建线性规划模型
# 初始化模型,目标为最小化MAE model = pulp.LpProblem("Constrained_MAE_Regression", pulp.LpMinimize) # 定义决策变量:回归系数与截距 m1 = pulp.LpVariable("m1", lowBound=-1, upBound=0) # speed_20-40的系数 m2 = pulp.LpVariable("m2", lowBound=0, upBound=1) # speed_40-50的系数 m3 = pulp.LpVariable("m3") # speed_50-60的系数 c = pulp.LpVariable("c", lowBound=2, upBound=3) # 截距 # 定义辅助变量:存储每个样本的误差绝对值 e = [pulp.LpVariable(f"e_{i}", lowBound=0) for i in range(len(df))] # 设置目标函数:最小化所有误差绝对值的和 model += pulp.lpSum(e) # 添加样本预测约束(线性化绝对值误差) for i in range(len(df)): # 计算当前样本的预测值 y_pred = m1 * df.loc[i, 'speed_20-40'] + m2 * df.loc[i, 'speed_40-50'] + m3 * df.loc[i, 'speed_50-60'] + c y_act = df.loc[i, 'fuel efficiency'] # 将|y_pred - y_act| ≤ e_i转化为两个线性约束 model += e[i] >= y_pred - y_act model += e[i] >= y_act - y_pred # 添加额外参数约束:m1 < m3 < m2 model += m3 > m1 model += m3 < m2
4. 求解模型并输出结果
# 调用PuLP自带的CBC求解器求解 model.solve() # 输出求解状态与参数结果 print(f"求解状态: {pulp.LpStatus[model.status]}") print(f"截距c: {pulp.value(c):.4f}") print(f"系数m1(speed_20-40): {pulp.value(m1):.4f}") print(f"系数m2(speed_40-50): {pulp.value(m2):.4f}") print(f"系数m3(speed_50-60): {pulp.value(m3):.4f}") print(f"最小平均绝对误差(MAE): {pulp.value(model.objective)/len(df):.4f}")
关键说明
- MAE线性化:绝对值函数无法直接用线性规划处理,通过引入非负辅助变量
e_i,将|y_pred - y_act|转化为两个线性不等式约束,适配线性规划求解器。 - 约束适配:严格按照你的要求定义变量上下界,额外添加
m1 < m3 < m2的线性约束。 - DataFrame集成:通过
df.loc遍历每个样本,直接提取特征与目标值,快速构建每个样本的预测约束。
内容的提问来源于stack exchange,提问作者Abhishek Chowdhuri
相关产品推荐
相关产品推荐

