Home > Back-end >  How to make a piecewise linear fit in Python with some constant pieces?
How to make a piecewise linear fit in Python with some constant pieces?

Time:01-15

I'm trying to make a piecewise linear fit consisting of 3 pieces whereof the first and last pieces are constant. As you can see in this figure figure

don't get the expected fit, since the fit doesn't capture the 3 linear pieces clearly visual from the original data points.

I've tried following piecewise linear fit

CodePudding user response:

This i consider a funny non-linear approach that works quite well:

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit


def pwl( x, m, b, a1, a2 ):
    if x < a1:
        out = pwl( a1, m, b, a1, a2 )
    elif x > a2:
        out = pwl( a2, m, b, a1, a2 )
    else:
        out = m * x   b
    return out

def func( x, m, b, a1, a2, p ):
    out = b   np.log(
    1 / ( 1   np.exp( m *( x - a1 ) )**p )
    ) / p - np.log(
    1 / ( 1   np.exp( m * ( x - a2 ) )**p )
    ) / p
    return out


nn = 36

xdata = np.linspace( -5, 19, nn )
ydata = np.fromiter( (pwl( x, -2.1, 11.6, -1.1, 12.7 ) for x in xdata ), float)
ydata  = np.random.normal( size=nn, scale=0.2)

xth = np.linspace( -5, 19, 150 )

popt, cov = curve_fit( func, xdata, ydata, p0=[2, 11, -1, 10, 1])

print( popt )
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )

ax.plot( xdata, ydata, ls='', marker=' ' )
ax.plot( xth, func( xth, 2, 11, -1, 10, 1 ) )
ax.plot( xth, func( xth, *popt ) )


plt.show()

Only the constant offset needs some extra treatment to get the true offset of the linear term.

enter image description here

  •  Tags:  
  • Related