Here is an example of multiple linear regression in which some of the variables are unbounded while others are bounded. I'm going to have ten unbounded parameters and ten non-negative parameters in this example. The quick gist is to use scipy.optimize.Bounds
in an optimizer that supports this argument such as 'trust-constr'
, along with the insight that it allows the use of np.inf
. You just set some of the bounds to be -np.inf
and np.inf
for the unbounded parameters, and set the bounds to be 0
and np.inf
for the non-negative parameters.
import numpy as np
from scipy.optimize import minimize, Bounds
np.random.seed(2022)
bounds = Bounds([-np.inf] * 10 + [0] * 10, [np.inf] * 20)
x = np.random.normal(size=100 * 20).reshape(100, 20)
true_a = np.arange(1,21)
true_y = x @ true_a + np.random.normal(size=100)
a0 = np.random.normal(size=20)
def f(a):
y_hat = x @ a
resid = true_y - y_hat
lsq = np.mean(np.power(resid, 2))
return lsq
result = minimize(f, x0=a0, method='trust-constr', bounds=bounds)
print(result.x)
Note that the last line accesses results.x
rather than results.a
because x
is priviliged in scipy.optimize
's programming to be the parameter. But this prints a result for the optimized vector of parameters a
as hoped. Here is the printout for this seed:
[ 0.9363189 2.01708136 3.07371156 4.03469035 4.97227273 5.91210627
6.86926581 8.05433955 8.83633234 9.93401828 10.96973645 12.05863185
12.95428506 13.9473809 14.93419422 16.05477142 17.13887755 18.37746539
19.05598047 19.78565871]