You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何scipy.optimize.minimize始终返回初始值,无法完成优化?

为什么scipy.optimize.minimize无法完成优化?

主要有两个核心问题:

  • 目标函数非光滑(不连续、不可导)
    你写的overlap函数里,通过min(index_range, key=lambda i: abs(data2_x[i]-x1))寻找最近索引的操作,会让函数值随shift的变化出现阶跃跳变——当shift微调时,某个x1对应的最近索引可能突然切换,导致求和结果sum_的数值不连续,也没有定义良好的梯度。而minimize默认的L-BFGS-B算法是基于梯度的光滑优化算法,遇到这种非光滑函数时,会认为初始点附近没有下降方向,直接返回初始值。

  • 优化方法选择不当
    默认的L-BFGS-B不适合处理非光滑目标函数,需要改用不需要梯度的启发式优化方法。


修复方案

1. 切换优化方法为Nelder-Mead

直接在调用minimize时指定方法为Nelder-Mead,这个方法不需要计算梯度,能处理非光滑函数:

result = opt.minimize(overlap, 40, args=(data1_x, data1_y, data2_x, data2_y), method='Nelder-Mead')

2. (可选)将目标函数改为光滑形式

如果想要更稳定的优化效果,可以用插值替代索引查找,让函数变得可导。比如用numpy.interp对data2做线性插值,直接计算对应位置的y值:

def overlap(shift, data1_x, data1_y, data2_x, data2_y):
    x1_shifted = np.array(data1_x) + shift[0]
    # 线性插值得到每个偏移后x对应的data2的y值
    y2_interp = np.interp(x1_shifted, data2_x, data2_y)
    # 筛选出在共同范围内的点
    idx = np.searchsorted(data2_x, x1_shifted)
    idx = np.clip(idx, 1, len(data2_x)-1)  # 避免越界
    dist_left = x1_shifted - np.array(data2_x)[idx-1]
    dist_right = np.array(data2_x)[idx] - x1_shifted
    min_dist = np.minimum(dist_left, dist_right)
    mask = min_dist <=5
    sum_ = np.sum(np.abs(y2_interp[mask] - np.array(data1_y)[mask]))
    return sum_

修改后目标函数变得光滑,用默认的L-BFGS-B算法也能正常找到最优解。

3. 验证效果

修改后运行代码,result.x会接近真实的50.5,下方的子图也能看到两个数据集成功对齐。


内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:36:15