2500 lines
275 KiB
HTML
2500 lines
275 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
<html lang="en" data-content_root="../../../" >
|
||
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>quapy.method.aggregative — QuaPy: A Python-based open-source framework for quantification 0.2.1 documentation</title>
|
||
|
||
|
||
|
||
<script data-cfasync="false">
|
||
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
|
||
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
|
||
</script>
|
||
<!--
|
||
this give us a css class that will be invisible only if js is disabled
|
||
-->
|
||
<noscript>
|
||
<style>
|
||
.pst-js-only { display: none !important; }
|
||
|
||
</style>
|
||
</noscript>
|
||
|
||
<!-- Loaded before other Sphinx assets -->
|
||
<link href="../../../_static/styles/theme.css?digest=90905a2f556bf617f1a9" rel="stylesheet" />
|
||
<link href="../../../_static/styles/pydata-sphinx-theme.css?digest=90905a2f556bf617f1a9" rel="stylesheet" />
|
||
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css?v=8f2a1f02" />
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/sphinx-design.min.css?v=95c83b7e" />
|
||
<link rel="stylesheet" type="text/css" href="../../../_static/custom.css?v=9f2a2228" />
|
||
|
||
<!-- So that users can add custom icons -->
|
||
<script defer src="../../../_static/scripts/fontawesome.js?digest=90905a2f556bf617f1a9"></script>
|
||
<!-- Pre-loaded scripts that we'll load fully later -->
|
||
<link rel="preload" as="script" href="../../../_static/scripts/bootstrap.js?digest=90905a2f556bf617f1a9" />
|
||
<link rel="preload" as="script" href="../../../_static/scripts/pydata-sphinx-theme.js?digest=90905a2f556bf617f1a9" />
|
||
|
||
<script src="../../../_static/documentation_options.js?v=37f418d5"></script>
|
||
<script src="../../../_static/doctools.js?v=fd6eb6e6"></script>
|
||
<script src="../../../_static/sphinx_highlight.js?v=6ffebe34"></script>
|
||
<script src="../../../_static/design-tabs.js?v=f930bc37"></script>
|
||
<script>DOCUMENTATION_OPTIONS.pagename = '_modules/quapy/method/aggregative';</script>
|
||
<script>DOCUMENTATION_OPTIONS.search_as_you_type = false;</script>
|
||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||
<link rel="search" title="Search" href="../../../search.html" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
<meta name="docsearch:language" content="en"/>
|
||
<meta name="docsearch:version" content="" />
|
||
|
||
|
||
<script src="../../../_static/searchtools.js"></script>
|
||
<script src="../../../_static/language_data.js"></script>
|
||
<script src="../../../searchindex.js"></script>
|
||
|
||
</head>
|
||
<body data-default-mode="">
|
||
|
||
|
||
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
|
||
|
||
|
||
<div id="pst-scroll-pixel-helper"></div>
|
||
|
||
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
|
||
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
|
||
|
||
|
||
|
||
|
||
<dialog id="pst-search-dialog">
|
||
|
||
<form class="bd-search d-flex align-items-center"
|
||
action="../../../search.html"
|
||
method="get">
|
||
<i class="fa-solid fa-magnifying-glass"></i>
|
||
<input type="search"
|
||
class="form-control"
|
||
name="q"
|
||
placeholder="Search the docs ..."
|
||
aria-label="Search the docs ..."
|
||
autocomplete="off"
|
||
autocorrect="off"
|
||
autocapitalize="off"
|
||
spellcheck="false"/>
|
||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
|
||
</form>
|
||
</dialog>
|
||
|
||
<div class="pst-async-banner-revealer d-none">
|
||
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
|
||
</div>
|
||
|
||
|
||
<header id="pst-header" class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
|
||
<div class="bd-header__inner bd-page-width">
|
||
<button class="pst-navbar-icon sidebar-toggle primary-toggle" aria-label="Site navigation">
|
||
<span class="fa-solid fa-bars"></span>
|
||
</button>
|
||
|
||
|
||
<div class="col-lg-3 navbar-header-items__start">
|
||
|
||
<div class="navbar-item">
|
||
|
||
|
||
|
||
|
||
|
||
<a class="navbar-brand logo" href="../../../index.html">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<img src="../../../_static/quapy_logo.png" class="logo__image only-light" alt="QuaPy: A Python-based open-source framework for quantification 0.2.1 documentation - Home"/>
|
||
<img src="../../../_static/quapy_logo_dark.png" class="logo__image only-dark pst-js-only" alt="QuaPy: A Python-based open-source framework for quantification 0.2.1 documentation - Home"/>
|
||
|
||
|
||
</a></div>
|
||
|
||
</div>
|
||
|
||
<div class="col-lg-9 navbar-header-items">
|
||
|
||
<div class="me-auto navbar-header-items__center">
|
||
|
||
<div class="navbar-item">
|
||
<nav>
|
||
<ul class="bd-navbar-elements navbar-nav">
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../index.html">
|
||
Home
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../manuals.html">
|
||
Manuals
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../quapy.html">
|
||
API
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</nav></div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="navbar-header-items__end">
|
||
|
||
<div class="navbar-item navbar-persistent--container">
|
||
|
||
|
||
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<i class="fa-solid fa-magnifying-glass"></i>
|
||
<span class="search-button__default-text">Search</span>
|
||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
|
||
</button>
|
||
</div>
|
||
|
||
|
||
<div class="navbar-item">
|
||
|
||
<div class="theme-switch-container dropdown pst-js-only" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Color mode">
|
||
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button dropdown-toggle" aria-label="Color mode" data-bs-toggle="dropdown">
|
||
<i class="theme-switch fa-solid fa-sun fa-lg fa-fw" data-mode="light" title="Light"></i>
|
||
<i class="theme-switch fa-solid fa-moon fa-lg fa-fw" data-mode="dark" title="Dark"></i>
|
||
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg fa-fw" data-mode="auto" title="System Settings"></i>
|
||
</button>
|
||
<ul class="dropdown-menu dropdown-menu-end">
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="auto"><i class="fa-solid fa-circle-half-stroke fa-lg fa-fw me-1"></i>System Settings</button></li>
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="light"><i class="fa-solid fa-sun fa-lg fa-fw me-1"></i>Light</button></li>
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="dark"><i class="fa-solid fa-moon fa-lg fa-fw me-1"></i>Dark</button></li>
|
||
</ul>
|
||
</div></div>
|
||
|
||
<div class="navbar-item"><ul class="navbar-icon-links"
|
||
aria-label="Icon Links">
|
||
<li class="nav-item">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://github.com/HLT-ISTI/QuaPy" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-github fa-lg" aria-hidden="true"></i><span class="visually-hidden">GitHub</span></a>
|
||
</li>
|
||
</ul></div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="navbar-persistent--mobile">
|
||
|
||
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<i class="fa-solid fa-magnifying-glass"></i>
|
||
<span class="search-button__default-text">Search</span>
|
||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
|
||
</button>
|
||
</div>
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</header>
|
||
|
||
|
||
<div class="bd-container">
|
||
<div class="bd-container__inner bd-page-width">
|
||
|
||
|
||
|
||
|
||
|
||
<dialog id="pst-primary-sidebar-modal"></dialog>
|
||
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar hide-on-wide">
|
||
|
||
|
||
|
||
<div class="sidebar-header-items sidebar-primary__section">
|
||
|
||
|
||
<div class="sidebar-header-items__center">
|
||
|
||
|
||
|
||
<div class="navbar-item">
|
||
<nav>
|
||
<ul class="bd-navbar-elements navbar-nav">
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../index.html">
|
||
Home
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../manuals.html">
|
||
Manuals
|
||
</a>
|
||
</li>
|
||
|
||
|
||
<li class="nav-item ">
|
||
<a class="nav-link nav-internal" href="../../../quapy.html">
|
||
API
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</nav></div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="sidebar-header-items__end">
|
||
|
||
<div class="navbar-item">
|
||
|
||
<div class="theme-switch-container dropdown pst-js-only" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Color mode">
|
||
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button dropdown-toggle" aria-label="Color mode" data-bs-toggle="dropdown">
|
||
<i class="theme-switch fa-solid fa-sun fa-lg fa-fw" data-mode="light" title="Light"></i>
|
||
<i class="theme-switch fa-solid fa-moon fa-lg fa-fw" data-mode="dark" title="Dark"></i>
|
||
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg fa-fw" data-mode="auto" title="System Settings"></i>
|
||
</button>
|
||
<ul class="dropdown-menu dropdown-menu-end">
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="auto"><i class="fa-solid fa-circle-half-stroke fa-lg fa-fw me-1"></i>System Settings</button></li>
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="light"><i class="fa-solid fa-sun fa-lg fa-fw me-1"></i>Light</button></li>
|
||
<li><button class="dropdown-item d-flex align-items-center theme-change-button" data-mode="dark"><i class="fa-solid fa-moon fa-lg fa-fw me-1"></i>Dark</button></li>
|
||
</ul>
|
||
</div></div>
|
||
|
||
<div class="navbar-item"><ul class="navbar-icon-links"
|
||
aria-label="Icon Links">
|
||
<li class="nav-item">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://github.com/HLT-ISTI/QuaPy" title="GitHub" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-brands fa-github fa-lg" aria-hidden="true"></i><span class="visually-hidden">GitHub</span></a>
|
||
</li>
|
||
</ul></div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="sidebar-primary-items__end sidebar-primary__section">
|
||
<div class="sidebar-primary-item">
|
||
<div id="ethical-ad-placement"
|
||
class="flat"
|
||
data-ea-publisher="readthedocs"
|
||
data-ea-type="readthedocs-sidebar"
|
||
data-ea-manual="true">
|
||
</div></div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<main id="main-content" class="bd-main" role="main">
|
||
|
||
|
||
<div class="bd-content">
|
||
<div class="bd-article-container">
|
||
|
||
<div class="bd-header-article d-print-none">
|
||
<div class="header-article-items header-article__inner">
|
||
|
||
<div class="header-article-items__start">
|
||
|
||
<div class="header-article-item">
|
||
|
||
<nav aria-label="Breadcrumb" class="d-print-none">
|
||
<ul class="bd-breadcrumbs">
|
||
|
||
<li class="breadcrumb-item breadcrumb-home">
|
||
<a href="../../../index.html" class="nav-link" aria-label="Home">
|
||
<i class="fa-solid fa-home"></i>
|
||
</a>
|
||
</li>
|
||
|
||
<li class="breadcrumb-item"><a href="../../index.html" class="nav-link">Module code</a></li>
|
||
|
||
<li class="breadcrumb-item active" aria-current="page"><span class="ellipsis">quapy.method.aggregative</span></li>
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div id="searchbox"></div>
|
||
<article class="bd-article">
|
||
|
||
<h1>Source code for quapy.method.aggregative</h1><div class="highlight"><pre>
|
||
<span></span><span class="kn">import</span><span class="w"> </span><span class="nn">warnings</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">abc</span><span class="w"> </span><span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">copy</span><span class="w"> </span><span class="kn">import</span> <span class="n">deepcopy</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">typing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">Literal</span><span class="p">,</span> <span class="n">Union</span>
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">numpy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">np</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseEstimator</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.calibration</span><span class="w"> </span><span class="kn">import</span> <span class="n">CalibratedClassifierCV</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.exceptions</span><span class="w"> </span><span class="kn">import</span> <span class="n">NotFittedError</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.metrics</span><span class="w"> </span><span class="kn">import</span> <span class="n">confusion_matrix</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.model_selection</span><span class="w"> </span><span class="kn">import</span> <span class="n">cross_val_predict</span><span class="p">,</span> <span class="n">train_test_split</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">sklearn.utils.validation</span><span class="w"> </span><span class="kn">import</span> <span class="n">check_is_fitted</span>
|
||
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">quapy</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">qp</span>
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">quapy.functional</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">F</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.functional</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_divergence</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.classification.svmperf</span><span class="w"> </span><span class="kn">import</span> <span class="n">SVMperf</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.data</span><span class="w"> </span><span class="kn">import</span> <span class="n">LabelledCollection</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.method.base</span><span class="w"> </span><span class="kn">import</span> <span class="n">BaseQuantifier</span><span class="p">,</span> <span class="n">BinaryQuantifier</span><span class="p">,</span> <span class="n">OneVsAllGeneric</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.method._energy</span><span class="w"> </span><span class="kn">import</span> <span class="n">_EnergyDistanceCore</span>
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">quapy.method._helper</span><span class="w"> </span><span class="kn">import</span> <span class="p">(</span>
|
||
<span class="n">_get_abstention_calibrators</span><span class="p">,</span>
|
||
<span class="n">_get_cvxpy</span><span class="p">,</span>
|
||
<span class="n">_rlls_check_mode</span><span class="p">,</span>
|
||
<span class="n">_rlls_joint_distribution</span><span class="p">,</span>
|
||
<span class="n">_rlls_predicted_marginal</span><span class="p">,</span>
|
||
<span class="n">_rlls_compute_3deltaC</span><span class="p">,</span>
|
||
<span class="n">_rlls_compute_weights</span><span class="p">,</span>
|
||
<span class="n">_labels_to_indices</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
|
||
|
||
|
||
<span class="c1"># Abstract classes</span>
|
||
<span class="c1"># ------------------------------------</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">AggregativeQuantifier</span><span class="p">(</span><span class="n">BaseQuantifier</span><span class="p">,</span> <span class="n">ABC</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Abstract class for quantification methods that base their estimations on the aggregation of classification</span>
|
||
<span class="sd"> results. Aggregative quantifiers implement a pipeline that consists of generating classification predictions</span>
|
||
<span class="sd"> and aggregating them. For this reason, the training phase is implemented by :meth:`classification_fit` followed</span>
|
||
<span class="sd"> by :meth:`aggregation_fit`, while the testing phase is implemented by :meth:`classify` followed by</span>
|
||
<span class="sd"> :meth:`aggregate`. Subclasses of this abstract class must provide implementations for these methods.</span>
|
||
<span class="sd"> Aggregative quantifiers also maintain a :attr:`classifier` attribute.</span>
|
||
|
||
<span class="sd"> The method :meth:`fit` comes with a default implementation based on :meth:`classification_fit`</span>
|
||
<span class="sd"> and :meth:`aggregation_fit`.</span>
|
||
|
||
<span class="sd"> The method :meth:`quantify` comes with a default implementation based on :meth:`classify`</span>
|
||
<span class="sd"> and :meth:`aggregate`.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple `(X,y)` defining the specific set of data to use for validation. Set to</span>
|
||
<span class="sd"> None when the method does not require any validation data, in order to avoid that some portion of</span>
|
||
<span class="sd"> the training data be wasted.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
|
||
<span class="n">classifier</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="kc">None</span><span class="p">,</span><span class="n">BaseEstimator</span><span class="p">],</span>
|
||
<span class="n">fit_classifier</span><span class="p">:</span><span class="nb">bool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">val_split</span><span class="p">:</span><span class="n">Union</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span><span class="nb">float</span><span class="p">,</span><span class="nb">tuple</span><span class="p">,</span><span class="kc">None</span><span class="p">]</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_classifier</span><span class="p">(</span><span class="n">classifier</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span> <span class="o">=</span> <span class="n">fit_classifier</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">val_split</span> <span class="o">=</span> <span class="n">val_split</span>
|
||
|
||
<span class="c1"># basic type checks</span>
|
||
<span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="s1">'fit'</span><span class="p">),</span> \
|
||
<span class="sa">f</span><span class="s1">'the classifier does not implement "fit"'</span>
|
||
|
||
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">fit_classifier</span><span class="p">,</span> <span class="nb">bool</span><span class="p">),</span> \
|
||
<span class="sa">f</span><span class="s1">'unexpected type for </span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1">; must be True or False'</span>
|
||
|
||
<span class="c1"># val_split is indicated as a number of folds for cross-validation</span>
|
||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="n">val_split</span> <span class="o">></span> <span class="mi">1</span><span class="p">,</span> \
|
||
<span class="p">(</span><span class="sa">f</span><span class="s1">'when </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> is indicated as an integer, it represents the number of folds in a kFCV '</span>
|
||
<span class="sa">f</span><span class="s1">'and must thus be >1'</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">val_split</span><span class="o">==</span><span class="mi">5</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">fit_classifier</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> will be ignored when the classifier is already trained '</span>
|
||
<span class="sa">f</span><span class="s1">'(</span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1">). Parameter </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> will be set to None. Set </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> '</span>
|
||
<span class="sa">f</span><span class="s1">'to None to avoid this warning.'</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="o">=</span><span class="kc">None</span>
|
||
<span class="k">if</span> <span class="n">val_split</span><span class="o">!=</span><span class="mi">5</span><span class="p">:</span>
|
||
<span class="k">assert</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="p">(</span><span class="sa">f</span><span class="s1">'Parameter </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> has been modified, but </span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1"> '</span>
|
||
<span class="sa">f</span><span class="s1">'indicates the classifier should not be retrained.'</span><span class="p">)</span>
|
||
<span class="c1"># val_split is indicated as a fraction of validation instances</span>
|
||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="mi">0</span> <span class="o"><</span> <span class="n">val_split</span> <span class="o"><</span> <span class="mi">1</span><span class="p">,</span> \
|
||
<span class="p">(</span><span class="sa">f</span><span class="s1">'when </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> is indicated as a float, it represents the fraction of training instances '</span>
|
||
<span class="sa">f</span><span class="s1">'to be used for validation, and must thus be in the range (0,1)'</span><span class="p">)</span>
|
||
<span class="k">assert</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="p">(</span><span class="sa">f</span><span class="s1">'when </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> is indicated as a float (the fraction of training instances '</span>
|
||
<span class="sa">f</span><span class="s1">'to be used for validation), the parameter </span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1"> must be True'</span><span class="p">)</span>
|
||
<span class="c1"># val_split is indicated as a validation collection (X,y)</span>
|
||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">val_split</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> \
|
||
<span class="p">(</span><span class="sa">f</span><span class="s1">'when </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> is indicated as a tuple, it represents the collection (X,y) on which the '</span>
|
||
<span class="sa">f</span><span class="s1">'validation must be performed, but this seems to have different cardinality'</span><span class="p">)</span>
|
||
<span class="k">elif</span> <span class="n">val_split</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">pass</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'unexpected type for </span><span class="si">{</span><span class="n">val_split</span><span class="si">=}</span><span class="s1">'</span><span class="p">)</span>
|
||
|
||
<span class="c1"># classifier is fitted?</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">check_is_fitted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">)</span>
|
||
<span class="n">fitted</span> <span class="o">=</span> <span class="kc">True</span>
|
||
<span class="k">except</span> <span class="n">NotFittedError</span><span class="p">:</span>
|
||
<span class="n">fitted</span> <span class="o">=</span> <span class="kc">False</span>
|
||
|
||
<span class="c1"># consistency checks: fit_classifier?</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="n">fitted</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">RuntimeWarning</span><span class="p">(</span><span class="sa">f</span><span class="s1">'the classifier is already fitted, but </span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1"> was requested'</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">assert</span> <span class="n">fitted</span><span class="p">,</span> <span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1"> requires the classifier to be already trained, '</span>
|
||
<span class="sa">f</span><span class="s1">'but this does not seem to be'</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Implements any check to be performed in the parameters of the init method before undertaking</span>
|
||
<span class="sd"> the training of the quantifier. This is made as to allow for a quick execution stop when the</span>
|
||
<span class="sd"> parameters are not valid.</span>
|
||
|
||
<span class="sd"> :return: Nothing. May raise an exception.</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">pass</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_non_empty_classes</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Asserts all classes have positive instances.</span>
|
||
|
||
<span class="sd"> :param labels: array-like of shape `(n_instances,)` with the label for each instance</span>
|
||
<span class="sd"> :param classes: the class labels. This is needed in order to correctly compute the prevalence vector even when</span>
|
||
<span class="sd"> some classes have no examples.</span>
|
||
<span class="sd"> :return: Nothing. May raise an exception.</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">sample_prevs</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_labels</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">)</span>
|
||
<span class="n">empty_classes</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">sample_prevs</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">flatten</span><span class="p">()</span>
|
||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">empty_classes</span><span class="p">)</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="n">empty_class_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">[</span><span class="n">empty_classes</span><span class="p">]</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'classes </span><span class="si">{</span><span class="n">empty_class_names</span><span class="si">}</span><span class="s1"> have no training examples'</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregative quantifier. This comes down to training a classifier (if requested) and an</span>
|
||
<span class="sd"> aggregation function.</span>
|
||
|
||
<span class="sd"> :param X: array-like of shape `(n_samples, n_features)`, the training instances</span>
|
||
<span class="sd"> :param y: array-like of shape `(n_samples,)`, the labels</span>
|
||
<span class="sd"> :return: self</span>
|
||
<span class="sd"> """</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_check_init_parameters</span><span class="p">()</span>
|
||
<span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier_fit_predict</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">aggregation_fit</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="bp">self</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.classifier_fit_predict">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.classifier_fit_predict">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classifier_fit_predict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the classifier if requested (`fit_classifier=True`) and generate the necessary predictions to</span>
|
||
<span class="sd"> train the aggregation function.</span>
|
||
|
||
<span class="sd"> :param X: array-like of shape `(n_samples, n_features)`, the training instances</span>
|
||
<span class="sd"> :param y: array-like of shape `(n_samples,)`, the labels</span>
|
||
<span class="sd"> """</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_check_classifier</span><span class="p">(</span><span class="n">adapt_if_necessary</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">)</span>
|
||
|
||
<span class="c1"># self._check_non_empty_classes(y)</span>
|
||
|
||
<span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
|
||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="si">}</span><span class="s1">: unexpected value for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1">'</span>
|
||
<span class="n">num_folds</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span>
|
||
<span class="n">n_jobs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'n_jobs'</span><span class="p">)</span> <span class="k">else</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="kc">None</span><span class="p">)</span>
|
||
<span class="n">predictions</span> <span class="o">=</span> <span class="n">cross_val_predict</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">cv</span><span class="o">=</span><span class="n">num_folds</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="n">n_jobs</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_classifier_method</span><span class="p">()</span>
|
||
<span class="p">)</span>
|
||
<span class="n">labels</span> <span class="o">=</span> <span class="n">y</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
|
||
<span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">,</span> <span class="sa">f</span><span class="s1">'unexpected value for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="si">=}</span><span class="s1">'</span>
|
||
<span class="n">train_prop</span> <span class="o">=</span> <span class="mf">1.</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span>
|
||
<span class="n">Xtr</span><span class="p">,</span> <span class="n">Xval</span><span class="p">,</span> <span class="n">ytr</span><span class="p">,</span> <span class="n">yval</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">train_size</span><span class="o">=</span><span class="n">train_prop</span><span class="p">,</span> <span class="n">stratify</span><span class="o">=</span><span class="n">y</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">Xtr</span><span class="p">,</span> <span class="n">ytr</span><span class="p">)</span>
|
||
<span class="n">predictions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">Xval</span><span class="p">)</span>
|
||
<span class="n">labels</span> <span class="o">=</span> <span class="n">yval</span>
|
||
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
|
||
<span class="n">Xval</span><span class="p">,</span> <span class="n">yval</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="n">predictions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">Xval</span><span class="p">)</span>
|
||
<span class="n">labels</span> <span class="o">=</span> <span class="n">yval</span>
|
||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">X</span><span class="p">),</span> <span class="n">y</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'unexpected type for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="si">=}</span><span class="s1">'</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.aggregation_fit">[docs]</a>
|
||
<span class="nd">@abstractmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the classification predictions</span>
|
||
<span class="sd"> (whatever the method :meth:`classify` returns)</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each classifier prediction</span>
|
||
<span class="sd"> """</span>
|
||
<span class="o">...</span></div>
|
||
|
||
|
||
<span class="nd">@property</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classifier</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Gives access to the classifier</span>
|
||
|
||
<span class="sd"> :return: the classifier (typically an sklearn's Estimator)</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier_</span>
|
||
|
||
<span class="nd">@classifier</span><span class="o">.</span><span class="n">setter</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classifier</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Setter for the classifier</span>
|
||
|
||
<span class="sd"> :param classifier: the classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier_</span> <span class="o">=</span> <span class="n">classifier</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.classify">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.classify">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Provides the label predictions for the given instances. The predictions should respect the format expected by</span>
|
||
<span class="sd"> :meth:`aggregate`, e.g., posterior probabilities for probabilistic quantifiers, or crisp predictions for</span>
|
||
<span class="sd"> non-probabilistic quantifiers. The default one is "decision_function".</span>
|
||
|
||
<span class="sd"> :param X: array-like of shape `(n_samples, n_features)`, the data instances</span>
|
||
<span class="sd"> :return: np.ndarray of shape `(n_instances,)` with classifier predictions</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_classifier_method</span><span class="p">())(</span><span class="n">X</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_classifier_method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Name of the method that must be used for issuing label predictions. The default one is "decision_function".</span>
|
||
|
||
<span class="sd"> :return: string</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="s1">'decision_function'</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_classifier</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">adapt_if_necessary</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Guarantees that the underlying classifier implements the method required for issuing predictions, i.e.,</span>
|
||
<span class="sd"> the method indicated by the :meth:`_classifier_method`</span>
|
||
|
||
<span class="sd"> :param adapt_if_necessary: unused unless overridden</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">assert</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_classifier_method</span><span class="p">()),</span> \
|
||
<span class="sa">f</span><span class="s2">"the method does not implement the required </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_classifier_method</span><span class="p">()</span><span class="si">}</span><span class="s2"> method"</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.predict">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.predict">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">predict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Generate class prevalence estimates for the sample's instances by aggregating the label predictions generated</span>
|
||
<span class="sd"> by the classifier.</span>
|
||
|
||
<span class="sd"> :param X: array-like of shape `(n_samples, n_features)`, the data instances</span>
|
||
<span class="sd"> :return: `np.ndarray` of shape `(n_classes)` with class prevalence estimates.</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">classif_predictions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeQuantifier.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeQuantifier.aggregate">[docs]</a>
|
||
<span class="nd">@abstractmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Implements the aggregation of the classifier predictions.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: `np.ndarray` of classifier predictions</span>
|
||
<span class="sd"> :return: `np.ndarray` of shape `(n_classes,)` with class prevalence estimates.</span>
|
||
<span class="sd"> """</span>
|
||
<span class="o">...</span></div>
|
||
|
||
|
||
<span class="nd">@property</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classes_</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Class labels, in the same order in which class prevalence values are to be computed.</span>
|
||
<span class="sd"> This default implementation actually returns the class labels of the learner.</span>
|
||
|
||
<span class="sd"> :return: array-like, the class labels</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeCrispQuantifier">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeCrispQuantifier">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">AggregativeCrispQuantifier</span><span class="p">(</span><span class="n">AggregativeQuantifier</span><span class="p">,</span> <span class="n">ABC</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Abstract class for quantification methods that base their estimations on the aggregation of crisp decisions</span>
|
||
<span class="sd"> as returned by a hard classifier. Aggregative crisp quantifiers thus extend Aggregative</span>
|
||
<span class="sd"> Quantifiers by implementing specifications about crisp predictions.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_classifier_method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Name of the method that must be used for issuing label predictions. For crisp quantifiers, the method</span>
|
||
<span class="sd"> is 'predict', that returns an array of shape `(n_instances,)` of label predictions.</span>
|
||
|
||
<span class="sd"> :return: the string "predict", i.e., the standard method name for scikit-learn hard predictions</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="s1">'predict'</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeSoftQuantifier">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeSoftQuantifier">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">AggregativeSoftQuantifier</span><span class="p">(</span><span class="n">AggregativeQuantifier</span><span class="p">,</span> <span class="n">ABC</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Abstract class for quantification methods that base their estimations on the aggregation of posterior</span>
|
||
<span class="sd"> probabilities as returned by a probabilistic classifier.</span>
|
||
<span class="sd"> Aggregative soft quantifiers thus extend Aggregative Quantifiers by implementing specifications</span>
|
||
<span class="sd"> about soft predictions.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_classifier_method</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Name of the method that must be used for issuing label predictions. For probabilistic quantifiers, the method</span>
|
||
<span class="sd"> is 'predict_proba', that returns an array of shape `(n_instances, n_dimensions,)` with posterior</span>
|
||
<span class="sd"> probabilities.</span>
|
||
|
||
<span class="sd"> :return: the string "predict_proba", i.e., the standard method name for scikit-learn soft predictions</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="s1">'predict_proba'</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_classifier</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">adapt_if_necessary</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Guarantees that the underlying classifier implements the method indicated by the :meth:`_classifier_method`.</span>
|
||
<span class="sd"> In case it does not, the classifier is calibrated (by means of the Platt's calibration method implemented by</span>
|
||
<span class="sd"> scikit-learn in CalibratedClassifierCV, with cv=5). This calibration is only allowed if `adapt_if_necessary`</span>
|
||
<span class="sd"> is set to True. If otherwise (i.e., the classifier is not probabilistic, and `adapt_if_necessary` is set</span>
|
||
<span class="sd"> to False), an exception will be raised.</span>
|
||
|
||
<span class="sd"> :param adapt_if_necessary: a hard classifier is turned into a soft classifier if `adapt_if_necessary==True`</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_classifier_method</span><span class="p">()):</span>
|
||
<span class="k">if</span> <span class="n">adapt_if_necessary</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="sa">f</span><span class="s1">'The learner </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s1"> does not seem to be '</span>
|
||
<span class="sa">f</span><span class="s1">'probabilistic. The learner will be calibrated (using CalibratedClassifierCV).'</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classifier</span> <span class="o">=</span> <span class="n">CalibratedClassifierCV</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="n">cv</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'error: The learner </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s1"> does not '</span>
|
||
<span class="sa">f</span><span class="s1">'seem to be probabilistic. The learner cannot be calibrated since '</span>
|
||
<span class="sa">f</span><span class="s1">'fit_classifier is set to False'</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="BinaryAggregativeQuantifier">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.BinaryAggregativeQuantifier">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">BinaryAggregativeQuantifier</span><span class="p">(</span><span class="n">AggregativeQuantifier</span><span class="p">,</span> <span class="n">BinaryQuantifier</span><span class="p">):</span>
|
||
|
||
<span class="nd">@property</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">pos_label</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||
|
||
<span class="nd">@property</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">neg_label</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||
|
||
<div class="viewcode-block" id="BinaryAggregativeQuantifier.fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.BinaryAggregativeQuantifier.fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_check_binary</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<span class="c1"># Methods</span>
|
||
<span class="c1"># ------------------------------------</span>
|
||
<div class="viewcode-block" id="CC">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.CC">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">CC</span><span class="p">(</span><span class="n">AggregativeCrispQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Classify & Count` (CC), the most basic quantification method, one that</span>
|
||
<span class="sd"> simply classifies all instances and counts how many have been attributed to</span>
|
||
<span class="sd"> each class in order to compute class prevalence estimates. This baseline is</span>
|
||
<span class="sd"> the unadjusted estimator discussed, among others, in</span>
|
||
<span class="sd"> `Forman, G. (2008). Quantifying counts and costs via classification.</span>
|
||
<span class="sd"> Data Mining and Knowledge Discovery, 17, 164-206</span>
|
||
<span class="sd"> <https://link.springer.com/article/10.1007/s10618-008-0097-y>`_.</span>
|
||
|
||
<span class="sd"> :param classifier: a sklearn's Estimator that generates a classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="CC.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.CC.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Nothing to do here!</span>
|
||
|
||
<span class="sd"> :param classif_predictions: unused</span>
|
||
<span class="sd"> :param labels: unused</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">pass</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="CC.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.CC.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Computes class prevalence estimates by counting the prevalence of each of the predicted labels.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with classifier predictions</span>
|
||
<span class="sd"> :return: `np.ndarray` of shape `(n_classes,)` with class prevalence estimates.</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_labels</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="PCC">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PCC">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">PCC</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Probabilistic Classify & Count` (PCC), the probabilistic variant of CC</span>
|
||
<span class="sd"> that relies on the posterior probabilities returned by a probabilistic</span>
|
||
<span class="sd"> classifier, introduced in</span>
|
||
<span class="sd"> `Bella, A., Ferri, C., Hernández-Orallo, J., and Ramírez-Quintana, M.J.</span>
|
||
<span class="sd"> (2010). Quantification via probability estimators. In Proceedings of the</span>
|
||
<span class="sd"> 2010 IEEE International Conference on Data Mining (ICDM 2010)</span>
|
||
<span class="sd"> <https://ieeexplore.ieee.org/abstract/document/5694031>`_.</span>
|
||
|
||
<span class="sd"> :param classifier: a sklearn's Estimator that generates a classifier</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="n">val_split</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="PCC.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PCC.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Nothing to do here!</span>
|
||
|
||
<span class="sd"> :param classif_predictions: unused</span>
|
||
<span class="sd"> :param labels: unused</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">pass</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="PCC.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PCC.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_probabilities</span><span class="p">(</span><span class="n">classif_posteriors</span><span class="p">,</span> <span class="n">binarize</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="ACC">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.ACC">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">ACC</span><span class="p">(</span><span class="n">AggregativeCrispQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Adjusted Classify & Count` (ACC), the "adjusted" variant of :class:`CC`</span>
|
||
<span class="sd"> that corrects the predictions of CC according to the</span>
|
||
<span class="sd"> misclassification rates, originally proposed in</span>
|
||
<span class="sd"> `Forman, G. (2008). Quantifying counts and costs via classification.</span>
|
||
<span class="sd"> Data Mining and Knowledge Discovery, 17, 164-206</span>
|
||
<span class="sd"> <https://link.springer.com/article/10.1007/s10618-008-0097-y>`_.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param str method: adjustment method to be used:</span>
|
||
|
||
<span class="sd"> * 'inversion': matrix inversion method based on the matrix equality :math:`P(C)=P(C|Y)P(Y)`,</span>
|
||
<span class="sd"> which tries to invert :math:`P(C|Y)` matrix.</span>
|
||
<span class="sd"> * 'invariant-ratio': invariant ratio estimator of `Vaz et al. 2018 <https://jmlr.org/papers/v20/18-456.html>`_,</span>
|
||
<span class="sd"> which replaces the last equation with the normalization condition.</span>
|
||
|
||
<span class="sd"> :param str solver: indicates the method to use for solving the system of linear equations. Valid options are:</span>
|
||
|
||
<span class="sd"> * 'exact-raise': tries to solve the system using matrix inversion. Raises an error if the matrix has rank</span>
|
||
<span class="sd"> strictly less than `n_classes`.</span>
|
||
<span class="sd"> * 'exact-cc': if the matrix is not of full rank, returns `p_c` as the estimates, which corresponds to</span>
|
||
<span class="sd"> no adjustment (i.e., the classify and count method. See :class:`quapy.method.aggregative.CC`)</span>
|
||
<span class="sd"> * 'exact': deprecated, defaults to 'exact-cc'</span>
|
||
<span class="sd"> * 'minimize': minimizes the L2 norm of :math:`|Ax-B|`. This one generally works better, and is the</span>
|
||
<span class="sd"> default parameter. More details about this can be consulted in `Bunse, M. "On Multi-Class Extensions of</span>
|
||
<span class="sd"> Adjusted Classify and Count", on proceedings of the 2nd International Workshop on Learning to Quantify:</span>
|
||
<span class="sd"> Methods and Applications (LQ 2022), ECML/PKDD 2022, Grenoble (France)</span>
|
||
<span class="sd"> <https://lq-2022.github.io/proceedings/CompleteVolume.pdf>`_.</span>
|
||
|
||
<span class="sd"> :param str norm: the method to use for normalization.</span>
|
||
|
||
<span class="sd"> * `clip`, the values are clipped to the range [0,1] and then L1-normalized.</span>
|
||
<span class="sd"> * `mapsimplex` projects vectors onto the probability simplex. This implementation relies on</span>
|
||
<span class="sd"> `Mathieu Blondel's projection_simplex_sort <https://gist.github.com/mblondel/6f3b7aaad90606b98f71>`_</span>
|
||
<span class="sd"> * `condsoftmax`, applies a softmax normalization only to prevalence vectors that lie outside the simplex</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="p">,</span>
|
||
<span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||
<span class="n">fit_classifier</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">val_split</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span>
|
||
<span class="n">solver</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'minimize'</span><span class="p">,</span> <span class="s1">'exact'</span><span class="p">,</span> <span class="s1">'exact-raise'</span><span class="p">,</span> <span class="s1">'exact-cc'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'minimize'</span><span class="p">,</span>
|
||
<span class="n">method</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'inversion'</span><span class="p">,</span> <span class="s1">'invariant-ratio'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'inversion'</span><span class="p">,</span>
|
||
<span class="n">norm</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'clip'</span><span class="p">,</span> <span class="s1">'mapsimplex'</span><span class="p">,</span> <span class="s1">'condsoftmax'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'clip'</span><span class="p">,</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||
<span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">solver</span> <span class="o">=</span> <span class="n">solver</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">=</span> <span class="n">method</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="o">=</span> <span class="n">norm</span>
|
||
|
||
<span class="n">SOLVERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'exact'</span><span class="p">,</span> <span class="s1">'minimize'</span><span class="p">,</span> <span class="s1">'exact-raise'</span><span class="p">,</span> <span class="s1">'exact-cc'</span><span class="p">]</span>
|
||
<span class="n">METHODS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'inversion'</span><span class="p">,</span> <span class="s1">'invariant-ratio'</span><span class="p">]</span>
|
||
<span class="n">NORMALIZATIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'clip'</span><span class="p">,</span> <span class="s1">'mapsimplex'</span><span class="p">,</span> <span class="s1">'condsoftmax'</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span>
|
||
|
||
<div class="viewcode-block" id="ACC.newInvariantRatioEstimation">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.ACC.newInvariantRatioEstimation">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newInvariantRatioEstimation</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Constructs a quantifier that implements the Invariant Ratio Estimator of</span>
|
||
<span class="sd"> `Vaz et al. 2018 <https://jmlr.org/papers/v20/18-456.html>`_. This amounts</span>
|
||
<span class="sd"> to setting method to 'invariant-ratio' and clipping to 'project'.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
|
||
<span class="sd"> :return: an instance of ACC configured so that it implements the Invariant Ratio Estimator</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">ACC</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="n">val_split</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'invariant-ratio'</span><span class="p">,</span> <span class="n">norm</span><span class="o">=</span><span class="s1">'mapsimplex'</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="n">n_jobs</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">solver</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">SOLVERS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown solver; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">SOLVERS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">METHODS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown method; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">METHODS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown normalization; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="ACC.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.ACC.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Estimates the misclassification rates.</span>
|
||
<span class="sd"> :param classif_predictions: array-like with the predicted labels</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each predicted label</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">true_labels</span> <span class="o">=</span> <span class="n">labels</span>
|
||
<span class="n">pred_labels</span> <span class="o">=</span> <span class="n">classif_predictions</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">cc</span> <span class="o">=</span> <span class="n">CC</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pte_cond_estim_</span> <span class="o">=</span> <span class="n">ACC</span><span class="o">.</span><span class="n">getPteCondEstim</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span><span class="p">,</span> <span class="n">true_labels</span><span class="p">,</span> <span class="n">pred_labels</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="ACC.getPteCondEstim">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.ACC.getPteCondEstim">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">getPteCondEstim</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">classes</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">y_</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Estimate the matrix with entry (i,j) being the estimate of P(hat_yi|yj), that is, the probability that a</span>
|
||
<span class="sd"> document that belongs to yj ends up being classified as belonging to yi</span>
|
||
|
||
<span class="sd"> :param classes: array-like with the class names</span>
|
||
<span class="sd"> :param y: array-like with the true labels</span>
|
||
<span class="sd"> :param y_: array-like with the estimated labels</span>
|
||
<span class="sd"> :return: np.ndarray</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">conf</span> <span class="o">=</span> <span class="n">confusion_matrix</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">y_</span><span class="p">,</span> <span class="n">labels</span><span class="o">=</span><span class="n">classes</span><span class="p">)</span><span class="o">.</span><span class="n">T</span>
|
||
<span class="n">conf</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="nb">float</span><span class="p">)</span>
|
||
<span class="n">class_counts</span> <span class="o">=</span> <span class="n">conf</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">classes</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="n">class_counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="n">conf</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">conf</span><span class="p">[:,</span> <span class="n">i</span><span class="p">]</span> <span class="o">/=</span> <span class="n">class_counts</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
||
<span class="k">return</span> <span class="n">conf</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="ACC.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.ACC.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">):</span>
|
||
<span class="n">prevs_estim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cc</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">)</span>
|
||
<span class="n">estimate</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">solve_adjustment</span><span class="p">(</span>
|
||
<span class="n">class_conditional_rates</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">Pte_cond_estim_</span><span class="p">,</span>
|
||
<span class="n">unadjusted_counts</span><span class="o">=</span><span class="n">prevs_estim</span><span class="p">,</span>
|
||
<span class="n">solver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">solver</span><span class="p">,</span>
|
||
<span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">method</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">normalize_prevalence</span><span class="p">(</span><span class="n">estimate</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">norm</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="PACC">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PACC">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">PACC</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Probabilistic Adjusted Classify & Count` (PACC), the probabilistic</span>
|
||
<span class="sd"> variant of ACC that relies on the posterior probabilities returned by a</span>
|
||
<span class="sd"> probabilistic classifier, introduced in</span>
|
||
<span class="sd"> `Bella, A., Ferri, C., Hernández-Orallo, J., and Ramírez-Quintana, M.J.</span>
|
||
<span class="sd"> (2010). Quantification via probability estimators. In Proceedings of the</span>
|
||
<span class="sd"> 2010 IEEE International Conference on Data Mining (ICDM 2010)</span>
|
||
<span class="sd"> <https://ieeexplore.ieee.org/abstract/document/5694031>`_.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param str method: adjustment method to be used:</span>
|
||
|
||
<span class="sd"> * 'inversion': matrix inversion method based on the matrix equality :math:`P(C)=P(C|Y)P(Y)`,</span>
|
||
<span class="sd"> which tries to invert `P(C|Y)` matrix.</span>
|
||
<span class="sd"> * 'invariant-ratio': invariant ratio estimator of `Vaz et al. <https://jmlr.org/papers/v20/18-456.html>`_,</span>
|
||
<span class="sd"> which replaces the last equation with the normalization condition.</span>
|
||
|
||
<span class="sd"> :param str solver: the method to use for solving the system of linear equations. Valid options are:</span>
|
||
|
||
<span class="sd"> * 'exact-raise': tries to solve the system using matrix inversion.</span>
|
||
<span class="sd"> Raises an error if the matrix has rank strictly less than `n_classes`.</span>
|
||
<span class="sd"> * 'exact-cc': if the matrix is not of full rank, returns `p_c` as the estimates, which</span>
|
||
<span class="sd"> corresponds to no adjustment (i.e., the classify and count method. See :class:`quapy.method.aggregative.CC`)</span>
|
||
<span class="sd"> * 'exact': deprecated, defaults to 'exact-cc'</span>
|
||
<span class="sd"> * 'minimize': minimizes the L2 norm of :math:`|Ax-B|`. This one generally works better, and is the</span>
|
||
<span class="sd"> default parameter. More details about this can be consulted in `Bunse, M. "On Multi-Class Extensions</span>
|
||
<span class="sd"> of Adjusted Classify and Count", on proceedings of the 2nd International Workshop on Learning to</span>
|
||
<span class="sd"> Quantify: Methods and Applications (LQ 2022), ECML/PKDD 2022, Grenoble (France)</span>
|
||
<span class="sd"> <https://lq-2022.github.io/proceedings/CompleteVolume.pdf>`_.</span>
|
||
|
||
<span class="sd"> :param str norm: the method to use for normalization.</span>
|
||
|
||
<span class="sd"> * `clip`, the values are clipped to the range [0,1] and then L1-normalized.</span>
|
||
<span class="sd"> * `mapsimplex` projects vectors onto the probability simplex. This implementation relies on</span>
|
||
<span class="sd"> `Mathieu Blondel's projection_simplex_sort <https://gist.github.com/mblondel/6f3b7aaad90606b98f71>`_</span>
|
||
<span class="sd"> * `condsoftmax`, applies a softmax normalization only to prevalence vectors that lie outside the simplex</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="p">,</span>
|
||
<span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||
<span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
|
||
<span class="n">solver</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'minimize'</span><span class="p">,</span> <span class="s1">'exact'</span><span class="p">,</span> <span class="s1">'exact-raise'</span><span class="p">,</span> <span class="s1">'exact-cc'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'minimize'</span><span class="p">,</span>
|
||
<span class="n">method</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'inversion'</span><span class="p">,</span> <span class="s1">'invariant-ratio'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'inversion'</span><span class="p">,</span>
|
||
<span class="n">norm</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'clip'</span><span class="p">,</span> <span class="s1">'mapsimplex'</span><span class="p">,</span> <span class="s1">'condsoftmax'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'clip'</span><span class="p">,</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span>
|
||
<span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">solver</span> <span class="o">=</span> <span class="n">solver</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">=</span> <span class="n">method</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="o">=</span> <span class="n">norm</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">solver</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">SOLVERS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown solver; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">SOLVERS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">METHODS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown method; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">METHODS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown normalization; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="PACC.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PACC.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Estimates the misclassification rates</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with posterior probabilities</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each vector of posterior probabilities</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">posteriors</span> <span class="o">=</span> <span class="n">classif_predictions</span>
|
||
<span class="n">true_labels</span> <span class="o">=</span> <span class="n">labels</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">pcc</span> <span class="o">=</span> <span class="n">PCC</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pte_cond_estim_</span> <span class="o">=</span> <span class="n">PACC</span><span class="o">.</span><span class="n">getPteCondEstim</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span><span class="p">,</span> <span class="n">true_labels</span><span class="p">,</span> <span class="n">posteriors</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="PACC.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PACC.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="n">prevs_estim</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pcc</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">classif_posteriors</span><span class="p">)</span>
|
||
|
||
<span class="n">estimate</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">solve_adjustment</span><span class="p">(</span>
|
||
<span class="n">class_conditional_rates</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">Pte_cond_estim_</span><span class="p">,</span>
|
||
<span class="n">unadjusted_counts</span><span class="o">=</span><span class="n">prevs_estim</span><span class="p">,</span>
|
||
<span class="n">solver</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">solver</span><span class="p">,</span>
|
||
<span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">method</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">normalize_prevalence</span><span class="p">(</span><span class="n">estimate</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">norm</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="PACC.getPteCondEstim">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.PACC.getPteCondEstim">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">getPteCondEstim</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">classes</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">y_</span><span class="p">):</span>
|
||
<span class="c1"># estimate the matrix with entry (i,j) being the estimate of P(hat_yi|yj), that is, the probability that a</span>
|
||
<span class="c1"># document that belongs to yj ends up being classified as belonging to yi</span>
|
||
<span class="n">n_classes</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">classes</span><span class="p">)</span>
|
||
<span class="n">confusion</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="n">n_classes</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">class_</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">classes</span><span class="p">):</span>
|
||
<span class="n">idx</span> <span class="o">=</span> <span class="n">y</span> <span class="o">==</span> <span class="n">class_</span>
|
||
<span class="k">if</span> <span class="n">idx</span><span class="o">.</span><span class="n">any</span><span class="p">():</span>
|
||
<span class="n">confusion</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">y_</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="n">confusion</span><span class="o">.</span><span class="n">T</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="RLLS">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.RLLS">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">RLLS</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Regularized Learning for Domain Adaptation under Label Shifts</span>
|
||
<span class="sd"> <https://arxiv.org/abs/1903.09734>`_, used here as an aggregative</span>
|
||
<span class="sd"> quantifier.</span>
|
||
|
||
<span class="sd"> This implementation ports the regularized weight-estimation component of</span>
|
||
<span class="sd"> RLLS to QuaPy's aggregative interface. It estimates label-shift ratios from</span>
|
||
<span class="sd"> validation posteriors and source labels, then rescales the source</span>
|
||
<span class="sd"> prevalence to obtain target prevalence estimates.</span>
|
||
|
||
<span class="sd"> This method relies on the optional `cvxpy` dependency.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case</span>
|
||
<span class="sd"> the classifier is taken to be the one indicated in</span>
|
||
<span class="sd"> `qp.environ['DEFAULT_CLS']`</span>
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set</span>
|
||
<span class="sd"> to False if the learner has been trained outside the quantifier.</span>
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier</span>
|
||
<span class="sd"> predictions. This specification can be made as float in (0, 1)</span>
|
||
<span class="sd"> indicating the proportion of stratified held-out validation set to be</span>
|
||
<span class="sd"> extracted from the training set; or as an integer (default 5),</span>
|
||
<span class="sd"> indicating that the predictions are to be generated in a `k`-fold</span>
|
||
<span class="sd"> cross-validation manner; or as a tuple `(X, y)` defining the specific</span>
|
||
<span class="sd"> set of data to use for validation. This method requires source</span>
|
||
<span class="sd"> predictions and therefore needs `val_split` whenever</span>
|
||
<span class="sd"> `fit_classifier=True`.</span>
|
||
<span class="sd"> :param mode: whether source- and target-domain quantities are estimated</span>
|
||
<span class="sd"> from posterior probabilities (`soft`, default) or from argmax</span>
|
||
<span class="sd"> predictions (`hard`)</span>
|
||
<span class="sd"> :param alpha: multiplicative factor for the regularization level (default</span>
|
||
<span class="sd"> 0.01)</span>
|
||
<span class="sd"> :param delta: confidence parameter used in the finite-sample regularizer</span>
|
||
<span class="sd"> (default 0.05)</span>
|
||
<span class="sd"> :param clip_weights: if True, clips negative importance weights to zero</span>
|
||
<span class="sd"> before converting them into prevalence estimates</span>
|
||
<span class="sd"> :param norm: the normalization method passed to</span>
|
||
<span class="sd"> :func:`quapy.functional.normalize_prevalence`</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="p">,</span>
|
||
<span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||
<span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
|
||
<span class="n">mode</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'soft'</span><span class="p">,</span> <span class="s1">'hard'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'soft'</span><span class="p">,</span>
|
||
<span class="n">alpha</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.01</span><span class="p">,</span>
|
||
<span class="n">delta</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">0.05</span><span class="p">,</span>
|
||
<span class="n">clip_weights</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">norm</span><span class="p">:</span> <span class="n">Literal</span><span class="p">[</span><span class="s1">'clip'</span><span class="p">,</span> <span class="s1">'mapsimplex'</span><span class="p">,</span> <span class="s1">'condsoftmax'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'clip'</span><span class="p">,</span>
|
||
<span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">mode</span> <span class="o">=</span> <span class="n">mode</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">alpha</span> <span class="o">=</span> <span class="n">alpha</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">delta</span> <span class="o">=</span> <span class="n">delta</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">clip_weights</span> <span class="o">=</span> <span class="n">clip_weights</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="o">=</span> <span class="n">norm</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">last_w_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">_get_cvxpy</span><span class="p">()</span>
|
||
<span class="n">_rlls_check_mode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mode</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">alpha</span><span class="p">,</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">))</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">alpha</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'expected a non-negative real value for alpha; found </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">alpha</span><span class="si">!r}</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">delta</span><span class="p">,</span> <span class="p">(</span><span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">))</span> <span class="ow">or</span> <span class="ow">not</span> <span class="p">(</span><span class="mi">0</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">delta</span> <span class="o"><</span> <span class="mi">1</span><span class="p">):</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'expected delta to be in (0,1); found </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">delta</span><span class="si">!r}</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">norm</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"unknown normalization; valid ones are </span><span class="si">{</span><span class="n">ACC</span><span class="o">.</span><span class="n">NORMALIZATIONS</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fit_classifier</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
||
<span class="s1">'RLLS requires validation predictions for aggregation_fit; '</span>
|
||
<span class="s1">'please set val_split to an integer, float, or validation tuple'</span>
|
||
<span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="RLLS.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.RLLS.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="n">classif_predictions</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">labels</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'RLLS requires source posterior predictions and source labels'</span><span class="p">)</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence_</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_labels</span><span class="p">(</span><span class="n">labels</span><span class="p">,</span> <span class="n">classes</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">C_zy_</span> <span class="o">=</span> <span class="n">_rlls_joint_distribution</span><span class="p">(</span>
|
||
<span class="n">classif_predictions</span><span class="p">,</span>
|
||
<span class="n">labels</span><span class="p">,</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">,</span>
|
||
<span class="n">mode</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mode</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">pz_</span> <span class="o">=</span> <span class="n">_rlls_predicted_marginal</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mode</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">rho_</span> <span class="o">=</span> <span class="n">_rlls_compute_3deltaC</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">),</span> <span class="nb">len</span><span class="p">(</span><span class="n">labels</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">delta</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="RLLS.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.RLLS.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="n">qz</span> <span class="o">=</span> <span class="n">_rlls_predicted_marginal</span><span class="p">(</span><span class="n">classif_posteriors</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mode</span><span class="p">)</span>
|
||
<span class="n">w</span> <span class="o">=</span> <span class="n">_rlls_compute_weights</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">C_zy_</span><span class="p">,</span>
|
||
<span class="n">qz</span><span class="p">,</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">pz_</span><span class="p">,</span>
|
||
<span class="n">rho</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">alpha</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">rho_</span><span class="p">,</span>
|
||
<span class="n">clip</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">clip_weights</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">last_w_</span> <span class="o">=</span> <span class="n">w</span>
|
||
<span class="n">estimate</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence_</span> <span class="o">*</span> <span class="n">w</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">normalize_prevalence</span><span class="p">(</span><span class="n">estimate</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">norm</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="EMQ">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">EMQ</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Expectation Maximization for Quantification <https://ieeexplore.ieee.org/abstract/document/6789744>`_ (EMQ),</span>
|
||
<span class="sd"> aka `Saerens-Latinne-Decaestecker` (SLD) algorithm.</span>
|
||
<span class="sd"> EMQ consists of using the well-known `Expectation Maximization algorithm` to iteratively update the posterior</span>
|
||
<span class="sd"> probabilities generated by a probabilistic classifier and the class prevalence estimates obtained via</span>
|
||
<span class="sd"> maximum-likelihood estimation, in a mutually recursive way, until convergence.</span>
|
||
|
||
<span class="sd"> This implementation also gives access to the heuristics proposed by `Alexandari et al. paper</span>
|
||
<span class="sd"> <http://proceedings.mlr.press/v119/alexandari20a.html>`_. These heuristics consist of using, as the training</span>
|
||
<span class="sd"> prevalence, an estimate of it obtained via k-fold cross validation (instead of the true training prevalence),</span>
|
||
<span class="sd"> and to recalibrate the posterior probabilities of the classifier.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the classifier (default is True). Set to False if the</span>
|
||
<span class="sd"> given classifier has already been trained.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating the classifier predictions on which the</span>
|
||
<span class="sd"> aggregation function is to be trained. This specification can be made as float in (0, 1) indicating</span>
|
||
<span class="sd"> the proportion of stratified held-out validation set to be extracted from the training set; or as</span>
|
||
<span class="sd"> an integer (default 5), indicating that the predictions are to be generated in a `k`-fold</span>
|
||
<span class="sd"> cross-validation manner (with this integer indicating the value for `k`); or as a tuple (X,y) defining</span>
|
||
<span class="sd"> the specific set of data to use for validation. This hyperparameter is only meant to be used when</span>
|
||
<span class="sd"> the heuristics are to be applied, i.e., if a calibration is required. The default value is None</span>
|
||
<span class="sd"> (meaning the calibration is not required). In case this hyperparameter is set to a value other than</span>
|
||
<span class="sd"> None, but the calibration is not required (calib=None), a warning message will be raised.</span>
|
||
|
||
<span class="sd"> :param exact_train_prev: set to True (default) for using the true training prevalence as the initial</span>
|
||
<span class="sd"> observation; set to False for computing the training prevalence as an estimate of it, i.e., as the</span>
|
||
<span class="sd"> expected value of the posterior probabilities of the training instances.</span>
|
||
|
||
<span class="sd"> :param calib: a string indicating the method of calibration.</span>
|
||
<span class="sd"> Available choices include "nbvs" (No-Bias Vector Scaling), "bcts" (Bias-Corrected Temperature Scaling),</span>
|
||
<span class="sd"> "ts" (Temperature Scaling), and "vs" (Vector Scaling). Default is None (no calibration).</span>
|
||
|
||
<span class="sd"> :param on_calib_error: a string indicating the policy to follow in case the calibrator fails at runtime.</span>
|
||
<span class="sd"> Options include "raise" (default), in which case a RuntimeException is raised; and "backup", in which</span>
|
||
<span class="sd"> case the calibrator is silently skipped.</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers. Only used for recalibrating the classifier if `val_split` is set to</span>
|
||
<span class="sd"> an integer `k` --the number of folds.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">MAX_ITER</span> <span class="o">=</span> <span class="mi">1000</span>
|
||
<span class="n">EPSILON</span> <span class="o">=</span> <span class="mf">1e-4</span>
|
||
<span class="n">ON_CALIB_ERROR_VALUES</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'raise'</span><span class="p">,</span> <span class="s1">'backup'</span><span class="p">]</span>
|
||
<span class="n">CALIB_OPTIONS</span> <span class="o">=</span> <span class="p">[</span><span class="kc">None</span><span class="p">,</span> <span class="s1">'nbvs'</span><span class="p">,</span> <span class="s1">'bcts'</span><span class="p">,</span> <span class="s1">'ts'</span><span class="p">,</span> <span class="s1">'vs'</span><span class="p">]</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">exact_train_prev</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">calib</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">on_calib_error</span><span class="o">=</span><span class="s1">'raise'</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
|
||
<span class="k">assert</span> <span class="n">calib</span> <span class="ow">in</span> <span class="n">EMQ</span><span class="o">.</span><span class="n">CALIB_OPTIONS</span><span class="p">,</span> \
|
||
<span class="sa">f</span><span class="s1">'invalid value for </span><span class="si">{</span><span class="n">calib</span><span class="si">=}</span><span class="s1">; valid ones are </span><span class="si">{</span><span class="n">EMQ</span><span class="o">.</span><span class="n">CALIB_OPTIONS</span><span class="si">}</span><span class="s1">'</span>
|
||
<span class="k">assert</span> <span class="n">on_calib_error</span> <span class="ow">in</span> <span class="n">EMQ</span><span class="o">.</span><span class="n">ON_CALIB_ERROR_VALUES</span><span class="p">,</span> \
|
||
<span class="sa">f</span><span class="s1">'invalid value for </span><span class="si">{</span><span class="n">on_calib_error</span><span class="si">=}</span><span class="s1">; valid ones are </span><span class="si">{</span><span class="n">EMQ</span><span class="o">.</span><span class="n">ON_CALIB_ERROR_VALUES</span><span class="si">}</span><span class="s1">'</span>
|
||
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">exact_train_prev</span> <span class="o">=</span> <span class="n">exact_train_prev</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">calib</span> <span class="o">=</span> <span class="n">calib</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span> <span class="o">=</span> <span class="n">on_calib_error</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="EMQ.EMQ_BCTS">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.EMQ_BCTS">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">EMQ_BCTS</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">on_calib_error</span><span class="o">=</span><span class="s2">"raise"</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Constructs an instance of EMQ using the best configuration found in the `Alexandari et al. paper</span>
|
||
<span class="sd"> <http://proceedings.mlr.press/v119/alexandari20a.html>`_, i.e., one that relies on Bias-Corrected Temperature</span>
|
||
<span class="sd"> Scaling (BCTS) as a calibration function, and that uses an estimate of the training prevalence instead of</span>
|
||
<span class="sd"> the true training prevalence.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param on_calib_error: a string indicating the policy to follow in case the calibrator fails at runtime.</span>
|
||
<span class="sd"> Options include "raise" (default), in which case a RuntimeException is raised; and "backup", in which</span>
|
||
<span class="sd"> case the calibrator is silently skipped.</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers. Only used for recalibrating the classifier if `val_split` is set to</span>
|
||
<span class="sd"> an integer `k` --the number of folds.</span>
|
||
|
||
<span class="sd"> :return: An instance of EMQ with BCTS</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">EMQ</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="n">val_split</span><span class="p">,</span> <span class="n">exact_train_prev</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
||
<span class="n">calib</span><span class="o">=</span><span class="s1">'bcts'</span><span class="p">,</span> <span class="n">on_calib_error</span><span class="o">=</span><span class="n">on_calib_error</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="n">n_jobs</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">val_split</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">exact_train_prev</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">calib</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="sa">f</span><span class="s1">'The parameter </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">val_split</span><span class="si">=}</span><span class="s1"> was specified for EMQ, while the parameters '</span>
|
||
<span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">exact_train_prev</span><span class="si">=}</span><span class="s1"> and </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="si">=}</span><span class="s1">. This has no effect and causes an '</span>
|
||
<span class="sa">f</span><span class="s1">'unnecessary overload.'</span><span class="p">,</span> <span class="ne">RuntimeWarning</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">calib</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="sa">f</span><span class="s1">'The parameter </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="si">=}</span><span class="s1"> requires the val_split be different from None. '</span>
|
||
<span class="sa">f</span><span class="s1">'This parameter will be set to 5. To avoid this warning, set this value to a float value '</span>
|
||
<span class="sa">f</span><span class="s1">'indicating the proportion of training data to be used as validation, or to an integer '</span>
|
||
<span class="sa">f</span><span class="s1">'indicating the number of folds for kFCV.'</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">val_split</span> <span class="o">=</span> <span class="mi">5</span>
|
||
|
||
<div class="viewcode-block" id="EMQ.classify">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.classify">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Provides the posterior probabilities for the given instances. The calibration function, if required,</span>
|
||
<span class="sd"> has no effect in this step, and is only involved in the aggregate method.</span>
|
||
|
||
<span class="sd"> :param X: array-like of shape `(n_instances, n_dimensions,)`</span>
|
||
<span class="sd"> :return: np.ndarray of shape `(n_instances, n_classes,)` with posterior probabilities</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">predict_proba</span><span class="p">(</span><span class="n">X</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="EMQ.classifier_fit_predict">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.classifier_fit_predict">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classifier_fit_predict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="n">classif_predictions</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">classifier_fit_predict</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_labels</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">classes</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">classif_predictions</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_fit_calibration</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">calibrator</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="n">n_classes</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">np</span><span class="o">.</span><span class="n">issubdtype</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">dtype</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">number</span><span class="p">):</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">searchsorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">calibration_function</span> <span class="o">=</span> <span class="n">calibrator</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">np</span><span class="o">.</span><span class="n">eye</span><span class="p">(</span><span class="n">n_classes</span><span class="p">)[</span><span class="n">y</span><span class="p">],</span> <span class="n">posterior_supplied</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span> <span class="o">==</span> <span class="s1">'raise'</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'calibration </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="si">}</span><span class="s1"> failed at fit time: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span> <span class="o">==</span> <span class="s1">'backup'</span><span class="p">:</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">calibration_function</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">P</span><span class="p">:</span> <span class="n">P</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_calibrate_if_requested</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uncalib_posteriors</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'calibration_function'</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">calibration_function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">calib_posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">calibration_function</span><span class="p">(</span><span class="n">uncalib_posteriors</span><span class="p">)</span>
|
||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span> <span class="o">==</span> <span class="s1">'raise'</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'calibration </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="si">}</span><span class="s1"> failed at predict time: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span> <span class="o">==</span> <span class="s1">'backup'</span><span class="p">:</span>
|
||
<span class="n">calib_posteriors</span> <span class="o">=</span> <span class="n">uncalib_posteriors</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'unexpected </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">on_calib_error</span><span class="si">=}</span><span class="s1">; '</span>
|
||
<span class="sa">f</span><span class="s1">'valid options are </span><span class="si">{</span><span class="n">EMQ</span><span class="o">.</span><span class="n">ON_CALIB_ERROR_VALUES</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">calib_posteriors</span>
|
||
<span class="k">return</span> <span class="n">uncalib_posteriors</span>
|
||
|
||
<div class="viewcode-block" id="EMQ.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function of EMQ. This comes down to recalibrating the posterior probabilities</span>
|
||
<span class="sd"> ir requested.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the raw (i.e., uncalibrated) posterior probabilities</span>
|
||
<span class="sd"> returned by the classifier</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each classifier prediction</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">P</span> <span class="o">=</span> <span class="n">classif_predictions</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">labels</span>
|
||
|
||
<span class="n">requires_predictions</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">exact_train_prev</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="n">P</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">requires_predictions</span><span class="p">:</span>
|
||
<span class="c1"># classifier predictions were not generated because val_split=None</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">+</span>
|
||
<span class="s2">": Classifier predictions for the aggregative fit were not generated because "</span>
|
||
<span class="s2">"val_split=None. This usually happens when you enable calibrations or heuristics "</span>
|
||
<span class="s2">"during model selection but left val_split set to its default value (None). "</span>
|
||
<span class="s2">"Please provide one of the following values for val_split: (i) an integer >1 "</span>
|
||
<span class="s2">"(e.g. val_split=5) for k-fold cross-validation; (ii) a float in (0,1) (e.g. "</span>
|
||
<span class="s2">"val_split=0.3) for a proportion split; or (iii) a tuple (X, y) with explicit "</span>
|
||
<span class="s2">"validation data"</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">calib</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">calibrator</span> <span class="o">=</span> <span class="n">_get_abstention_calibrators</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">calibrator</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s1">'invalid value for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">calib</span><span class="si">=}</span><span class="s1">; valid ones are </span><span class="si">{</span><span class="n">EMQ</span><span class="o">.</span><span class="n">CALIB_OPTIONS</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_fit_calibration</span><span class="p">(</span><span class="n">calibrator</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">exact_train_prev</span><span class="p">:</span>
|
||
<span class="n">P</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_calibrate_if_requested</span><span class="p">(</span><span class="n">P</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence</span> <span class="o">=</span> <span class="n">F</span><span class="o">.</span><span class="n">prevalence_from_probabilities</span><span class="p">(</span><span class="n">P</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="EMQ.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">,</span> <span class="n">epsilon</span><span class="o">=</span><span class="n">EPSILON</span><span class="p">):</span>
|
||
<span class="n">classif_posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_calibrate_if_requested</span><span class="p">(</span><span class="n">classif_posteriors</span><span class="p">)</span>
|
||
<span class="n">priors</span><span class="p">,</span> <span class="n">posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">EM</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">,</span> <span class="n">epsilon</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">priors</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="EMQ.predict_proba">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.predict_proba">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">predict_proba</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instances</span><span class="p">,</span> <span class="n">epsilon</span><span class="o">=</span><span class="n">EPSILON</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Returns the posterior probabilities updated by the EM algorithm.</span>
|
||
|
||
<span class="sd"> :param instances: np.ndarray of shape `(n_instances, n_dimensions)`</span>
|
||
<span class="sd"> :param epsilon: error tolerance</span>
|
||
<span class="sd"> :return: np.ndarray of shape `(n_instances, n_classes)`</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">classif_posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">instances</span><span class="p">)</span>
|
||
<span class="n">classif_posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_calibrate_if_requested</span><span class="p">(</span><span class="n">classif_posteriors</span><span class="p">)</span>
|
||
<span class="n">priors</span><span class="p">,</span> <span class="n">posteriors</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">EM</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">train_prevalence</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">,</span> <span class="n">epsilon</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">posteriors</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="EMQ.EM">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EMQ.EM">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">EM</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">tr_prev</span><span class="p">,</span> <span class="n">posterior_probabilities</span><span class="p">,</span> <span class="n">epsilon</span><span class="o">=</span><span class="n">EPSILON</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Computes the `Expectation Maximization` routine.</span>
|
||
|
||
<span class="sd"> :param tr_prev: array-like, the training prevalence</span>
|
||
<span class="sd"> :param posterior_probabilities: `np.ndarray` of shape `(n_instances, n_classes,)` with the</span>
|
||
<span class="sd"> posterior probabilities</span>
|
||
<span class="sd"> :param epsilon: float, the threshold different between two consecutive iterations</span>
|
||
<span class="sd"> to reach before stopping the loop</span>
|
||
<span class="sd"> :return: a tuple with the estimated prevalence values (shape `(n_classes,)`) and</span>
|
||
<span class="sd"> the corrected posterior probabilities (shape `(n_instances, n_classes,)`)</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">posterior_probabilities</span>
|
||
<span class="n">Ptr</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">tr_prev</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">np</span><span class="o">.</span><span class="n">prod</span><span class="p">(</span><span class="n">Ptr</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># some entry is 0; we should smooth the values to avoid 0 division</span>
|
||
<span class="n">Ptr</span> <span class="o">+=</span> <span class="n">epsilon</span>
|
||
<span class="n">Ptr</span> <span class="o">/=</span> <span class="n">Ptr</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
|
||
<span class="n">qs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">Ptr</span><span class="p">)</span> <span class="c1"># qs (the running estimate) is initialized as the training prevalence</span>
|
||
|
||
<span class="n">s</span><span class="p">,</span> <span class="n">converged</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="kc">False</span>
|
||
<span class="n">qs_prev_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="k">while</span> <span class="ow">not</span> <span class="n">converged</span> <span class="ow">and</span> <span class="n">s</span> <span class="o"><</span> <span class="n">EMQ</span><span class="o">.</span><span class="n">MAX_ITER</span><span class="p">:</span>
|
||
<span class="c1"># E-step: ps is Ps(y|xi)</span>
|
||
<span class="n">ps_unnormalized</span> <span class="o">=</span> <span class="p">(</span><span class="n">qs</span> <span class="o">/</span> <span class="n">Ptr</span><span class="p">)</span> <span class="o">*</span> <span class="n">Px</span>
|
||
<span class="n">ps</span> <span class="o">=</span> <span class="n">ps_unnormalized</span> <span class="o">/</span> <span class="n">ps_unnormalized</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">keepdims</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
|
||
<span class="c1"># M-step:</span>
|
||
<span class="n">qs</span> <span class="o">=</span> <span class="n">ps</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="n">qs_prev_</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">qp</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="n">mae</span><span class="p">(</span><span class="n">qs</span><span class="p">,</span> <span class="n">qs_prev_</span><span class="p">)</span> <span class="o"><</span> <span class="n">epsilon</span> <span class="ow">and</span> <span class="n">s</span> <span class="o">></span> <span class="mi">10</span><span class="p">:</span>
|
||
<span class="n">converged</span> <span class="o">=</span> <span class="kc">True</span>
|
||
|
||
<span class="n">qs_prev_</span> <span class="o">=</span> <span class="n">qs</span>
|
||
<span class="n">s</span> <span class="o">+=</span> <span class="mi">1</span>
|
||
|
||
<span class="k">if</span> <span class="ow">not</span> <span class="n">converged</span><span class="p">:</span>
|
||
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s1">'the method has reached the maximum number of iterations; it might have not converged'</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="n">qs</span><span class="p">,</span> <span class="n">ps</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="HDy">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.HDy">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">HDy</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">,</span> <span class="n">BinaryAggregativeQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `Hellinger Distance y <https://www.sciencedirect.com/science/article/pii/S0020025512004069>`_ (HDy).</span>
|
||
<span class="sd"> HDy is a probabilistic method for training binary quantifiers, that models quantification as the problem of</span>
|
||
<span class="sd"> minimizing the divergence (in terms of the Hellinger Distance) between two distributions of posterior</span>
|
||
<span class="sd"> probabilities returned by the classifier. One of the distributions is generated from the unlabelled examples and</span>
|
||
<span class="sd"> the other is generated from a validation set. This latter distribution is defined as a mixture of the</span>
|
||
<span class="sd"> class-conditional distributions of the posterior probabilities returned for the positive and negative validation</span>
|
||
<span class="sd"> examples, respectively. The parameters of the mixture thus represent the estimates of the class prevalence values.</span>
|
||
|
||
<span class="sd"> This dedicated class is kept for backward compatibility as the historical</span>
|
||
<span class="sd"> HDy implementation. The same historical preset is also available as</span>
|
||
<span class="sd"> :meth:`DMy.HDy`.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="HDy.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.HDy.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function of HDy.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the posterior probabilities returned by the classifier</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each posterior</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">P</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">P</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">neg_label</span><span class="p">]</span>
|
||
|
||
<span class="c1"># pre-compute the histogram for positive and negative examples</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">bins</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">int</span><span class="p">)</span> <span class="c1"># [10, 20, 30, ..., 100, 110]</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">hist</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">bins</span><span class="p">):</span>
|
||
<span class="n">h</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="k">return</span> <span class="n">h</span> <span class="o">/</span> <span class="n">h</span><span class="o">.</span><span class="n">sum</span><span class="p">()</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_density</span> <span class="o">=</span> <span class="p">{</span><span class="n">bins</span><span class="p">:</span> <span class="n">hist</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span><span class="p">,</span> <span class="n">bins</span><span class="p">)</span> <span class="k">for</span> <span class="n">bins</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">bins</span><span class="p">}</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_density</span> <span class="o">=</span> <span class="p">{</span><span class="n">bins</span><span class="p">:</span> <span class="n">hist</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span><span class="p">,</span> <span class="n">bins</span><span class="p">)</span> <span class="k">for</span> <span class="n">bins</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">bins</span><span class="p">}</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="HDy.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.HDy.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="c1"># "In this work, the number of bins b used in HDx and HDy was chosen from 10 to 110 in steps of 10,</span>
|
||
<span class="c1"># and the final estimated a priori probability was taken as the median of these 11 estimates."</span>
|
||
<span class="c1"># (González-Castro, et al., 2013).</span>
|
||
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">classif_posteriors</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
|
||
<span class="n">prev_estimations</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="k">for</span> <span class="n">bins</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">bins</span><span class="p">:</span>
|
||
<span class="n">Pxy0_density</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_density</span><span class="p">[</span><span class="n">bins</span><span class="p">]</span>
|
||
<span class="n">Pxy1_density</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_density</span><span class="p">[</span><span class="n">bins</span><span class="p">]</span>
|
||
|
||
<span class="n">Px_test</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">Px</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||
|
||
<span class="c1"># the authors proposed to search for the prevalence yielding the best matching as a linear search</span>
|
||
<span class="c1"># at small steps (modern implementations resort to an optimization procedure,</span>
|
||
<span class="c1"># see class DistributionMatching)</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">loss</span><span class="p">(</span><span class="n">prev</span><span class="p">):</span>
|
||
<span class="n">class1_prev</span> <span class="o">=</span> <span class="n">prev</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="n">Px_train</span> <span class="o">=</span> <span class="n">class1_prev</span> <span class="o">*</span> <span class="n">Pxy1_density</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">class1_prev</span><span class="p">)</span> <span class="o">*</span> <span class="n">Pxy0_density</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">HellingerDistance</span><span class="p">(</span><span class="n">Px_train</span><span class="p">,</span> <span class="n">Px_test</span><span class="p">)</span>
|
||
|
||
<span class="n">prev_estimations</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">F</span><span class="o">.</span><span class="n">linear_search</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">n_classes</span><span class="o">=</span><span class="mi">2</span><span class="p">)[</span><span class="mi">1</span><span class="p">])</span>
|
||
|
||
<span class="n">class1_prev</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="n">prev_estimations</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">as_binary_prevalence</span><span class="p">(</span><span class="n">class1_prev</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="DyS">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DyS">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">DyS</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">,</span> <span class="n">BinaryAggregativeQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `DyS framework <https://ojs.aaai.org/index.php/AAAI/article/view/4376>`_ (DyS).</span>
|
||
<span class="sd"> DyS is a generalization of HDy method, using a Ternary Search in order to find the prevalence that</span>
|
||
<span class="sd"> minimizes the distance between distributions.</span>
|
||
<span class="sd"> Details for the ternary search have been got from <https://dl.acm.org/doi/pdf/10.1145/3219819.3220059></span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param n_bins: an int with the number of bins to use to compute the histograms.</span>
|
||
|
||
<span class="sd"> :param divergence: a str indicating the name of divergence (currently supported ones are "HD" or "topsoe"), or a</span>
|
||
<span class="sd"> callable function computes the divergence between two distributions (two equally sized arrays).</span>
|
||
|
||
<span class="sd"> :param tol: a float with the tolerance for the ternary search algorithm.</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">n_bins</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span>
|
||
<span class="n">divergence</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Callable</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'HD'</span><span class="p">,</span> <span class="n">tol</span><span class="o">=</span><span class="mf">1e-05</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">tol</span> <span class="o">=</span> <span class="n">tol</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">divergence</span> <span class="o">=</span> <span class="n">divergence</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_bins</span> <span class="o">=</span> <span class="n">n_bins</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_ternary_search</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">,</span> <span class="n">tol</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Find maximum of unimodal function f() within [left, right]</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">while</span> <span class="nb">abs</span><span class="p">(</span><span class="n">right</span> <span class="o">-</span> <span class="n">left</span><span class="p">)</span> <span class="o">>=</span> <span class="n">tol</span><span class="p">:</span>
|
||
<span class="n">left_third</span> <span class="o">=</span> <span class="n">left</span> <span class="o">+</span> <span class="p">(</span><span class="n">right</span> <span class="o">-</span> <span class="n">left</span><span class="p">)</span> <span class="o">/</span> <span class="mi">3</span>
|
||
<span class="n">right_third</span> <span class="o">=</span> <span class="n">right</span> <span class="o">-</span> <span class="p">(</span><span class="n">right</span> <span class="o">-</span> <span class="n">left</span><span class="p">)</span> <span class="o">/</span> <span class="mi">3</span>
|
||
|
||
<span class="k">if</span> <span class="n">f</span><span class="p">(</span><span class="n">left_third</span><span class="p">)</span> <span class="o">></span> <span class="n">f</span><span class="p">(</span><span class="n">right_third</span><span class="p">):</span>
|
||
<span class="n">left</span> <span class="o">=</span> <span class="n">left_third</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">right</span> <span class="o">=</span> <span class="n">right_third</span>
|
||
|
||
<span class="c1"># Left and right are the current bounds; the maximum is between them</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">left</span> <span class="o">+</span> <span class="n">right</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span>
|
||
|
||
<div class="viewcode-block" id="DyS.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DyS.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function of DyS.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the posterior probabilities returned by the classifier</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each posterior</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">Px</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">neg_label</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_density</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_bins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_density</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_bins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="k">return</span> <span class="bp">self</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="DyS.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DyS.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">classif_posteriors</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
|
||
<span class="n">Px_test</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">Px</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_bins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="n">divergence</span> <span class="o">=</span> <span class="n">get_divergence</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">divergence</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">distribution_distance</span><span class="p">(</span><span class="n">prev</span><span class="p">):</span>
|
||
<span class="n">Px_train</span> <span class="o">=</span> <span class="n">prev</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_density</span> <span class="o">+</span> <span class="p">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">prev</span><span class="p">)</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_density</span>
|
||
<span class="k">return</span> <span class="n">divergence</span><span class="p">(</span><span class="n">Px_train</span><span class="p">,</span> <span class="n">Px_test</span><span class="p">)</span>
|
||
|
||
<span class="n">class1_prev</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_ternary_search</span><span class="p">(</span><span class="n">f</span><span class="o">=</span><span class="n">distribution_distance</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">tol</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">tol</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">as_binary_prevalence</span><span class="p">(</span><span class="n">class1_prev</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="SMM">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.SMM">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">SMM</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">,</span> <span class="n">BinaryAggregativeQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> `SMM method <https://ieeexplore.ieee.org/document/9260028>`_ (SMM).</span>
|
||
<span class="sd"> SMM is a simplification of matching distribution methods where the representation of the examples</span>
|
||
<span class="sd"> is created using the mean instead of a histogram (conceptually equivalent to PACC).</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="SMM.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.SMM.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function of SMM.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the posterior probabilities returned by the classifier</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each posterior</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">Px</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span> <span class="o">=</span> <span class="n">Px</span><span class="p">[</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">neg_label</span><span class="p">]</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_mean</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy1</span><span class="p">)</span> <span class="c1"># equiv. TPR</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_mean</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy0</span><span class="p">)</span> <span class="c1"># equiv. FPR</span>
|
||
<span class="k">return</span> <span class="bp">self</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="SMM.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.SMM.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_posteriors</span><span class="p">):</span>
|
||
<span class="n">Px</span> <span class="o">=</span> <span class="n">classif_posteriors</span><span class="p">[:,</span> <span class="bp">self</span><span class="o">.</span><span class="n">pos_label</span><span class="p">]</span> <span class="c1"># takes only the P(y=+1|x)</span>
|
||
<span class="n">Px_mean</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">Px</span><span class="p">)</span>
|
||
|
||
<span class="n">class1_prev</span> <span class="o">=</span> <span class="p">(</span><span class="n">Px_mean</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_mean</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">Pxy1_mean</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">Pxy0_mean</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">as_binary_prevalence</span><span class="p">(</span><span class="n">class1_prev</span><span class="p">,</span> <span class="n">clip_if_necessary</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="DMy">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DMy">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">DMy</span><span class="p">(</span><span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Generic Distribution Matching quantifier for binary or multiclass quantification based on the space of posterior</span>
|
||
<span class="sd"> probabilities. This implementation takes the number of bins, the divergence, and the possibility to work on CDF</span>
|
||
<span class="sd"> as hyperparameters.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None, in which case the classifier is taken to be</span>
|
||
<span class="sd"> the one indicated in `qp.environ['DEFAULT_CLS']`</span>
|
||
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default is True). Set to False if the</span>
|
||
<span class="sd"> learner has been trained outside the quantifier.</span>
|
||
|
||
<span class="sd"> :param val_split: specifies the data used for generating classifier predictions. This specification</span>
|
||
<span class="sd"> can be made as float in (0, 1) indicating the proportion of stratified held-out validation set to</span>
|
||
<span class="sd"> be extracted from the training set; or as an integer (default 5), indicating that the predictions</span>
|
||
<span class="sd"> are to be generated in a `k`-fold cross-validation manner (with this integer indicating the value</span>
|
||
<span class="sd"> for `k`); or as a tuple (X,y) defining the specific set of data to use for validation.</span>
|
||
|
||
<span class="sd"> :param nbins: number of bins used to discretize the distributions (default 8)</span>
|
||
|
||
<span class="sd"> :param divergence: a string representing a divergence measure (currently, "HD" and "topsoe" are implemented)</span>
|
||
<span class="sd"> or a callable function taking two ndarrays of the same dimension as input (default "HD", meaning Hellinger</span>
|
||
<span class="sd"> Distance)</span>
|
||
|
||
<span class="sd"> :param cdf: whether to use CDF instead of PDF (default False)</span>
|
||
|
||
<span class="sd"> :param search: string indicating the search strategy used to estimate the prevalence values.</span>
|
||
<span class="sd"> Valid options are `optim_minimize` (default, works for binary and multiclass problems),</span>
|
||
<span class="sd"> `linear_search` (binary only), and `ternary_search` (binary only)</span>
|
||
|
||
<span class="sd"> :param n_jobs: number of parallel workers (default None)</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">nbins</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span>
|
||
<span class="n">divergence</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Callable</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'HD'</span><span class="p">,</span> <span class="n">cdf</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">search</span><span class="o">=</span><span class="s1">'optim_minimize'</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">nbins</span> <span class="o">=</span> <span class="n">nbins</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">divergence</span> <span class="o">=</span> <span class="n">divergence</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">cdf</span> <span class="o">=</span> <span class="n">cdf</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">search</span> <span class="o">=</span> <span class="n">search</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="DMy.HDy">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DMy.HDy">[docs]</a>
|
||
<span class="nd">@classmethod</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">HDy</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Historical HDy preset expressed as a configuration of :class:`DMy`.</span>
|
||
|
||
<span class="sd"> This preset reproduces the original HDy setup by using Hellinger</span>
|
||
<span class="sd"> distance, PDF matching, linear search, and a median sweep over</span>
|
||
<span class="sd"> `nbins` in `[10, 20, ..., 110]`.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn's BaseEstimator, or None</span>
|
||
<span class="sd"> :param fit_classifier: whether to train the learner</span>
|
||
<span class="sd"> :param val_split: validation specification for generating posteriors</span>
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
<span class="sd"> :return: an instance of :class:`AggregativeMedianEstimator` configured</span>
|
||
<span class="sd"> to reproduce the historical HDy preset</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">base</span> <span class="o">=</span> <span class="bp">cls</span><span class="p">(</span>
|
||
<span class="n">classifier</span><span class="o">=</span><span class="n">classifier</span><span class="p">,</span>
|
||
<span class="n">fit_classifier</span><span class="o">=</span><span class="n">fit_classifier</span><span class="p">,</span>
|
||
<span class="n">val_split</span><span class="o">=</span><span class="n">val_split</span><span class="p">,</span>
|
||
<span class="n">nbins</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span>
|
||
<span class="n">divergence</span><span class="o">=</span><span class="s1">'HD'</span><span class="p">,</span>
|
||
<span class="n">cdf</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
||
<span class="n">search</span><span class="o">=</span><span class="s1">'linear_search'</span><span class="p">,</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="n">n_jobs</span><span class="p">,</span>
|
||
<span class="p">)</span>
|
||
<span class="n">param_grid</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'nbins'</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">110</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">int</span><span class="p">)}</span>
|
||
<span class="k">return</span> <span class="n">AggregativeMedianEstimator</span><span class="p">(</span><span class="n">base_quantifier</span><span class="o">=</span><span class="n">base</span><span class="p">,</span> <span class="n">param_grid</span><span class="o">=</span><span class="n">param_grid</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="n">n_jobs</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_get_distributions</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">posteriors</span><span class="p">):</span>
|
||
<span class="n">histograms</span> <span class="o">=</span> <span class="p">[]</span>
|
||
<span class="n">post_dims</span> <span class="o">=</span> <span class="n">posteriors</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="k">if</span> <span class="n">post_dims</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
||
<span class="c1"># in binary quantification we can use only one class, since the other one is its complement</span>
|
||
<span class="n">post_dims</span> <span class="o">=</span> <span class="mi">1</span>
|
||
<span class="k">for</span> <span class="n">dim</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">post_dims</span><span class="p">):</span>
|
||
<span class="n">hist</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">posteriors</span><span class="p">[:,</span> <span class="n">dim</span><span class="p">],</span> <span class="n">bins</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">nbins</span><span class="p">,</span> <span class="nb">range</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))[</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="n">histograms</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">hist</span><span class="p">)</span>
|
||
|
||
<span class="n">counts</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">vstack</span><span class="p">(</span><span class="n">histograms</span><span class="p">)</span>
|
||
<span class="n">distributions</span> <span class="o">=</span> <span class="n">counts</span> <span class="o">/</span> <span class="n">counts</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)[:,</span> <span class="n">np</span><span class="o">.</span><span class="n">newaxis</span><span class="p">]</span>
|
||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">cdf</span><span class="p">:</span>
|
||
<span class="n">distributions</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">cumsum</span><span class="p">(</span><span class="n">distributions</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">distributions</span>
|
||
|
||
<div class="viewcode-block" id="DMy.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DMy.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Trains the aggregation function of a distribution matching method. This comes down to generating the</span>
|
||
<span class="sd"> validation distributions out of the training data.</span>
|
||
<span class="sd"> The validation distributions have shape `(n, ch, nbins)`, with `n` the number of classes, `ch` the number of</span>
|
||
<span class="sd"> channels, and `nbins` the number of bins. In particular, let `V` be the validation distributions; then `di=V[i]`</span>
|
||
<span class="sd"> are the distributions obtained from training data labelled with class `i`; while `dij = di[j]` is the discrete</span>
|
||
<span class="sd"> distribution of posterior probabilities `P(Y=j|X=x)` for training data labelled with class `i`, and `dij[k]`</span>
|
||
<span class="sd"> is the fraction of instances with a value in the `k`-th bin.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: array-like with the posterior probabilities returned by the classifier</span>
|
||
<span class="sd"> :param labels: array-like with the true labels associated to each posterior</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">posteriors</span><span class="p">,</span> <span class="n">true_labels</span> <span class="o">=</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span>
|
||
<span class="n">classes</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">classifier</span><span class="o">.</span><span class="n">classes_</span>
|
||
<span class="n">n_classes</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">classes</span><span class="p">)</span>
|
||
<span class="n">true_labels</span> <span class="o">=</span> <span class="n">_labels_to_indices</span><span class="p">(</span><span class="n">true_labels</span><span class="p">,</span> <span class="n">classes</span><span class="p">)</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">validation_distribution</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">parallel</span><span class="p">(</span>
|
||
<span class="n">func</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_get_distributions</span><span class="p">,</span>
|
||
<span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="n">posteriors</span><span class="p">[</span><span class="n">true_labels</span> <span class="o">==</span> <span class="n">cat</span><span class="p">]</span> <span class="k">for</span> <span class="n">cat</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_classes</span><span class="p">)],</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span><span class="p">,</span>
|
||
<span class="n">backend</span><span class="o">=</span><span class="s1">'threading'</span>
|
||
<span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="DMy.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.DMy.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">posteriors</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Searches for the mixture model parameter (the sought prevalence values) that yields a validation distribution</span>
|
||
<span class="sd"> (the mixture) that best matches the test distribution, in terms of the divergence measure of choice.</span>
|
||
<span class="sd"> In the multiclass case, with `n` the number of classes, the test and mixture distributions contain</span>
|
||
<span class="sd"> `n` channels (proper distributions of binned posterior probabilities), on which the divergence is computed</span>
|
||
<span class="sd"> independently. The matching is computed as an average of the divergence across all channels.</span>
|
||
|
||
<span class="sd"> :param posteriors: posterior probabilities of the instances in the sample</span>
|
||
<span class="sd"> :return: a vector of class prevalence estimates</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">test_distribution</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_distributions</span><span class="p">(</span><span class="n">posteriors</span><span class="p">)</span>
|
||
<span class="n">divergence</span> <span class="o">=</span> <span class="n">get_divergence</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">divergence</span><span class="p">)</span>
|
||
<span class="n">n_classes</span><span class="p">,</span> <span class="n">n_channels</span><span class="p">,</span> <span class="n">nbins</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">validation_distribution</span><span class="o">.</span><span class="n">shape</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">loss</span><span class="p">(</span><span class="n">prev</span><span class="p">):</span>
|
||
<span class="n">prev</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">expand_dims</span><span class="p">(</span><span class="n">prev</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="n">mixture_distribution</span> <span class="o">=</span> <span class="p">(</span><span class="n">prev</span> <span class="o">@</span> <span class="bp">self</span><span class="o">.</span><span class="n">validation_distribution</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">n_classes</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">))</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">n_channels</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="n">divs</span> <span class="o">=</span> <span class="p">[</span><span class="n">divergence</span><span class="p">(</span><span class="n">test_distribution</span><span class="p">[</span><span class="n">ch</span><span class="p">],</span> <span class="n">mixture_distribution</span><span class="p">[</span><span class="n">ch</span><span class="p">])</span> <span class="k">for</span> <span class="n">ch</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_channels</span><span class="p">)]</span>
|
||
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">divs</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">argmin_prevalence</span><span class="p">(</span><span class="n">loss</span><span class="p">,</span> <span class="n">n_classes</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">search</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newELM">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newELM">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'01'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Explicit Loss Minimization (ELM) quantifiers.</span>
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param loss: the loss to optimize (see :attr:`quapy.classification.svmperf.SVMperf.valid_losses`)</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">if</span> <span class="n">svmperf_base</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">svmperf_base</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">'SVMPERF_HOME'</span><span class="p">]</span>
|
||
<span class="k">assert</span> <span class="n">svmperf_base</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">,</span> \
|
||
<span class="s1">'param svmperf_base was not specified, and the variable SVMPERF_HOME has not been set in the environment'</span>
|
||
<span class="k">return</span> <span class="n">CC</span><span class="p">(</span><span class="n">SVMperf</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="n">loss</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">))</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newSVMQ">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newSVMQ">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newSVMQ</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> SVM(Q) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the `Q` loss combining a</span>
|
||
<span class="sd"> classification-oriented loss and a quantification-oriented loss, as proposed by</span>
|
||
<span class="sd"> `Barranquero et al. 2015 <https://www.sciencedirect.com/science/article/pii/S003132031400291X>`_.</span>
|
||
<span class="sd"> Equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss='q', C=C))</span>
|
||
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function is a wrapper around CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'q'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newSVMKLD">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newSVMKLD">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newSVMKLD</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Kullback-Leibler Divergence</span>
|
||
<span class="sd"> as proposed by `Esuli et al. 2015 <https://dl.acm.org/doi/abs/10.1145/2700406>`_.</span>
|
||
<span class="sd"> Equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss='kld', C=C))</span>
|
||
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function is a wrapper around CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'kld'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newSVMNKLD">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newSVMNKLD">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newSVMNKLD</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> SVM(NKLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Kullback-Leibler Divergence</span>
|
||
<span class="sd"> normalized via the logistic function, as proposed by</span>
|
||
<span class="sd"> `Esuli et al. 2015 <https://dl.acm.org/doi/abs/10.1145/2700406>`_.</span>
|
||
<span class="sd"> Equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss='nkld', C=C))</span>
|
||
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function is a wrapper around CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'nkld'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newSVMAE">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newSVMAE">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newSVMAE</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Absolute Error as first used by</span>
|
||
<span class="sd"> `Moreo and Sebastiani, 2021 <https://arxiv.org/abs/2011.02552>`_.</span>
|
||
<span class="sd"> Equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss='mae', C=C))</span>
|
||
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function is a wrapper around CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'mae'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="newSVMRAE">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.newSVMRAE">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">newSVMRAE</span><span class="p">(</span><span class="n">svmperf_base</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> SVM(KLD) is an Explicit Loss Minimization (ELM) quantifier set to optimize for the Relative Absolute Error as first</span>
|
||
<span class="sd"> used by `Moreo and Sebastiani, 2021 <https://arxiv.org/abs/2011.02552>`_.</span>
|
||
<span class="sd"> Equivalent to:</span>
|
||
|
||
<span class="sd"> >>> CC(SVMperf(svmperf_base, loss='mrae', C=C))</span>
|
||
|
||
<span class="sd"> Quantifiers based on ELM represent a family of methods based on structured output learning;</span>
|
||
<span class="sd"> these quantifiers rely on classifiers that have been optimized using a quantification-oriented loss</span>
|
||
<span class="sd"> measure. This implementation relies on</span>
|
||
<span class="sd"> `Joachims’ SVM perf <https://www.cs.cornell.edu/people/tj/svm_light/svm_perf.html>`_ structured output</span>
|
||
<span class="sd"> learning algorithm, which has to be installed and patched for the purpose (see this</span>
|
||
<span class="sd"> `script <https://github.com/HLT-ISTI/QuaPy/blob/master/prepare_svmperf.sh>`_).</span>
|
||
<span class="sd"> This function is a wrapper around CC(SVMperf(svmperf_base, loss, C))</span>
|
||
|
||
<span class="sd"> :param svmperf_base: path to the folder containing the binary files of `SVM perf`; if set to None (default)</span>
|
||
<span class="sd"> this path will be obtained from qp.environ['SVMPERF_HOME']</span>
|
||
<span class="sd"> :param C: trade-off between training error and margin (default 0.01)</span>
|
||
<span class="sd"> :return: returns an instance of CC set to work with SVMperf (with loss and C set properly) as the</span>
|
||
<span class="sd"> underlying classifier</span>
|
||
<span class="sd"> """</span>
|
||
<span class="k">return</span> <span class="n">newELM</span><span class="p">(</span><span class="n">svmperf_base</span><span class="p">,</span> <span class="n">loss</span><span class="o">=</span><span class="s1">'mrae'</span><span class="p">,</span> <span class="n">C</span><span class="o">=</span><span class="n">C</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="OneVsAllAggregative">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.OneVsAllAggregative">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">OneVsAllAggregative</span><span class="p">(</span><span class="n">OneVsAllGeneric</span><span class="p">,</span> <span class="n">AggregativeQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Allows any binary quantifier to perform quantification on single-label datasets.</span>
|
||
<span class="sd"> The method maintains one binary quantifier for each class, and then l1-normalizes the outputs so that the</span>
|
||
<span class="sd"> class prevelences sum up to 1.</span>
|
||
<span class="sd"> This variant was used, along with the :class:`EMQ` quantifier, in</span>
|
||
<span class="sd"> `Gao and Sebastiani, 2016 <https://link.springer.com/content/pdf/10.1007/s13278-016-0327-z.pdf>`_.</span>
|
||
|
||
<span class="sd"> :param binary_quantifier: a quantifier (binary) that will be employed to work on multiclass model in a</span>
|
||
<span class="sd"> one-vs-all manner (default PACC(LogitsticRegression()))</span>
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
<span class="sd"> :param parallel_backend: the parallel backend for joblib (default "loky"); this is helpful for some quantifiers</span>
|
||
<span class="sd"> (e.g., ELM-based ones) that cannot be run with multiprocessing, since the temp dir they create during fit will</span>
|
||
<span class="sd"> is removed and no longer available at predict time.</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">binary_quantifier</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">parallel_backend</span><span class="o">=</span><span class="s1">'multiprocessing'</span><span class="p">):</span>
|
||
<span class="k">if</span> <span class="n">binary_quantifier</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||
<span class="n">binary_quantifier</span> <span class="o">=</span> <span class="n">PACC</span><span class="p">()</span>
|
||
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">binary_quantifier</span><span class="p">,</span> <span class="n">BaseQuantifier</span><span class="p">),</span> \
|
||
<span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">binary_quantifier</span><span class="si">}</span><span class="s1"> does not seem to be a Quantifier'</span>
|
||
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">binary_quantifier</span><span class="p">,</span> <span class="n">AggregativeQuantifier</span><span class="p">),</span> \
|
||
<span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">binary_quantifier</span><span class="si">}</span><span class="s1"> does not seem to be of type Aggregative'</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">binary_quantifier</span> <span class="o">=</span> <span class="n">binary_quantifier</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">parallel_backend</span> <span class="o">=</span> <span class="n">parallel_backend</span>
|
||
|
||
<div class="viewcode-block" id="OneVsAllAggregative.classify">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.OneVsAllAggregative.classify">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">classify</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> If the base quantifier is not probabilistic, returns a matrix of shape `(n,m,)` with `n` the number of</span>
|
||
<span class="sd"> instances and `m` the number of classes. The entry `(i,j)` is a binary value indicating whether instance</span>
|
||
<span class="sd"> `i` belongs to class `j`. The binary classifications are independent of each other, meaning that an instance</span>
|
||
<span class="sd"> can end up be attributed to 0, 1, or more classes.</span>
|
||
<span class="sd"> If the base quantifier is probabilistic, returns a matrix of shape `(n,m,2)` with `n` the number of instances</span>
|
||
<span class="sd"> and `m` the number of classes. The entry `(i,j,1)` (resp. `(i,j,0)`) is a value in [0,1] indicating the</span>
|
||
<span class="sd"> posterior probability that instance `i` belongs (resp. does not belong) to class `j`. The posterior</span>
|
||
<span class="sd"> probabilities are independent of each other, meaning that, in general, they do not sum up to one.</span>
|
||
|
||
<span class="sd"> :param X: array-like</span>
|
||
<span class="sd"> :return: `np.ndarray`</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="n">classif_predictions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parallel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_delayed_binary_classification</span><span class="p">,</span> <span class="n">X</span><span class="p">)</span>
|
||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">binary_quantifier</span><span class="p">,</span> <span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">swapaxes</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="k">return</span> <span class="n">classif_predictions</span><span class="o">.</span><span class="n">T</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="OneVsAllAggregative.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.OneVsAllAggregative.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">):</span>
|
||
<span class="n">prevalences</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parallel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_delayed_binary_aggregate</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">F</span><span class="o">.</span><span class="n">normalize_prevalence</span><span class="p">(</span><span class="n">prevalences</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="OneVsAllAggregative.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.OneVsAllAggregative.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_parallel</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_delayed_binary_aggregate_fit</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="bp">self</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_binary_classification</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">X</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">dict_binary_quantifiers</span><span class="p">[</span><span class="n">c</span><span class="p">]</span><span class="o">.</span><span class="n">classify</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_binary_aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">):</span>
|
||
<span class="c1"># the estimation for the positive class prevalence</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">dict_binary_quantifiers</span><span class="p">[</span><span class="n">c</span><span class="p">]</span><span class="o">.</span><span class="n">aggregate</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">[:,</span> <span class="n">c</span><span class="p">])[</span><span class="mi">1</span><span class="p">]</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_binary_aggregate_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="c1"># trains the aggregation function of the cth quantifier</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">dict_binary_quantifiers</span><span class="p">[</span><span class="n">c</span><span class="p">]</span><span class="o">.</span><span class="n">aggregation_fit</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">[:,</span> <span class="n">c</span><span class="p">],</span> <span class="n">labels</span> <span class="o">==</span> <span class="n">c</span><span class="p">)</span></div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeMedianEstimator">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeMedianEstimator">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">AggregativeMedianEstimator</span><span class="p">(</span><span class="n">BinaryQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> This method is a meta-quantifier that returns, as the estimated class prevalence values, the median of the</span>
|
||
<span class="sd"> estimation returned by differently (hyper)parameterized base quantifiers.</span>
|
||
<span class="sd"> The median of unit-vectors is only guaranteed to be a unit-vector for n=2 dimensions,</span>
|
||
<span class="sd"> i.e., in cases of binary quantification.</span>
|
||
|
||
<span class="sd"> :param base_quantifier: the base, binary quantifier</span>
|
||
<span class="sd"> :param random_state: a seed to be set before fitting any base quantifier (default None)</span>
|
||
<span class="sd"> :param param_grid: the grid or parameters towards which the median will be computed</span>
|
||
<span class="sd"> :param n_jobs: number of parallel workers</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">base_quantifier</span><span class="p">:</span> <span class="n">AggregativeQuantifier</span><span class="p">,</span> <span class="n">param_grid</span><span class="p">:</span> <span class="nb">dict</span><span class="p">,</span> <span class="n">random_state</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span> <span class="o">=</span> <span class="n">base_quantifier</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">param_grid</span> <span class="o">=</span> <span class="n">param_grid</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">random_state</span> <span class="o">=</span> <span class="n">random_state</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeMedianEstimator.get_params">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeMedianEstimator.get_params">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">get_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">deep</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span><span class="o">.</span><span class="n">get_params</span><span class="p">(</span><span class="n">deep</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="AggregativeMedianEstimator.set_params">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeMedianEstimator.set_params">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">set_params</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span><span class="o">.</span><span class="n">set_params</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
||
<span class="k">with</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">temp_seed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">random_state</span><span class="p">):</span>
|
||
<span class="n">params</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">args</span>
|
||
<span class="n">model</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span><span class="p">)</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">set_params</span><span class="p">(</span><span class="o">**</span><span class="n">params</span><span class="p">)</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">model</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_fit_classifier</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
||
<span class="k">with</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">temp_seed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">random_state</span><span class="p">):</span>
|
||
<span class="n">cls_params</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">args</span>
|
||
<span class="n">model</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span><span class="p">)</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">set_params</span><span class="p">(</span><span class="o">**</span><span class="n">cls_params</span><span class="p">)</span>
|
||
<span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">classifier_fit_predict</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">)</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_fit_aggregation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
||
<span class="k">with</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">temp_seed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">random_state</span><span class="p">):</span>
|
||
<span class="p">((</span><span class="n">model</span><span class="p">,</span> <span class="n">predictions</span><span class="p">,</span> <span class="n">y</span><span class="p">),</span> <span class="n">q_params</span><span class="p">)</span> <span class="o">=</span> <span class="n">args</span>
|
||
<span class="n">model</span> <span class="o">=</span> <span class="n">deepcopy</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">set_params</span><span class="p">(</span><span class="o">**</span><span class="n">q_params</span><span class="p">)</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">aggregation_fit</span><span class="p">(</span><span class="n">predictions</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">model</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeMedianEstimator.fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeMedianEstimator.fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
|
||
<span class="kn">import</span><span class="w"> </span><span class="nn">itertools</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_check_binary</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span><span class="p">,</span> <span class="n">AggregativeQuantifier</span><span class="p">):</span>
|
||
<span class="n">cls_configs</span><span class="p">,</span> <span class="n">q_configs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">model_selection</span><span class="o">.</span><span class="n">group_params</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">param_grid</span><span class="p">)</span>
|
||
|
||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">cls_configs</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
||
<span class="n">models_preds</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">parallel</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_delayed_fit_classifier</span><span class="p">,</span>
|
||
<span class="p">((</span><span class="n">params</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">params</span> <span class="ow">in</span> <span class="n">cls_configs</span><span class="p">),</span>
|
||
<span class="n">seed</span><span class="o">=</span><span class="n">qp</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_R_SEED'</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span><span class="p">,</span>
|
||
<span class="n">asarray</span><span class="o">=</span><span class="kc">False</span>
|
||
<span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">model</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">base_quantifier</span>
|
||
<span class="n">model</span><span class="o">.</span><span class="n">set_params</span><span class="p">(</span><span class="o">**</span><span class="n">cls_configs</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
||
<span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">classifier_fit_predict</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="n">models_preds</span> <span class="o">=</span> <span class="p">[(</span><span class="n">model</span><span class="p">,</span> <span class="n">predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">)]</span>
|
||
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">models</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">parallel</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_delayed_fit_aggregation</span><span class="p">,</span>
|
||
<span class="n">itertools</span><span class="o">.</span><span class="n">product</span><span class="p">(</span><span class="n">models_preds</span><span class="p">,</span> <span class="n">q_configs</span><span class="p">),</span>
|
||
<span class="n">seed</span><span class="o">=</span><span class="n">qp</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_R_SEED'</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span>
|
||
<span class="p">)</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">configs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">model_selection</span><span class="o">.</span><span class="n">expand_grid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">param_grid</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">models</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">parallel</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_delayed_fit</span><span class="p">,</span>
|
||
<span class="p">((</span><span class="n">params</span><span class="p">,</span> <span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">params</span> <span class="ow">in</span> <span class="n">configs</span><span class="p">),</span>
|
||
<span class="n">seed</span><span class="o">=</span><span class="n">qp</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_R_SEED'</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span>
|
||
<span class="p">)</span>
|
||
<span class="k">return</span> <span class="bp">self</span></div>
|
||
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_delayed_predict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span>
|
||
<span class="n">model</span><span class="p">,</span> <span class="n">instances</span> <span class="o">=</span> <span class="n">args</span>
|
||
<span class="k">return</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">instances</span><span class="p">)</span>
|
||
|
||
<div class="viewcode-block" id="AggregativeMedianEstimator.predict">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.AggregativeMedianEstimator.predict">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">predict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instances</span><span class="p">):</span>
|
||
<span class="n">prev_preds</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">parallel</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_delayed_predict</span><span class="p">,</span>
|
||
<span class="p">((</span><span class="n">model</span><span class="p">,</span> <span class="n">instances</span><span class="p">)</span> <span class="k">for</span> <span class="n">model</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">models</span><span class="p">),</span>
|
||
<span class="n">seed</span><span class="o">=</span><span class="n">qp</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">'_R_SEED'</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span>
|
||
<span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="n">prev_preds</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="viewcode-block" id="EDy">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EDy">[docs]</a>
|
||
<span class="k">class</span><span class="w"> </span><span class="nc">EDy</span><span class="p">(</span><span class="n">_EnergyDistanceCore</span><span class="p">,</span> <span class="n">AggregativeSoftQuantifier</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Energy Distance y (EDy), a posterior-space distribution-matching quantifier</span>
|
||
<span class="sd"> based on energy distance.</span>
|
||
|
||
<span class="sd"> The method represents each class by the posterior-probability vectors</span>
|
||
<span class="sd"> produced by a probabilistic classifier on validation data, and estimates the</span>
|
||
<span class="sd"> test prevalence vector by matching the test posterior distribution against</span>
|
||
<span class="sd"> the class-conditional validation distributions through an energy-distance</span>
|
||
<span class="sd"> objective solved as a quadratic program. The method is therefore another</span>
|
||
<span class="sd"> instance of the general mixture-matching view of quantification, but it</span>
|
||
<span class="sd"> operates directly on posterior vectors rather than on histogram summaries.</span>
|
||
|
||
<span class="sd"> This implementation works for binary and multiclass single-label</span>
|
||
<span class="sd"> quantification and relies on the optional ``quadprog`` dependency. It was</span>
|
||
<span class="sd"> adapted to QuaPy's current aggregative API from the original implementation</span>
|
||
<span class="sd"> available in `quantificationlib <https://github.com/AICGijon/quantificationlib>`_,</span>
|
||
<span class="sd"> and now shares its numerical core with the classifier-free</span>
|
||
<span class="sd"> :class:`quapy.method.non_aggregative.EDx` variant.</span>
|
||
|
||
<span class="sd"> The current implementation follows the energy-distance formulation discussed</span>
|
||
<span class="sd"> in:</span>
|
||
|
||
<span class="sd"> * Alberto Castaño, Laura Morán-Fernández, Jaime Alonso,</span>
|
||
<span class="sd"> Verónica Bolón-Canedo, Amparo Alonso-Betanzos, and Juan José del Coz.</span>
|
||
<span class="sd"> *An analysis of quantification methods based on matching distributions*.</span>
|
||
<span class="sd"> * Hideko Kawakubo, Marthinus Christoffel du Plessis, and Masashi Sugiyama</span>
|
||
<span class="sd"> (2016). *Computationally efficient class-prior estimation under class</span>
|
||
<span class="sd"> balance change using energy distance*. IEICE Transactions on Information</span>
|
||
<span class="sd"> and Systems, 99(1):176-186.</span>
|
||
|
||
<span class="sd"> :param classifier: a scikit-learn ``BaseEstimator``, or ``None`` to use</span>
|
||
<span class="sd"> ``qp.environ['DEFAULT_CLS']``</span>
|
||
<span class="sd"> :param fit_classifier: whether to train the learner (default ``True``).</span>
|
||
<span class="sd"> Set to ``False`` if the learner has already been trained outside the</span>
|
||
<span class="sd"> quantifier</span>
|
||
<span class="sd"> :param val_split: specification of the data used for generating validation</span>
|
||
<span class="sd"> posterior probabilities. This can be an integer (default ``5``) for</span>
|
||
<span class="sd"> k-fold cross-validation, a float in ``(0, 1)`` for a held-out split,</span>
|
||
<span class="sd"> or a tuple ``(X, y)`` with explicit validation data</span>
|
||
<span class="sd"> :param distance: distance used to compare posterior vectors. Valid string</span>
|
||
<span class="sd"> aliases are ``'manhattan'`` (default) and ``'euclidean'``; a custom</span>
|
||
<span class="sd"> callable compatible with pairwise-distance signatures can also be used</span>
|
||
<span class="sd"> :param n_jobs: number of parallel workers (default ``None``, meaning the</span>
|
||
<span class="sd"> value is taken from the environment)</span>
|
||
<span class="sd"> """</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span>
|
||
<span class="bp">self</span><span class="p">,</span>
|
||
<span class="n">classifier</span><span class="p">:</span> <span class="n">BaseEstimator</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
||
<span class="n">fit_classifier</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
||
<span class="n">val_split</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span>
|
||
<span class="n">distance</span><span class="p">:</span> <span class="n">Union</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">Callable</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'manhattan'</span><span class="p">,</span>
|
||
<span class="n">n_jobs</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||
<span class="p">):</span>
|
||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">classifier</span><span class="p">,</span> <span class="n">fit_classifier</span><span class="p">,</span> <span class="n">val_split</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">distance</span> <span class="o">=</span> <span class="n">distance</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">n_jobs</span> <span class="o">=</span> <span class="n">qp</span><span class="o">.</span><span class="n">_get_njobs</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">)</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">train_n_cls_i_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">train_distrib_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">K_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">G_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">C_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">b_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">a_</span> <span class="o">=</span> <span class="kc">None</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">_check_init_parameters</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">_check_ed_init_parameters</span><span class="p">()</span>
|
||
|
||
<div class="viewcode-block" id="EDy.aggregation_fit">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EDy.aggregation_fit">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregation_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">classif_predictions</span><span class="p">,</span> <span class="n">labels</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""</span>
|
||
<span class="sd"> Estimate the class-conditional posterior distributions on validation</span>
|
||
<span class="sd"> data and pre-compute the quadratic-program parameters that depend only</span>
|
||
<span class="sd"> on the training side.</span>
|
||
|
||
<span class="sd"> In EDy, the validation posteriors are not discretized into histograms.</span>
|
||
<span class="sd"> Instead, each class is represented by the cloud of posterior vectors</span>
|
||
<span class="sd"> observed for that class, and these clouds are then compared through the</span>
|
||
<span class="sd"> selected pairwise distance.</span>
|
||
|
||
<span class="sd"> :param classif_predictions: posterior probabilities returned by the</span>
|
||
<span class="sd"> classifier on validation data</span>
|
||
<span class="sd"> :param labels: true labels associated to each posterior vector</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">posteriors</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">classif_predictions</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span>
|
||
<span class="n">labels</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">labels</span><span class="p">)</span>
|
||
<span class="n">train_distrib</span> <span class="o">=</span> <span class="p">[</span><span class="n">posteriors</span><span class="p">[</span><span class="n">labels</span> <span class="o">==</span> <span class="n">class_</span><span class="p">]</span> <span class="k">for</span> <span class="n">class_</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">classes_</span><span class="p">]</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fit_energy_model</span><span class="p">(</span><span class="n">train_distrib</span><span class="p">)</span></div>
|
||
|
||
|
||
<div class="viewcode-block" id="EDy.aggregate">
|
||
<a class="viewcode-back" href="../../../quapy.method.html#quapy.method.aggregative.EDy.aggregate">[docs]</a>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">aggregate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">posteriors</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">ndarray</span><span class="p">):</span>
|
||
<span class="w"> </span><span class="sd">"""Estimate the prevalence vector for a test sample.</span>
|
||
|
||
<span class="sd"> :param posteriors: posterior probabilities returned by the classifier</span>
|
||
<span class="sd"> for the instances in the test sample</span>
|
||
<span class="sd"> :return: a prevalence vector of shape ``(n_classes,)``</span>
|
||
<span class="sd"> """</span>
|
||
<span class="n">posteriors</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">posteriors</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">float</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_predict_energy</span><span class="p">(</span><span class="n">posteriors</span><span class="p">)</span></div>
|
||
</div>
|
||
|
||
|
||
|
||
<span class="c1"># ---------------------------------------------------------------</span>
|
||
<span class="c1"># imports</span>
|
||
<span class="c1"># ---------------------------------------------------------------</span>
|
||
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">.</span><span class="w"> </span><span class="kn">import</span> <span class="n">_threshold_optim</span>
|
||
|
||
<span class="n">T50</span> <span class="o">=</span> <span class="n">_threshold_optim</span><span class="o">.</span><span class="n">T50</span>
|
||
<span class="n">MAX</span> <span class="o">=</span> <span class="n">_threshold_optim</span><span class="o">.</span><span class="n">MAX</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="n">_threshold_optim</span><span class="o">.</span><span class="n">X</span>
|
||
<span class="n">MS</span> <span class="o">=</span> <span class="n">_threshold_optim</span><span class="o">.</span><span class="n">MS</span>
|
||
<span class="n">MS2</span> <span class="o">=</span> <span class="n">_threshold_optim</span><span class="o">.</span><span class="n">MS2</span>
|
||
|
||
<span class="kn">from</span><span class="w"> </span><span class="nn">.</span><span class="w"> </span><span class="kn">import</span> <span class="n">_kdey</span>
|
||
|
||
<span class="n">KDEyML</span> <span class="o">=</span> <span class="n">_kdey</span><span class="o">.</span><span class="n">KDEyML</span>
|
||
<span class="n">KDEyHD</span> <span class="o">=</span> <span class="n">_kdey</span><span class="o">.</span><span class="n">KDEyHD</span>
|
||
<span class="n">KDEyCS</span> <span class="o">=</span> <span class="n">_kdey</span><span class="o">.</span><span class="n">KDEyCS</span>
|
||
|
||
|
||
<span class="c1"># ---------------------------------------------------------------</span>
|
||
<span class="c1"># aliases</span>
|
||
<span class="c1"># ---------------------------------------------------------------</span>
|
||
|
||
<span class="n">ClassifyAndCount</span> <span class="o">=</span> <span class="n">CC</span>
|
||
<span class="n">AdjustedClassifyAndCount</span> <span class="o">=</span> <span class="n">ACC</span>
|
||
<span class="n">ProbabilisticClassifyAndCount</span> <span class="o">=</span> <span class="n">PCC</span>
|
||
<span class="n">ProbabilisticAdjustedClassifyAndCount</span> <span class="o">=</span> <span class="n">PACC</span>
|
||
<span class="n">ExpectationMaximizationQuantifier</span> <span class="o">=</span> <span class="n">EMQ</span>
|
||
<span class="n">SLD</span> <span class="o">=</span> <span class="n">EMQ</span>
|
||
<span class="n">DistributionMatchingY</span> <span class="o">=</span> <span class="n">DMy</span>
|
||
<span class="n">EnergyDistanceY</span> <span class="o">=</span> <span class="n">EDy</span>
|
||
<span class="n">HellingerDistanceY</span> <span class="o">=</span> <span class="n">HDy</span>
|
||
<span class="n">HistoricalHDy</span> <span class="o">=</span> <span class="n">DMy</span><span class="o">.</span><span class="n">HDy</span>
|
||
<span class="n">MedianSweep</span> <span class="o">=</span> <span class="n">MS</span>
|
||
<span class="n">MedianSweep2</span> <span class="o">=</span> <span class="n">MS2</span>
|
||
</pre></div>
|
||
|
||
</article>
|
||
|
||
|
||
|
||
|
||
|
||
<footer class="prev-next-footer d-print-none">
|
||
|
||
<div class="prev-next-area">
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
<footer class="bd-footer-content">
|
||
|
||
</footer>
|
||
|
||
</main>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Scripts loaded after <body> so the DOM is not blocked -->
|
||
<script defer src="../../../_static/scripts/bootstrap.js?digest=90905a2f556bf617f1a9"></script>
|
||
<script defer src="../../../_static/scripts/pydata-sphinx-theme.js?digest=90905a2f556bf617f1a9"></script>
|
||
|
||
<footer class="bd-footer">
|
||
<div class="bd-footer__inner bd-page-width">
|
||
|
||
<div class="footer-items__start">
|
||
|
||
<div class="footer-item">
|
||
|
||
<p class="copyright">
|
||
|
||
© Copyright 2024, Alejandro Moreo.
|
||
<br/>
|
||
|
||
</p>
|
||
</div>
|
||
|
||
<div class="footer-item">
|
||
|
||
<p class="sphinx-version">
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 9.0.4.
|
||
<br/>
|
||
</p>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="footer-items__end">
|
||
|
||
<div class="footer-item">
|
||
<p class="theme-version">
|
||
<!-- # L10n: Setting the PST URL as an argument as this does not need to be localized -->
|
||
Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.20.0.
|
||
</p></div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</footer>
|
||
</body>
|
||
</html> |