cjekel / piecewise_linear_fit_py

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

Re-constructing Piecewise PWLF #106

Open iiwolf opened 1 year ago

iiwolf commented 1 year ago

Hello, thanks for your hard work on this library, I've found it very useful! Issue #85 may be referencing this issue, but I would like to construct a PWFL piecewise curve from a modeled set of coefficients.

Essentially I'm creating a Kriging model to predict the coefficients and breakpoints required to construct the curve. For example with something simple like poly1d:

# Kriging model predicts coeffs and end time from model inputs <x>
coeffs,  t_end = coeff_model.predict(x)

# Create model
model = np.poly1d(coeffs)

# Construct input time vector and predict y response
t = np.arange(0,t_end,0.1)
y = model(t)

Is there a way to do this with PWFL? Maybe with setting betas and intercepts as mentioned #85? Or is that not available with polynomials? For example, I'll probably try to get something like this to work:

# Kriging model predicts coeffs and end time from model inputs <x>
betas, intercepts,  breaks = coeff_model.predict(x)

# Construct input time vector and predict y response
t = np.arange(0,breaks[-1],0.1)

# Create model with empty y
model = pwlf.PiecewiseLinFit(t, np.empty_like(t), degree=2)
model.beta = betas
model.intercept = intercepts
model.fit_breaks = breaks

y = model(t)

I've been able to successfully do this process with basic non-piecewise polynomial fits and my own PiecewisePolynomial class. But PWLF seems to be more robust so I'd like to use it!

Thanks!

iiwolf commented 1 year ago

It seems to work that way! With this snippet it seems to be working

def create_pwlf_from_coeffs(fit_breaks, beta, slopes):
    model = pwlf.PiecewiseLinFit(None, None, degree=2)
    model.fit_breaks = fit_breaks
    model.beta = beta
    model.slopes = slopes
    return model

I'd still be interested to here you thoughts, as modeling all those variables is more than I'd like. But that might just come with the complexity.

Thanks!

cjekel commented 1 year ago

Good question!

check out https://github.com/cjekel/piecewise_linear_fit_py/issues/13 for model persistence and https://github.com/cjekel/piecewise_linear_fit_py/issues/44 for looking at the individual polynomial equations

Is there a way to do this with PWFL? Maybe with setting betas and intercepts as mentioned https://github.com/cjekel/piecewise_linear_fit_py/issues/85? Or is that not available with polynomials?

Yes you can do that. You just need to be careful about the polynomial expansion. The first (left most) polynomial is independent, the second polynomial would be a combination of the first polynomial. This continues just like it does for piecewise linear models.

It seems to work that way! With this snippet it seems to be working

def create_pwlf_from_coeffs(fit_breaks, beta, slopes):
model = pwlf.PiecewiseLinFit(None, None, degree=2)
model.fit_breaks = fit_breaks
model.beta = beta
model.slopes = slopes
return model

Yup! that will work.

So .beta and .fit_breaks are the only model parameters. You can also expose them in the prediction calls like

y_hat = my_pwlf_new.predict(x, beta=my_prev_beta, breaks=my_prev_breakpoints)

which will set all the correct attributes (at least I think so).

Happy to answer any questions!

Multiple quadratic polynomials seems like you will get a lot of coefficients quickly. Is that an issue for your Kriging model?

Thanks, CJ