[英]Why scipy.optimize.minimize does not work with a constraint and initial value 0
[英]Why does my optimization (scipy.optimize.minimize) not work and return the initial values instead?
我有一组数据; 每列对应于特定时间的光谱。 我想将一般时间 (t_i) 的光谱拟合为时间 0(在第一列中)、时间 5(在第 30 列中)和时间 35(在第 210 列中)的光谱的线性组合。 所以我想拟合的方程是:
在哪里:
0 <= a, b, c <= 1
a + b + c = 1
我发现这个问题的解决方案( Minimizing Least Squares with Algebraic Constraints and Bounds )非常有用。 但是当我用我的数据集进行尝试时,结果显然是错误的。 我尝试将方法修改为“Nelder-Mead”,但它不尊重我的界限,所以我得到了负值。
这是我的脚本:
t0= df.iloc[:,0] #Spectrum at time 0
t5 = df.iloc[:,30] # Spectrum at time 5
t35 = df.iloc[:,120] # Spectrum at time 35
ti= df.iloc[:,20]
# Bounds that make every coefficient be between 0 and 1
bnds = [(0, 1), (0, 1), (0, 1)]
# Constrain the sum of the coefficient to 1
cons = [{"type": "eq", "fun": lambda x: x[0] + x[1] + x[2] - 1}]
xinit = np.array([1, 0, 0])
fun = lambda x: np.sum((ti -(x[0] * t0 + x[1] * t5 + x[2] * t35))**2)
res = minimize(fun, xinit,method='Nelder-Mead', bounds=bnds, constraints=cons)
print(res.x)
如果我使用 Nelder-Mead 方法,我会得到: Out: [ 0.02732053 1.01961422 -0.04504698]
,如果我不指定我得到的方法: [1. 0. 0.]
[1. 0. 0.]
(我相信在这种情况下使用的是 SLSQP 方法)。
我指的数据类似于以下内容:
0 3.333 5 35.001
0.001045089 0.001109701 0.001169798 0.000725486
0.001083051 0.001138815 0.001176665 0.000713021
0.001090994 0.001142676 0.001186642 0.000716149
0.001096258 0.001156476 0.001190218 0.00071286
你能找出问题所在吗? 你能建议其他方法来解决这个问题吗? 我也尝试过使用least_squares
,但失败了。
局部优化的结果很大程度上取决于初始值。
对于上述情况,它可能会返回[1, 0, 0]
,因为优化器根本不可能找到通向[0. 1. 0.]
[0. 1. 0.]
. 事实上,您可能已经从局部最小值开始,并且所有摆脱困境的方法都走上坡路。 所以优化器选择留下来。 这就是这些优化器的工作方式。
尝试
xinit = np.array([0.0, 1.0, 0.0])
对于t_i = t5
,我很确定优化器将返回初始值。
对于您的情况,请执行我在此处所述的操作:多次运行优化器,每次在您的边界内选择随机初始值。 您可以选择发布在那里的代码并添加您的约束,使用 SLSQP 或 trust-constr。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.