为什么我的优化(scipy.optimization.minimum)不能工作,而是返回初始值?

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

我有一组数据,每一列对应于某一时间的频谱,我想把一般时间(t_i)的频谱拟合为时间0的线性组合。我想要拟合一个通用时间(t_i)的光谱,作为时间0(第一列)、时间5(第30列)和时间35(第210列)的光谱的线性组合。因此,我想拟合的方程是。

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

其中:0 <=a, b, c <=1

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

  2. A+B+C=1

我在这个问题上找到了解决方案(用代数约束和边界最小化最小二乘法。)超级有用。但当我用我的数据集尝试时,结果显然是错误的。我试着将方法修改为 "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
投票

局部优化的结果很大程度上取决于初始值。

它可能返回 [1, 0, 0] 因为优化器根本不可能找到一个 "只在下坡的 "方法来实现 [0. 1. 0.]. 事实上,你可能从局部的最小值开始,所有的出路都是上坡。所以优化器选择留下来。这就是这些优化器的工作原理。

试试

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

对于 t_i = t5 我很肯定优化器会返回初始值。

对于你的情况,请按照我说的做 此处: 多次运行优化器,每次在你的边界内随机选取初始值。你可以选取那里发布的代码,然后添加你的约束条件,使用SLSQP或trust-constr。

热门问题
推荐问题
最新问题