Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TICA fit-once transform-many #254

Closed
stefdoerr opened this issue Sep 7, 2022 · 6 comments
Closed

TICA fit-once transform-many #254

stefdoerr opened this issue Sep 7, 2022 · 6 comments

Comments

@stefdoerr
Copy link

Hi, in the past with pyEMMA I was able to fit once with TICA and project on different amount of dimensions after.
Currently if I use

tica = TICA(lagtime=20)
tica.fit(mydata)
tica.set_params(dim=3)
tica.transform(mydata)

after fitting it seems to ignore it and just returns the full dimensions (minus correlated features)
Is there any way to achieve the same using deeptime? Since fitting takes lots of time it's quite useful to be able to test different number of dimensions without re-fitting the whole model.

@clonker
Copy link
Member

clonker commented Sep 7, 2022

Hi, you can obtain the tica model from the tica esimator by

tica_model = TICA(lagtime=10).fit(data).fetch_model()

The model is autonomous from the estimator (so you can view the estimator as kind of a model factory) and possesses a transform method as well as a dim property. Updating its dim, i.e., tica_model.dim = 3, propagates to the transform behavior.

@stefdoerr
Copy link
Author

I see. So the dim does not get passed from TICA to the model. Fine for me, I didn't realize I was able to modify the dims in the produced model, I thought it inherited them from the TICA object.

In [7]: tica = TICA(lagtime=20)

In [8]: datalist = data.dat.tolist()

In [9]: datalist[0].shape
Out[9]: (500, 561)

In [10]: tica.fit(datalist)
Out[10]: 
TICA-140042979864480:dim=None, epsilon=1e-06, lagtime=20,
           observable_transform=<deeptime.basis._monomials.Identity object at 0x7f5e4c48b7f0>,
           scaling='kinetic_map', var_cutoff=None]

In [11]: tica.dim = 3

In [12]: model = tica.fetch_model()

In [13]: model.dim
None

In [14]: model.dim = 3
In [15]: model.transform(datalist[0])
Out[15]: 
array([[ 0.00207281,  0.0065552 , -0.22179741],
       [-0.16369845,  0.09626266, -0.41545123],
       [ 0.11997534,  0.08670353,  0.81057031],
       ...,
       [ 0.59074738, -0.62799219, -0.16474592],
       [ 0.75157073, -0.55068053,  0.02105977],
       [ 0.57698269, -0.50769678, -0.21268016]])

@stefdoerr
Copy link
Author

stefdoerr commented Sep 7, 2022

Oh there is a funny behaviour though once you set var_cutoff
Once you set var_cutoff once it's not possible to go back to projecting by dimensions?

In [27]: tica = TICA(lagtime=20)

In [28]: tica.fit(datalist)
Out[28]: 
TICA-140041037950736:dim=None, epsilon=1e-06, lagtime=20,
           observable_transform=<deeptime.basis._monomials.Identity object at 0x7f5e4c48b7f0>,
           scaling='kinetic_map', var_cutoff=None]

In [29]: model = tica.fetch_model()

In [30]: model.dim = 3

In [31]: model.transform(datalist[0]).shape
Out[31]: (500, 3)

In [36]: model.var_cutoff = 0.85

In [37]: model.transform(datalist[0]).shape
Out[37]: (500, 155)

In [38]: model.var_cutoff = 1

In [39]: model.transform(datalist[0]).shape
Out[39]: (500, 496)

In [40]: model.dim
Out[40]: 2

In [43]: model.var_cutoff = None
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [43], line 1
----> 1 model.var_cutoff = None

File ~/miniconda3/envs/htmd3.9/lib/python3.9/site-packages/deeptime/decomposition/_koopman.py:354, in CovarianceKoopmanModel.var_cutoff(self, value)
    352 @var_cutoff.setter
    353 def var_cutoff(self, value):
--> 354     assert 0 < value <= 1., "Invalid dimension parameter, if it is given in terms of a variance cutoff, " \
    355                             "it can only be in the interval (0, 1]."
    356     self._var_cutoff = value
    357     self._update_output_dimension()

TypeError: '<' not supported between instances of 'int' and 'NoneType'

@stefdoerr stefdoerr reopened this Sep 7, 2022
@stefdoerr
Copy link
Author

stefdoerr commented Sep 7, 2022

I was able to hack around it like this but I'm not sure it's desirable to do it this way. It would probably be better to fix the setter to accept None as a value for var_cutoff

In [45]: model._var_cutoff = None

In [49]: model._update_output_dimension()

In [50]: model.transform(datalist[0]).shape
Out[50]: (500, 3)

@clonker
Copy link
Member

clonker commented Sep 7, 2022

Definitely not desirable and I agree on fixing the setter, thanks!

@clonker
Copy link
Member

clonker commented Sep 7, 2022

Fixed in #255

@clonker clonker closed this as completed Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants