【发布时间】:2018-10-21 16:30:30
【问题描述】:
我正在尝试使用 scipy.optimize 中的 curve_fit 库将梯形拟合到一组时间序列。我用来生成梯形的函数如下:
def trapezoid(x, a, b, c, tau1, tau2):
y = np.zeros(len(x))
c = -np.abs(c)
a = np.abs(a)
y[:int(tau1)] = a*x[:int(tau1)] + b
y[int(tau1):int(tau2)] = a*tau1 + b
y[int(tau2):] = c*(x[int(tau2):]-tau2) + (a*tau1 + b)
return y
其中 a 和 c 是斜率,tau1 和 tau2 标志着平坦阶段的开始和结束。
为了适应,我只使用:
popt, pcov = curve_fit(trapezoid, xdata, ydata, method = 'lm')
在大多数情况下,它都可以正常工作,例如:
但是,我也遇到了一些无法拟合数据的情况,看起来它应该可以正常工作:
这些情况的问题在于它设置的 tau2(平坦阶段的结束)小于 tau1(它的开始)。
谁能提出解决这个问题的方法?是通过施加约束还是以其他方式?
不适合的示例数组:
array([1.2, 1.21, 1.2, 1.19, 1.21, 1.22, 2.47, 2.53, 2.49, 2.39, 2.28, 2.16、2.07、1.99、1.91、1.83、1.74、1.65、1.57、1.5、1.45、1.41、 1.38, 1.35, 1.33, 1.29, 1.24, 1.19, 1.14, 1.11, 1.07, 1.04, 1. , 0.95, 0.91, 0.87, 0.84, 0.8, 0.77, 0.74, 0.72, 0.7, 0.68, 0.66, 0.63, 0.61, 0.59, 0.57, 0.55, 0.52, 0.5, 0.48, 0.45, 0.43, 0.41, 0.39, 0.38, 0.37, 0.37, 0.36, 0.35, 0.34, 0.34, 0.33])
产生:tau1:8.45,tau2:5.99
【问题讨论】:
-
将 tau2 设置为 tau1 和 tau2 的最大值,就完成了
-
由于初始解决方案错误,优化器似乎陷入了局部最小值。您没有为 curve_fit 提供 p0 参数,因此您的梯形参数都初始化为 1。您可能想找到一种方法来正确初始化参数,否则最好使用全局优化器,例如 SciPy 的 differential_evolution。
-
@Glostas,问题是当它由于这个原因而无法适应时,它会分配一个完全错误的 tau1 和 tau2,强加你提到的分配并不能解决问题。理想的情况是能够添加一个强制 tau2>tau1 的约束,但显然使用这个库是不可能的。
-
与其将 tau2 定义为平坦阶段的索引,不如将其定义为其长度,而 tau1 仍标记其开始.
-
@Mr.T 不,这不是假设,只是更新了一个例子
标签: python scipy curve-fitting