handling qunfold versioning, and more bug fix

This commit is contained in:
Alejandro Moreo Fernandez 2025-06-15 13:22:24 +02:00
parent 934750ea44
commit 5b7f7d4f70
4 changed files with 43 additions and 11 deletions

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -17,6 +17,7 @@ from quapy.method.composable import (
ClassTransformer,
HistogramTransformer,
CVClassifier,
check_compatible_qunfold_version
)
COMPOSABLE_METHODS = [
ComposableQuantifier( # ACC
@ -111,6 +112,8 @@ class TestMethods(unittest.TestCase):
self.assertTrue(check_prevalence_vector(estim_prevalences))
def test_composable(self):
from packaging.version import Version
if check_compatible_qunfold_version():
for dataset in TestMethods.datasets:
for q in COMPOSABLE_METHODS:
print('testing', q)
@ -118,6 +121,9 @@ class TestMethods(unittest.TestCase):
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__':