QuaPy/BayesianKDEy/methods.py

169 lines
6.3 KiB
Python

from abc import ABC, abstractmethod
import numpy as np
from sklearn.linear_model import LogisticRegression
from BayesianKDEy._bayeisan_kdey import BayesianKDEy
from BayesianKDEy._bayesian_mapls import BayesianMAPLS
from BayesianKDEy.commons import KDEyCLR, KDEyCLR2
from quapy.method.aggregative import CC, ACC, EMQ, DMy, KDEyML
from quapy.method.base import BaseQuantifier
from quapy.method.confidence import AggregativeBootstrap, BayesianCC
def get_experimental_methods():
#yield BootsCC()
#yield BayACC()
#yield BayEMQ()
#yield BayKDEyGau()
#yield BayKDEyAit()
yield BayKDEyAit2()
# commons
# ------------------------------------------------------------
Cls = LogisticRegression
cls_hyper = {
'classifier__C': np.logspace(-4,4,9),
'classifier__class_weight': ['balanced', None]
}
hdy_hyper = {'nbins': [3, 4, 5, 8, 9, 10, 12, 14, 16, 32], **cls_hyper}
kdey_hyper = {'bandwidth': np.logspace(-3, -1, 10), **cls_hyper}
kdey_hyper_clr = {'bandwidth': np.logspace(-2, 2, 10), **cls_hyper}
def hyper2cls(hyperparams):
return {k.replace('classifier__', ''): v for k, v in hyperparams.items()}
# method descriptor logic
# ------------------------------------------------------------
class MethodDescriptor(ABC):
def __init__(self,
name: str,
surrogate_quantifier: BaseQuantifier,
hyper_parameters: dict,
):
self.name = name
self.surrogate_quantifier_ = surrogate_quantifier
self.hyper_parameters = hyper_parameters
@abstractmethod
def binary_only(self): ...
def surrogate_quantifier(self):
return self.surrogate_quantifier_
def surrogate_quantifier_name(self):
return self.surrogate_quantifier_.__class__.__name__
@abstractmethod
def uncertainty_aware_quantifier(self, hyperparameters): ...
class MulticlassMethodDescriptor(MethodDescriptor):
def binary_only(self):
return False
# specific methods definitions
# ------------------------------------------------------------
# ------------------------------------------------------------
# Bootstrap approaches:
# ------------------------------------------------------------
class BootsCC(MulticlassMethodDescriptor):
def __init__(self):
super().__init__(name='BoCC', surrogate_quantifier=CC(Cls()), hyper_parameters=cls_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
quantifier = CC(Cls()).set_params(**hyperparameters)
return AggregativeBootstrap(quantifier, n_test_samples=1000, random_state=0)
# class BootsACC(MulticlassMethodDescriptor):
# def __init__(self):
# super().__init__(name='BoACC', surrogate_quantifier=ACC(Cls()), hyper_parameters=cls_hyper)
#
# def uncertainty_aware_quantifier(self, hyperparameters):
# quantifier = ACC(Cls()).set_params(**hyperparameters)
# return AggregativeBootstrap(quantifier, n_test_samples=1000, random_state=0)
#
#
# class BootsEMQ(MulticlassMethodDescriptor):
# def __init__(self):
# super().__init__(name='BoEMQ', surrogate_quantifier=EMQ(Cls(), exact_train_prev=False), hyper_parameters=cls_hyper)
#
# def uncertainty_aware_quantifier(self, hyperparameters):
# quantifier = EMQ(Cls(), exact_train_prev=False).set_params(**hyperparameters)
# return AggregativeBootstrap(quantifier, n_test_samples=1000, random_state=0)
# class BootsHDy(MethodDescriptor):
# def __init__(self):
# super().__init__(name='BoHDy', surrogate_quantifier=DMy(Cls()), hyper_parameters=hdy_hyper)
#
# def uncertainty_aware_quantifier(self, hyperparameters):
# quantifier = DMy(Cls()).set_params(**hyperparameters)
# return AggregativeBootstrap(quantifier, n_test_samples=1000, random_state=0)
#
# def binary_only(self):
# return True
# class BootsKDEy(MulticlassMethodDescriptor):
# def __init__(self):
# super().__init__(name='BoKDEy', surrogate_quantifier=KDEyML(Cls()), hyper_parameters=kdey_hyper)
#
# def uncertainty_aware_quantifier(self, hyperparameters):
# quantifier = KDEyML(Cls()).set_params(**hyperparameters)
# return AggregativeBootstrap(quantifier, n_test_samples=1000, random_state=0)
# Bayesian approaches:
# ------------------------------------------------------------
class BayACC(MulticlassMethodDescriptor):
def __init__(self):
super().__init__(name='BaACC!', surrogate_quantifier=ACC(Cls()), hyper_parameters=cls_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
classifier = Cls(**hyper2cls(hyperparameters))
return BayesianCC(classifier, temperature=None, mcmc_seed=0) # is actually a Bayesian variant of ACC
class BayEMQ(MulticlassMethodDescriptor):
def __init__(self):
super().__init__(name='BaEMQ!', surrogate_quantifier=EMQ(Cls(), exact_train_prev=False), hyper_parameters=cls_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
classifier = Cls(**hyper2cls(hyperparameters))
return BayesianMAPLS(classifier, prior='uniform', temperature=None, exact_train_prev=False)
class BayKDEyGau(MulticlassMethodDescriptor):
def __init__(self):
kdey_hyper = {'bandwidth': np.logspace(-3, -1, 10), **cls_hyper}
super().__init__(name='BaKDE-Gau-T!', surrogate_quantifier=KDEyML(Cls()), hyper_parameters=kdey_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
return BayesianKDEy(Cls(), kernel='gaussian', temperature=None, mcmc_seed=0, **hyperparameters)
class BayKDEyAit(MulticlassMethodDescriptor):
def __init__(self):
kdey_hyper = {'bandwidth': np.logspace(-2, 2, 10), **cls_hyper}
super().__init__(name='BaKDE-Ait-T!', surrogate_quantifier=KDEyCLR(Cls()), hyper_parameters=kdey_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
return BayesianKDEy(Cls(), kernel='aitchison', temperature=None, mcmc_seed=0, **hyperparameters)
class BayKDEyAit2(MulticlassMethodDescriptor):
def __init__(self):
kdey_hyper = {'bandwidth': np.linspace(0.05, 2., 10), **cls_hyper}
super().__init__(name='BaKDE-Ait-T!2', surrogate_quantifier=KDEyCLR2(Cls()), hyper_parameters=kdey_hyper)
def uncertainty_aware_quantifier(self, hyperparameters):
return BayesianKDEy(Cls(), kernel='aitchison', temperature=None, mcmc_seed=0, **hyperparameters)