Skip to content

Commit

Permalink
Remove deprecated CK Test validator (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
clonker authored Sep 13, 2022
1 parent 1729ab7 commit 11182ac
Show file tree
Hide file tree
Showing 8 changed files with 10 additions and 193 deletions.
32 changes: 1 addition & 31 deletions deeptime/decomposition/_vamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@

import numpy as np

from ._koopman import CovarianceKoopmanModel, KoopmanObservable
from ._koopman import CovarianceKoopmanModel
from ..base import EstimatorTransformer
from ..basis import Identity
from ..covariance import Covariance, CovarianceModel
from ..numeric import spd_inv_split
from ..util.decorators import deprecated_method
from ..util.types import to_dataset
from ..util.validation import DeprecatedCKValidator


class VAMP(EstimatorTransformer):
Expand Down Expand Up @@ -460,31 +458,3 @@ def fetch_model(self) -> CovarianceKoopmanModel:
self._model = self._decompose(self._covariance_estimator.fetch_model())
self._covariance_estimator = None
return self._model

@deprecated_method("Deprecated in v0.4.1 and will be removed soon, please use model.ck_test.")
def chapman_kolmogorov_validator(self, mlags, test_model: CovarianceKoopmanModel = None,
n_observables=None, observables='phi', statistics='psi'):
r""" Replaced by `deeptime.decomposition.CovarianceKoopmanModel.ck_test`. """
test_model = self.fetch_model() if test_model is None else test_model
assert test_model is not None, "We need a test model via argument or an estimator which was already " \
"fit to data."

def fit_for_lag(data, lagtime):
est = VAMP(lagtime=lagtime, dim=self.dim, var_cutoff=self.var_cutoff, scaling=self.scaling,
epsilon=self.epsilon, observable_transform=self.observable_transform)
return est.fit(data).fetch_model()

if isinstance(observables, str) and observables == 'phi':
observables = test_model.singular_vectors_right[:, :n_observables]
observables_mean_free = True
else:
observables_mean_free = False

if isinstance(statistics, str) and statistics == 'psi':
statistics = test_model.singular_vectors_left[:, :n_observables]
statistics_mean_free = True
else:
statistics_mean_free = False

observable = KoopmanObservable(observables, statistics, observables_mean_free, statistics_mean_free)
return DeprecatedCKValidator(self, fit_for_lag, mlags, observable, test_model)
47 changes: 6 additions & 41 deletions deeptime/markov/hmm/_bayesian_hmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,19 @@
from typing import Optional, Union, List

import numpy as np

from deeptime.markov.tools.analysis import is_connected
from deeptime.markov.tools.estimation import sample_tmatrix, transition_matrix
from deeptime.markov.hmm._hmm_bindings import util as _bd_util

from deeptime.base import Estimator
from deeptime.markov import TransitionCountModel, compute_dtrajs_effective, number_of_states
from deeptime.markov._base import BayesianMSMPosterior
from deeptime.markov._transition_matrix import stationary_distribution
from deeptime.markov.hmm import HiddenMarkovModel
from ._output_model import DiscreteOutputModel
from ._util import observations_in_state, sample_hidden_state_trajectory
from deeptime.markov.msm import MarkovStateModel
from deeptime.markov import TransitionCountModel, compute_dtrajs_effective, number_of_states
from deeptime.markov.hmm._hmm_bindings import util as _bd_util
from deeptime.markov.tools.analysis import is_connected
from deeptime.markov.tools.estimation import sample_tmatrix, transition_matrix
from deeptime.util.types import ensure_dtraj_list

__author__ = 'noe, clonker'

__all__ = [
'BayesianHMMPosterior',
'BayesianHMM',
]

from ...util.decorators import deprecated_method
from ._output_model import DiscreteOutputModel
from ._util import observations_in_state, sample_hidden_state_trajectory

from ...util.platform import handle_progress_bar
from ...util.validation import ck_test
Expand Down Expand Up @@ -651,28 +641,3 @@ def _append_sample(self, models, prior, sample_model):
reversible=self.reversible, count_model=count_model),
output_model=model_copy.output_model, initial_distribution=model_copy.initial_distribution,
hidden_state_trajectories=model_copy.hidden_trajs))

@deprecated_method("Deprecated in v0.4.1 and will be removed soon, please use model.ck_test.")
def chapman_kolmogorov_validator(self, mlags, test_model: BayesianHMMPosterior = None):
r""" Replaced by `deeptime.markov.hmm.BayesianHMMPosterior.ck_test`. """
test_model = self.fetch_model() if test_model is None else test_model
assert test_model is not None, "We need a test model via argument or an estimator which was already" \
"fit to data."

from . import DiscreteOutputModel
assert isinstance(test_model.prior.output_model, DiscreteOutputModel), \
"Can only perform CKTest for discrete output models"

from deeptime.markov._observables import MembershipsObservable
obs = MembershipsObservable(test_model, np.eye(test_model.prior.n_hidden_states))
from deeptime.util.validation import DeprecatedCKValidator

def fit_for_lag(data, lag):
estimator = BayesianHMM.default(dtrajs=data, n_hidden_states=self.initial_hmm.n_hidden_states,
lagtime=lag, n_samples=self.n_samples, stride=self.stride,
initial_distribution_prior=self.initial_distribution_prior,
transition_matrix_prior=self.transition_matrix_prior,
reversible=self.reversible, stationary=self.stationary)
return estimator.fit(data).fetch_model()

return DeprecatedCKValidator(self, fit_for_lag, mlags, obs, test_model)
28 changes: 0 additions & 28 deletions deeptime/markov/hmm/_maximum_likelihood_hmm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from ..msm import MarkovStateModel
from .. import TransitionCountModel, compute_dtrajs_effective
from ._hmm_bindings import util as _util
from ...util.decorators import deprecated_method
from ...util.types import ensure_timeseries_data


Expand Down Expand Up @@ -423,30 +422,3 @@ def _update_model(self, model: _HMMModelStorage, observations: List[np.ndarray],
model.initial_distribution[:] = pi
model.transition_matrix[:] = T
model.output_model.fit(observations, gammas)

@deprecated_method("Deprecated in v0.4.1 and will be removed soon, please use model.ck_test.")
def chapman_kolmogorov_validator(self, mlags, test_model: HiddenMarkovModel = None):
r""" Replaced by `deeptime.markov.hmm.MaximumLikelihoodHMM.ck_test`. """
test_model = self.fetch_model() if test_model is None else test_model
assert test_model is not None, "We need a test model via argument or an estimator which was already" \
"fit to data."
from . import DiscreteOutputModel
assert isinstance(test_model.output_model, DiscreteOutputModel), \
"Can only perform CKTest for discrete output models"

from deeptime.markov._observables import MembershipsObservable
obs = MembershipsObservable(test_model, np.eye(test_model.n_hidden_states))
from deeptime.util.validation import DeprecatedCKValidator

def fit_for_lag(data, lag):
from .init.discrete import metastable_from_data
initial_model = metastable_from_data(data, n_hidden_states=test_model.n_hidden_states, lagtime=lag,
stride=self.stride, reversible=self.reversible,
stationary=self.stationary)
estimator = MaximumLikelihoodHMM(initial_model, lagtime=lag, reversible=self.reversible,
stationary=self.stationary, accuracy=self.accuracy,
maxit=self.maxit, maxit_reversible=self.maxit_reversible)
hmm = estimator.fit(data).fetch_model()
return hmm.submodel_largest(dtrajs=data)

return DeprecatedCKValidator(self, fit_for_lag, mlags, obs, test_model)
27 changes: 2 additions & 25 deletions deeptime/markov/msm/_bayesian_msm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

import numpy as np

from . import MarkovStateModel, MaximumLikelihoodMSM
from .._base import _MSMBaseEstimator, BayesianMSMPosterior
from .._transition_counting import TransitionCountEstimator
from ...base import Estimator
from ...numeric import is_square_matrix
from .._base import _MSMBaseEstimator, BayesianMSMPosterior
from . import MarkovStateModel, MaximumLikelihoodMSM
from ...util.decorators import deprecated_method

__author__ = 'noe, marscher, clonker'

Expand Down Expand Up @@ -353,25 +352,3 @@ def fit_from_counts(self, counts, callback=None, **kw):
sparse=self.sparse, maxiter=self.maxiter, maxerr=self.maxerr
).fit(counts).fetch_model()
return self.fit_from_msm(msm, callback=callback, **kw)

@deprecated_method("Deprecated in v0.4.1 and will be removed soon, please use model.ck_test.")
def chapman_kolmogorov_validator(self, n_metastable_sets: int, mlags, test_model=None):
r""" Replaced by `deeptime.markov.msm.BayesianMSMPosterior.ck_test`. """
test_model = self.fetch_model() if test_model is None else test_model
assert test_model is not None, "We need a test model via argument or an estimator which was already" \
"fit to data."
prior = test_model.prior
assert prior.has_count_model, "The test model needs to have a count model, i.e., be estimated from data."
pcca = prior.pcca(n_metastable_sets)
from deeptime.markov._observables import MembershipsObservable
obs = MembershipsObservable(test_model, pcca)
from deeptime.util.validation import DeprecatedCKValidator

def fit_for_lag(data, lag):
from deeptime.markov import TransitionCountEstimator
counting_mode = test_model.prior.count_model.counting_mode
counts = TransitionCountEstimator(lag, counting_mode).fit(data, n_jobs=1).fetch_model().submodel_largest()
return self.fit(counts).fetch_model()

return DeprecatedCKValidator(self, fit_for_lag, mlags, obs, test_model)

20 changes: 0 additions & 20 deletions deeptime/markov/msm/_maximum_likelihood_msm.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from .._base import _MSMBaseEstimator
from .._transition_counting import TransitionCountModel, TransitionCountEstimator
from ...numeric import is_square_matrix
from ...util.decorators import deprecated_method

log = logging.getLogger(__file__)

Expand Down Expand Up @@ -358,22 +357,3 @@ def fit(self, data, *args, **kw):
raise ValueError("To fit directly from a discrete timeseries, a lagtime must be provided!")
return self.fit_from_discrete_timeseries(data, kw.pop('lagtime', self.lagtime),
kw.pop("count_mode", "sliding"))

@deprecated_method("Deprecated in v0.4.1 and will be removed soon, please use model.ck_test.")
def chapman_kolmogorov_validator(self, n_metastable_sets: int, mlags, test_model=None):
r""" Removed and replaced by `deeptime.markov.msm.MarkovStateModel.ck_test`. """
from deeptime.markov._observables import MembershipsObservable
test_model = self.fetch_model() if test_model is None else test_model
assert test_model is not None, "We need a test model via argument or an estimator which was already" \
"fit to data."
assert test_model.has_count_model, "The test model needs to have a count model, i.e., be estimated from data."
pcca = test_model.pcca(n_metastable_sets)
obs = MembershipsObservable(test_model, pcca)
from deeptime.util.validation import DeprecatedCKValidator

def fit_for_lag(data, lag):
counting_mode = test_model.count_model.counting_mode
counts = TransitionCountEstimator(lag, counting_mode).fit(data).fetch_model().submodel_largest()
return self.fit(counts).fetch_model()

return DeprecatedCKValidator(self, fit_for_lag, mlags, obs, test_model)
25 changes: 1 addition & 24 deletions deeptime/util/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .decorators import plotting_function
from .platform import handle_progress_bar
from ..base import Observable, BayesianModel, Estimator
from ..base import Observable, BayesianModel


def implied_timescales(models, n_its=None):
Expand Down Expand Up @@ -364,26 +364,3 @@ def plot(self, height=2.5, aspect=1., conf: float = 0.95, color=None, grid = Non
from deeptime.plots import plot_ck_test
return plot_ck_test(self, height=height, aspect=aspect, conf=conf, color=color, grid=grid, legend=legend,
xlabel=xlabel, ylabel=ylabel, y01=y01, sharey=sharey, **plot_kwargs)


class DeprecatedCKValidator(Estimator):

def __init__(self, estimator, fit_for_lag, mlags, observable, test_model):
super().__init__()
self.estimator = estimator
self.mlags = mlags
self.fit_for_lag = fit_for_lag
self.observable = observable
self.test_model = test_model

def fit(self, data, **kwargs):
if hasattr(self.test_model, 'prior'):
test_lag = self.test_model.prior.lagtime
else:
test_lag = self.test_model.lagtime
models = []
for factor in range(1, self.mlags):
lagtime = factor * test_lag
models.append(self.fit_for_lag(data, lagtime))
self._model = ck_test(models, observable=self.observable, test_model=self.test_model)
return self
2 changes: 0 additions & 2 deletions tests/decomposition/test_vamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,6 @@ def test_cktest():
models.append(VAMP(lag, dim=1).fit_fetch(traj))
test_model = models[0]
ck_test = test_model.ck_test(models)
# validator = estimator.chapman_kolmogorov_validator(4)
# cktest = validator.fit(traj).fetch_model()
np.testing.assert_almost_equal(ck_test.predictions, ck_test.estimates, decimal=1)


Expand Down
22 changes: 0 additions & 22 deletions tests/plots/test_ck_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,3 @@ def test_sanity_vamp(fractional):
plot_ck_test(models[0].ck_test(models))
else:
plot_ck_test(models[0].ck_test(models))


@pytest.mark.parametrize("hidden", [False, True], ids=lambda x: f"hidden={x}")
@pytest.mark.parametrize("bayesian", [False, True], ids=lambda x: f"bayesian={x}")
def test_sanity_deprecated_msm(hidden, bayesian):
traj = ellipsoids().observations(20000)
dtraj = KMeans(n_clusters=15).fit_transform(traj)
est, _ = estimate_markov_model(1, dtraj, hidden=hidden, bayesian=bayesian, n_hidden=2, return_estimator=True)
with pytest.deprecated_call():
if not hidden:
validator = est.chapman_kolmogorov_validator(2, 5)
else:
validator = est.chapman_kolmogorov_validator(5)

validator.fit_fetch(dtraj)


def test_deprecated_vamp():
with pytest.deprecated_call():
traj = ellipsoids().observations(20000)
validator = VAMP(1, dim=2).fit(traj).chapman_kolmogorov_validator(mlags=10)
validator.fit_fetch(traj)

0 comments on commit 11182ac

Please sign in to comment.