繁体   English   中英

在回归中使用 gurobi python 的荒谬解决方案

[英]Absurd solution using gurobi python in regression

所以我是 gurobi 的新手,我决定开始使用它来解决一个众所周知的问题,即回归。 我找到了这个官方笔记本,其中解决了 L0 惩罚回归 model 并且我只取出了回归 model 的一部分。 然而,当我在 gurobi 中解决这个问题时,我得到了一个非常奇怪的解决方案,与实际正确的回归解决方案完全不同。

我正在运行的代码是:

import gurobipy as gp
from gurobipy import GRB
import numpy as np
from sklearn.datasets import load_boston
from itertools import product
boston = load_boston()
x = boston.data
x = x[:, [0, 2, 4, 5, 6, 7, 10, 11, 12]] # select non-categorical variables
response = boston.target

samples, dim = x.shape

regressor = gp.Model()

# Append a column of ones to the feature matrix to account for the y-intercept
x = np.concatenate([x, np.ones((samples, 1))], axis=1)

# Decision variables
beta = regressor.addVars(dim + 1, name="beta") # Beta

# Objective Function (OF): minimize 1/2 * RSS using the fact that
# if x* is a minimizer of f(x), it is also a minimizer of k*f(x) iff k > 0
Quad = np.dot(x.T, x)
lin = np.dot(response.T, x)
obj = sum(0.5 * Quad[i, j] * beta[i] * beta[j] for i, j in product(range(dim + 1), repeat=2))
obj -= sum(lin[i] * beta[i] for i in range(dim + 1))
obj += 0.5 * np.dot(response, response)

regressor.setObjective(obj, GRB.MINIMIZE)

regressor.optimize()
beta_sol_gurobi = np.array([beta[i].X for i in range(dim+1)])

此代码提供的解决方案是

array([1.22933632e-14, 2.40073891e-15, 1.10109084e-13, 2.93142174e+00,
       6.14486489e-16, 3.93021623e-01, 5.52707727e-15, 8.61271603e-03,
       1.55963041e-15, 3.19117429e-13])

而真正的线性回归解决方案应该是

from sklearn import linear_model
lr = linear_model.LinearRegression()
lr.fit(x, response)
lr.coef_
lr.intercept_

这会产生,

array([-5.23730841e-02, -3.35655253e-02, -1.39501039e+01,  4.40955833e+00,
       -7.33680982e-03, -1.24312668e+00, -9.59615262e-01,  8.60275557e-03,
       -5.17452533e-01])
29.531492975441015

所以 gurobi 解决方案是完全不同的。 关于发生了什么的任何猜测/建议? 我在这里做错什么了吗?

PD:我知道这个问题可以使用其他包,甚至其他优化框架来解决,但我对在 gurobi python 中解决它特别感兴趣,因为我想在一些更复杂的问题中开始使用 gurobi。

错误的结果是由于您的决策变量造成的。 由于 Gurobi 默认假定所有变量的下限为 0,因此您需要显式设置下限:

beta = regressor.addVars(dim + 1, lb = -GRB.INFINITY, name="beta") # Beta

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM