diff --git a/CHANGE_LOG.txt b/CHANGE_LOG.txt index c3880e7..48ee2f3 100644 --- a/CHANGE_LOG.txt +++ b/CHANGE_LOG.txt @@ -15,6 +15,7 @@ CLEAN TODO-FILE my_acc.fit(the_data, fit_classifier=False) in which case the_data is to be used for validation purposes. However, the val_split could be set as a fraction indicating only part of the_data must be used for validation, and the rest wasted... it was certainly confusing. + - This change imposes a versioning constrain with qunfold, which now must be >= 0.1.6 - EMQ has been modified, so that the representation function "classify" now only provides posterior probabilities and, if required, these are recalibrated (e.g., by "bcts") during the aggregation function. - A new parameter "on_calib_error" is passed to the constructor, which informs of the policy to follow diff --git a/TODO.txt b/TODO.txt index 8430eea..3c3cbfb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,3 +1,5 @@ +Update READMEs, wiki, & examples for new fit-predict interface + Add the fix suggested by Alexander: For a more general application, I would maybe first stablish a per-class threshold value of plausible prevalence diff --git a/quapy/method/composable.py b/quapy/method/composable.py index 5d40aad..3aacab6 100644 --- a/quapy/method/composable.py +++ b/quapy/method/composable.py @@ -1,13 +1,21 @@ """This module allows the composition of quantification methods from loss functions and feature transformations. This functionality is realized through an integration of the qunfold package: https://github.com/mirkobunse/qunfold.""" -_import_error_message = """qunfold, the back-end of quapy.method.composable, is not properly installed. - +__install_istructions = """ To fix this error, call: pip install --upgrade pip setuptools wheel pip install "jax[cpu]" - pip install "qunfold @ git+https://github.com/mirkobunse/qunfold@v0.1.4" + pip install "qunfold @ git+https://github.com/mirkobunse/qunfold@v0.1.5" """ +__import_error_message = ( + "qunfold, the back-end of quapy.method.composable, is not properly installed." + __install_istructions +) +__old_version_message = ( + "The version of qunfold you have installed is not compatible with current quapy's version, " + "which requires qunfold>=0.1.5. " + __install_istructions +) + +from packaging.version import Version try: import qunfold @@ -51,7 +59,19 @@ try: "GaussianRFFKernelTransformer", ] except ImportError as e: - raise ImportError(_import_error_message) from e + raise ImportError(__import_error_message) from e + + +def check_compatible_qunfold_version(): + try: + version_str = qunfold.__version__ + except AttributeError: + # versions of qunfold <= 0.1.4 did not declare __version__ in the __init__.py but only in the setup.py + version_str = "0.1.4" + + compatible = Version(version_str) >= Version("0.1.5") + return compatible + def ComposableQuantifier(loss, transformer, **kwargs): """A generic quantification / unfolding method that solves a linear system of equations. @@ -99,4 +119,7 @@ def ComposableQuantifier(loss, transformer, **kwargs): >>> ClassTransformer(CVClassifier(LogisticRegression(), 10)) >>> ) """ + if not check_compatible_qunfold_version(): + raise ImportError(__old_version_message) + return QuaPyWrapper(qunfold.GenericMethod(loss, transformer, **kwargs)) diff --git a/quapy/tests/test_methods.py b/quapy/tests/test_methods.py index f2d9cdd..a156d8c 100644 --- a/quapy/tests/test_methods.py +++ b/quapy/tests/test_methods.py @@ -17,6 +17,7 @@ from quapy.method.composable import ( ClassTransformer, HistogramTransformer, CVClassifier, + check_compatible_qunfold_version ) COMPOSABLE_METHODS = [ ComposableQuantifier( # ACC @@ -111,13 +112,18 @@ class TestMethods(unittest.TestCase): self.assertTrue(check_prevalence_vector(estim_prevalences)) def test_composable(self): - for dataset in TestMethods.datasets: - for q in COMPOSABLE_METHODS: - print('testing', q) - q.fit(*dataset.training.Xy) - estim_prevalences = q.predict(dataset.test.X) - print(estim_prevalences) - self.assertTrue(check_prevalence_vector(estim_prevalences)) + from packaging.version import Version + if check_compatible_qunfold_version(): + for dataset in TestMethods.datasets: + for q in COMPOSABLE_METHODS: + print('testing', q) + q.fit(*dataset.training.Xy) + estim_prevalences = q.predict(dataset.test.X) + print(estim_prevalences) + self.assertTrue(check_prevalence_vector(estim_prevalences)) + else: + from quapy.method.composable import __old_version_message + print(__old_version_message) if __name__ == '__main__':