使用lmfit.minimize时如何为参数添加k1>k2>k3的大小约束
正确实现k1>k2>k3参数约束的方法
你引入非负delta参数做参数转换的思路是完全可行的,现有代码的问题是重复定义了k2参数:第一行params.add('k2', value = 1, expr = "k1 - delta1")已经给k2绑定了关联表达式,你紧接着又执行了params.add('k2', value = 1),直接覆盖了之前的绑定逻辑,导致k2的关联约束失效。
修正后的参数定义代码如下:
params = Parameters() params.add('k1', value = 2.4) # 建议用无约束拟合的结果作为初始值,加快收敛速度 params.add('delta1', value = 1, min = 0) params.add('k2', expr = "k1 - delta1") # 不要重复定义k2 params.add('delta2', value = 1, min = 0) params.add('k3', expr = "k2 - delta2")
为什么会出现k2与k3几乎相等的情况
这个结果是当前数据集在你给定约束下的最优解:
你原始生成的y数据只有x²项,线性项、常数项的真实值都是0,无约束拟合结果里k2、k3的相对误差都超过了50%,说明这两个参数的取值对拟合残差的影响非常小。而无约束结果里k3≈1.03、k2≈-0.43,本身不满足k2>k3的约束,所以拟合过程会调整delta2到允许的最小值(你之前设的是0),让k3尽可能接近k2,以此最小化拟合残差,就出现了两者几乎相等的结果。
避免k2与k3几乎相等的方法
如果你业务上要求k2必须严格大于k3,不能无限接近,只需要给delta1、delta2设置一个大于0的极小下限即可,比如:
# 强制k1 -k2 >= 0.001,k2 -k3 >=0.001,自然不会出现几乎相等的情况 params.add('delta1', value = 1, min = 1e-3) params.add('delta2', value = 1, min = 1e-3)
注意:这个下限设置得越大,你需要为约束付出的拟合精度代价越高,最终得到的拟合残差也会越大。
内容的提问来源于stack exchange,提问作者lsr729
相关产品推荐
相关产品推荐

