cjekel / piecewise_linear_fit_py

fit piecewise linear data for a specified number of line segments
MIT License
289 stars 59 forks source link

How to force the fit process to have a fixed Intercept? #103

Open riemanncode opened 1 year ago

riemanncode commented 1 year ago

is it possible to choose the value of the intercept for the first segment? In a simple linear regression this can be done easily, but I don't know how to specify a "fixed intercept" here.

considering your main example, you have the intercept of this fitted data that is b0=5.

import numpy as np
import matplotlib.pyplot as plt
import pwlf

x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
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])

my_pwlf = pwlf.PiecewiseLinFit(x, y)
breaks = my_pwlf.fit(2)
print(breaks)

Can I force the fitting process to have the intercept value equal to 6? Something like..

breaks1 = my_pwlf.fit(2,fixed_b0=6)

That would be helpful. Thank you

cjekel commented 1 year ago

What you can do in the meantime is use constraints x_c and y_c.

It's not the same solution as what you would do to explicitly fix the intercept, because technically the intercept is still a model parameter this way. The constrained least squares fit should figure out how to solve the constrain by fixing the intercept easily. However, this constrained least squares fit is less robust than a method that explicitly fixes the intercept.

import numpy as np
import matplotlib.pyplot as plt
import pwlf
import matplotlib.pyplot as plt

x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
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])

my_pwlf = pwlf.PiecewiseLinFit(x, y)
breaks = my_pwlf.fit(2, x_c=[0.0], y_c=[6.0])
print(breaks)

print(my_pwlf.predict([0.0]))

x_hat = np.linspace(-1.0, 20, 100)
y_hat = my_pwlf.predict(x_hat)

plt.figure()
plt.plot(x_hat, y_hat)
plt.plot([0.0],[6.0], '*k')
plt.show()

image