简体   繁体   English

为什么我的优化(scipy.optimize.minimize)不起作用并返回初始值?

[英]Why does my optimization (scipy.optimize.minimize) not work and return the initial values instead?

I have a set of data;我有一组数据; each column corresponds to a spectrum at a certain time.每列对应于特定时间的光谱。 I want to fit the spectrum at a generic time (t_i) as a linear combination of the spectrum at time 0 (in the first column), at time 5 (in column 30) and time 35 (in column 210).我想将一般时间 (t_i) 的光谱拟合为时间 0(在第一列中)、时间 5(在第 30 列中)和时间 35(在第 210 列中)的光谱的线性组合。 So the equation I want to fit is:所以我想拟合的方程是:

S(t_i) = a * S(t_0) + b * S(t_5) + c * S(t_35) S(t_i) = a * S(t_0) + b * S(t_5) + c * S(t_35)

where:在哪里:

  1. 0 <= a, b, c <= 1 0 <= a, b, c <= 1

  2. a + b + c = 1 a + b + c = 1

I found the solution at this question ( Minimizing Least Squares with Algebraic Constraints and Bounds ) super useful.我发现这个问题的解决方案( Minimizing Least Squares with Algebraic Constraints and Bounds )非常有用。 But when I try it with my set of data the results are obviously wrong.但是当我用我的数据集进行尝试时,结果显然是错误的。 I tried modifying the method to 'Nelder-Mead' but it doesn't respect my bound so I get negative values.我尝试将方法修改为“Nelder-Mead”,但它不尊重我的界限,所以我得到了负值。

This is my script:这是我的脚本:

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)

If I use the Nelder-Mead method I get: Out: [ 0.02732053 1.01961422 -0.04504698] , if I don't specify the method I get: [1. 0. 0.]如果我使用 Nelder-Mead 方法,我会得到: Out: [ 0.02732053 1.01961422 -0.04504698] ,如果我不指定我得到的方法: [1. 0. 0.] [1. 0. 0.] (I believe that in this case the SLSQP method is being used). [1. 0. 0.] (我相信在这种情况下使用的是 SLSQP 方法)。

The data I'm referring to is similar to the following:我指的数据类似于以下内容:

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

Can you identify the problem?你能找出问题所在吗? Can you suggest other ways to solve this problem?你能建议其他方法来解决这个问题吗? I have also tried using least_squares , but it failed.我也尝试过使用least_squares ,但失败了。

The result of a local optimization strongly depends on the initial values.局部优化的结果很大程度上取决于初始值。

It might return [1, 0, 0] for the case you stated above because there simply was no possibility for the optimizer to find a "downhill-only" way to [0. 1. 0.]对于上述情况,它可能会返回[1, 0, 0] ,因为优化器根本不可能找到通向[0. 1. 0.] [0. 1. 0.] . [0. 1. 0.] . In fact, you might have started in a local minima and all ways out of the dip went uphill.事实上,您可能已经从局部最小值开始,并且所有摆脱困境的方法都走上坡路。 So the optimizer chose to stay.所以优化器选择留下来。 That's how these optimizers work.这就是这些优化器的工作方式。

Try尝试

xinit = np.array([0.0, 1.0, 0.0])

for t_i = t5 and I am quite sure the optimizer will return the initial value.对于t_i = t5 ,我很确定优化器将返回初始值。

For your case do what I stated here : Run the optimizer several times, each time pick random initial values inside your boundaries.对于您的情况,请执行我在此处所述的操作:多次运行优化器,每次在您的边界内选择随机初始值。 You can pick the code posted there and just add your constraints, use SLSQP or trust-constr.您可以选择发布在那里的代码并添加您的约束,使用 SLSQP 或 trust-constr。

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

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