连续分段线性拟合法在Python中的实现 [英] Continuous Piecewise-Linear Fit in Python

查看:0
本文介绍了连续分段线性拟合法在Python中的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些短时间序列(可能是30-100个时间点),它们有一个大致的形状:它们从高开始,快速下降,可能在零附近稳定,也可能不稳定在零附近,然后回升。如果它们不平坦,它们看起来就像简单的二次曲线,如果它们平坦,你可能会得到一长串的零。

我正在尝试使用lmfit模块来拟合一条连续的分段线性曲线。我想推断直线在哪里改变了渐变,也就是说,我想知道曲线在哪里"定性"地改变了渐变。一般说来,我想知道梯度何时停止下降,何时又开始增加。我对它有一些问题:

  • lmfit似乎至少需要两个参数,所以我必须传递_
  • 我不确定如何将一个参数约束为大于另一个参数。
  • 我收到could not broadcast input array from shape (something) into shape (something) 错误

以下是一些代码。首先,我的目标函数要最小化。

def piecewiselinear(params, data, _) :

    t1 = params["t1"].value
    t2 = params["t2"].value
    m1 = params["m1"].value
    m2 = params["m2"].value
    m3 = params["m3"].value
    c = params["c"].value

    # Construct continuous, piecewise-linear fit
    model = np.zeros_like(data)
    model[:t1] = c + m1 * np.arange(t1)
    model[t1:t2] = model[t1-1] + m2 * np.arange(t2 - t1)
    model[t2:] = model[t2-1] + m3 * np.arange(len(data) - t2)

    return model - data

然后我打电话,

p = lmfit.Parameters()
p.add("t1", value = len(data)/4, min = 1, max = len(data))
p.add("t2", value = len(data)/4*3, min = 2, max = len(data))
p.add("m1", value = -100., max=0)
p.add("m2", value = 0.)
p.add("m3", value = 20., min = 1.)
p.add("c", min=0, value = 800.)

result = lmfit.minimize(piecewiselinear, p, args = (data, _) )
模型是,在某个时间t1,直线的梯度发生变化,在t2也发生同样的变化。这两个参数以及线段(和一个截距)的坡度都需要推断。

我可以使用MCMC方法完成此操作,但我有太多这样的系列,这将花费太长时间。

部分回溯:

     15     model = np.zeros_like(data)
     16     model[:t1] = c + m1 * np.arange(t1)
---> 17     model[t1:t2] = model[t1-1] + m2 * np.arange(t2-t1)
     18     model[t2:] = model[t2-1] + m3 * np.arange(len(data) - t2)
     19 

ValueError: could not broadcast input array from shape (151) into shape (28)

时间序列的几个示例:

欢迎任何建议。非常感谢。

推荐答案

这是一个相当凶猛的3-pwlin钳工的情节; 将用粗略的代码换取测试用例。

还有几个链接:
Fit-piecewise-linear-data 可能会为您提供一些想法;添加了一些 Dynamic programming
github.com/NickFoubert/simple-segment 具有用于分割例如具有max_error(而不是片数)的ECG的PYTHON, 摘自Keogh等人的一篇不错的论文, An online algorithm for segmenting time series,2001,8页

和一个可能的替代方案:您是否可以将p的幂y ~ x^plog y ~ p log x^2 (将x移至[-1.1]和y1e-6左右)?
这将是可靠快速,并且易于绘制和理解。
应该称一下两端的重量。 因此误差大致是平坦和正常的。
也可以将pp'分别放在左右两半。

这篇关于连续分段线性拟合法在Python中的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆