Source code for quapy.data.datasets
-
-[docs]
-def warn(*args, **kwargs):
+
-
import warnings
warnings.warn = warn
import os
@@ -142,9 +140,7 @@
}
-
-[docs]
-def fetch_reviews(dataset_name, tfidf=False, min_df=None, data_home=None, pickle=False) -> Dataset:
+[docs]def fetch_reviews(dataset_name, tfidf=False, min_df=None, data_home=None, pickle=False) -> Dataset:
"""
Loads a Reviews dataset as a Dataset instance, as used in
`Esuli, A., Moreo, A., and Sebastiani, F. "A recurrent neural network for sentiment quantification."
@@ -190,10 +186,7 @@
return data
-
-
-[docs]
-def fetch_twitter(dataset_name, for_model_selection=False, min_df=None, data_home=None, pickle=False) -> Dataset:
+[docs]def fetch_twitter(dataset_name, for_model_selection=False, min_df=None, data_home=None, pickle=False) -> Dataset:
"""
Loads a Twitter dataset as a :class:`quapy.data.base.Dataset` instance, as used in:
`Gao, W., Sebastiani, F.: From classification to quantification in tweet sentiment analysis.
@@ -267,10 +260,7 @@
return data
-
-
-[docs]
-def fetch_UCIBinaryDataset(dataset_name, data_home=None, test_split=0.3, verbose=False) -> Dataset:
+[docs]def fetch_UCIBinaryDataset(dataset_name, data_home=None, test_split=0.3, verbose=False) -> Dataset:
"""
Loads a UCI dataset as an instance of :class:`quapy.data.base.Dataset`, as used in
`Pérez-Gállego, P., Quevedo, J. R., & del Coz, J. J. (2017).
@@ -295,10 +285,7 @@
return Dataset(*data.split_stratified(1 - test_split, random_state=0))
-
-
-[docs]
-def fetch_UCIBinaryLabelledCollection(dataset_name, data_home=None, verbose=False) -> LabelledCollection:
+[docs]def fetch_UCIBinaryLabelledCollection(dataset_name, data_home=None, verbose=False) -> LabelledCollection:
"""
Loads a UCI collection as an instance of :class:`quapy.data.base.LabelledCollection`, as used in
`Pérez-Gállego, P., Quevedo, J. R., & del Coz, J. J. (2017).
@@ -642,10 +629,7 @@
return data
-
-
-[docs]
-def fetch_UCIMulticlassDataset(dataset_name, data_home=None, test_split=0.3, verbose=False) -> Dataset:
+[docs]def fetch_UCIMulticlassDataset(dataset_name, data_home=None, test_split=0.3, verbose=False) -> Dataset:
"""
Loads a UCI multiclass dataset as an instance of :class:`quapy.data.base.Dataset`.
@@ -675,10 +659,7 @@
return Dataset(*data.split_stratified(1 - test_split, random_state=0))
-
-
-[docs]
-def fetch_UCIMulticlassLabelledCollection(dataset_name, data_home=None, verbose=False) -> LabelledCollection:
+[docs]def fetch_UCIMulticlassLabelledCollection(dataset_name, data_home=None, verbose=False) -> LabelledCollection:
"""
Loads a UCI multiclass collection as an instance of :class:`quapy.data.base.LabelledCollection`.
@@ -751,14 +732,11 @@
return data
-
def _df_replace(df, col, repl={'yes': 1, 'no':0}, astype=float):
df[col] = df[col].apply(lambda x:repl[x]).astype(astype, copy=False)
-
-[docs]
-def fetch_lequa2022(task, data_home=None):
+[docs]def fetch_lequa2022(task, data_home=None):
"""
Loads the official datasets provided for the `LeQua <https://lequa2022.github.io/index>`_ competition.
In brief, there are 4 tasks (T1A, T1B, T2A, T2B) having to do with text quantification
@@ -830,10 +808,7 @@
return train, val_gen, test_gen
-
-
-[docs]
-def fetch_IFCB(single_sample_train=True, for_model_selection=False, data_home=None):
+[docs]def fetch_IFCB(single_sample_train=True, for_model_selection=False, data_home=None):
"""
Loads the IFCB dataset for quantification from `Zenodo <https://zenodo.org/records/10036244>`_ (for more
information on this dataset, please follow the zenodo link).
@@ -912,7 +887,6 @@
return train, test_gen
else:
return train_gen, test_gen
-
diff --git a/docs/build/html/_modules/quapy/error.html b/docs/build/html/_modules/quapy/error.html
index 5c1ce33..1613468 100644
--- a/docs/build/html/_modules/quapy/error.html
+++ b/docs/build/html/_modules/quapy/error.html
@@ -1,22 +1,23 @@
-
+
quapy.error — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -77,9 +78,7 @@
import quapy as qp
-
-[docs]
-def from_name(err_name):
+[docs]def from_name(err_name):
"""Gets an error function from its name. E.g., `from_name("mae")`
will return function :meth:`quapy.error.mae`
@@ -91,10 +90,7 @@
return callable_error
-
-
-[docs]
-def f1e(y_true, y_pred):
+[docs]def f1e(y_true, y_pred):
"""F1 error: simply computes the error in terms of macro :math:`F_1`, i.e.,
:math:`1-F_1^M`, where :math:`F_1` is the harmonic mean of precision and recall,
defined as :math:`\\frac{2tp}{2tp+fp+fn}`, with `tp`, `fp`, and `fn` standing
@@ -109,10 +105,7 @@
return 1. - f1_score(y_true, y_pred, average='macro')
-
-
-[docs]
-def acce(y_true, y_pred):
+[docs]def acce(y_true, y_pred):
"""Computes the error in terms of 1-accuracy. The accuracy is computed as
:math:`\\frac{tp+tn}{tp+fp+fn+tn}`, with `tp`, `fp`, `fn`, and `tn` standing
for true positives, false positives, false negatives, and true negatives,
@@ -125,10 +118,7 @@
return 1. - (y_true == y_pred).mean()
-
-
-[docs]
-def mae(prevs, prevs_hat):
+[docs]def mae(prevs, prevs_hat):
"""Computes the mean absolute error (see :meth:`quapy.error.ae`) across the sample pairs.
:param prevs: array-like of shape `(n_samples, n_classes,)` with the true prevalence values
@@ -139,10 +129,7 @@
return ae(prevs, prevs_hat).mean()
-
-
-[docs]
-def ae(prevs, prevs_hat):
+[docs]def ae(prevs, prevs_hat):
"""Computes the absolute error between the two prevalence vectors.
Absolute error between two prevalence vectors :math:`p` and :math:`\\hat{p}` is computed as
:math:`AE(p,\\hat{p})=\\frac{1}{|\\mathcal{Y}|}\\sum_{y\\in \\mathcal{Y}}|\\hat{p}(y)-p(y)|`,
@@ -156,10 +143,7 @@
return abs(prevs_hat - prevs).mean(axis=-1)
-
-
-[docs]
-def nae(prevs, prevs_hat):
+[docs]def nae(prevs, prevs_hat):
"""Computes the normalized absolute error between the two prevalence vectors.
Normalized absolute error between two prevalence vectors :math:`p` and :math:`\\hat{p}` is computed as
:math:`NAE(p,\\hat{p})=\\frac{AE(p,\\hat{p})}{z_{AE}}`,
@@ -174,10 +158,7 @@
return abs(prevs_hat - prevs).sum(axis=-1)/(2*(1-prevs.min(axis=-1)))
-
-
-[docs]
-def mnae(prevs, prevs_hat):
+[docs]def mnae(prevs, prevs_hat):
"""Computes the mean normalized absolute error (see :meth:`quapy.error.nae`) across the sample pairs.
:param prevs: array-like of shape `(n_samples, n_classes,)` with the true prevalence values
@@ -188,10 +169,7 @@
return nae(prevs, prevs_hat).mean()
-
-
-[docs]
-def mse(prevs, prevs_hat):
+[docs]def mse(prevs, prevs_hat):
"""Computes the mean squared error (see :meth:`quapy.error.se`) across the sample pairs.
:param prevs: array-like of shape `(n_samples, n_classes,)` with the
@@ -203,10 +181,7 @@
return se(prevs, prevs_hat).mean()
-
-
-[docs]
-def se(prevs, prevs_hat):
+[docs]def se(prevs, prevs_hat):
"""Computes the squared error between the two prevalence vectors.
Squared error between two prevalence vectors :math:`p` and :math:`\\hat{p}` is computed as
:math:`SE(p,\\hat{p})=\\frac{1}{|\\mathcal{Y}|}\\sum_{y\\in \\mathcal{Y}}(\\hat{p}(y)-p(y))^2`,
@@ -220,10 +195,7 @@
return ((prevs_hat - prevs) ** 2).mean(axis=-1)
-
-
-[docs]
-def mkld(prevs, prevs_hat, eps=None):
+[docs]def mkld(prevs, prevs_hat, eps=None):
"""Computes the mean Kullback-Leibler divergence (see :meth:`quapy.error.kld`) across the
sample pairs. The distributions are smoothed using the `eps` factor
(see :meth:`quapy.error.smooth`).
@@ -241,10 +213,7 @@
return kld(prevs, prevs_hat, eps).mean()
-
-
-[docs]
-def kld(prevs, prevs_hat, eps=None):
+[docs]def kld(prevs, prevs_hat, eps=None):
"""Computes the Kullback-Leibler divergence between the two prevalence distributions.
Kullback-Leibler divergence between two prevalence distributions :math:`p` and :math:`\\hat{p}`
is computed as
@@ -267,10 +236,7 @@
return (smooth_prevs*np.log(smooth_prevs/smooth_prevs_hat)).sum(axis=-1)
-
-
-[docs]
-def mnkld(prevs, prevs_hat, eps=None):
+[docs]def mnkld(prevs, prevs_hat, eps=None):
"""Computes the mean Normalized Kullback-Leibler divergence (see :meth:`quapy.error.nkld`)
across the sample pairs. The distributions are smoothed using the `eps` factor
(see :meth:`quapy.error.smooth`).
@@ -287,10 +253,7 @@
return nkld(prevs, prevs_hat, eps).mean()
-
-
-[docs]
-def nkld(prevs, prevs_hat, eps=None):
+[docs]def nkld(prevs, prevs_hat, eps=None):
"""Computes the Normalized Kullback-Leibler divergence between the two prevalence distributions.
Normalized Kullback-Leibler divergence between two prevalence distributions :math:`p` and
:math:`\\hat{p}` is computed as
@@ -311,10 +274,7 @@
return 2. * ekld / (1 + ekld) - 1.
-
-
-[docs]
-def mrae(prevs, prevs_hat, eps=None):
+[docs]def mrae(prevs, prevs_hat, eps=None):
"""Computes the mean relative absolute error (see :meth:`quapy.error.rae`) across
the sample pairs. The distributions are smoothed using the `eps` factor (see
:meth:`quapy.error.smooth`).
@@ -332,10 +292,7 @@
return rae(prevs, prevs_hat, eps).mean()
-
-
-[docs]
-def rae(prevs, prevs_hat, eps=None):
+[docs]def rae(prevs, prevs_hat, eps=None):
"""Computes the absolute relative error between the two prevalence vectors.
Relative absolute error between two prevalence vectors :math:`p` and :math:`\\hat{p}`
is computed as
@@ -358,10 +315,7 @@
return (abs(prevs - prevs_hat) / prevs).mean(axis=-1)
-
-
-[docs]
-def nrae(prevs, prevs_hat, eps=None):
+[docs]def nrae(prevs, prevs_hat, eps=None):
"""Computes the normalized absolute relative error between the two prevalence vectors.
Relative absolute error between two prevalence vectors :math:`p` and :math:`\\hat{p}`
is computed as
@@ -386,10 +340,7 @@
return (abs(prevs - prevs_hat) / prevs).sum(axis=-1)/(prevs.shape[-1]-1+(1-min_p)/min_p)
-
-
-[docs]
-def mnrae(prevs, prevs_hat, eps=None):
+[docs]def mnrae(prevs, prevs_hat, eps=None):
"""Computes the mean normalized relative absolute error (see :meth:`quapy.error.nrae`) across
the sample pairs. The distributions are smoothed using the `eps` factor (see
:meth:`quapy.error.smooth`).
@@ -407,10 +358,7 @@
return nrae(prevs, prevs_hat, eps).mean()
-
-
-[docs]
-def smooth(prevs, eps):
+[docs]def smooth(prevs, eps):
""" Smooths a prevalence distribution with :math:`\\epsilon` (`eps`) as:
:math:`\\underline{p}(y)=\\frac{\\epsilon+p(y)}{\\epsilon|\\mathcal{Y}|+
\\displaystyle\\sum_{y\\in \\mathcal{Y}}p(y)}`
@@ -423,7 +371,6 @@
return (prevs + eps) / (eps * n_classes + 1)
-
def __check_eps(eps=None):
if eps is None:
sample_size = qp.environ['SAMPLE_SIZE']
diff --git a/docs/build/html/_modules/quapy/evaluation.html b/docs/build/html/_modules/quapy/evaluation.html
index 2208550..56d34a5 100644
--- a/docs/build/html/_modules/quapy/evaluation.html
+++ b/docs/build/html/_modules/quapy/evaluation.html
@@ -1,22 +1,23 @@
-
+
quapy.evaluation — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -79,9 +80,7 @@
import pandas as pd
-
-[docs]
-def prediction(
+[docs]def prediction(
model: BaseQuantifier,
protocol: AbstractProtocol,
aggr_speedup: Union[str, bool] = 'auto',
@@ -140,7 +139,6 @@
return __prediction_helper(model.quantify, protocol, verbose)
-
def __prediction_helper(quantification_fn, protocol: AbstractProtocol, verbose=False):
true_prevs, estim_prevs = [], []
for sample_instances, sample_prev in tqdm(protocol(), total=protocol.total(), desc='predicting') if verbose else protocol():
@@ -153,9 +151,7 @@
return true_prevs, estim_prevs
-
-[docs]
-def evaluation_report(model: BaseQuantifier,
+[docs]def evaluation_report(model: BaseQuantifier,
protocol: AbstractProtocol,
error_metrics: Iterable[Union[str,Callable]] = 'mae',
aggr_speedup: Union[str, bool] = 'auto',
@@ -186,7 +182,6 @@
return _prevalence_report(true_prevs, estim_prevs, error_metrics)
-
def _prevalence_report(true_prevs, estim_prevs, error_metrics: Iterable[Union[str, Callable]] = 'mae'):
if isinstance(error_metrics, str):
@@ -208,9 +203,7 @@
return df
-
-[docs]
-def evaluate(
+[docs]def evaluate(
model: BaseQuantifier,
protocol: AbstractProtocol,
error_metric: Union[str, Callable],
@@ -242,10 +235,7 @@
return error_metric(true_prevs, estim_prevs)
-
-
-[docs]
-def evaluate_on_samples(
+[docs]def evaluate_on_samples(
model: BaseQuantifier,
samples: Iterable[qp.data.LabelledCollection],
error_metric: Union[str, Callable],
@@ -269,7 +259,6 @@
-
diff --git a/docs/build/html/_modules/quapy/functional.html b/docs/build/html/_modules/quapy/functional.html
index 1d41ac8..1b02248 100644
--- a/docs/build/html/_modules/quapy/functional.html
+++ b/docs/build/html/_modules/quapy/functional.html
@@ -1,22 +1,23 @@
-
+
quapy.functional — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -78,9 +79,7 @@
import numpy as np
-
-[docs]
-def prevalence_linspace(n_prevalences=21, repeats=1, smooth_limits_epsilon=0.01):
+[docs]def prevalence_linspace(n_prevalences=21, repeats=1, smooth_limits_epsilon=0.01):
"""
Produces an array of uniformly separated values of prevalence.
By default, produces an array of 21 prevalence values, with
@@ -102,10 +101,7 @@
return p
-
-
-[docs]
-def prevalence_from_labels(labels, classes):
+[docs]def prevalence_from_labels(labels, classes):
"""
Computed the prevalence values from a vector of labels.
@@ -123,10 +119,7 @@
return prevalences
-
-
-[docs]
-def prevalence_from_probabilities(posteriors, binarize: bool = False):
+[docs]def prevalence_from_probabilities(posteriors, binarize: bool = False):
"""
Returns a vector of prevalence values from a matrix of posterior probabilities.
@@ -146,10 +139,7 @@
return prevalences
-
-
-[docs]
-def as_binary_prevalence(positive_prevalence: Union[float, np.ndarray], clip_if_necessary=False):
+[docs]def as_binary_prevalence(positive_prevalence: Union[float, np.ndarray], clip_if_necessary=False):
"""
Helper that, given a float representing the prevalence for the positive class, returns a np.ndarray of two
values representing a binary distribution.
@@ -167,10 +157,7 @@
-
-
-[docs]
-def HellingerDistance(P, Q) -> float:
+[docs]def HellingerDistance(P, Q) -> float:
"""
Computes the Hellingher Distance (HD) between (discretized) distributions `P` and `Q`.
The HD for two discrete distributions of `k` bins is defined as:
@@ -185,10 +172,7 @@
return np.sqrt(np.sum((np.sqrt(P) - np.sqrt(Q))**2))
-
-
-[docs]
-def TopsoeDistance(P, Q, epsilon=1e-20):
+[docs]def TopsoeDistance(P, Q, epsilon=1e-20):
"""
Topsoe distance between two (discretized) distributions `P` and `Q`.
The Topsoe distance for two discrete distributions of `k` bins is defined as:
@@ -202,12 +186,9 @@
:return: float
"""
return np.sum(P*np.log((2*P+epsilon)/(P+Q+epsilon)) + Q*np.log((2*Q+epsilon)/(P+Q+epsilon)))
-
-
-[docs]
-def uniform_prevalence_sampling(n_classes, size=1):
+[docs]def uniform_prevalence_sampling(n_classes, size=1):
"""
Implements the `Kraemer algorithm <http://www.cs.cmu.edu/~nasmith/papers/smith+tromble.tr04.pdf>`_
for sampling uniformly at random from the unit simplex. This implementation is adapted from this
@@ -233,13 +214,10 @@
return u
-
uniform_simplex_sampling = uniform_prevalence_sampling
-
-[docs]
-def strprev(prevalences, prec=3):
+[docs]def strprev(prevalences, prec=3):
"""
Returns a string representation for a prevalence vector. E.g.,
@@ -253,10 +231,7 @@
return '['+ ', '.join([f'{p:.{prec}f}' for p in prevalences]) + ']'
-
-
-[docs]
-def adjusted_quantification(prevalence_estim, tpr, fpr, clip=True):
+[docs]def adjusted_quantification(prevalence_estim, tpr, fpr, clip=True):
"""
Implements the adjustment of ACC and PACC for the binary case. The adjustment for a prevalence estimate of the
positive class `p` comes down to computing:
@@ -280,10 +255,7 @@
return adjusted
-
-
-[docs]
-def normalize_prevalence(prevalences):
+[docs]def normalize_prevalence(prevalences):
"""
Normalize a vector or matrix of prevalence values. The normalization consists of applying a L1 normalization in
cases in which the prevalence values are not all-zeros, and to convert the prevalence values into `1/n_classes` in
@@ -305,7 +277,6 @@
return prevalences
-
def __num_prevalence_combinations_depr(n_prevpoints:int, n_classes:int, n_repeats:int=1):
"""
Computes the number of prevalence combinations in the n_classes-dimensional simplex if `nprevpoints` equally distant
@@ -330,9 +301,7 @@
return __f(n_classes, n_prevpoints) * n_repeats
-
-[docs]
-def num_prevalence_combinations(n_prevpoints:int, n_classes:int, n_repeats:int=1):
+[docs]def num_prevalence_combinations(n_prevpoints:int, n_classes:int, n_repeats:int=1):
"""
Computes the number of valid prevalence combinations in the n_classes-dimensional simplex if `n_prevpoints` equally
distant prevalence values are generated and `n_repeats` repetitions are requested.
@@ -357,10 +326,7 @@
return int(scipy.special.binom(N + C - 1, C - 1) * r)
-
-
-[docs]
-def get_nprevpoints_approximation(combinations_budget:int, n_classes:int, n_repeats:int=1):
+[docs]def get_nprevpoints_approximation(combinations_budget:int, n_classes:int, n_repeats:int=1):
"""
Searches for the largest number of (equidistant) prevalence points to define for each of the `n_classes` classes so
that the number of valid prevalence values generated as combinations of prevalence points (points in a
@@ -381,10 +347,7 @@
n_prevpoints += 1
-
-
-[docs]
-def check_prevalence_vector(p, raise_exception=False, toleranze=1e-08):
+[docs]def check_prevalence_vector(p, raise_exception=False, toleranze=1e-08):
"""
Checks that p is a valid prevalence vector, i.e., that it contains values in [0,1] and that the values sum up to 1.
@@ -407,10 +370,7 @@
return True
-
-
-[docs]
-def get_divergence(divergence: Union[str, Callable]):
+[docs]def get_divergence(divergence: Union[str, Callable]):
if isinstance(divergence, str):
if divergence=='HD':
return HellingerDistance
@@ -424,10 +384,7 @@
raise ValueError(f'argument "divergence" not understood; use a str or a callable function')
-
-
-[docs]
-def argmin_prevalence(loss, n_classes, method='optim_minimize'):
+[docs]def argmin_prevalence(loss, n_classes, method='optim_minimize'):
if method == 'optim_minimize':
return optim_minimize(loss, n_classes)
elif method == 'linear_search':
@@ -438,10 +395,7 @@
raise NotImplementedError()
-
-
-[docs]
-def optim_minimize(loss, n_classes):
+[docs]def optim_minimize(loss, n_classes):
"""
Searches for the optimal prevalence values, i.e., an `n_classes`-dimensional vector of the (`n_classes`-1)-simplex
that yields the smallest lost. This optimization is carried out by means of a constrained search using scipy's
@@ -463,10 +417,7 @@
return r.x
-
-
-[docs]
-def linear_search(loss, n_classes):
+[docs]def linear_search(loss, n_classes):
"""
Performs a linear search for the best prevalence value in binary problems. The search is carried out by exploring
the range [0,1] stepping by 0.01. This search is inefficient, and is added only for completeness (some of the
@@ -485,7 +436,6 @@
prev_selected, min_score = prev, score
return np.asarray([1 - prev_selected, prev_selected])
-
diff --git a/docs/build/html/_modules/quapy/method/_kdey.html b/docs/build/html/_modules/quapy/method/_kdey.html
index 198113f..4e96e56 100644
--- a/docs/build/html/_modules/quapy/method/_kdey.html
+++ b/docs/build/html/_modules/quapy/method/_kdey.html
@@ -1,22 +1,23 @@
-
+
quapy.method._kdey — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -83,9 +84,7 @@
from sklearn.metrics.pairwise import rbf_kernel
-
-[docs]
-class KDEBase:
+[docs]class KDEBase:
"""
Common ancestor for KDE-based methods. Implements some common routines.
"""
@@ -105,9 +104,7 @@
if isinstance(bandwidth, float):
assert 0 < bandwidth < 1, "the bandwith for KDEy should be in (0,1), since this method models the unit simplex"
-
-[docs]
- def get_kde_function(self, X, bandwidth):
+[docs] def get_kde_function(self, X, bandwidth):
"""
Wraps the KDE function from scikit-learn.
@@ -117,10 +114,7 @@
"""
return KernelDensity(bandwidth=bandwidth).fit(X)
-
-
-[docs]
- def pdf(self, kde, X):
+[docs] def pdf(self, kde, X):
"""
Wraps the density evalution of scikit-learn's KDE. Scikit-learn returns log-scores (s), so this
function returns :math:`e^{s}`
@@ -131,10 +125,7 @@
"""
return np.exp(kde.score_samples(X))
-
-
-[docs]
- def get_mixture_components(self, X, y, n_classes, bandwidth):
+[docs] def get_mixture_components(self, X, y, n_classes, bandwidth):
"""
Returns an array containing the mixture components, i.e., the KDE functions for each class.
@@ -144,15 +135,11 @@
:param bandwidth: float, the bandwidth of the kernel
:return: a list of KernelDensity objects, each fitted with the corresponding class-specific covariates
"""
- return [self.get_kde_function(X[y == cat], bandwidth) for cat in range(n_classes)]
-
+ return [self.get_kde_function(X[y == cat], bandwidth) for cat in range(n_classes)]
-
-
-[docs]
-class KDEyML(AggregativeSoftQuantifier, KDEBase):
+[docs]class KDEyML(AggregativeSoftQuantifier, KDEBase):
"""
Kernel Density Estimation model for quantification (KDEy) relying on the Kullback-Leibler divergence (KLD) as
the divergence measure to be minimized. This method was first proposed in the paper
@@ -199,16 +186,11 @@
self.n_jobs = n_jobs
self.random_state=random_state
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
self.mix_densities = self.get_mixture_components(*classif_predictions.Xy, data.n_classes, self.bandwidth)
return self
-
-
-[docs]
- def aggregate(self, posteriors: np.ndarray):
+[docs] def aggregate(self, posteriors: np.ndarray):
"""
Searches for the mixture model parameter (the sought prevalence values) that maximizes the likelihood
of the data (i.e., that minimizes the negative log-likelihood)
@@ -226,14 +208,10 @@
test_loglikelihood = np.log(test_mixture_likelihood + epsilon)
return -np.sum(test_loglikelihood)
- return F.optim_minimize(neg_loglikelihood, n_classes)
-
+ return F.optim_minimize(neg_loglikelihood, n_classes)
-
-
-[docs]
-class KDEyHD(AggregativeSoftQuantifier, KDEBase):
+[docs]class KDEyHD(AggregativeSoftQuantifier, KDEBase):
"""
Kernel Density Estimation model for quantification (KDEy) relying on the squared Hellinger Disntace (HD) as
the divergence measure to be minimized. This method was first proposed in the paper
@@ -290,9 +268,7 @@
self.random_state=random_state
self.montecarlo_trials = montecarlo_trials
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
self.mix_densities = self.get_mixture_components(*classif_predictions.Xy, data.n_classes, self.bandwidth)
N = self.montecarlo_trials
@@ -304,10 +280,7 @@
return self
-
-
-[docs]
- def aggregate(self, posteriors: np.ndarray):
+[docs] def aggregate(self, posteriors: np.ndarray):
# we retain all n*N examples (sampled from a mixture with uniform parameter), and then
# apply importance sampling (IS). In this version we compute D(p_alpha||q) with IS
n_classes = len(self.mix_densities)
@@ -336,14 +309,10 @@
ps_div_qs = prev @ fracs
return np.mean( f(ps_div_qs) * iw )
- return F.optim_minimize(divergence, n_classes)
-
+ return F.optim_minimize(divergence, n_classes)
-
-
-[docs]
-class KDEyCS(AggregativeSoftQuantifier):
+[docs]class KDEyCS(AggregativeSoftQuantifier):
"""
Kernel Density Estimation model for quantification (KDEy) relying on the Cauchy-Schwarz divergence (CS) as
the divergence measure to be minimized. This method was first proposed in the paper
@@ -387,9 +356,7 @@
self.bandwidth = bandwidth
self.n_jobs = n_jobs
-
-[docs]
- def gram_matrix_mix_sum(self, X, Y=None):
+[docs] def gram_matrix_mix_sum(self, X, Y=None):
# this adapts the output of the rbf_kernel function (pairwise evaluations of Gaussian kernels k(x,y))
# to contain pairwise evaluations of N(x|mu,Sigma1+Sigma2) with mu=y and Sigma1 and Sigma2 are
# two "scalar matrices" (h^2)*I each, so Sigma1+Sigma2 has scalar 2(h^2) (h is the bandwidth)
@@ -401,10 +368,7 @@
gram = norm_factor * rbf_kernel(X, Y, gamma=gamma)
return gram.sum()
-
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
P, y = classif_predictions.Xy
n = data.n_classes
@@ -435,10 +399,7 @@
return self
-
-
-[docs]
- def aggregate(self, posteriors: np.ndarray):
+[docs] def aggregate(self, posteriors: np.ndarray):
Ptr = self.Ptr
Pte = posteriors
y = self.ytr
@@ -467,9 +428,7 @@
partB = 0.5 * np.log(alpha_ratio @ tr_tr_sums @ alpha_ratio)
return partA + partB #+ partC
- return F.optim_minimize(divergence, n)
-
-
+ return F.optim_minimize(divergence, n)
diff --git a/docs/build/html/_modules/quapy/method/_neural.html b/docs/build/html/_modules/quapy/method/_neural.html
index a4f6a27..706a7cc 100644
--- a/docs/build/html/_modules/quapy/method/_neural.html
+++ b/docs/build/html/_modules/quapy/method/_neural.html
@@ -1,22 +1,23 @@
-
+
quapy.method._neural — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -84,9 +85,7 @@
from tqdm import tqdm
-
-[docs]
-class QuaNetTrainer(BaseQuantifier):
+[docs]class QuaNetTrainer(BaseQuantifier):
"""
Implementation of `QuaNet <https://dl.acm.org/doi/abs/10.1145/3269206.3269287>`_, a neural network for
quantification. This implementation uses `PyTorch <https://pytorch.org/>`_ and can take advantage of GPU
@@ -185,9 +184,7 @@
self.__check_params_colision(self.quanet_params, self.classifier.get_params())
self._classes_ = None
-
-[docs]
- def fit(self, data: LabelledCollection, fit_classifier=True):
+[docs] def fit(self, data: LabelledCollection, fit_classifier=True):
"""
Trains QuaNet.
@@ -266,7 +263,6 @@
return self
-
def _get_aggregative_estims(self, posteriors):
label_predictions = np.argmax(posteriors, axis=-1)
prevs_estim = []
@@ -278,9 +274,7 @@
return prevs_estim
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
posteriors = self.classifier.predict_proba(instances)
embeddings = self.classifier.transform(instances)
quant_estims = self._get_aggregative_estims(posteriors)
@@ -292,7 +286,6 @@
prevalence = prevalence.numpy().flatten()
return prevalence
-
def _epoch(self, data: LabelledCollection, posteriors, iterations, epoch, early_stop, train):
mse_loss = MSELoss()
@@ -343,17 +336,12 @@
f'val-mseloss={self.status["va-loss"]:.5f} val-maeloss={self.status["va-mae"]:.5f} '
f'patience={early_stop.patience}/{early_stop.PATIENCE_LIMIT}')
-
-[docs]
- def get_params(self, deep=True):
+[docs] def get_params(self, deep=True):
classifier_params = self.classifier.get_params()
classifier_params = {'classifier__'+k:v for k,v in classifier_params.items()}
return {**classifier_params, **self.quanet_params}
-
-
-[docs]
- def set_params(self, **parameters):
+[docs] def set_params(self, **parameters):
learner_params = {}
for key, val in parameters.items():
if key in self.quanet_params:
@@ -364,7 +352,6 @@
raise ValueError('unknown parameter ', key)
self.classifier.set_params(**learner_params)
-
def __check_params_colision(self, quanet_params, learner_params):
quanet_keys = set(quanet_params.keys())
learner_keys = set(learner_params.keys())
@@ -373,34 +360,25 @@
raise ValueError(f'the use of parameters {intersection} is ambiguous sine those can refer to '
f'the parameters of QuaNet or the learner {self.classifier.__class__.__name__}')
-
-[docs]
- def clean_checkpoint(self):
+
-
-
-[docs]
- def clean_checkpoint_dir(self):
+[docs] def clean_checkpoint_dir(self):
"""
Removes anything contained in the checkpoint directory
"""
import shutil
shutil.rmtree(self.checkpointdir, ignore_errors=True)
-
@property
def classes_(self):
return self._classes_
-
-
-[docs]
-def mae_loss(output, target):
+[docs]def mae_loss(output, target):
"""
Torch-like wrapper for the Mean Absolute Error
@@ -411,10 +389,7 @@
return torch.mean(torch.abs(output - target))
-
-
-[docs]
-class QuaNetModule(torch.nn.Module):
+[docs]class QuaNetModule(torch.nn.Module):
"""
Implements the `QuaNet <https://dl.acm.org/doi/abs/10.1145/3269206.3269287>`_ forward pass.
See :class:`QuaNetTrainer` for training QuaNet.
@@ -477,9 +452,7 @@
var_hidden, var_cell = var_hidden.cuda(), var_cell.cuda()
return var_hidden, var_cell
-
-[docs]
- def forward(self, doc_embeddings, doc_posteriors, statistics):
+[docs] def forward(self, doc_embeddings, doc_posteriors, statistics):
device = self.device
doc_embeddings = torch.as_tensor(doc_embeddings, dtype=torch.float, device=device)
doc_posteriors = torch.as_tensor(doc_posteriors, dtype=torch.float, device=device)
@@ -509,9 +482,7 @@
logits = self.output(abstracted).view(1, -1)
prevalence = torch.softmax(logits, -1)
- return prevalence
-
-
+ return prevalence
diff --git a/docs/build/html/_modules/quapy/method/_threshold_optim.html b/docs/build/html/_modules/quapy/method/_threshold_optim.html
index 0aa215b..486aa61 100644
--- a/docs/build/html/_modules/quapy/method/_threshold_optim.html
+++ b/docs/build/html/_modules/quapy/method/_threshold_optim.html
@@ -1,22 +1,23 @@
-
+
quapy.method._threshold_optim — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -80,9 +81,7 @@
from quapy.method.aggregative import BinaryAggregativeQuantifier
-
-[docs]
-class ThresholdOptimization(BinaryAggregativeQuantifier):
+[docs]class ThresholdOptimization(BinaryAggregativeQuantifier):
"""
Abstract class of Threshold Optimization variants for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -106,9 +105,7 @@
self.val_split = val_split
self.n_jobs = qp._get_njobs(n_jobs)
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def condition(self, tpr, fpr) -> float:
"""
Implements the criterion according to which the threshold should be selected.
@@ -120,10 +117,7 @@
"""
...
-
-
-[docs]
- def discard(self, tpr, fpr) -> bool:
+[docs] def discard(self, tpr, fpr) -> bool:
"""
Indicates whether a combination of tpr and fpr should be discarded
@@ -134,7 +128,6 @@
return (tpr - fpr) == 0
-
def _eval_candidate_thresholds(self, decision_scores, y):
"""
Seeks for the best `tpr` and `fpr` according to the score obtained at different
@@ -170,9 +163,7 @@
return candidates
-
-[docs]
- def aggregate_with_threshold(self, classif_predictions, tprs, fprs, thresholds):
+[docs] def aggregate_with_threshold(self, classif_predictions, tprs, fprs, thresholds):
# This function performs the adjusted count for given tpr, fpr, and threshold.
# Note that, due to broadcasting, tprs, fprs, and thresholds could be arrays of length > 1
prevs_estims = np.mean(classif_predictions[:, None] >= thresholds, axis=0)
@@ -180,7 +171,6 @@
prevs_estims = F.as_binary_prevalence(prevs_estims, clip_if_necessary=True)
return prevs_estims.squeeze()
-
def _compute_table(self, y, y_):
TP = np.logical_and(y == y_, y == self.pos_label).sum()
FP = np.logical_and(y != y_, y == self.neg_label).sum()
@@ -198,27 +188,18 @@
return 0
return FP / (FP + TN)
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
decision_scores, y = classif_predictions.Xy
# the standard behavior is to keep the best threshold only
self.tpr, self.fpr, self.threshold = self._eval_candidate_thresholds(decision_scores, y)[0]
return self
-
-
-[docs]
- def aggregate(self, classif_predictions: np.ndarray):
+[docs] def aggregate(self, classif_predictions: np.ndarray):
# the standard behavior is to compute the adjusted count using the best threshold found
- return self.aggregate_with_threshold(classif_predictions, self.tpr, self.fpr, self.threshold)
-
+ return self.aggregate_with_threshold(classif_predictions, self.tpr, self.fpr, self.threshold)
-
-
-[docs]
-class T50(ThresholdOptimization):
+[docs]class T50(ThresholdOptimization):
"""
Threshold Optimization variant for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -238,17 +219,11 @@
def __init__(self, classifier: BaseEstimator, val_split=5):
super().__init__(classifier, val_split)
-
-
+
-
-
-[docs]
-class MAX(ThresholdOptimization):
+[docs]class MAX(ThresholdOptimization):
"""
Threshold Optimization variant for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -268,18 +243,12 @@
def __init__(self, classifier: BaseEstimator, val_split=5):
super().__init__(classifier, val_split)
-
-[docs]
- def condition(self, tpr, fpr) -> float:
+[docs] def condition(self, tpr, fpr) -> float:
# MAX strives to maximize (tpr - fpr), which is equivalent to minimize (fpr - tpr)
- return (fpr - tpr)
-
+ return (fpr - tpr)
-
-
-[docs]
-class X(ThresholdOptimization):
+[docs]class X(ThresholdOptimization):
"""
Threshold Optimization variant for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -299,17 +268,11 @@
def __init__(self, classifier: BaseEstimator, val_split=5):
super().__init__(classifier, val_split)
-
-
+
-
-
-[docs]
-class MS(ThresholdOptimization):
+[docs]class MS(ThresholdOptimization):
"""
Median Sweep. Threshold Optimization variant for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -328,15 +291,10 @@
def __init__(self, classifier: BaseEstimator, val_split=5):
super().__init__(classifier, val_split)
-
-[docs]
- def condition(self, tpr, fpr) -> float:
+
-
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
decision_scores, y = classif_predictions.Xy
# keeps all candidates
tprs_fprs_thresholds = self._eval_candidate_thresholds(decision_scores, y)
@@ -345,21 +303,14 @@
self.thresholds = tprs_fprs_thresholds[:, 2]
return self
-
-
-[docs]
- def aggregate(self, classif_predictions: np.ndarray):
+[docs] def aggregate(self, classif_predictions: np.ndarray):
prevalences = self.aggregate_with_threshold(classif_predictions, self.tprs, self.fprs, self.thresholds)
if prevalences.ndim==2:
prevalences = np.median(prevalences, axis=0)
- return prevalences
-
+ return prevalences
-
-
-[docs]
-class MS2(MS):
+[docs]class MS2(MS):
"""
Median Sweep 2. Threshold Optimization variant for :class:`ACC` as proposed by
`Forman 2006 <https://dl.acm.org/doi/abs/10.1145/1150402.1150423>`_ and
@@ -379,12 +330,8 @@
def __init__(self, classifier: BaseEstimator, val_split=5):
super().__init__(classifier, val_split)
-
-
-
+
diff --git a/docs/build/html/_modules/quapy/method/aggregative.html b/docs/build/html/_modules/quapy/method/aggregative.html
index f34498e..8311baa 100644
--- a/docs/build/html/_modules/quapy/method/aggregative.html
+++ b/docs/build/html/_modules/quapy/method/aggregative.html
@@ -1,22 +1,23 @@
-
+
quapy.method.aggregative — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -93,9 +94,7 @@
# Abstract classes
# ------------------------------------
-
-[docs]
-class AggregativeQuantifier(BaseQuantifier, ABC):
+[docs]class AggregativeQuantifier(BaseQuantifier, ABC):
"""
Abstract class for quantification methods that base their estimations on the aggregation of classification
results. Aggregative quantifiers implement a pipeline that consists of generating classification predictions
@@ -147,9 +146,7 @@
empty_class_names = data.classes_[empty_classes]
raise ValueError(f'classes {empty_class_names} have no training examples')
-
-[docs]
- def fit(self, data: LabelledCollection, fit_classifier=True, val_split=None):
+[docs] def fit(self, data: LabelledCollection, fit_classifier=True, val_split=None):
"""
Trains the aggregative quantifier. This comes down to training a classifier and an aggregation function.
@@ -163,10 +160,7 @@
self.aggregation_fit(classif_predictions, data)
return self
-
-
-[docs]
- def classifier_fit_predict(self, data: LabelledCollection, fit_classifier=True, predict_on=None):
+[docs] def classifier_fit_predict(self, data: LabelledCollection, fit_classifier=True, predict_on=None):
"""
Trains the classifier if requested (`fit_classifier=True`) and generate the necessary predictions to
train the aggregation function.
@@ -236,10 +230,7 @@
return predictions
-
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Trains the aggregation function.
@@ -250,7 +241,6 @@
"""
...
-
@property
def classifier(self):
"""
@@ -269,9 +259,7 @@
"""
self.classifier_ = classifier
-
-[docs]
- def classify(self, instances):
+[docs] def classify(self, instances):
"""
Provides the label predictions for the given instances. The predictions should respect the format expected by
:meth:`aggregate`, e.g., posterior probabilities for probabilistic quantifiers, or crisp predictions for
@@ -282,7 +270,6 @@
"""
return getattr(self.classifier, self._classifier_method())(instances)
-
def _classifier_method(self):
"""
Name of the method that must be used for issuing label predictions. The default one is "decision_function".
@@ -301,9 +288,7 @@
assert hasattr(self.classifier, self._classifier_method()), \
f"the method does not implement the required {self._classifier_method()} method"
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
"""
Generate class prevalence estimates for the sample's instances by aggregating the label predictions generated
by the classifier.
@@ -314,10 +299,7 @@
classif_predictions = self.classify(instances)
return self.aggregate(classif_predictions)
-
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def aggregate(self, classif_predictions: np.ndarray):
"""
Implements the aggregation of label predictions.
@@ -327,7 +309,6 @@
"""
...
-
@property
def classes_(self):
"""
@@ -339,10 +320,7 @@
return self.classifier.classes_
-
-
-[docs]
-class AggregativeCrispQuantifier(AggregativeQuantifier, ABC):
+[docs]class AggregativeCrispQuantifier(AggregativeQuantifier, ABC):
"""
Abstract class for quantification methods that base their estimations on the aggregation of crips decisions
as returned by a hard classifier. Aggregative crisp quantifiers thus extend Aggregative
@@ -359,10 +337,7 @@
return 'predict'
-
-
-[docs]
-class AggregativeSoftQuantifier(AggregativeQuantifier, ABC):
+[docs]class AggregativeSoftQuantifier(AggregativeQuantifier, ABC):
"""
Abstract class for quantification methods that base their estimations on the aggregation of posterior
probabilities as returned by a probabilistic classifier.
@@ -401,10 +376,7 @@
f'fit_classifier is set to False')
-
-
-[docs]
-class BinaryAggregativeQuantifier(AggregativeQuantifier, BinaryQuantifier):
+[docs]class BinaryAggregativeQuantifier(AggregativeQuantifier, BinaryQuantifier):
@property
def pos_label(self):
@@ -414,20 +386,14 @@
def neg_label(self):
return self.classifier.classes_[0]
-
-[docs]
- def fit(self, data: LabelledCollection, fit_classifier=True, val_split=None):
+[docs] def fit(self, data: LabelledCollection, fit_classifier=True, val_split=None):
self._check_binary(data, self.__class__.__name__)
- return super().fit(data, fit_classifier, val_split)
-
-
+ return super().fit(data, fit_classifier, val_split)
# Methods
# ------------------------------------
-
-[docs]
-class CC(AggregativeCrispQuantifier):
+[docs]class CC(AggregativeCrispQuantifier):
"""
The most basic Quantification method. One that simply classifies all instances and counts how many have been
attributed to each of the classes in order to compute class prevalence estimates.
@@ -438,9 +404,7 @@
def __init__(self, classifier: BaseEstimator):
self.classifier = classifier
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Nothing to do here!
@@ -448,24 +412,17 @@
"""
pass
-
-
-[docs]
- def aggregate(self, classif_predictions: np.ndarray):
+[docs] def aggregate(self, classif_predictions: np.ndarray):
"""
Computes class prevalence estimates by counting the prevalence of each of the predicted labels.
:param classif_predictions: array-like with label predictions
:return: `np.ndarray` of shape `(n_classes,)` with class prevalence estimates.
"""
- return F.prevalence_from_labels(classif_predictions, self.classes_)
-
+ return F.prevalence_from_labels(classif_predictions, self.classes_)
-
-
-[docs]
-class ACC(AggregativeCrispQuantifier):
+[docs]class ACC(AggregativeCrispQuantifier):
"""
`Adjusted Classify & Count <https://link.springer.com/article/10.1007/s10618-008-0097-y>`_,
the "adjusted" variant of :class:`CC`, that corrects the predictions of CC
@@ -502,9 +459,7 @@
def _check_init_parameters(self):
assert self.solver in ['exact', 'minimize'], "unknown solver; valid ones are 'exact', 'minimize'"
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Estimates the misclassification rates.
@@ -514,10 +469,7 @@
self.cc = CC(self.classifier)
self.Pte_cond_estim_ = self.getPteCondEstim(self.classifier.classes_, true_labels, pred_labels)
-
-
-[docs]
- @classmethod
+[docs] @classmethod
def getPteCondEstim(cls, classes, y, y_):
# estimate the matrix with entry (i,j) being the estimate of P(hat_yi|yj), that is, the probability that a
# document that belongs to yj ends up being classified as belonging to yi
@@ -531,17 +483,11 @@
conf[:, i] /= class_counts[i]
return conf
-
-
-[docs]
- def aggregate(self, classif_predictions):
+[docs] def aggregate(self, classif_predictions):
prevs_estim = self.cc.aggregate(classif_predictions)
return ACC.solve_adjustment(self.Pte_cond_estim_, prevs_estim, solver=self.solver)
-
-
-[docs]
- @classmethod
+[docs] @classmethod
def solve_adjustment(cls, PteCondEstim, prevs_estim, solver='exact'):
"""
Solves the system linear system :math:`Ax = B` with :math:`A` = `PteCondEstim` and :math:`B` = `prevs_estim`
@@ -577,14 +523,10 @@
def loss(prev):
return np.linalg.norm(A @ prev - B)
- return F.optim_minimize(loss, n_classes=A.shape[0])
-
+ return F.optim_minimize(loss, n_classes=A.shape[0])
-
-
-[docs]
-class PCC(AggregativeSoftQuantifier):
+[docs]class PCC(AggregativeSoftQuantifier):
"""
`Probabilistic Classify & Count <https://ieeexplore.ieee.org/abstract/document/5694031>`_,
the probabilistic variant of CC that relies on the posterior probabilities returned by a probabilistic classifier.
@@ -595,9 +537,7 @@
def __init__(self, classifier: BaseEstimator):
self.classifier = classifier
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Nothing to do here!
@@ -605,18 +545,11 @@
"""
pass
-
-
-[docs]
- def aggregate(self, classif_posteriors):
- return F.prevalence_from_probabilities(classif_posteriors, binarize=False)
-
+[docs] def aggregate(self, classif_posteriors):
+ return F.prevalence_from_probabilities(classif_posteriors, binarize=False)
-
-
-[docs]
-class PACC(AggregativeSoftQuantifier):
+[docs]class PACC(AggregativeSoftQuantifier):
"""
`Probabilistic Adjusted Classify & Count <https://ieeexplore.ieee.org/abstract/document/5694031>`_,
the probabilistic variant of ACC that relies on the posterior probabilities returned by a probabilistic classifier.
@@ -652,9 +585,7 @@
def _check_init_parameters(self):
assert self.solver in ['exact', 'minimize'], "unknown solver; valid ones are 'exact', 'minimize'"
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Estimates the misclassification rates
@@ -664,17 +595,11 @@
self.pcc = PCC(self.classifier)
self.Pte_cond_estim_ = self.getPteCondEstim(self.classifier.classes_, true_labels, posteriors)
-
-
-[docs]
- def aggregate(self, classif_posteriors):
+[docs] def aggregate(self, classif_posteriors):
prevs_estim = self.pcc.aggregate(classif_posteriors)
return ACC.solve_adjustment(self.Pte_cond_estim_, prevs_estim, solver=self.solver)
-
-
-[docs]
- @classmethod
+[docs] @classmethod
def getPteCondEstim(cls, classes, y, y_):
# estimate the matrix with entry (i,j) being the estimate of P(hat_yi|yj), that is, the probability that a
# document that belongs to yj ends up being classified as belonging to yi
@@ -685,14 +610,10 @@
if idx.any():
confusion[i] = y_[idx].mean(axis=0)
- return confusion.T
-
+ return confusion.T
-
-
-[docs]
-class EMQ(AggregativeSoftQuantifier):
+[docs]class EMQ(AggregativeSoftQuantifier):
"""
`Expectation Maximization for Quantification <https://ieeexplore.ieee.org/abstract/document/6789744>`_ (EMQ),
aka `Saerens-Latinne-Decaestecker` (SLD) algorithm.
@@ -736,9 +657,7 @@
self.recalib = recalib
self.n_jobs = n_jobs
-
-[docs]
- @classmethod
+[docs] @classmethod
def EMQ_BCTS(cls, classifier: BaseEstimator, n_jobs=None):
"""
Constructs an instance of EMQ using the best configuration found in the `Alexandari et al. paper
@@ -752,7 +671,6 @@
"""
return EMQ(classifier, val_split=5, exact_train_prev=False, recalib='bcts', n_jobs=n_jobs)
-
def _check_init_parameters(self):
if self.val_split is not None:
if self.exact_train_prev and self.recalib is None:
@@ -767,9 +685,7 @@
f'indicating the number of folds for kFCV.')
self.val_split=5
-
-[docs]
- def classify(self, instances):
+[docs] def classify(self, instances):
"""
Provides the posterior probabilities for the given instances. If the classifier was required
to be recalibrated, then these posteriors are recalibrated accordingly.
@@ -782,10 +698,7 @@
posteriors = self.calibration_function(posteriors)
return posteriors
-
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
if self.recalib is not None:
P, y = classif_predictions.Xy
if self.recalib == 'nbvs':
@@ -810,17 +723,11 @@
train_posteriors = self.calibration_function(train_posteriors)
self.train_prevalence = F.prevalence_from_probabilities(train_posteriors)
-
-
-[docs]
- def aggregate(self, classif_posteriors, epsilon=EPSILON):
+[docs] def aggregate(self, classif_posteriors, epsilon=EPSILON):
priors, posteriors = self.EM(self.train_prevalence, classif_posteriors, epsilon)
return priors
-
-
-[docs]
- def predict_proba(self, instances, epsilon=EPSILON):
+[docs] def predict_proba(self, instances, epsilon=EPSILON):
"""
Returns the posterior probabilities updated by the EM algorithm.
@@ -832,10 +739,7 @@
priors, posteriors = self.EM(self.train_prevalence, classif_posteriors, epsilon)
return posteriors
-
-
-[docs]
- @classmethod
+[docs] @classmethod
def EM(cls, tr_prev, posterior_probabilities, epsilon=EPSILON):
"""
Computes the `Expectation Maximization` routine.
@@ -871,14 +775,10 @@
if not converged:
print('[warning] the method has reached the maximum number of iterations; it might have not converged')
- return qs, ps
-
+ return qs, ps
-
-
-[docs]
-class HDy(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
+[docs]class HDy(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
"""
`Hellinger Distance y <https://www.sciencedirect.com/science/article/pii/S0020025512004069>`_ (HDy).
HDy is a probabilistic method for training binary quantifiers, that models quantification as the problem of
@@ -897,9 +797,7 @@
self.classifier = classifier
self.val_split = val_split
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Trains a HDy quantifier.
@@ -927,10 +825,7 @@
return self
-
-
-[docs]
- def aggregate(self, classif_posteriors):
+[docs] def aggregate(self, classif_posteriors):
# "In this work, the number of bins b used in HDx and HDy was chosen from 10 to 110 in steps of 10,
# and the final estimated a priori probability was taken as the median of these 11 estimates."
# (González-Castro, et al., 2013).
@@ -959,14 +854,10 @@
prev_estimations.append(prev_selected)
class1_prev = np.median(prev_estimations)
- return F.as_binary_prevalence(class1_prev)
-
+ return F.as_binary_prevalence(class1_prev)
-
-
-[docs]
-class DyS(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
+[docs]class DyS(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
"""
`DyS framework <https://ojs.aaai.org/index.php/AAAI/article/view/4376>`_ (DyS).
DyS is a generalization of HDy method, using a Ternary Search in order to find the prevalence that
@@ -1007,9 +898,7 @@
# Left and right are the current bounds; the maximum is between them
return (left + right) / 2
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
Px, y = classif_predictions.Xy
Px = Px[:, self.pos_label] # takes only the P(y=+1|x)
self.Pxy1 = Px[y == self.pos_label]
@@ -1018,10 +907,7 @@
self.Pxy0_density = np.histogram(self.Pxy0, bins=self.n_bins, range=(0, 1), density=True)[0]
return self
-
-
-[docs]
- def aggregate(self, classif_posteriors):
+[docs] def aggregate(self, classif_posteriors):
Px = classif_posteriors[:, self.pos_label] # takes only the P(y=+1|x)
Px_test = np.histogram(Px, bins=self.n_bins, range=(0, 1), density=True)[0]
@@ -1032,14 +918,10 @@
return divergence(Px_train, Px_test)
class1_prev = self._ternary_search(f=distribution_distance, left=0, right=1, tol=self.tol)
- return F.as_binary_prevalence(class1_prev)
-
+ return F.as_binary_prevalence(class1_prev)
-
-
-[docs]
-class SMM(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
+[docs]class SMM(AggregativeSoftQuantifier, BinaryAggregativeQuantifier):
"""
`SMM method <https://ieeexplore.ieee.org/document/9260028>`_ (SMM).
SMM is a simplification of matching distribution methods where the representation of the examples
@@ -1054,9 +936,7 @@
self.classifier = classifier
self.val_split = val_split
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
Px, y = classif_predictions.Xy
Px = Px[:, self.pos_label] # takes only the P(y=+1|x)
self.Pxy1 = Px[y == self.pos_label]
@@ -1065,22 +945,15 @@
self.Pxy0_mean = np.mean(self.Pxy0) # equiv. FPR
return self
-
-
-[docs]
- def aggregate(self, classif_posteriors):
+[docs] def aggregate(self, classif_posteriors):
Px = classif_posteriors[:, self.pos_label] # takes only the P(y=+1|x)
Px_mean = np.mean(Px)
class1_prev = (Px_mean - self.Pxy0_mean)/(self.Pxy1_mean - self.Pxy0_mean)
- return F.as_binary_prevalence(class1_prev, clip_if_necessary=True)
-
+ return F.as_binary_prevalence(class1_prev, clip_if_necessary=True)
-
-
-[docs]
-class DMy(AggregativeSoftQuantifier):
+[docs]class DMy(AggregativeSoftQuantifier):
"""
Generic Distribution Matching quantifier for binary or multiclass quantification based on the space of posterior
probabilities. This implementation takes the number of bins, the divergence, and the possibility to work on CDF
@@ -1135,9 +1008,7 @@
distributions = np.cumsum(distributions, axis=1)
return distributions
-
-[docs]
- def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
+[docs] def aggregation_fit(self, classif_predictions: LabelledCollection, data: LabelledCollection):
"""
Trains the classifier (if requested) and generates the validation distributions out of the training data.
The validation distributions have shape `(n, ch, nbins)`, with `n` the number of classes, `ch` the number of
@@ -1163,10 +1034,7 @@
backend='threading'
)
-
-
-[docs]
- def aggregate(self, posteriors: np.ndarray):
+[docs] def aggregate(self, posteriors: np.ndarray):
"""
Searches for the mixture model parameter (the sought prevalence values) that yields a validation distribution
(the mixture) that best matches the test distribution, in terms of the divergence measure of choice.
@@ -1186,15 +1054,11 @@
divs = [divergence(test_distribution[ch], mixture_distribution[ch]) for ch in range(n_channels)]
return np.mean(divs)
- return F.argmin_prevalence(loss, n_classes, method=self.search)
-
+ return F.argmin_prevalence(loss, n_classes, method=self.search)
-
-
-[docs]
-def newELM(svmperf_base=None, loss='01', C=1):
+[docs]def newELM(svmperf_base=None, loss='01', C=1):
"""
Explicit Loss Minimization (ELM) quantifiers.
Quantifiers based on ELM represent a family of methods based on structured output learning;
@@ -1221,10 +1085,7 @@
return CC(SVMperf(svmperf_base, loss=loss, C=C))
-
-
-[docs]
-def newSVMQ(svmperf_base=None, C=1):
+[docs]def newSVMQ(svmperf_base=None, C=1):
"""
SVM(Q) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the `Q` loss combining a
classification-oriented loss and a quantification-oriented loss, as proposed by
@@ -1249,7 +1110,6 @@
"""
return newELM(svmperf_base, loss='q', C=C)
-
def newSVMKLD(svmperf_base=None, C=1):
"""
SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Kullback-Leibler Divergence
@@ -1275,9 +1135,7 @@
return newELM(svmperf_base, loss='kld', C=C)
-
-[docs]
-def newSVMKLD(svmperf_base=None, C=1):
+[docs]def newSVMKLD(svmperf_base=None, C=1):
"""
SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Kullback-Leibler Divergence
normalized via the logistic function, as proposed by
@@ -1302,10 +1160,7 @@
"""
return newELM(svmperf_base, loss='nkld', C=C)
-
-
-[docs]
-def newSVMAE(svmperf_base=None, C=1):
+[docs]def newSVMAE(svmperf_base=None, C=1):
"""
SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Absolute Error as first used by
`Moreo and Sebastiani, 2021 <https://arxiv.org/abs/2011.02552>`_.
@@ -1329,10 +1184,7 @@
"""
return newELM(svmperf_base, loss='mae', C=C)
-
-
-[docs]
-def newSVMRAE(svmperf_base=None, C=1):
+[docs]def newSVMRAE(svmperf_base=None, C=1):
"""
SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Relative Absolute Error as first
used by `Moreo and Sebastiani, 2021 <https://arxiv.org/abs/2011.02552>`_.
@@ -1357,10 +1209,7 @@
return newELM(svmperf_base, loss='mrae', C=C)
-
-
-[docs]
-class OneVsAllAggregative(OneVsAllGeneric, AggregativeQuantifier):
+[docs]class OneVsAllAggregative(OneVsAllGeneric, AggregativeQuantifier):
"""
Allows any binary quantifier to perform quantification on single-label datasets.
The method maintains one binary quantifier for each class, and then l1-normalizes the outputs so that the
@@ -1385,9 +1234,7 @@
self.n_jobs = qp._get_njobs(n_jobs)
self.parallel_backend = parallel_backend
-
-[docs]
- def classify(self, instances):
+[docs] def classify(self, instances):
"""
If the base quantifier is not probabilistic, returns a matrix of shape `(n,m,)` with `n` the number of
instances and `m` the number of classes. The entry `(i,j)` is a binary value indicating whether instance
@@ -1408,14 +1255,10 @@
else:
return classif_predictions.T
-
-
-[docs]
- def aggregate(self, classif_predictions):
+[docs] def aggregate(self, classif_predictions):
prevalences = self._parallel(self._delayed_binary_aggregate, classif_predictions)
return F.normalize_prevalence(prevalences)
-
def _delayed_binary_classification(self, c, X):
return self.dict_binary_quantifiers[c].classify(X)
@@ -1424,10 +1267,7 @@
return self.dict_binary_quantifiers[c].aggregate(classif_predictions[:, c])[1]
-
-
-[docs]
-class AggregativeMedianEstimator(BinaryQuantifier):
+[docs]class AggregativeMedianEstimator(BinaryQuantifier):
"""
This method is a meta-quantifier that returns, as the estimated class prevalence values, the median of the
estimation returned by differently (hyper)parameterized base quantifiers.
@@ -1445,18 +1285,12 @@
self.random_state = random_state
self.n_jobs = qp._get_njobs(n_jobs)
-
-[docs]
- def get_params(self, deep=True):
+
-
-
-[docs]
- def set_params(self, **params):
+
-
def _delayed_fit(self, args):
with qp.util.temp_seed(self.random_state):
params, training = args
@@ -1484,9 +1318,7 @@
return model
-
-[docs]
- def fit(self, training: LabelledCollection, **kwargs):
+[docs] def fit(self, training: LabelledCollection, **kwargs):
import itertools
self._check_binary(training, self.__class__.__name__)
@@ -1528,14 +1360,11 @@
)
return self
-
def _delayed_predict(self, args):
model, instances = args
return model.quantify(instances)
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
prev_preds = qp.util.parallel(
self._delayed_predict,
((model, instances) for model in self.models),
@@ -1543,9 +1372,7 @@
n_jobs=self.n_jobs,
backend='threading'
)
- return np.median(prev_preds, axis=0)
-
-
+ return np.median(prev_preds, axis=0)
#---------------------------------------------------------------
diff --git a/docs/build/html/_modules/quapy/method/base.html b/docs/build/html/_modules/quapy/method/base.html
index cdc483c..6288bd1 100644
--- a/docs/build/html/_modules/quapy/method/base.html
+++ b/docs/build/html/_modules/quapy/method/base.html
@@ -1,22 +1,23 @@
-
+
quapy.method.base — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -83,18 +84,14 @@
# Base Quantifier abstract class
# ------------------------------------
-
-[docs]
-class BaseQuantifier(BaseEstimator):
+[docs]class BaseQuantifier(BaseEstimator):
"""
Abstract Quantifier. A quantifier is defined as an object of a class that implements the method :meth:`fit` on
:class:`quapy.data.base.LabelledCollection`, the method :meth:`quantify`, and the :meth:`set_params` and
:meth:`get_params` for model selection (see :meth:`quapy.model_selection.GridSearchQ`)
"""
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def fit(self, data: LabelledCollection):
"""
Trains a quantifier.
@@ -104,10 +101,7 @@
"""
...
-
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def quantify(self, instances):
"""
Generate class prevalence estimates for the sample's instances
@@ -115,14 +109,10 @@
:param instances: array-like
:return: `np.ndarray` of shape `(n_classes,)` with class prevalence estimates.
"""
- ...
-
+ ...
-
-
-[docs]
-class BinaryQuantifier(BaseQuantifier):
+[docs]class BinaryQuantifier(BaseQuantifier):
"""
Abstract class of binary quantifiers, i.e., quantifiers estimating class prevalence values for only two classes
(typically, to be interpreted as one class and its complement).
@@ -133,17 +123,11 @@
f'Use the class OneVsAll to enable {quantifier_name} work on single-label data.'
-
-
-[docs]
-class OneVsAll:
+
-
-
-[docs]
-def newOneVsAll(binary_quantifier, n_jobs=None):
+[docs]def newOneVsAll(binary_quantifier, n_jobs=None):
assert isinstance(binary_quantifier, BaseQuantifier), \
f'{binary_quantifier} does not seem to be a Quantifier'
if isinstance(binary_quantifier, qp.method.aggregative.AggregativeQuantifier):
@@ -152,10 +136,7 @@
return OneVsAllGeneric(binary_quantifier, n_jobs)
-
-
-[docs]
-class OneVsAllGeneric(OneVsAll, BaseQuantifier):
+[docs]class OneVsAllGeneric(OneVsAll, BaseQuantifier):
"""
Allows any binary quantifier to perform quantification on single-label datasets. The method maintains one binary
quantifier for each class, and then l1-normalizes the outputs so that the class prevelence values sum up to 1.
@@ -170,9 +151,7 @@
self.binary_quantifier = binary_quantifier
self.n_jobs = qp._get_njobs(n_jobs)
-
-[docs]
- def fit(self, data: LabelledCollection, fit_classifier=True):
+[docs] def fit(self, data: LabelledCollection, fit_classifier=True):
assert not data.binary, f'{self.__class__.__name__} expect non-binary data'
assert fit_classifier == True, 'fit_classifier must be True'
@@ -180,7 +159,6 @@
self._parallel(self._delayed_binary_fit, data)
return self
-
def _parallel(self, func, *args, **kwargs):
return np.asarray(
Parallel(n_jobs=self.n_jobs, backend='threading')(
@@ -188,13 +166,10 @@
)
)
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
prevalences = self._parallel(self._delayed_binary_predict, instances)
return qp.functional.normalize_prevalence(prevalences)
-
@property
def classes_(self):
return sorted(self.dict_binary_quantifiers.keys())
@@ -205,7 +180,6 @@
def _delayed_binary_fit(self, c, data):
bindata = LabelledCollection(data.instances, data.labels == c, classes=[False, True])
self.dict_binary_quantifiers[c].fit(bindata)
-
diff --git a/docs/build/html/_modules/quapy/method/meta.html b/docs/build/html/_modules/quapy/method/meta.html
index b24dcc3..ca38440 100644
--- a/docs/build/html/_modules/quapy/method/meta.html
+++ b/docs/build/html/_modules/quapy/method/meta.html
@@ -1,22 +1,23 @@
-
+
quapy.method.meta — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -98,9 +99,7 @@
QuaNet = "QuaNet is not available due to missing torch package"
-
-[docs]
-class MedianEstimator2(BinaryQuantifier):
+[docs]class MedianEstimator2(BinaryQuantifier):
"""
This method is a meta-quantifier that returns, as the estimated class prevalence values, the median of the
estimation returned by differently (hyper)parameterized base quantifiers.
@@ -118,18 +117,12 @@
self.random_state = random_state
self.n_jobs = qp._get_njobs(n_jobs)
-
-[docs]
- def get_params(self, deep=True):
+
-
-
-[docs]
- def set_params(self, **params):
+
-
def _delayed_fit(self, args):
with qp.util.temp_seed(self.random_state):
params, training = args
@@ -138,9 +131,7 @@
model.fit(training)
return model
-
-[docs]
- def fit(self, training: LabelledCollection):
+[docs] def fit(self, training: LabelledCollection):
self._check_binary(training, self.__class__.__name__)
configs = qp.model_selection.expand_grid(self.param_grid)
@@ -152,14 +143,11 @@
)
return self
-
def _delayed_predict(self, args):
model, instances = args
return model.quantify(instances)
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
prev_preds = qp.util.parallel(
self._delayed_predict,
((model, instances) for model in self.models),
@@ -167,14 +155,10 @@
n_jobs=self.n_jobs
)
prev_preds = np.asarray(prev_preds)
- return np.median(prev_preds, axis=0)
-
+ return np.median(prev_preds, axis=0)
-
-
-[docs]
-class MedianEstimator(BinaryQuantifier):
+[docs]class MedianEstimator(BinaryQuantifier):
"""
This method is a meta-quantifier that returns, as the estimated class prevalence values, the median of the
estimation returned by differently (hyper)parameterized base quantifiers.
@@ -192,18 +176,12 @@
self.random_state = random_state
self.n_jobs = qp._get_njobs(n_jobs)
-
-[docs]
- def get_params(self, deep=True):
+
-
-
-[docs]
- def set_params(self, **params):
+
-
def _delayed_fit(self, args):
with qp.util.temp_seed(self.random_state):
params, training = args
@@ -229,9 +207,7 @@
return model
-
-[docs]
- def fit(self, training: LabelledCollection):
+[docs] def fit(self, training: LabelledCollection):
self._check_binary(training, self.__class__.__name__)
if isinstance(self.base_quantifier, AggregativeQuantifier):
@@ -269,14 +245,11 @@
)
return self
-
def _delayed_predict(self, args):
model, instances = args
return model.quantify(instances)
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
prev_preds = qp.util.parallel(
self._delayed_predict,
((model, instances) for model in self.models),
@@ -285,14 +258,10 @@
asarray=False
)
prev_preds = np.asarray(prev_preds)
- return np.median(prev_preds, axis=0)
-
+ return np.median(prev_preds, axis=0)
-
-
-[docs]
-class Ensemble(BaseQuantifier):
+[docs]class Ensemble(BaseQuantifier):
VALID_POLICIES = {'ave', 'ptr', 'ds'} | qp.error.QUANTIFICATION_ERROR_NAMES
"""
@@ -361,9 +330,7 @@
if self.verbose:
print('[Ensemble]' + msg)
-
-[docs]
- def fit(self, data: qp.data.LabelledCollection, val_split: Union[qp.data.LabelledCollection, float] = None):
+[docs] def fit(self, data: qp.data.LabelledCollection, val_split: Union[qp.data.LabelledCollection, float] = None):
if self.policy == 'ds' and not data.binary:
raise ValueError(f'ds policy is only defined for binary quantification, but this dataset is not binary')
@@ -400,10 +367,7 @@
self._sout('Fit [Done]')
return self
-
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
predictions = np.asarray(
qp.util.parallel(_delayed_quantify, ((Qi, instances) for Qi in self.ensemble), n_jobs=self.n_jobs)
)
@@ -416,10 +380,7 @@
predictions = np.mean(predictions, axis=0)
return F.normalize_prevalence(predictions)
-
-
-[docs]
- def set_params(self, **parameters):
+[docs] def set_params(self, **parameters):
"""
This function should not be used within :class:`quapy.model_selection.GridSearchQ` (is here for compatibility
with the abstract class).
@@ -435,10 +396,7 @@
f'or Ensemble(Q(GridSearchCV(l))) with Q a quantifier class that has a classifier '
f'l optimized for classification (not recommended).')
-
-
-[docs]
- def get_params(self, deep=True):
+[docs] def get_params(self, deep=True):
"""
This function should not be used within :class:`quapy.model_selection.GridSearchQ` (is here for compatibility
with the abstract class).
@@ -452,7 +410,6 @@
raise NotImplementedError()
-
def _accuracy_policy(self, error_name):
"""
Selects the red_size best performant quantifiers in a static way (i.e., dropping all non-selected instances).
@@ -538,10 +495,7 @@
return False
-
-
-[docs]
-def get_probability_distribution(posterior_probabilities, bins=8):
+[docs]def get_probability_distribution(posterior_probabilities, bins=8):
"""
Gets a histogram out of the posterior probabilities (only for the binary case).
@@ -555,7 +509,6 @@
return distribution
-
def _select_k(elements, order, k):
return [elements[idx] for idx in order[:k]]
@@ -649,9 +602,7 @@
f'the name of an error function in {qp.error.ERROR_NAMES}')
-
-[docs]
-def ensembleFactory(classifier, base_quantifier_class, param_grid=None, optim=None, param_model_sel: dict = None,
+[docs]def ensembleFactory(classifier, base_quantifier_class, param_grid=None, optim=None, param_model_sel: dict = None,
**kwargs):
"""
Ensemble factory. Provides a unified interface for instantiating ensembles that can be optimized (via model
@@ -702,10 +653,7 @@
return _instantiate_ensemble(classifier, base_quantifier_class, param_grid, error, param_model_sel, **kwargs)
-
-
-[docs]
-def ECC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
+[docs]def ECC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
"""
Implements an ensemble of :class:`quapy.method.aggregative.CC` quantifiers, as used by
`Pérez-Gállego et al., 2019 <https://www.sciencedirect.com/science/article/pii/S1566253517303652>`_.
@@ -728,10 +676,7 @@
return ensembleFactory(classifier, CC, param_grid, optim, param_mod_sel, **kwargs)
-
-
-[docs]
-def EACC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
+[docs]def EACC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
"""
Implements an ensemble of :class:`quapy.method.aggregative.ACC` quantifiers, as used by
`Pérez-Gállego et al., 2019 <https://www.sciencedirect.com/science/article/pii/S1566253517303652>`_.
@@ -754,10 +699,7 @@
return ensembleFactory(classifier, ACC, param_grid, optim, param_mod_sel, **kwargs)
-
-
-[docs]
-def EPACC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
+[docs]def EPACC(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
"""
Implements an ensemble of :class:`quapy.method.aggregative.PACC` quantifiers.
@@ -779,10 +721,7 @@
return ensembleFactory(classifier, PACC, param_grid, optim, param_mod_sel, **kwargs)
-
-
-[docs]
-def EHDy(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
+[docs]def EHDy(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
"""
Implements an ensemble of :class:`quapy.method.aggregative.HDy` quantifiers, as used by
`Pérez-Gállego et al., 2019 <https://www.sciencedirect.com/science/article/pii/S1566253517303652>`_.
@@ -805,10 +744,7 @@
return ensembleFactory(classifier, HDy, param_grid, optim, param_mod_sel, **kwargs)
-
-
-[docs]
-def EEMQ(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
+[docs]def EEMQ(classifier, param_grid=None, optim=None, param_mod_sel=None, **kwargs):
"""
Implements an ensemble of :class:`quapy.method.aggregative.EMQ` quantifiers.
@@ -828,7 +764,6 @@
"""
return ensembleFactory(classifier, EMQ, param_grid, optim, param_mod_sel, **kwargs)
-
diff --git a/docs/build/html/_modules/quapy/method/non_aggregative.html b/docs/build/html/_modules/quapy/method/non_aggregative.html
index 3363c35..aeb5b96 100644
--- a/docs/build/html/_modules/quapy/method/non_aggregative.html
+++ b/docs/build/html/_modules/quapy/method/non_aggregative.html
@@ -1,22 +1,23 @@
-
+
quapy.method.non_aggregative — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -79,9 +80,7 @@
import quapy.functional as F
-
-[docs]
-class MaximumLikelihoodPrevalenceEstimation(BaseQuantifier):
+[docs]class MaximumLikelihoodPrevalenceEstimation(BaseQuantifier):
"""
The `Maximum Likelihood Prevalence Estimation` (MLPE) method is a lazy method that assumes there is no prior
probability shift between training and test instances (put it other way, that the i.i.d. assumpion holds).
@@ -93,9 +92,7 @@
def __init__(self):
self._classes_ = None
-
-[docs]
- def fit(self, data: LabelledCollection):
+[docs] def fit(self, data: LabelledCollection):
"""
Computes the training prevalence and stores it.
@@ -105,24 +102,17 @@
self.estimated_prevalence = data.prevalence()
return self
-
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
"""
Ignores the input instances and returns, as the class prevalence estimantes, the training prevalence.
:param instances: array-like (ignored)
:return: the class prevalence seen during training
"""
- return self.estimated_prevalence
-
+ return self.estimated_prevalence
-
-
-[docs]
-class DMx(BaseQuantifier):
+[docs]class DMx(BaseQuantifier):
"""
Generic Distribution Matching quantifier for binary or multiclass quantification based on the space of covariates.
This implementation takes the number of bins, the divergence, and the possibility to work on CDF as hyperparameters.
@@ -142,9 +132,7 @@
self.search = search
self.n_jobs = n_jobs
-
-[docs]
- @classmethod
+[docs] @classmethod
def HDx(cls, n_jobs=None):
"""
`Hellinger Distance x <https://www.sciencedirect.com/science/article/pii/S0020025512004069>`_ (HDx).
@@ -168,7 +156,6 @@
hdx = MedianEstimator(base_quantifier=dmx, param_grid=nbins, n_jobs=n_jobs)
return hdx
-
def __get_distributions(self, X):
histograms = []
@@ -185,9 +172,7 @@
return distributions
-
-[docs]
- def fit(self, data: LabelledCollection):
+[docs] def fit(self, data: LabelledCollection):
"""
Generates the validation distributions out of the training data (covariates).
The validation distributions have shape `(n, nfeats, nbins)`, with `n` the number of classes, `nfeats`
@@ -209,10 +194,7 @@
return self
-
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
"""
Searches for the mixture model parameter (the sought prevalence values) that yields a validation distribution
(the mixture) that best matches the test distribution, in terms of the divergence measure of choice.
@@ -234,9 +216,7 @@
divs = [divergence(test_distribution[feat], mixture_distribution[feat]) for feat in range(n_feats)]
return np.mean(divs)
- return F.argmin_prevalence(loss, n_classes, method=self.search)
-
-
+ return F.argmin_prevalence(loss, n_classes, method=self.search)
diff --git a/docs/build/html/_modules/quapy/model_selection.html b/docs/build/html/_modules/quapy/model_selection.html
index 84fd962..172c8f3 100644
--- a/docs/build/html/_modules/quapy/model_selection.html
+++ b/docs/build/html/_modules/quapy/model_selection.html
@@ -1,22 +1,23 @@
-
+
quapy.model_selection — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -89,19 +90,14 @@
from time import time
-
-[docs]
-class Status(Enum):
+
-
-
-[docs]
-class ConfigStatus:
+[docs]class ConfigStatus:
def __init__(self, params, status, msg=''):
self.params = params
self.status = status
@@ -113,23 +109,14 @@
def __repr__(self):
return str(self)
-
+
-
-
-[docs]
-class GridSearchQ(BaseQuantifier):
+[docs]class GridSearchQ(BaseQuantifier):
"""Grid Search optimization targeting a quantification-oriented metric.
Optimizes the hyperparameters of a quantification method, based on an evaluation method and on an evaluation
@@ -296,9 +283,7 @@
else:
self._sout(f'error={status}')
-
-[docs]
- def fit(self, training: LabelledCollection):
+[docs] def fit(self, training: LabelledCollection):
""" Learning routine. Fits methods with all combinations of hyperparameters and selects the one minimizing
the error metric.
@@ -362,10 +347,7 @@
return self
-
-
-[docs]
- def quantify(self, instances):
+[docs] def quantify(self, instances):
"""Estimate class prevalence values using the best model found after calling the :meth:`fit` method.
:param instances: sample contanining the instances
@@ -375,20 +357,14 @@
assert hasattr(self, 'best_model_'), 'quantify called before fit'
return self.best_model().quantify(instances)
-
-
-[docs]
- def set_params(self, **parameters):
+[docs] def set_params(self, **parameters):
"""Sets the hyper-parameters to explore.
:param parameters: a dictionary with keys the parameter names and values the list of values to explore
"""
self.param_grid = parameters
-
-
-[docs]
- def get_params(self, deep=True):
+[docs] def get_params(self, deep=True):
"""Returns the dictionary of hyper-parameters to explore (`param_grid`)
:param deep: Unused
@@ -396,10 +372,7 @@
"""
return self.param_grid
-
-
-[docs]
- def best_model(self):
+[docs] def best_model(self):
"""
Returns the best model found after calling the :meth:`fit` method, i.e., the one trained on the combination
of hyper-parameters that minimized the error function.
@@ -410,7 +383,6 @@
return self.best_model_
raise ValueError('best_model called before fit')
-
def _error_handler(self, func, params):
"""
Endorses one job with two returned values: the status, and the time of execution
@@ -449,10 +421,7 @@
return output, status, took
-
-
-[docs]
-def cross_val_predict(quantifier: BaseQuantifier, data: LabelledCollection, nfolds=3, random_state=0):
+[docs]def cross_val_predict(quantifier: BaseQuantifier, data: LabelledCollection, nfolds=3, random_state=0):
"""
Akin to `scikit-learn's cross_val_predict <https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_val_predict.html>`_
but for quantification.
@@ -475,10 +444,7 @@
return total_prev
-
-
-[docs]
-def expand_grid(param_grid: dict):
+[docs]def expand_grid(param_grid: dict):
"""
Expands a param_grid dictionary as a list of configurations.
Example:
@@ -497,10 +463,7 @@
return configs
-
-
-[docs]
-def group_params(param_grid: dict):
+[docs]def group_params(param_grid: dict):
"""
Partitions a param_grid dictionary as two lists of configurations, one for the classifier-specific
hyper-parameters, and another for que quantifier-specific hyper-parameters
@@ -521,7 +484,6 @@
return classifier_configs, quantifier_configs
-
diff --git a/docs/build/html/_modules/quapy/protocol.html b/docs/build/html/_modules/quapy/protocol.html
index f0330c2..7d96338 100644
--- a/docs/build/html/_modules/quapy/protocol.html
+++ b/docs/build/html/_modules/quapy/protocol.html
@@ -1,22 +1,23 @@
-
+
quapy.protocol — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -82,9 +83,7 @@
from glob import glob
-
-[docs]
-class AbstractProtocol(metaclass=ABCMeta):
+[docs]class AbstractProtocol(metaclass=ABCMeta):
"""
Abstract parent class for sample generation protocols.
"""
@@ -99,22 +98,16 @@
"""
...
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Indicates the total number of samples that the protocol generates.
:return: The number of samples to generate if known, or `None` otherwise.
"""
- return None
-
+ return None
-
-
-[docs]
-class IterateProtocol(AbstractProtocol):
+[docs]class IterateProtocol(AbstractProtocol):
"""
A very simple protocol which simply iterates over a list of previously generated samples
@@ -133,22 +126,16 @@
for sample in self.samples:
yield sample.Xp
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Returns the number of samples in this protocol
:return: int
"""
- return len(self.samples)
-
+ return len(self.samples)
-
-
-[docs]
-class AbstractStochasticSeededProtocol(AbstractProtocol):
+[docs]class AbstractStochasticSeededProtocol(AbstractProtocol):
"""
An `AbstractStochasticSeededProtocol` is a protocol that generates, via any random procedure (e.g.,
via random sampling), sequences of :class:`quapy.data.base.LabelledCollection` samples.
@@ -176,9 +163,7 @@
def random_state(self, random_state):
self._random_state = random_state
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def samples_parameters(self):
"""
This function has to return all the necessary parameters to replicate the samples
@@ -187,10 +172,7 @@
"""
...
-
-
-[docs]
- @abstractmethod
+[docs] @abstractmethod
def sample(self, params):
"""
Extract one sample determined by the given parameters
@@ -200,7 +182,6 @@
"""
...
-
def __call__(self):
"""
Yields one sample at a time. The type of object returned depends on the `collator` function. The
@@ -218,9 +199,7 @@
for params in self.samples_parameters():
yield self.collator(self.sample(params))
-
-[docs]
- def collator(self, sample, *args):
+[docs] def collator(self, sample, *args):
"""
The collator prepares the sample to accommodate the desired output format before returning the output.
This collator simply returns the sample as it is. Classes inheriting from this abstract class can
@@ -230,23 +209,17 @@
:param args: additional arguments
:return: the sample adhering to a desired output format (in this case, the sample is returned as it is)
"""
- return sample
-
+ return sample
-
-
-[docs]
-class OnLabelledCollectionProtocol:
+[docs]class OnLabelledCollectionProtocol:
"""
Protocols that generate samples from a :class:`qp.data.LabelledCollection` object.
"""
RETURN_TYPES = ['sample_prev', 'labelled_collection', 'index']
-
-[docs]
- def get_labelled_collection(self):
+[docs] def get_labelled_collection(self):
"""
Returns the labelled collection on which this protocol acts.
@@ -254,10 +227,7 @@
"""
return self.data
-
-
-[docs]
- def on_preclassified_instances(self, pre_classifications, in_place=False):
+[docs] def on_preclassified_instances(self, pre_classifications, in_place=False):
"""
Returns a copy of this protocol that acts on a modified version of the original
:class:`qp.data.LabelledCollection` in which the original instances have been replaced
@@ -280,10 +250,7 @@
new = deepcopy(self)
return new.on_preclassified_instances(pre_classifications, in_place=True)
-
-
-[docs]
- @classmethod
+[docs] @classmethod
def get_collator(cls, return_type='sample_prev'):
"""
Returns a collator function, i.e., a function that prepares the yielded data
@@ -299,14 +266,10 @@
if return_type=='sample_prev':
return lambda lc:lc.Xp
elif return_type=='labelled_collection':
- return lambda lc:lc
-
+ return lambda lc:lc
-
-
-[docs]
-class APP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
+[docs]class APP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
"""
Implementation of the artificial prevalence protocol (APP).
The APP consists of exploring a grid of prevalence values containing `n_prevalences` points (e.g.,
@@ -350,9 +313,7 @@
self.collator = OnLabelledCollectionProtocol.get_collator(return_type)
-
-[docs]
- def prevalence_grid(self):
+[docs] def prevalence_grid(self):
"""
Generates vectors of prevalence values from an exhaustive grid of prevalence values. The
number of prevalence values explored for each dimension depends on `n_prevalences`, so that, if, for example,
@@ -377,10 +338,7 @@
prevs = np.repeat(prevs, self.repeats, axis=0)
return prevs
-
-
-[docs]
- def samples_parameters(self):
+[docs] def samples_parameters(self):
"""
Return all the necessary parameters to replicate the samples as according to the APP protocol.
@@ -392,10 +350,7 @@
indexes.append(index)
return indexes
-
-
-[docs]
- def sample(self, index):
+[docs] def sample(self, index):
"""
Realizes the sample given the index of the instances.
@@ -404,23 +359,16 @@
"""
return self.data.sampling_from_index(index)
-
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Returns the number of samples that will be generated
:return: int
"""
- return F.num_prevalence_combinations(self.n_prevalences, self.data.n_classes, self.repeats)
-
+ return F.num_prevalence_combinations(self.n_prevalences, self.data.n_classes, self.repeats)
-
-
-[docs]
-class NPP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
+[docs]class NPP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
"""
A generator of samples that implements the natural prevalence protocol (NPP). The NPP consists of drawing
samples uniformly at random, therefore approximately preserving the natural prevalence of the collection.
@@ -444,9 +392,7 @@
self.random_state = random_state
self.collator = OnLabelledCollectionProtocol.get_collator(return_type)
-
-[docs]
- def samples_parameters(self):
+[docs] def samples_parameters(self):
"""
Return all the necessary parameters to replicate the samples as according to the NPP protocol.
@@ -458,10 +404,7 @@
indexes.append(index)
return indexes
-
-
-[docs]
- def sample(self, index):
+[docs] def sample(self, index):
"""
Realizes the sample given the index of the instances.
@@ -470,23 +413,16 @@
"""
return self.data.sampling_from_index(index)
-
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Returns the number of samples that will be generated (equals to "repeats")
:return: int
"""
- return self.repeats
-
+ return self.repeats
-
-
-[docs]
-class UPP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
+[docs]class UPP(AbstractStochasticSeededProtocol, OnLabelledCollectionProtocol):
"""
A variant of :class:`APP` that, instead of using a grid of equidistant prevalence values,
relies on the Kraemer algorithm for sampling unit (k-1)-simplex uniformly at random, with
@@ -514,9 +450,7 @@
self.random_state = random_state
self.collator = OnLabelledCollectionProtocol.get_collator(return_type)
-
-[docs]
- def samples_parameters(self):
+[docs] def samples_parameters(self):
"""
Return all the necessary parameters to replicate the samples as according to the UPP protocol.
@@ -528,10 +462,7 @@
indexes.append(index)
return indexes
-
-
-[docs]
- def sample(self, index):
+[docs] def sample(self, index):
"""
Realizes the sample given the index of the instances.
@@ -540,23 +471,16 @@
"""
return self.data.sampling_from_index(index)
-
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Returns the number of samples that will be generated (equals to "repeats")
:return: int
"""
- return self.repeats
-
+ return self.repeats
-
-
-[docs]
-class DomainMixer(AbstractStochasticSeededProtocol):
+[docs]class DomainMixer(AbstractStochasticSeededProtocol):
"""
Generates mixtures of two domains (A and B) at controlled rates, but preserving the original class prevalence.
@@ -607,9 +531,7 @@
self.random_state = random_state
self.collator = OnLabelledCollectionProtocol.get_collator(return_type)
-
-[docs]
- def samples_parameters(self):
+[docs] def samples_parameters(self):
"""
Return all the necessary parameters to replicate the samples as according to the this protocol.
@@ -626,10 +548,7 @@
indexesB.append(sampleBidx)
return list(zip(indexesA, indexesB))
-
-
-[docs]
- def sample(self, indexes):
+[docs] def sample(self, indexes):
"""
Realizes the sample given a pair of indexes of the instances from A and B.
@@ -641,18 +560,13 @@
sampleB = self.B.sampling_from_index(indexesB)
return sampleA+sampleB
-
-
-[docs]
- def total(self):
+[docs] def total(self):
"""
Returns the number of samples that will be generated (equals to "repeats * mixture_points")
:return: int
"""
- return self.repeats * len(self.mixture_points)
-
-
+ return self.repeats * len(self.mixture_points)
# aliases
diff --git a/docs/build/html/_modules/quapy/util.html b/docs/build/html/_modules/quapy/util.html
index be2ae3b..25532bd 100644
--- a/docs/build/html/_modules/quapy/util.html
+++ b/docs/build/html/_modules/quapy/util.html
@@ -1,22 +1,23 @@
-
+
quapy.util — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -94,9 +95,7 @@
return [slice(job * batch, (job + 1) * batch + (remainder if job == n_jobs - 1 else 0)) for job in range(n_jobs)]
-
-[docs]
-def map_parallel(func, args, n_jobs):
+[docs]def map_parallel(func, args, n_jobs):
"""
Applies func to n_jobs slices of args. E.g., if args is an array of 99 items and n_jobs=2, then
func is applied in two parallel processes to args[0:50] and to args[50:99]. func is a function
@@ -114,10 +113,7 @@
return list(itertools.chain.from_iterable(results))
-
-
-[docs]
-def parallel(func, args, n_jobs, seed=None, asarray=True, backend='loky'):
+[docs]def parallel(func, args, n_jobs, seed=None, asarray=True, backend='loky'):
"""
A wrapper of multiprocessing:
@@ -151,10 +147,7 @@
return out
-
-
-[docs]
-@contextlib.contextmanager
+[docs]@contextlib.contextmanager
def temp_seed(random_state):
"""
Can be used in a "with" context to set a temporal seed without modifying the outer numpy's current state. E.g.:
@@ -176,10 +169,7 @@
np.random.set_state(state)
-
-
-[docs]
-def download_file(url, archive_filename):
+[docs]def download_file(url, archive_filename):
"""
Downloads a file from a url
@@ -195,10 +185,7 @@
print("")
-
-
-[docs]
-def download_file_if_not_exists(url, archive_filename):
+[docs]def download_file_if_not_exists(url, archive_filename):
"""
Dowloads a function (using :meth:`download_file`) if the file does not exist.
@@ -211,10 +198,7 @@
download_file(url, archive_filename)
-
-
-[docs]
-def create_if_not_exist(path):
+[docs]def create_if_not_exist(path):
"""
An alias to `os.makedirs(path, exist_ok=True)` that also returns the path. This is useful in cases like, e.g.:
@@ -227,10 +211,7 @@
return path
-
-
-[docs]
-def get_quapy_home():
+[docs]def get_quapy_home():
"""
Gets the home directory of QuaPy, i.e., the directory where QuaPy saves permanent data, such as dowloaded datasets.
This directory is `~/quapy_data`
@@ -242,10 +223,7 @@
return home
-
-
-[docs]
-def create_parent_dir(path):
+[docs]def create_parent_dir(path):
"""
Creates the parent dir (if any) of a given path, if not exists. E.g., for `./path/to/file.txt`, the path `./path/to`
is created.
@@ -257,10 +235,7 @@
os.makedirs(parentdir, exist_ok=True)
-
-
-[docs]
-def save_text_file(path, text):
+[docs]def save_text_file(path, text):
"""
Saves a text file to disk, given its full path, and creates the parent directory if missing.
@@ -272,10 +247,7 @@
fout.write(text)
-
-
-[docs]
-def pickled_resource(pickle_path:str, generation_func:callable, *args):
+[docs]def pickled_resource(pickle_path:str, generation_func:callable, *args):
"""
Allows for fast reuse of resources that are generated only once by calling generation_func(\\*args). The next times
this function is invoked, it loads the pickled resource. Example:
@@ -302,7 +274,6 @@
return instance
-
def _check_sample_size(sample_size):
if sample_size is None:
assert qp.environ['SAMPLE_SIZE'] is not None, \
@@ -313,9 +284,7 @@
return sample_size
-
-[docs]
-class EarlyStop:
+[docs]class EarlyStop:
"""
A class implementing the early-stopping condition typically used for training neural networks.
@@ -370,10 +339,7 @@
self.STOP = True
-
-
diff --git a/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js
index 8141580..8549469 100644
--- a/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js
+++ b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js
@@ -1,9 +1,20 @@
-/* Compatability shim for jQuery and underscores.js.
+/*
+ * _sphinx_javascript_frameworks_compat.js
+ * ~~~~~~~~~~
+ *
+ * Compatability shim for jQuery and underscores.js.
+ *
+ * WILL BE REMOVED IN Sphinx 6.0
+ * xref RemovedInSphinx60Warning
*
- * Copyright Sphinx contributors
- * Released under the two clause BSD licence
*/
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+
/**
* small helper function to urldecode strings
*
diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css
index f316efc..4e9a9f1 100644
--- a/docs/build/html/_static/basic.css
+++ b/docs/build/html/_static/basic.css
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic theme.
*
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@@ -237,10 +237,6 @@ a.headerlink {
visibility: hidden;
}
-a:visited {
- color: #551A8B;
-}
-
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
@@ -328,7 +324,6 @@ aside.sidebar {
p.sidebar-title {
font-weight: bold;
}
-
nav.contents,
aside.topic,
div.admonition, div.topic, blockquote {
@@ -336,7 +331,6 @@ div.admonition, div.topic, blockquote {
}
/* -- topics ---------------------------------------------------------------- */
-
nav.contents,
aside.topic,
div.topic {
@@ -612,7 +606,6 @@ ol.simple p,
ul.simple p {
margin-bottom: 0;
}
-
aside.footnote > span,
div.citation > span {
float: left;
@@ -674,16 +667,6 @@ dd {
margin-left: 30px;
}
-.sig dd {
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
-.sig dl {
- margin-top: 0px;
- margin-bottom: 0px;
-}
-
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
@@ -752,14 +735,6 @@ abbr, acronym {
cursor: help;
}
-.translated {
- background-color: rgba(207, 255, 207, 0.2)
-}
-
-.untranslated {
- background-color: rgba(255, 207, 207, 0.2)
-}
-
/* -- code displays --------------------------------------------------------- */
pre {
diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js
index 4d67807..527b876 100644
--- a/docs/build/html/_static/doctools.js
+++ b/docs/build/html/_static/doctools.js
@@ -4,7 +4,7 @@
*
* Base JavaScript utilities for all Sphinx HTML documentation.
*
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
diff --git a/docs/build/html/_static/documentation_options.js b/docs/build/html/_static/documentation_options.js
index 4099efb..05c1a51 100644
--- a/docs/build/html/_static/documentation_options.js
+++ b/docs/build/html/_static/documentation_options.js
@@ -1,4 +1,5 @@
-const DOCUMENTATION_OPTIONS = {
+var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.1.8',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
diff --git a/docs/build/html/_static/language_data.js b/docs/build/html/_static/language_data.js
index 017600c..2e22b06 100644
--- a/docs/build/html/_static/language_data.js
+++ b/docs/build/html/_static/language_data.js
@@ -5,7 +5,7 @@
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
diff --git a/docs/build/html/_static/searchtools.js b/docs/build/html/_static/searchtools.js
index 8bb1af5..e89e34d 100644
--- a/docs/build/html/_static/searchtools.js
+++ b/docs/build/html/_static/searchtools.js
@@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for the full-text search.
*
- * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@@ -57,12 +57,12 @@ const _removeChildren = (element) => {
const _escapeRegExp = (string) =>
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
-const _displayItem = (item, searchTerms, highlightTerms) => {
+const _displayItem = (item, searchTerms) => {
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
+ const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
- const contentRoot = document.documentElement.dataset.content_root;
const [docName, title, anchor, descr, score, _filename] = item;
@@ -75,24 +75,20 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
if (dirname.match(/\/index\/$/))
dirname = dirname.substring(0, dirname.length - 6);
else if (dirname === "index/") dirname = "";
- requestUrl = contentRoot + dirname;
+ requestUrl = docUrlRoot + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
- requestUrl = contentRoot + docName + docFileSuffix;
+ requestUrl = docUrlRoot + docName + docFileSuffix;
linkUrl = docName + docLinkSuffix;
}
let linkEl = listItem.appendChild(document.createElement("a"));
linkEl.href = linkUrl + anchor;
linkEl.dataset.score = score;
linkEl.innerHTML = title;
- if (descr) {
+ if (descr)
listItem.appendChild(document.createElement("span")).innerHTML =
" (" + descr + ")";
- // highlight search terms in the description
- if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
- highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
- }
else if (showSearchSummary)
fetch(requestUrl)
.then((responseData) => responseData.text())
@@ -101,9 +97,6 @@ const _displayItem = (item, searchTerms, highlightTerms) => {
listItem.appendChild(
Search.makeSearchSummary(data, searchTerms)
);
- // highlight search terms in the summary
- if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js
- highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted"));
});
Search.output.appendChild(listItem);
};
@@ -122,15 +115,14 @@ const _finishSearch = (resultCount) => {
const _displayNextItem = (
results,
resultCount,
- searchTerms,
- highlightTerms,
+ searchTerms
) => {
// results left, load the summary and display it
// this is intended to be dynamic (don't sub resultsCount)
if (results.length) {
- _displayItem(results.pop(), searchTerms, highlightTerms);
+ _displayItem(results.pop(), searchTerms);
setTimeout(
- () => _displayNextItem(results, resultCount, searchTerms, highlightTerms),
+ () => _displayNextItem(results, resultCount, searchTerms),
5
);
}
@@ -164,7 +156,7 @@ const Search = {
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
const docContent = htmlElement.querySelector('[role="main"]');
- if (docContent) return docContent.textContent;
+ if (docContent !== undefined) return docContent.textContent;
console.warn(
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
);
@@ -288,9 +280,9 @@ const Search = {
let results = [];
_removeChildren(document.getElementById("search-progress"));
- const queryLower = query.toLowerCase().trim();
+ const queryLower = query.toLowerCase();
for (const [title, foundTitles] of Object.entries(allTitles)) {
- if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) {
+ if (title.toLowerCase().includes(queryLower) && (queryLower.length >= title.length/2)) {
for (const [file, id] of foundTitles) {
let score = Math.round(100 * queryLower.length / title.length)
results.push([
@@ -368,7 +360,7 @@ const Search = {
// console.info("search results:", Search.lastresults);
// print the results
- _displayNextItem(results, results.length, searchTerms, highlightTerms);
+ _displayNextItem(results, results.length, searchTerms);
},
/**
diff --git a/docs/build/html/_static/sphinx_highlight.js b/docs/build/html/_static/sphinx_highlight.js
index 8a96c69..aae669d 100644
--- a/docs/build/html/_static/sphinx_highlight.js
+++ b/docs/build/html/_static/sphinx_highlight.js
@@ -29,19 +29,14 @@ const _highlight = (node, addItems, text, className) => {
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
- const rest = document.createTextNode(val.substr(pos + text.length));
parent.insertBefore(
span,
parent.insertBefore(
- rest,
+ document.createTextNode(val.substr(pos + text.length)),
node.nextSibling
)
);
node.nodeValue = val.substr(0, pos);
- /* There may be more occurrences of search term in this node. So call this
- * function recursively on the remaining fragment.
- */
- _highlight(rest, addItems, text, className);
if (isInSVG) {
const rect = document.createElementNS(
@@ -145,10 +140,5 @@ const SphinxHighlight = {
},
};
-_ready(() => {
- /* Do not call highlightSearchWords() when we are on the search page.
- * It will highlight words from the *previous* search query.
- */
- if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords();
- SphinxHighlight.initEscapeListener();
-});
+_ready(SphinxHighlight.highlightSearchWords);
+_ready(SphinxHighlight.initEscapeListener);
diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html
index c2451c9..77a4444 100644
--- a/docs/build/html/genindex.html
+++ b/docs/build/html/genindex.html
@@ -1,22 +1,23 @@
-
+
Index — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -686,7 +687,7 @@
module
- - quapy, [1]
+
- quapy
- quapy.classification
@@ -919,7 +920,7 @@
quapy
-
@@ -1261,6 +1262,16 @@
- train_test (quapy.data.base.Dataset property)
+ - training (quapy.classification.neural.CNNnet attribute)
+
+
- transform() (quapy.classification.methods.LowRankLogisticRegression method)
diff --git a/docs/build/html/index.html b/docs/build/html/index.html
index 89d92c8..b40a81c 100644
--- a/docs/build/html/index.html
+++ b/docs/build/html/index.html
@@ -1,24 +1,24 @@
-
+
Welcome to QuaPy’s documentation! — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -73,21 +73,21 @@
-Welcome to QuaPy’s documentation!
+Welcome to QuaPy’s documentation!
QuaPy is a Python-based open-source framework for quantification.
This document contains the API of the modules included in QuaPy.
-Installation
+Installation
pip install quapy
-GitHub
+GitHub
QuaPy is hosted in GitHub at https://github.com/HLT-ISTI/QuaPy
-Contents
+Contents
- quapy
@@ -128,12 +128,14 @@
CNNnet
LSTMnet
@@ -154,6 +156,7 @@
TextClassifierNet.forward()
TextClassifierNet.get_params()
TextClassifierNet.predict_proba()
+TextClassifierNet.training
TextClassifierNet.vocabulary_size
TextClassifierNet.xavier_uniform()
@@ -385,6 +388,7 @@
QuaNetModule
QuaNetTrainer
@@ -673,7 +677,7 @@
-Indices and tables
+Indices and tables
diff --git a/docs/build/html/modules.html b/docs/build/html/modules.html
index 4942493..7ec6971 100644
--- a/docs/build/html/modules.html
+++ b/docs/build/html/modules.html
@@ -1,24 +1,24 @@
-
+
quapy — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
@@ -77,7 +77,7 @@
-quapy
+quapy
- quapy package
diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv
index 35f1681..36ffc9b 100644
Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ
diff --git a/docs/build/html/py-modindex.html b/docs/build/html/py-modindex.html
index 20305fe..8ea21cb 100644
--- a/docs/build/html/py-modindex.html
+++ b/docs/build/html/py-modindex.html
@@ -1,22 +1,23 @@
-
+
Python Module Index — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
diff --git a/docs/build/html/quapy.classification.html b/docs/build/html/quapy.classification.html
index b181a3b..ed5ca09 100644
--- a/docs/build/html/quapy.classification.html
+++ b/docs/build/html/quapy.classification.html
@@ -1,23 +1,24 @@
-
+
quapy.classification package — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -95,15 +96,15 @@
-quapy.classification package
+quapy.classification package
-Submodules
+Submodules
-quapy.classification.calibration module
+quapy.classification.calibration module
-
-class quapy.classification.calibration.BCTSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
+class quapy.classification.calibration.BCTSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
Bases: RecalibratedProbabilisticClassifierBase
Applies the Bias-Corrected Temperature Scaling (BCTS) calibration method from abstention.calibration, as defined in
Alexandari et al. paper:
@@ -124,7 +125,7 @@ training set afterwards. Default value is 5.
-
-class quapy.classification.calibration.NBVSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
+class quapy.classification.calibration.NBVSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
Bases: RecalibratedProbabilisticClassifierBase
Applies the No-Bias Vector Scaling (NBVS) calibration method from abstention.calibration, as defined in
Alexandari et al. paper:
@@ -145,7 +146,7 @@ training set afterwards. Default value is 5.
-
-class quapy.classification.calibration.RecalibratedProbabilisticClassifier[source]
+class quapy.classification.calibration.RecalibratedProbabilisticClassifier[source]
Bases: object
Abstract class for (re)calibration method from abstention.calibration, as defined in
Alexandari, A., Kundaje, A., & Shrikumar, A. (2020, November). Maximum likelihood with bias-corrected calibration
@@ -154,7 +155,7 @@ is hard-to-beat at label shift adaptation. In International Conference on Machin
-
-class quapy.classification.calibration.RecalibratedProbabilisticClassifierBase(classifier, calibrator, val_split=5, n_jobs=None, verbose=False)[source]
+class quapy.classification.calibration.RecalibratedProbabilisticClassifierBase(classifier, calibrator, val_split=5, n_jobs=None, verbose=False)[source]
Bases: BaseEstimator
, RecalibratedProbabilisticClassifier
Applies a (re)calibration method from abstention.calibration, as defined in
Alexandari et al. paper.
@@ -174,7 +175,7 @@ training set afterwards. Default value is 5.
-
-property classes_
+property classes_
Returns the classes on which the classifier has been trained on
- Returns:
@@ -185,7 +186,7 @@ training set afterwards. Default value is 5.
-
-fit(X, y)[source]
+fit(X, y)[source]
Fits the calibration for the probabilistic classifier.
- Parameters:
@@ -202,7 +203,7 @@ training set afterwards. Default value is 5.
-
-fit_cv(X, y)[source]
+fit_cv(X, y)[source]
Fits the calibration in a cross-validation manner, i.e., it generates posterior probabilities for all
training instances via cross-validation, and then retrains the classifier on all training instances.
The posterior probabilities thus generated are used for calibrating the outputs of the classifier.
@@ -221,7 +222,7 @@ The posterior probabilities thus generated are used for calibrating the outputs
-
-fit_tr_val(X, y)[source]
+fit_tr_val(X, y)[source]
Fits the calibration in a train/val-split manner, i.e.t, it partitions the training instances into a
training and a validation set, and then uses the training samples to learn classifier which is then used
to generate posterior probabilities for the held-out validation data. These posteriors are used to calibrate
@@ -241,7 +242,7 @@ the classifier. The classifier is not retrained on the whole dataset.
-
-predict(X)[source]
+predict(X)[source]
Predicts class labels for the data instances in X
- Parameters:
@@ -255,7 +256,7 @@ the classifier. The classifier is not retrained on the whole dataset.
-
-predict_proba(X)[source]
+predict_proba(X)[source]
Generates posterior probabilities for the data instances in X
- Parameters:
@@ -271,7 +272,7 @@ the classifier. The classifier is not retrained on the whole dataset.
-
-class quapy.classification.calibration.TSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
+class quapy.classification.calibration.TSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
Bases: RecalibratedProbabilisticClassifierBase
Applies the Temperature Scaling (TS) calibration method from abstention.calibration, as defined in
Alexandari et al. paper:
@@ -292,7 +293,7 @@ training set afterwards. Default value is 5.
-
-class quapy.classification.calibration.VSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
+class quapy.classification.calibration.VSCalibration(classifier, val_split=5, n_jobs=None, verbose=False)[source]
Bases: RecalibratedProbabilisticClassifierBase
Applies the Vector Scaling (VS) calibration method from abstention.calibration, as defined in
Alexandari et al. paper:
@@ -313,10 +314,10 @@ training set afterwards. Default value is 5.
-quapy.classification.methods module
+quapy.classification.methods module
-
-class quapy.classification.methods.LowRankLogisticRegression(n_components=100, **kwargs)[source]
+class quapy.classification.methods.LowRankLogisticRegression(n_components=100, **kwargs)[source]
Bases: BaseEstimator
An example of a classification method (i.e., an object that implements fit, predict, and predict_proba)
that also generates embedded inputs (i.e., that implements transform), as those required for
@@ -335,7 +336,7 @@ while classification is performed using
-
-fit(X, y)[source]
+fit(X, y)[source]
Fit the model according to the given training data. The fit consists of
fitting TruncatedSVD and then LogisticRegression on the low-rank representation.
-
-predict_proba(X)[source]
+predict_proba(X)[source]
Predicts posterior probabilities for the instances X embedded into the low-rank space.
-quapy.classification.neural module
+quapy.classification.neural module
-
-class quapy.classification.neural.CNNnet(vocabulary_size, n_classes, embedding_size=100, hidden_size=256, repr_size=100, kernel_heights=[3, 5, 7], stride=1, padding=0, drop_p=0.5)[source]
+class quapy.classification.neural.CNNnet(vocabulary_size, n_classes, embedding_size=100, hidden_size=256, repr_size=100, kernel_heights=[3, 5, 7], stride=1, padding=0, drop_p=0.5)[source]
Bases: TextClassifierNet
An implementation of quapy.classification.neural.TextClassifierNet
based on
Convolutional Neural Networks.
@@ -448,7 +449,7 @@ consecutive tokens that each kernel covers
-
-document_embedding(input)[source]
+document_embedding(input)[source]
Embeds documents (i.e., performs the forward pass up to the
next-to-last layer).
@@ -466,7 +467,7 @@ dimensionality of the embedding
-
-get_params()[source]
+get_params()[source]
Get hyper-parameters for this estimator
- Returns:
@@ -475,9 +476,14 @@ dimensionality of the embedding
+
+-
+training: bool
+
+
-
-property vocabulary_size
+property vocabulary_size
Return the size of the vocabulary
- Returns:
@@ -490,7 +496,7 @@ dimensionality of the embedding
-
-class quapy.classification.neural.LSTMnet(vocabulary_size, n_classes, embedding_size=100, hidden_size=256, repr_size=100, lstm_class_nlayers=1, drop_p=0.5)[source]
+class quapy.classification.neural.LSTMnet(vocabulary_size, n_classes, embedding_size=100, hidden_size=256, repr_size=100, lstm_class_nlayers=1, drop_p=0.5)[source]
Bases: TextClassifierNet
An implementation of quapy.classification.neural.TextClassifierNet
based on
Long Short Term Memory networks.
@@ -509,7 +515,7 @@ Long Short Term Memory networks.
-
-document_embedding(x)[source]
+document_embedding(x)[source]
Embeds documents (i.e., performs the forward pass up to the
next-to-last layer).
@@ -527,7 +533,7 @@ dimensionality of the embedding
-
-get_params()[source]
+get_params()[source]
Get hyper-parameters for this estimator
- Returns:
@@ -536,9 +542,14 @@ dimensionality of the embedding
+
+-
+training: bool
+
+
-
-property vocabulary_size
+property vocabulary_size
Return the size of the vocabulary
- Returns:
@@ -551,7 +562,7 @@ dimensionality of the embedding
-
-class quapy.classification.neural.NeuralClassifierTrainer(net: TextClassifierNet, lr=0.001, weight_decay=0, patience=10, epochs=200, batch_size=64, batch_size_test=512, padding_length=300, device='cuda', checkpointpath='../checkpoint/classifier_net.dat')[source]
+class quapy.classification.neural.NeuralClassifierTrainer(net: TextClassifierNet, lr=0.001, weight_decay=0, patience=10, epochs=200, batch_size=64, batch_size_test=512, padding_length=300, device='cuda', checkpointpath='../checkpoint/classifier_net.dat')[source]
Bases: object
Trains a neural network for text classification.
@@ -574,7 +585,7 @@ according to the evaluation in the held-out validation split (default ‘../chec
-
-property device
+property device
Gets the device in which the network is allocated
- Returns:
@@ -585,7 +596,7 @@ according to the evaluation in the held-out validation split (default ‘../chec
-
-fit(instances, labels, val_split=0.3)[source]
+fit(instances, labels, val_split=0.3)[source]
Fits the model according to the given training data.
- Parameters:
@@ -603,7 +614,7 @@ according to the evaluation in the held-out validation split (default ‘../chec
-
-get_params()[source]
+get_params()[source]
Get hyper-parameters for this estimator
- Returns:
@@ -614,7 +625,7 @@ according to the evaluation in the held-out validation split (default ‘../chec
-
-predict(instances)[source]
+predict(instances)[source]
Predicts labels for the instances
- Parameters:
@@ -629,7 +640,7 @@ instances in X
-
-predict_proba(instances)[source]
+predict_proba(instances)[source]
Predicts posterior probabilities for the instances
- Parameters:
@@ -643,7 +654,7 @@ instances in X
-
-reset_net_params(vocab_size, n_classes)[source]
+reset_net_params(vocab_size, n_classes)[source]
Reinitialize the network parameters
- Parameters:
@@ -657,7 +668,7 @@ instances in X
-
-set_params(**params)[source]
+set_params(**params)[source]
Set the parameters of this trainer and the learner it is training.
In this current version, parameter names for the trainer and learner should
be disjoint.
@@ -670,7 +681,7 @@ be disjoint.
-
-transform(instances)[source]
+transform(instances)[source]
Returns the embeddings of the instances
- Parameters:
@@ -687,12 +698,12 @@ where embed_size is defined by the classification network
-
-class quapy.classification.neural.TextClassifierNet(*args, **kwargs)[source]
+class quapy.classification.neural.TextClassifierNet(*args, **kwargs)[source]
Bases: Module
Abstract Text classifier (torch.nn.Module)
-
-dimensions()[source]
+dimensions()[source]
Gets the number of dimensions of the embedding space
- Returns:
@@ -703,7 +714,7 @@ where embed_size is defined by the classification network
-
-abstract document_embedding(x)[source]
+abstract document_embedding(x)[source]
Embeds documents (i.e., performs the forward pass up to the
next-to-last layer).
@@ -721,7 +732,7 @@ dimensionality of the embedding
-
-forward(x)[source]
+forward(x)[source]
Performs the forward pass.
- Parameters:
@@ -737,7 +748,7 @@ for each of the instances and classes
-
-abstract get_params()[source]
+abstract get_params()[source]
Get hyper-parameters for this estimator
- Returns:
@@ -748,7 +759,7 @@ for each of the instances and classes
-
-predict_proba(x)[source]
+predict_proba(x)[source]
Predicts posterior probabilities for the instances in x
- Parameters:
@@ -762,9 +773,14 @@ is length of the pad in the batch
+
+-
+training: bool
+
+
-
-property vocabulary_size
+property vocabulary_size
Return the size of the vocabulary
- Returns:
@@ -775,7 +791,7 @@ is length of the pad in the batch
-
-xavier_uniform()[source]
+xavier_uniform()[source]
Performs Xavier initialization of the network parameters
@@ -783,7 +799,7 @@ is length of the pad in the batch
-
-class quapy.classification.neural.TorchDataset(instances, labels=None)[source]
+class quapy.classification.neural.TorchDataset(instances, labels=None)[source]
Bases: Dataset
Transforms labelled instances into a Torch’s torch.utils.data.DataLoader
object
@@ -796,7 +812,7 @@ is length of the pad in the batch
-
-asDataloader(batch_size, shuffle, pad_length, device)[source]
+asDataloader(batch_size, shuffle, pad_length, device)[source]
Converts the labelled collection into a Torch DataLoader with dynamic padding for
the batch
@@ -820,10 +836,10 @@ applied, meaning that if the longest document in the batch is shorter than
-quapy.classification.svmperf module
+quapy.classification.svmperf module
-
-class quapy.classification.svmperf.SVMperf(svmperf_base, C=0.01, verbose=False, loss='01', host_folder=None)[source]
+class quapy.classification.svmperf.SVMperf(svmperf_base, C=0.01, verbose=False, loss='01', host_folder=None)[source]
Bases: BaseEstimator
, ClassifierMixin
A wrapper for the SVM-perf package by Thorsten Joachims.
When using losses for quantification, the source code has to be patched. See
@@ -848,7 +864,7 @@ for further details.
-
-decision_function(X, y=None)[source]
+decision_function(X, y=None)[source]
Evaluate the decision function for the samples in X.
-Module contents
+Module contents
diff --git a/docs/build/html/quapy.data.html b/docs/build/html/quapy.data.html
index fd7a730..ff193e0 100644
--- a/docs/build/html/quapy.data.html
+++ b/docs/build/html/quapy.data.html
@@ -1,23 +1,24 @@
-
+
quapy.data package — QuaPy: A Python-based open-source framework for quantification 0.1.8 documentation
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
@@ -95,15 +96,15 @@
-quapy.data package
+quapy.data package
-Submodules
+Submodules
-quapy.data.base module
+quapy.data.base module
-
-class quapy.data.base.Dataset(training: LabelledCollection, test: LabelledCollection, vocabulary: dict | None = None, name='')[source]
+class quapy.data.base.Dataset(training: LabelledCollection, test: LabelledCollection, vocabulary: Optional[dict] = None, name='')[source]
Bases: object
Abstraction of training and test LabelledCollection
objects.
@@ -118,7 +119,7 @@
-
-classmethod SplitStratified(collection: LabelledCollection, train_size=0.6)[source]
+classmethod SplitStratified(collection: LabelledCollection, train_size=0.6)[source]
Generates a Dataset
from a stratified split of a LabelledCollection
instance.
See LabelledCollection.split_stratified()
@@ -136,7 +137,7 @@ See
-
-property binary
+property binary
Returns True if the training collection is labelled according to two classes
- Returns:
@@ -147,7 +148,7 @@ See
-
-property classes_
+property classes_
The classes according to which the training collection is labelled
- Returns:
@@ -158,7 +159,7 @@ See
-
-classmethod kFCV(data: LabelledCollection, nfolds=5, nrepeats=1, random_state=0)[source]
+classmethod kFCV(data: LabelledCollection, nfolds=5, nrepeats=1, random_state=0)[source]
Generator of stratified folds to be used in k-fold cross validation. This function is only a wrapper around
LabelledCollection.kFCV()
that returns Dataset
instances made of training and test folds.
@@ -177,7 +178,7 @@ See
-
-classmethod load(train_path, test_path, loader_func: callable, classes=None, **loader_kwargs)[source]
+classmethod load(train_path, test_path, loader_func: callable, classes=None, **loader_kwargs)[source]
Loads a training and a test labelled set of data and convert it into a Dataset
instance.
The function in charge of reading the instances must be specified. This function can be a custom one, or any of
the reading functions defined in quapy.data.reader
module.
@@ -201,7 +202,7 @@ See
-
-property n_classes
+property n_classes
The number of classes according to which the training collection is labelled
- Returns:
@@ -212,7 +213,7 @@ See
-
-reduce(n_train=100, n_test=100)[source]
+reduce(n_train=100, n_test=100)[source]
Reduce the number of instances in place for quick experiments. Preserves the prevalence of each set.
- Parameters:
@@ -229,7 +230,7 @@ See
-
-stats(show=True)[source]
+stats(show=True)[source]
Returns (and eventually prints) a dictionary with some stats of this dataset. E.g.,:
>>> data = qp.datasets.fetch_reviews('kindle', tfidf=True, min_df=5)
>>> data.stats()
@@ -252,7 +253,7 @@ the collection), prevs (the prevalence values for each class)
-
-property train_test
+property train_test
Alias to self.training and self.test
- Returns:
@@ -266,7 +267,7 @@ the collection), prevs (the prevalence values for each class)
-
-property vocabulary_size
+property vocabulary_size
If the dataset is textual, and the vocabulary was indicated, returns the size of the vocabulary
- Returns:
@@ -279,7 +280,7 @@ the collection), prevs (the prevalence values for each class)
-
-class quapy.data.base.LabelledCollection(instances, labels, classes=None)[source]
+class quapy.data.base.LabelledCollection(instances, labels, classes=None)[source]
Bases: object
A LabelledCollection is a set of objects each with a label attached to each of them.
This class implements several sampling routines and other utilities.
@@ -296,7 +297,7 @@ from the labels. The classes must be indicated in cases in which some of the lab
-
-property X
+property X
An alias to self.instances
- Returns:
@@ -307,7 +308,7 @@ from the labels. The classes must be indicated in cases in which some of the lab
-
-property Xp
+property Xp
Gets the instances and the true prevalence. This is useful when implementing evaluation protocols from
a LabelledCollection
object.
@@ -319,7 +320,7 @@ a
-
-property Xy
+property Xy
Gets the instances and labels. This is useful when working with sklearn estimators, e.g.:
>>> svm = LinearSVC().fit(*my_collection.Xy)
@@ -333,7 +334,7 @@ a
-
-property binary
+property binary
Returns True if the number of classes is 2
- Returns:
@@ -344,7 +345,7 @@ a
-
-counts()[source]
+counts()[source]
Returns the number of instances for each of the classes in the codeframe.
- Returns:
@@ -356,7 +357,7 @@ as listed by self.classes_
-
-classmethod join(*args: Iterable[LabelledCollection])[source]
+classmethod join(*args: Iterable[LabelledCollection])[source]
Returns a new LabelledCollection
as the union of the collections given in input.
- Parameters:
@@ -370,7 +371,7 @@ as listed by self.classes_
-
-kFCV(nfolds=5, nrepeats=1, random_state=None)[source]
+kFCV(nfolds=5, nrepeats=1, random_state=None)[source]
Generator of stratified folds to be used in k-fold cross validation.
- Parameters:
@@ -388,7 +389,7 @@ as listed by self.classes_
-
-classmethod load(path: str, loader_func: callable, classes=None, **loader_kwargs)[source]
+classmethod load(path: str, loader_func: callable, classes=None, **loader_kwargs)[source]
Loads a labelled set of data and convert it into a LabelledCollection
instance. The function in charge
of reading the instances must be specified. This function can be a custom one, or any of the reading functions
defined in quapy.data.reader
module.
@@ -411,7 +412,7 @@ these arguments are used to call loader_func(path, **loader_kwargs)
-
-property n_classes
+property n_classes
The number of classes
- Returns:
@@ -422,7 +423,7 @@ these arguments are used to call loader_func(path, **loader_kwargs)
-
-property p
+property p
An alias to self.prevalence()
- Returns:
@@ -433,7 +434,7 @@ these arguments are used to call loader_func(path, **loader_kwargs)
-
-prevalence()[source]
+prevalence()[source]
Returns the prevalence, or relative frequency, of the classes in the codeframe.
- Returns:
@@ -445,7 +446,7 @@ as listed by self.classes_
-
-sampling(size, *prevs, shuffle=True, random_state=None)[source]
+sampling(size, *prevs, shuffle=True, random_state=None)[source]
Return a random sample (an instance of LabelledCollection
) of desired size and desired prevalence
values. For each class, the sampling is drawn without replacement if the requested prevalence is larger than
the actual prevalence of the class, or with replacement otherwise.
@@ -469,7 +470,7 @@ prevalence == prevs if the exact prevalence values can be met as pr
-
-sampling_from_index(index)[source]
+sampling_from_index(index)[source]
Returns an instance of LabelledCollection
whose elements are sampled from this collection using the
index.
@@ -484,7 +485,7 @@ index.
-
-sampling_index(size, *prevs, shuffle=True, random_state=None)[source]
+sampling_index(size, *prevs, shuffle=True, random_state=None)[source]
Returns an index to be used to extract a random sample of desired size and desired prevalence values. If the
prevalence values are not specified, then returns the index of a uniform sampling.
For each class, the sampling is drawn with replacement if the requested prevalence is larger than
@@ -508,7 +509,7 @@ it is constrained. E.g., for binary collections, only the prevalence p
-
-