cjekel / piecewise_linear_fit_py

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

AttributeError: 'PiecewiseLinFit' object has no attribute 'beta' #40

Closed tomsilver closed 4 years ago

tomsilver commented 4 years ago

Hi, thanks for the package!

When trying to run the examples here https://jekel.me/piecewise_linear_fit_py/examples.html, I am consistently running into the error AttributeError: 'PiecewiseLinFit' object has no attribute 'beta'. For example, following the 'fit for specified number of line segments' example, I get:

    yHat = my_pwlf.predict(xHat)
  File "/Users/tom/phd/entity_extraction/piecewise_linear_fit_py/pwlf/pwlf.py", line 609, in predict
    y_hat = np.dot(A, self.beta)
AttributeError: 'PiecewiseLinFit' object has no attribute 'beta'

I am using Python 3.5.6. I tried both pip install pwlf and installing from source and got the same issue. Let me know if you need any more info. Thanks!

cjekel commented 4 years ago

Are you sure you are performing a fit before calling predict? All of the fit functions should calculate beta, but if one isn't this would be a big problem. I tried running all of the examples that call predict, and they work on my end.

Does the falling code raise the same error?

import numpy as np
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)
x_hat = np.linspace(x.min(), x.max(), 100)
y_hat = my_pwlf.predict(x_hat)
tomsilver commented 4 years ago

Thanks for the quick reply! That code too raises the same error. I realized the problem though -- I was using an older version of scipy (1.1.0). Upgrading to 1.3.0 resolves the issue for me.

cjekel commented 4 years ago

I'm glad you got it working. That's a very strange issue to have. Please let me know if it comes up again.

cjekel commented 4 years ago

This has come up again in https://github.com/cjekel/piecewise_linear_fit_py/pull/59

I'm unable to reproduce. I've tried with conda and venv to create environments with this older scipy and pwlf works fine on my end. Here is my latest environment attempt:

backcall==0.1.0
cycler==0.10.0
decorator==4.4.1
ipython==7.12.0
ipython-genutils==0.2.0
jedi==0.16.0
kiwisolver==1.1.0
matplotlib==3.1.3
numpy==1.17.4
parso==0.6.0
pexpect==4.8.0
pickleshare==0.7.5
prompt-toolkit==3.0.3
ptyprocess==0.6.0
pwlf==1.1.6
pyDOE==0.3.8
Pygments==2.5.2
pyparsing==2.4.6
PyQt5==5.14.1
PyQt5-sip==12.7.1
python-dateutil==2.8.1
scipy==1.1.0
six==1.14.0
traitlets==4.3.3
wcwidth==0.1.8

There was no syntactical change in scipy from what this library uses, and I think there is something else going on.

It would be useful to see the values for my_pwlf.breaks and my_pwlf.ssr in the above case. If I had to guess, I'd say that scipy.lingl.lstsq is broken in your installation, and always throws linalg.LinAlgError.

Feel free to chime in if you understand what is happening here, or have experienced the same issue.

bezineb5 commented 4 years ago

I have the issue with SciPy 1.1.0. I checked and in my case, my_pwlf.breaks is not defined (AttributeError: 'PiecewiseLinFit' object has no attribute 'breaks') and my_pwlf.ssr == +inf. It works fine with scipy 1.2.0. I'm on MacOS, maybe that the cause: before 1.2.0, SciPy was using Apple Accelerate as LAPACK implementation. They dropped it in 1.2.0 because it had bugs (among other reasons), as described here: https://github.com/scipy/scipy/wiki/Dropping-support-for-Accelerate I'm not sure how to confirm that, as I don't know which OS the initial report was on.

tomsilver commented 4 years ago

Thanks for following up. I can confirm that the initial report was also on MacOS.

cjekel commented 4 years ago

That makes sense with LAPACK issues. Going to release a new version on PyPi shortly. Thanks for everyone's help.

cjekel commented 4 years ago

https://github.com/cjekel/piecewise_linear_fit_py/pull/59