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

问题描述 投票:0回答:1

我有一组数据;每列对应于特定时间的光谱。我想将通用时间(t_i)的频谱拟合为时间0(在第一列),时间5(在第30列)和时间35(在第210列)中频谱的线性组合。所以我想拟合的方程是:

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

其中:

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

  2. 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.](我相信在这种情况下,将使用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,但失败。

python pandas least-squares minimize
1个回答
0
投票

局部优化的结果很强ly取决于初始值。

对于您在上述情况下,它可能返回[1, 0, 0],因为优化器根本不可能找到[0. 1. 0.]的“仅下坡”方式。实际上,您可能曾经在当地的最低要求中走出低谷。因此,优化器选择保留。

但是这些优化器就是这样工作的。尝试

xinit = np.array([1, 0, 0])

对于t_i = t5,我很确定优化器将返回初始值。

对于您的情况,请执行我所说的here:多次运行优化器,每次选择您边界内的随机初始值。您可以选择此处发布的代码,然后添加约束,使用SLSQP或trust-constr。

© www.soinside.com 2019 - 2024. All rights reserved.