分段回归python

时间:2017-09-07 04:36:57

标签: python linear-regression piecewise

我试图在Python中进行分段线性回归,数据看起来像这样,

image

我需要为每个部分设置3行。知道怎么样?我有以下代码,但结果如下所示。任何帮助将不胜感激。

    import numpy as np
    import matplotlib
    import matplotlib.cm as cm
    import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt
    from scipy import optimize

    def piecewise(x,x0,x1,y0,y1,k0,k1,k2):
        return np.piecewise(x , [x <= x0, np.logical_and(x0<x, x< x1),x>x1] , [lambda x:k0*x + y0, lambda x:k1*(x-x0)+y1+k0*x0 lambda x:k2*(x-x1) y0+y1+k0*x0+k1*(x1-x0)])

    x1 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15,16,17,18,19,20,21], dtype=float)
    y1 = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03,145,147,149,151,153,155])
    y1 = np.flip(y1,0)
    x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15,16,17,18,19,20,21], dtype=float)
    y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03,145,147,149,151,153,155])
    y = np.flip(y,0)

    perr_min = np.inf
    p_best = None
    for n in range(100):
        k = np.random.rand(7)*20
        p , e = optimize.curve_fit(piecewise, x1, y1,p0=k)
        perr = np.sum(np.abs(y1-piecewise(x1, *p)))
        if(perr < perr_min):
            perr_min = perr
            p_best = p

    xd = np.linspace(0, 21, 100)
    plt.figure()
    plt.plot(x1, y1, "o")
    y_out = piecewise(xd, *p_best)
    plt.plot(xd, y_out)
    plt.show()

数据合适 image

感谢。

1 个答案:

答案 0 :(得分:2)

一个非常简单的方法(没有迭代,没有初始猜测)可以解决这个问题。

微积分方法来自本文第30页:https://fr.scribd.com/document/380941024/Regression-par-morceaux-Piecewise-Regression-pdf(下面复制)。

enter image description here

下图显示了结果:

enter image description here

拟合函数的等式是:

enter image description here

或等效地:

enter image description here

H 是Heaviside函数。

enter image description here

此外,数值计算的细节如下:

enter image description here