Scipy.soptimize.miminize()两个用于非线性目标的数组



我拟合了一个对数正态模型,现在我想使用该模型的系数来找到能提供最大响应的变量值组合。我打算稍后引入一些约束,但目前我只想运行优化。复杂的问题是,该模型是一个混合方法模型,所以我有模型中每个个体的系数。因此,我需要优化每个个体的变量值,给定它们各自的系数。

我的例子:

import numpy as np
from scipy.optimize import minimize
def objective(x, beta):
x1, x2 = x
beta1, beta2 = beta
return -1 * np.sum(np.exp(3 + x1*beta1 + x2*beta2))
# initial guesses for variables x1 and x2
n = 2
x1 = np.zeros(n)
x1[0] = 1.0
x1[1] = 2.0
x2 = np.zeros(n)
x2[0] = 3.0
x2[1] = 4.0
x0 = np.vstack((x1,x2))
# the coefficients (weights) for each of n individuals, in each variable
beta1 = np.zeros(n)
beta1[0] = 1.1
beta1[1] = 1.01
beta2 = np.zeros(n)
beta2[0] = 1.1
beta2[1] = 1.01
beta0 = np.vstack((beta1, beta2))
# show initial objective
print('Initial SSE Objective: ' + str(objective(x0, beta0)))  # this works as intended
# but I'm not sure how to specify bounds given my shape
b = (1.0,5.0)  #min = 1, max = 5 on any one channel for any one individual
bnds = (b, b)
# running without bounds
solution = minimize(objective, x0, method='SLSQP',
args=beta0)

给出以下错误;


File "<ipython-input-92-554f967ca90b>", line 2, in objective
x1, x2 = x
ValueError: too many values to unpack (expected 2)

如果我给目标函数传递args,它就可以工作,这是minimize((的限制吗?函数的形状(2,2(不能取x吗?

此外,我很难正确指定边界。。。

# running with bounds
solution = minimize(objective, x0, method='SLSQP',
args=beta0, bounds=bnds)

给出错误;

ValueError: operands could not be broadcast together with shapes (4,) (2,) (2,) 

我能够用gekko DOCS HERE 做到这一点

from gekko import GEKKO
m = GEKKO() # Initialize gekko
n = 2

# Init the coefficients for each HCP
alpha_list = np.random.normal(3, 0.1, n)
beta1_list = np.random.normal(1.01, 0.1, n)
beta2_list = np.random.normal(1.02, 0.1, n)
beta3_list = np.random.normal(1.04, 0.1, n)

# Initialize variables
x1 = [m.Var(value=1,lb=0,ub=4) for i in range(n)]
x2 = [m.Var(value=1,lb=0,ub=4) for i in range(n)]
x3 = [m.Var(value=1,lb=0,ub=4) for i in range(n)]

# Init the coefficients
alpha = [m.Const(value=alpha_list[i]) for i in range(n)]
beta1 = [m.Const(value=beta1_list[i]) for i in range(n)]
beta2 = [m.Const(value=beta2_list[i]) for i in range(n)]
beta3 = [m.Const(value=beta3_list[i]) for i in range(n)]

# Inequality constraints
m.Equation(m.sum(x1) + m.sum(x2) + m.sum(x3) <= n*10)

m.Obj(-1 * m.sum([m.exp(alpha[i] + x1[i]*beta1[i] + x2[i]*beta2[i] + x3[i]*beta3[i]) for i in range(n)])) # Objective
m.options.IMODE = 3 # Steady state optimization set to 3, change to 1 for integer
m.options.MAX_ITER = 1000
m.solve() # Solve
print('Results')
print('x1: ' + str(x1))
print('x2: ' + str(x2))
print('x3: ' + str(x3))

但为了我自己的学习,我也想和scipy一起做这件事。

我会报告,以防其他人遇到同样的问题。我认为限制是从最小化到目标函数的输入必须是一个平面数组,所以我的(2,2(形状不起作用(如果我错了,请纠正我(。

因此,一种解决方法是输入一个平面数组,然后在目标函数本身中对其进行解包。如果你把预期的个人数量交给函数,函数可以处理数组,这样每个通道都会得到一个1xN作为我们试图优化的回归方程的输入。

import numpy as np
from scipy.optimize import minimize
def objective(x, beta, n):
x1, x2 = x.reshape(2,n)
beta1, beta2 = beta.reshape(2,n)
return -1 * np.sum(np.exp(3 + x1*beta1 + x2*beta2))
# initial guesses for variables x1 and x2
n = 2
x1 = np.zeros(n)
x1[0] = 1.0
x1[1] = 2.0
x2 = np.zeros(n)
x2[0] = 3.0
x2[1] = 4.0
x0 = np.concatenate((x1,x2))
# the coefficients (weights) for each of n individuals, in each variable
beta1 = np.zeros(n)
beta1[0] = 1.1
beta1[1] = 1.01
beta2 = np.zeros(n)
beta2[0] = 1.1
beta2[1] = 1.01
beta0 = np.concatenate((beta1, beta2))
# show initial objective
print('Initial SSE Objective: ' + str(objective(x0, beta0, 2)))  # this works as intended
# specifying bounds is much easier now we just have a flat array
b = (1.0,5.0)  #min = 1, max = 5 on any one channel for any one individual
bnds = (b , b)*n
# running with bounds
solution = minimize(objective, x0, method='SLSQP',
args=(beta0,n), bounds=bnds)
x = solution.x
# show final objective
print('Final SSE Objective: ' + str(objective(x, beta0, n)))
# print solution
print('Solution')
x_sol = x.reshape(2,n)
print('x1 = ' + str(x_sol[0]))
print('x2 = ' + str(x_sol[1]))

正如预期的那样,在没有约束的情况下,最小化调用只会使等式中每个变量的值最大化。我的下一步将是对这个函数进行约束。

最新更新