diff --git a/bibliography/thesis.bib b/bibliography/thesis.bib index 47bea7f..c5cd624 100644 --- a/bibliography/thesis.bib +++ b/bibliography/thesis.bib @@ -9,6 +9,15 @@ publisher={Wiley} } +@book{silverman1986density, + title={Density Estimation for Statistics and Data Analysis}, + author={Silverman, B. W.}, + year={1986}, + publisher={Chapman and Hall}, + address={London}, + series={Chapman \& Hall/CRC Monographs on Statistics and Applied Probability} +} + @article{botev2010kde, title={Kernel density estimation via diffusion}, author={Botev, Z. I. and Grotowski, J. F. and Kroese, D. P.}, @@ -49,6 +58,25 @@ publisher={Springer} } +@article{xie2024wsauc, + title={Weakly Supervised {AUC} Optimization: A Unified Partial {AUC} Approach}, + author={Xie, Zheng and Liu, Yu and He, Hao-Yuan and Li, Ming and Zhou, Zhi-Hua}, + journal={IEEE Transactions on Pattern Analysis and Machine Intelligence}, + year={2024}, + doi={10.1109/TPAMI.2024.3357814}, + eprint={2305.14258}, + archivePrefix={arXiv} +} + +@inproceedings{wu2025preserving, + title={Preserving {AUC} Fairness in Learning with Noisy Protected Groups}, + author={Wu, Mingyang and Lin, Li and Zhang, Wenbin and Wang, Xin and Yang, Zhenhuan and Hu, Shu}, + booktitle={Proceedings of the 42nd International Conference on Machine Learning}, + year={2025}, + eprint={2505.18532}, + archivePrefix={arXiv} +} + @article{altman1989solving, title={Solving the jigsaw puzzle problem in linear time}, author={Altman, Tom}, diff --git a/content/appendixs/appendix_gauss_grad.tex b/content/appendixs/appendix_gauss_grad.tex new file mode 100644 index 0000000..0f6929d --- /dev/null +++ b/content/appendixs/appendix_gauss_grad.tex @@ -0,0 +1,68 @@ +We derive the gradient of \eqref{eq:roll-tpr-at-fpr-gaussian} with respect to +$f_\theta(\mathbf{x}_i)$, instantiating the general structure~\eqref{eq:roll-gradient} +for the Gaussian case. Throughout, $\tau = \hat{F}_0^{-1}(1-\alpha) = +\mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(1-2\alpha)$. + +\paragraph{Case $y_i = 1$.} + +The score $f_\theta(\mathbf{x}_i)$ enters through $\mu_1$ and $\sigma_1$. +Differentiating $\hat{F}_1(\tau) = \frac{1}{2}\bigl[1+\operatorname{erf}\!\bigl(\frac{\tau-\mu_1}{\sigma_1\sqrt{2}}\bigr)\bigr]$: + +\[ + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial \mu_1} = + -\frac{1}{\sigma_1\sqrt{2\pi}}\exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) +\] + +\[ + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial \sigma_1} = + \frac{\mu_1 - \tau}{\sigma_1^2\sqrt{2\pi}}\exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) +\] + +Combined with $\frac{\partial \mu_1}{\partial f_\theta(\mathbf{x}_i)} = \frac{1}{|\mathcal{B}_1|}$ +and $\frac{\partial \sigma_1}{\partial f_\theta(\mathbf{x}_i)} = \frac{f_\theta(\mathbf{x}_i)-\mu_1}{|\mathcal{B}_1|\sigma_1}$, +the chain rule gives: + +\begin{equation} + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial f_{\theta}(\mathbf{x}_i)} + = -\frac{1}{|\mathcal{B}_1|\,\sigma_1\sqrt{2\pi}} + \exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) + \left(1 + \frac{(\tau - \mu_1)(f_\theta(\mathbf{x}_i) - \mu_1)}{\sigma_1^2}\right) + \label{eq:gauss-grad-y1} +\end{equation} + +\paragraph{Case $y_i = 0$.} + +The score $f_\theta(\mathbf{x}_i)$ affects the loss only through $\tau$. By the chain rule: + +\[ + \frac{\partial \hat{F}_1(\tau)}{\partial f_\theta(\mathbf{x}_i)} + = \underbrace{\frac{\partial \hat{F}_1(\tau)}{\partial \tau}}_{\text{PDF of class 1 at }\tau} + \cdot \frac{\partial \tau}{\partial f_\theta(\mathbf{x}_i)} +\] + +The first factor is the Gaussian PDF at $\tau$: +\[ + \frac{\partial \hat{F}_1(\tau)}{\partial \tau} + = \frac{1}{\sigma_1\sqrt{2\pi}}\exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) +\] + +For the second factor, since $\tau = \mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(1-2\alpha)$: +$\frac{\partial\tau}{\partial\mu_0}=1$ and +$\frac{\partial\tau}{\partial\sigma_0}=\frac{\tau-\mu_0}{\sigma_0}$. +Combined with $\frac{\partial\mu_0}{\partial f_\theta(\mathbf{x}_i)}=\frac{1}{|\mathcal{B}_0|}$ +and $\frac{\partial\sigma_0}{\partial f_\theta(\mathbf{x}_i)}=\frac{f_\theta(\mathbf{x}_i)-\mu_0}{|\mathcal{B}_0|\sigma_0}$: +\[ + \frac{\partial\tau}{\partial f_\theta(\mathbf{x}_i)} + = \frac{1}{|\mathcal{B}_0|}\!\left(1+\frac{(\tau-\mu_0)(f_\theta(\mathbf{x}_i)-\mu_0)}{\sigma_0^2}\right) +\] + +Therefore: +\begin{equation} + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial f_\theta(\mathbf{x}_i)} + = \frac{1}{|\mathcal{B}_0|\,\sigma_1\sqrt{2\pi}} + \exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) + \left(1 + \frac{(\tau - \mu_0)(f_\theta(\mathbf{x}_i) - \mu_0)}{\sigma_0^2}\right) + \label{eq:gauss-grad-y0} +\end{equation} + +Substituting \eqref{eq:gauss-grad-y1} and \eqref{eq:gauss-grad-y0} into \eqref{eq:roll-gradient} yields \eqref{eq:gauss-grad-combined}. diff --git a/content/appendixs/appendix_kde_bisection.tex b/content/appendixs/appendix_kde_bisection.tex new file mode 100644 index 0000000..7c930f2 --- /dev/null +++ b/content/appendixs/appendix_kde_bisection.tex @@ -0,0 +1,30 @@ +We describe the bisection procedure used to compute $\tau = \hat{F}_0^{-1}(1-\alpha;\mathcal{B}_0)$ +in the KDE-ROLL forward pass (\Cref{sec:roll-kde-forward}). + +\paragraph{Bracket initialisation.} +Because $\sigma(u;\,v) \to 0$ exponentially as $u \to -\infty$ and $\sigma(u;\,v) \to 1$ +as $u \to +\infty$, with tails decaying within roughly $10/v_0$ of the data range, the +interval +\[ + \mathrm{lo} = \min(\mathbf{s}^{(0)}) - \tfrac{10}{v_0}, + \qquad + \mathrm{hi} = \max(\mathbf{s}^{(0)}) + \tfrac{10}{v_0} +\] +is guaranteed to satisfy $\hat{F}_0(\mathrm{lo}) < 1-\alpha < \hat{F}_0(\mathrm{hi})$. + +\paragraph{Bisection iterations.} +At each step we evaluate the midpoint, +\[ + \tau_{\mathrm{mid}} = \tfrac{1}{2}(\mathrm{lo} + \mathrm{hi}), +\] +and update the bracket: +\[ + \begin{cases} + \mathrm{lo} \leftarrow \tau_{\mathrm{mid}} & \text{if } \hat{F}_0(\tau_{\mathrm{mid}};\,\mathcal{B}_0) < 1-\alpha, \\ + \mathrm{hi} \leftarrow \tau_{\mathrm{mid}} & \text{otherwise.} + \end{cases} +\] +Iteration continues until $\lvert\hat{F}_0(\tau_{\mathrm{mid}};\,\mathcal{B}_0)-(1-\alpha)\rvert < \varepsilon$ +(with $\varepsilon = 10^{-4}$), or until a maximum iteration count is reached. +The method converges unconditionally and requires no derivative evaluation, in contrast +to the Newton--Raphson alternative documented in Appendix~\ref{appendix:kde-nr}. diff --git a/content/appendixs/appendix_kde_grad.tex b/content/appendixs/appendix_kde_grad.tex new file mode 100644 index 0000000..b20ea72 --- /dev/null +++ b/content/appendixs/appendix_kde_grad.tex @@ -0,0 +1,142 @@ +We derive the KDE gradient, instantiating the general form~\eqref{eq:roll-gradient}. +Throughout, $\tau = \hat{F}_0^{-1}(1-\alpha;\mathcal{B}_0)$ and bandwidths $v_0, v_1$ +are as defined in \Cref{sec:kde-bandwidth}. + +\paragraph{Case $y_i = 1$: expanding the KDE sum.} + +When $\mathbf{x}_i \in \mathcal{B}_1$, the score $f_\theta(\mathbf{x}_i)$ appears directly +in $\hat{F}_1$ and has no effect on $\tau$. Expanding the KDE CDF: +% +\[ + \dfrac{\partial \hat{F}_1\!\left(\hat{F}_0^{-1}(1-\alpha)\right)}{\partial f_{\theta}(\mathbf{x}_i)} + = \frac{\partial}{\partial f_{\theta}(\mathbf{x}_i)} + \frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1} + \sigma_1\!\left(\tau - f_{\theta}(\mathbf{x}_j)\right) +\] +% +Separating the $j = i$ term (the only one depending on $f_\theta(\mathbf{x}_i)$): +% +\[ + = \frac{\partial}{\partial f_{\theta}(\mathbf{x}_i)}\!\left( + \sum_{\substack{\mathbf{x}_j \in \mathcal{B}_1 \\ j \neq i}} + \frac{\sigma_1\!\left(\tau - f_{\theta}(\mathbf{x}_j)\right)}{|\mathcal{B}_1|} + \;+\; + \frac{\sigma_1\!\left(\tau - f_{\theta}(\mathbf{x}_i)\right)}{|\mathcal{B}_1|} + \right) +\] +% +The first sum is constant in $f_\theta(\mathbf{x}_i)$. Applying the chain rule to the +last term with $\partial(\tau - f_\theta(\mathbf{x}_i))/\partial f_\theta(\mathbf{x}_i) = -1$: +% +\begin{equation} + \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial f_{\theta}(\mathbf{x}_i)} + = -\frac{1}{|\mathcal{B}_1|}\sigma_1'(\tau - f_{\theta}(\mathbf{x}_i)) + \label{eq:kde-grad-y1} +\end{equation} + +\paragraph{Case $y_i = 0$: derivative of $\hat{F}_1$ with respect to $\tau$.} + +Differentiating the KDE CDF with respect to $\tau$: +% +\[ + \frac{\partial \hat{F}_1\!\left(\hat{F}_0^{-1}(1-\alpha)\right)}{\partial \hat{F}_0^{-1}(1-\alpha)} + = \frac{\partial}{\partial \tau} + \frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1} + \sigma_1\!\left(\tau - f_{\theta}(\mathbf{x}_j)\right) +\] +% +Since $\partial(\tau - f_\theta(\mathbf{x}_j))/\partial\tau = +1$ for every $j$, +the chain rule gives: +% +\begin{equation} + \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial \hat{F}_0^{-1}(1-\alpha)} + = +\frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1}\sigma_1'(\tau - f_{\theta}(\mathbf{x}_j)) + \label{eq:kde-dF1-dtau} +\end{equation} + +\paragraph{Case $y_i = 0$: derivative of $\tau$ with respect to $f_\theta(\mathbf{x}_i)$.} + +Since $\tau = \hat{F}_0^{-1}(1-\alpha;\mathcal{B}_0)$ is computed numerically, we apply the \emph{inverse function theorem}: if $h$ has inverse $g$, +then $g'(y) = 1/h'(g(y))$. + +We view $\hat{F}_0^{-1}(1-\alpha;\mathcal{B}_0)$ as a function of $f_\theta(\mathbf{x}_i)$ +and find its inverse. From the defining equation +$|\mathcal{B}_0|\cdot(1-\alpha) = \sum_{\mathbf{x}_j \in \mathcal{B}_0} +\sigma_0(\tau - f_\theta(\mathbf{x}_j))$, solving for $f_\theta(\mathbf{x}_i)$: +% +\[ + f_\theta(\mathbf{x}_i) + = \tau - \sigma_0^{-1}\!\!\left( + |\mathcal{B}_0|\cdot(1-\alpha) + - \sum_{\substack{\mathbf{x}_j \in \mathcal{B}_0 \\ j \neq i}} + \sigma_0\!\left(\tau - f_{\theta}(\mathbf{x}_j)\right) + \right) +\] +% +Differentiating this expression with respect to $\tau$ and applying the chain rule: +% +\[ + \frac{\partial f_\theta(\mathbf{x}_i)}{\partial \tau} + = 1 + \sigma_0^{-1}{}'\!\!\left(\cdots\right) + \cdot + \sum_{\substack{\mathbf{x}_j \in \mathcal{B}_0 \\ j \neq i}} + \sigma_0'\!\left(\tau - f_{\theta}(\mathbf{x}_j)\right) +\] +% +(the leading $+1$ comes from differentiating $\tau$; the second term from differentiating +through $\sigma_0^{-1}$). By the inverse function theorem: +% +\[ + \frac{\partial \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} + = \frac{1}{\displaystyle + 1 + \sigma_0^{-1}{}'\!\!\left( + |\mathcal{B}_0|\cdot(1-\alpha) + - \sum_{j \neq i}\sigma_0(\tau - f_\theta(\mathbf{x}_j)) + \right) + \cdot \sum_{j \neq i}\sigma_0'(\tau - f_\theta(\mathbf{x}_j))} +\] +% +Using $|\mathcal{B}_0|\cdot(1-\alpha) = \sum_j \sigma_0(\tau - f_\theta(\mathbf{x}_j))$, +the argument of $\sigma_0^{-1}{}'$ simplifies: +% +\[ + |\mathcal{B}_0|\cdot(1-\alpha) + - \sum_{j \neq i}\sigma_0(\tau - f_\theta(\mathbf{x}_j)) + = \sigma_0(\tau - f_\theta(\mathbf{x}_i)) +\] +% +Substituting and applying $\sigma_0^{-1}{}'(\sigma_0(u)) = 1/\sigma_0'(u)$, +then multiplying numerator and denominator by $\sigma_0'(\tau - f_\theta(\mathbf{x}_i))$: +% +\begin{equation} + \frac{\partial \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} = + \frac{\sigma_0'(\tau - f_{\theta}(\mathbf{x}_i))}{\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0}\sigma_0'(\tau - f_{\theta}(\mathbf{x}_j))} + \label{eq:kde-grad-tau} +\end{equation} + +\paragraph{Efficient computation via the sigmoid identity.} + +Direct evaluation of \eqref{eq:kde-grad-tau} requires computing $\sigma_0'$ for every +point — potentially unstable when a point is far from $\tau$. For the sigmoid kernel, +the identity + +\begin{equation} + \sigma(u;\,v)\,\bigl(1 - \sigma(u;\,v)\bigr) = \frac{\sigma'(u;\,v)}{v} + \label{eq:sigmoid-identity} +\end{equation} + +(proved by direct substitution: both sides equal $\exp(-v|u|)/(1+\exp(-v|u|))^2$) +allows $v_0$ to cancel between numerator and denominator, so the ratio is expressed +entirely in terms of sigmoid values already cached from the forward pass: + +\begin{equation} + \frac{\partial \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} + = + \frac{\sigma_0(\tau-f_\theta(\mathbf{x}_i))\,\bigl(1-\sigma_0(\tau-f_\theta(\mathbf{x}_i))\bigr)} + {\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0} + \sigma_0(\tau-f_\theta(\mathbf{x}_j))\,\bigl(1-\sigma_0(\tau-f_\theta(\mathbf{x}_j))\bigr)} + \label{eq:kde-grad-tau-efficient} +\end{equation} + +Substituting \eqref{eq:kde-grad-y1}, \eqref{eq:kde-dF1-dtau}, and \eqref{eq:kde-grad-tau} +into \eqref{eq:roll-gradient} yields \eqref{eq:kde-grad-combined}. diff --git a/content/appendixs/appendix_kde_nr.tex b/content/appendixs/appendix_kde_nr.tex new file mode 100644 index 0000000..7e03f70 --- /dev/null +++ b/content/appendixs/appendix_kde_nr.tex @@ -0,0 +1,28 @@ +An earlier version of the implementation used Newton--Raphson to invert the KDE CDF +instead of bisection (\Cref{sec:roll-kde-forward}). We document it here as a reference +alternative. + +\paragraph{Method.} +To find $\tau = \hat{F}_0^{-1}(1-\alpha;\mathcal{B}_0)$, choose an initial guess $\tau_0$ +and iterate: +\begin{equation} + \tau_{n+1} = \tau_n + - \frac{\hat{F}_0(\tau_n;\,\mathcal{B}_0) - (1-\alpha)} + {\dfrac{\partial\hat{F}_0(\tau_n;\,\mathcal{B}_0)}{\partial\tau}}, + \label{eq:kde-nr-step} +\end{equation} +where the denominator is the KDE density evaluated at $\tau_n$: +\[ + \frac{\partial\hat{F}_0(\tau_n;\,\mathcal{B}_0)}{\partial\tau} + = \frac{1}{|\mathcal{B}_0|}\sum_{\mathbf{x}_j\in\mathcal{B}_0} + \sigma_0'(\tau_n - f_\theta(\mathbf{x}_j)). +\] +Iteration continues until +$\lvert\hat{F}_0(\tau_n;\,\mathcal{B}_0)-(1-\alpha)\rvert < \varepsilon$. + +\paragraph{Limitations.} +Newton--Raphson requires evaluating $\sigma_0'$ at every step and can diverge if +$\tau_0$ is far from the root or if the KDE density is very small near the target +quantile (e.g.\ early in training when scores cluster tightly and $v_0$ is large). +These failure modes motivated the switch to bisection, which requires no derivative +evaluation in the forward pass and is guaranteed to converge given a valid bracket. diff --git a/content/appendixs/appendix_kde_sigmoid.tex b/content/appendixs/appendix_kde_sigmoid.tex new file mode 100644 index 0000000..e62b23e --- /dev/null +++ b/content/appendixs/appendix_kde_sigmoid.tex @@ -0,0 +1,70 @@ +We instantiate the KDE gradient~\eqref{eq:kde-grad-combined} for the logistic sigmoid +kernel used in our implementation. + +\paragraph{Kernel definition.} + +\begin{equation} + \sigma(x ; v) = \frac{1}{1 + \exp(-vx)}, + \qquad + \sigma'(x ; v) = \frac{v\,\exp(-v|x|)}{\bigl(1 + \exp(-v|x|)\bigr)^{2}} + \label{eq:sigmoid-kernel} +\end{equation} + +where $v > 0$ is the bandwidth parameter. The derivative uses $|x|$ rather than $x$: +since $\sigma'$ is even, both forms are mathematically identical, but $\exp(-v|x|) \to 0$ +as $|x| \to \infty$ whereas $\exp(-vx) \to \infty$ for $x \to -\infty$, so the $|x|$ +form avoids floating-point overflow when scores fall well below $\tau$. + +\paragraph{Forward pass.} + +Substituting \eqref{eq:sigmoid-kernel} into the KDE CDF: +% +\begin{equation} + \hat{F}_{k}(\tau ; \mathbf{s}^{(k)}) = + \frac{1}{|\mathcal{B}_k|} + \sum_{\mathbf{x}_j \in \mathcal{B}_k} + \frac{1}{1 + \exp\!\bigl(-v_k\bigl(\tau - f_\theta(\mathbf{x}_j)\bigr)\bigr)} + \label{eq:kde-sigmoid-cdf} +\end{equation} +% +The derivative of $\hat{F}_k$ with respect to $\tau$ — used in Newton--Raphson inversion +and in the gradient — is: +% +\begin{equation} + \frac{\partial \hat{F}_{k}(\tau)}{\partial \tau} + = + \frac{1}{|\mathcal{B}_k|} + \sum_{\mathbf{x}_j \in \mathcal{B}_k} + \frac{v_k\,\exp\!\bigl(-v_k\bigl|\tau - f_\theta(\mathbf{x}_j)\bigr|\bigr)} + {\Bigl(1 + \exp\!\bigl(-v_k\bigl|\tau - f_\theta(\mathbf{x}_j)\bigr|\bigr)\Bigr)^{2}} + \label{eq:kde-sigmoid-pdf} +\end{equation} + +\paragraph{Gradient.} + +Define the shorthand $\varphi_k(u) = \sigma'(u ; v_k)$: +\begin{equation} + \varphi_k(u) \;=\; + \frac{v_k\,\exp(-v_k|u|)}{\bigl(1+\exp(-v_k|u|)\bigr)^{2}} + \label{eq:sigmoid-phi} +\end{equation} + +Substituting \eqref{eq:sigmoid-kernel} into \eqref{eq:kde-grad-combined}: + +\begin{equation} + \frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}}{\partial f_\theta(\mathbf{x}_i)} = + \begin{cases} + -\dfrac{\varphi_1\!\left(\tau - f_\theta(\mathbf{x}_i)\right)}{|\mathcal{B}_1|} + & \text{if } y_i = 1\\[14pt] + +\,\dfrac{\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_1} + \varphi_1\!\left(\tau - f_\theta(\mathbf{x}_j)\right)}{|\mathcal{B}_1|} + \;\cdot\; + \dfrac{\varphi_0\!\left(\tau-f_\theta(\mathbf{x}_i)\right)} + {\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0} + \varphi_0\!\left(\tau-f_\theta(\mathbf{x}_j)\right)} + & \text{if } y_i = 0 + \end{cases} + \label{eq:kde-sigmoid-grad} +\end{equation} + +where $\tau = \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)$. diff --git a/content/method/figures/density_fit_comparison.png b/content/method/figures/density_fit_comparison.png new file mode 100644 index 0000000..94bc736 Binary files /dev/null and b/content/method/figures/density_fit_comparison.png differ diff --git a/content/method/figures/density_fit_comparison.py b/content/method/figures/density_fit_comparison.py new file mode 100644 index 0000000..7a076be --- /dev/null +++ b/content/method/figures/density_fit_comparison.py @@ -0,0 +1,181 @@ +""" +Comparison of density estimators on real model output scores. + +For each class (negative / positive) plots four curves against the empirical CDF: + - ECDF — ground truth step function + - KDE (ISJ) — Gaussian-kernel KDE with Improved Sheather-Jones bandwidth + - Gaussian fit — MLE normal distribution + - Beta fit — sigmoid-transformed scores fitted with Beta MLE, CDF + mapped back to the original logit axis + +Data: test split of a ROLL model trained on the glass0 dataset. + +Run from the impl directory (KDEpy lives in that flake): + cd impl && nix develop --command python3 ../thesis/content/method/figures/density_fit_comparison.py +""" + +import sys, pickle +from pathlib import Path +import numpy as np +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt +from scipy.stats import norm, beta as sp_beta +from scipy.special import expit +from KDEpy import FFTKDE +from KDEpy.bw_selection import silvermans_rule, improved_sheather_jones + +# Resolve paths relative to this script's location so the script runs from anywhere. +_HERE = Path(__file__).resolve().parent # .../thesis/content/method/figures +_THESIS = _HERE.parents[2] # .../thesis +_IMPL = _THESIS.parent / "impl" # .../impl + +sys.path.insert(0, str(_IMPL)) # pickle needs 'import src.experiment' → impl/src/experiment.py + +# ── Config ────────────────────────────────────────────────────────────────── +RESULT_PKL = _IMPL / "results/glass0/2026-07-08-22-25/roll/0/test-res.pkl" +OUT_DIR = _HERE +SPLIT = "test" + +C_NEG = "#4477AA" +C_POS = "#CC6633" + +plt.rcParams.update({ + "text.usetex": False, + "mathtext.fontset": "cm", + "pdf.fonttype": 42, +}) + +# ── Load data ──────────────────────────────────────────────────────────────── +with open(RESULT_PKL, "rb") as f: + ep = pickle.load(f) + +res = ep.split_results[SPLIT] +yh = res.yh.astype(np.float64) # raw logit scores +y = res.y + +scores_neg = yh[y == 0] +scores_pos = yh[y == 1] + +print(f"Loaded {SPLIT} split: {len(scores_neg)} negatives, {len(scores_pos)} positives") +print(f"Score range: [{yh.min():.3f}, {yh.max():.3f}]") + + +# ── Helpers ────────────────────────────────────────────────────────────────── +def ecdf(scores): + """Return (x, p) for a step-function ECDF.""" + s = np.sort(scores) + p = np.arange(1, len(s) + 1) / len(s) + return s, p + + +def _kde_pdf(scores, x_grid, h): + pdf = FFTKDE(kernel="gaussian", bw=h).fit(scores).evaluate(x_grid) + dx = x_grid[1] - x_grid[0] + cdf = np.cumsum(pdf) * dx + cdf /= cdf[-1] + return cdf + +def kde_isj_cdf(scores, x_grid): + """ISJ bandwidth; Silverman fallback on failure.""" + data = scores[:, np.newaxis].astype(np.float64) + try: + h = float(improved_sheather_jones(data)) + except Exception: + h = float(silvermans_rule(data)) + return _kde_pdf(scores, x_grid, h) + +def kde_silverman_cdf(scores, x_grid): + h = float(silvermans_rule(scores[:, np.newaxis].astype(np.float64))) + return _kde_pdf(scores, x_grid, h) + + +def gauss_cdf(scores, x_grid): + loc, scale = norm.fit(scores) + return norm.cdf(x_grid, loc, scale) + + +def beta_cdf(scores, x_grid): + """Fit Beta in sigmoid space; evaluate CDF back on the logit x_grid.""" + s01 = expit(scores).clip(1e-6, 1 - 1e-6) + a, b, _, _ = sp_beta.fit(s01, floc=0, fscale=1) + return sp_beta.cdf(expit(x_grid), a, b) + + +# ── Shared x-grid (covers both classes with a small margin) ────────────────── +margin = 0.5 +x_lo = yh.min() - margin +x_hi = yh.max() + margin +x_grid = np.linspace(x_lo, x_hi, 2048) + + +# ── Compute all curves ─────────────────────────────────────────────────────── +neg_ecdf_x, neg_ecdf_p = ecdf(scores_neg) +neg_cdf_kde = kde_isj_cdf(scores_neg, x_grid) +neg_cdf_silverman = kde_silverman_cdf(scores_neg, x_grid) +neg_cdf_gauss = gauss_cdf(scores_neg, x_grid) +neg_cdf_beta = beta_cdf(scores_neg, x_grid) + +pos_ecdf_x, pos_ecdf_p = ecdf(scores_pos) +pos_cdf_kde = kde_isj_cdf(scores_pos, x_grid) +pos_cdf_silverman = kde_silverman_cdf(scores_pos, x_grid) +pos_cdf_gauss = gauss_cdf(scores_pos, x_grid) +pos_cdf_beta = beta_cdf(scores_pos, x_grid) + + +# ── Plot ───────────────────────────────────────────────────────────────────── +fig, (ax0, ax1) = plt.subplots( + 2, 1, figsize=(5.5, 4.8), sharex=True, + gridspec_kw={"height_ratios": [1, 1]}, +) +fig.subplots_adjust(hspace=0.08) + + +def _plot_class(ax, color, ecdf_x, ecdf_p, + cdf_isj, cdf_silverman, cdf_gauss, cdf_beta, label_prefix): + ax.step(ecdf_x, ecdf_p, + color=color, lw=1.0, alpha=0.55, where="post", + label="ECDF") + ax.plot(x_grid, cdf_isj, + color=color, lw=1.8, linestyle="-", + label="KDE (ISJ)") + ax.plot(x_grid, cdf_silverman, + color=color, lw=1.4, linestyle="-.", + label="KDE (Silverman)") + ax.plot(x_grid, cdf_gauss, + color=color, lw=1.4, linestyle="--", + label="Gaussian") + ax.plot(x_grid, cdf_beta, + color=color, lw=1.6, linestyle=":", + label="Beta") + ax.set_ylabel("CDF", fontsize=9) + ax.set_yticks([0.0, 0.25, 0.50, 0.75, 1.0]) + ax.set_yticklabels(["0", ".25", ".5", ".75", "1"], fontsize=7.5) + ax.tick_params(labelsize=8) + ax.spines[["top", "right"]].set_visible(False) + ax.text(0.97, 0.05, label_prefix, + transform=ax.transAxes, fontsize=8, + ha="right", va="bottom", color=color) + + +_plot_class(ax0, C_NEG, + neg_ecdf_x, neg_ecdf_p, + neg_cdf_kde, neg_cdf_silverman, neg_cdf_gauss, neg_cdf_beta, + r"Negative class ($y=0$)") + +_plot_class(ax1, C_POS, + pos_ecdf_x, pos_ecdf_p, + pos_cdf_kde, pos_cdf_silverman, pos_cdf_gauss, pos_cdf_beta, + r"Positive class ($y=1$)") + +ax0.legend(fontsize=7.5, loc="upper left", framealpha=0.88) +ax1.set_xlabel(r"Score $f_\theta(\mathbf{x})$", fontsize=9) +ax0.set_xlim(x_lo, x_hi) + +for path_suffix in ("pdf", "png"): + kw = {"bbox_inches": "tight"} + if path_suffix == "png": + kw["dpi"] = 180 + fig.savefig(OUT_DIR / f"density_fit_comparison.{path_suffix}", **kw) + +print(f"Saved to {OUT_DIR}/density_fit_comparison.{{pdf,png}}") diff --git a/content/method/figures/threshold_weighting_gaussian.png b/content/method/figures/threshold_weighting_gaussian.png new file mode 100644 index 0000000..8519e5f Binary files /dev/null and b/content/method/figures/threshold_weighting_gaussian.png differ diff --git a/content/method/figures/threshold_weighting_gaussian.py b/content/method/figures/threshold_weighting_gaussian.py new file mode 100644 index 0000000..026f2dc --- /dev/null +++ b/content/method/figures/threshold_weighting_gaussian.py @@ -0,0 +1,123 @@ +""" +Illustrates the gradient locality property of Gaussian-ROLL. + +Upper panel: score distributions for both classes with fitted Gaussian PDFs + and operating threshold. +Lower panel: gradient magnitude per sample using the Gaussian gradient formula + (eq:gauss-grad-combined). + +Run from the thesis root: + nix develop --command python3 content/method/figures/threshold_weighting_gaussian.py +""" + +import numpy as np +from scipy import stats +import matplotlib +matplotlib.use("Agg") +import matplotlib.pyplot as plt + +plt.rcParams.update({ + "text.usetex": False, + "mathtext.fontset": "cm", + "pdf.fonttype": 42 +}) + +OUT_DIR = "content/method/figures" + +np.random.seed(7) + +# --- Data ------------------------------------------------------------------ +n = 120 +alpha = 0.25 # target FPR + +neg_scores = np.sort(np.random.normal(-0.6, 0.75, n)) +pos_scores = np.sort(np.random.normal(1.1, 0.80, n)) + +n0 = len(neg_scores) +n1 = len(pos_scores) + +# --- Gaussian MLE parameters ----------------------------------------------- +mu0, sigma0 = neg_scores.mean(), neg_scores.std() +mu1, sigma1 = pos_scores.mean(), pos_scores.std() + +# Threshold: (1-alpha)-quantile of negative class so that FPR = alpha +# (FPR = P(score > tau | y=0) = 1 - F_0(tau), so F_0(tau) = 1-alpha) +tau = stats.norm.ppf(1 - alpha, loc=mu0, scale=sigma0) + +# Shared scalar: pdf of positive class evaluated at the threshold +common = (1.0 / (sigma1 * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((tau - mu1) / sigma1) ** 2) + +# --- Gaussian ROLL gradients (eq:gauss-grad-combined) --------------------- +# y=1: -(1/n1) * common * (1 + (tau-mu1)*(s-mu1)/sigma1^2) +grad_pos_signed = -(1.0 / n1) * common * ( + 1 + (tau - mu1) * (pos_scores - mu1) / sigma1 ** 2 +) +grad_pos_abs = np.abs(grad_pos_signed) + +# y=0: +(1/n0) * common * (1 + (tau-mu0)*(s-mu0)/sigma0^2) +grad_neg_signed = (1.0 / n0) * common * ( + 1 + (tau - mu0) * (neg_scores - mu0) / sigma0 ** 2 +) +grad_neg_abs = np.abs(grad_neg_signed) + +# Gradient balance check (should be ~0) +print(f"Gradient balance: pos sum = {grad_pos_signed.sum():.6f}, " + f"neg sum = {grad_neg_signed.sum():.6f}, " + f"total = {(grad_pos_signed.sum() + grad_neg_signed.sum()):.2e}") + +# --- Smooth reference curves (continuous gradient functions) --------------- +x_ref = np.linspace(neg_scores.min() - 0.3, pos_scores.max() + 0.3, 400) +smooth_pos_abs = np.abs(-(1.0 / n1) * common * ( + 1 + (tau - mu1) * (x_ref - mu1) / sigma1 ** 2 +)) +smooth_neg_abs = np.abs((1.0 / n0) * common * ( + 1 + (tau - mu0) * (x_ref - mu0) / sigma0 ** 2 +)) + +# --- Plot ----------------------------------------------------------------- +C_NEG = "#4477AA" +C_POS = "#CC6633" +C_TAU = "#333333" + +fig, (ax1, ax2) = plt.subplots( + 2, 1, figsize=(5.5, 4.2), sharex=True, + gridspec_kw={"height_ratios": [1.3, 1.0]} +) +fig.subplots_adjust(hspace=0.06) + +# — Top: score distributions with fitted Gaussian PDFs — +ax1.hist(neg_scores, bins=20, density=True, alpha=0.35, color=C_NEG, + label=r"Negative class ($y=0$)") +ax1.hist(pos_scores, bins=20, density=True, alpha=0.35, color=C_POS, + label=r"Positive class ($y=1$)") +ax1.plot(x_ref, stats.norm.pdf(x_ref, mu0, sigma0), + color=C_NEG, linewidth=1.8, label=r"Fitted $\mathcal{N}(\mu_0,\sigma_0^2)$") +ax1.plot(x_ref, stats.norm.pdf(x_ref, mu1, sigma1), + color=C_POS, linewidth=1.8, label=r"Fitted $\mathcal{N}(\mu_1,\sigma_1^2)$") +ax1.axvline(tau, color=C_TAU, linestyle="--", linewidth=1.4, + label=rf"Threshold $\tau$ (FPR $=\alpha={alpha}$)") +ax1.set_ylabel("Density", fontsize=9) +ax1.set_yticks([]) +ax1.legend(fontsize=7, loc="upper right", framealpha=0.85) + +# — Bottom: gradient magnitudes — +ax2.scatter(neg_scores, grad_neg_abs, color=C_NEG, s=12, zorder=3, + alpha=0.75, label=r"$|\partial\mathcal{L}/\partial f_\theta(\mathbf{x})|$, $y=0$") +ax2.scatter(pos_scores, grad_pos_abs, color=C_POS, s=12, zorder=3, + alpha=0.75, label=r"$|\partial\mathcal{L}/\partial f_\theta(\mathbf{x})|$, $y=1$") +ax2.plot(x_ref, smooth_neg_abs, color=C_NEG, linewidth=1.2, alpha=0.55) +ax2.plot(x_ref, smooth_pos_abs, color=C_POS, linewidth=1.2, alpha=0.55) +ax2.axvline(tau, color=C_TAU, linestyle="--", linewidth=1.4) +ax2.set_ylabel("Gradient magnitude", fontsize=9) +ax2.set_xlabel(r"Score $f_\theta(\mathbf{x})$", fontsize=9) +ax2.set_yticks([]) +ax2.legend(fontsize=7.5, loc="upper right", framealpha=0.85) + +for ax in (ax1, ax2): + ax.tick_params(labelsize=8) + ax.spines[["top", "right"]].set_visible(False) + +out_base = f"{OUT_DIR}/threshold_weighting_gaussian" +fig.savefig(f"{out_base}.pdf", bbox_inches="tight") +fig.savefig(f"{out_base}.png", bbox_inches="tight", dpi=180) +print(f"Saved to {out_base}.{{pdf,png}}") diff --git a/content/method/method.tex b/content/method/method.tex index 6a18150..e1128d2 100644 --- a/content/method/method.tex +++ b/content/method/method.tex @@ -19,8 +19,8 @@ The positive and negative subsets of $\mathcal{D}$ are: Applying a threshold $\tau$ produces predictions $\hat{y} = \mathbf{1}[f_\theta(\mathbf{x}) > \tau]$. The \emph{true positive rate} (TPR) and \emph{false positive rate} (FPR) at $\tau$ are: \begin{align} - \operatorname{TPR}(\tau) &= P\!\bigl(f_\theta(\mathbf{x}) > \tau \mid y = 1\bigr), \\ - \operatorname{FPR}(\tau) &= P\!\bigl(f_\theta(\mathbf{x}) > \tau \mid y = 0\bigr). + \operatorname{TPR}(\alpha) &= P\!\bigl(f_\theta(\mathbf{x}) > \tau \mid y = 1\bigr), \\ + \operatorname{FPR}(\alpha) &= P\!\bigl(f_\theta(\mathbf{x}) > \tau \mid y = 0\bigr). \end{align} In our scenario, we either wish to learn $f_{\theta}$ in order to maximize $\operatorname{TPR}$ subject to a fixed $\operatorname{FPR}$, or vice versa. Our fixed $\operatorname{TPR}$ or $\operatorname{FPR}$ @@ -112,7 +112,8 @@ This necessitates a different approach, to make these calculations differentiabl The way to overcome this problem in differentiability is not to calculate the TPR and FPR directly, but to estimate them by fitting probability distributions to the score output of the model at -every step. Contiguous probability distributions are contiguous w.r.t their inputs. Additionally, we can calculate the TPR, FPR given the probability distributions CDF and ICDF functions. If we can gaurantee these functions to be differentiable, which proved to be the main challenge of this work, we can gaurantee this process to be differentiable. +every step. Contiguous probability distributions are contiguous w.r.t their defining parameters, and a derivation of the parameters w.r.t the distributions themselves can be made. +Additionally, we can calculate the TPR, FPR given the probability distributions CDF and ICDF functions. If we can gaurantee these functions to be differentiable, which proved to be the main challenge of this work, we can gaurantee the entire process to be differentiable. Once we do so, a derivative of the scores themselves w.r.t. the loss can be acheived. \subsection{General ROLL Formulation and Derivation} @@ -157,11 +158,11 @@ Let $\hat{F}_1$ and $\hat{F}_0$ denote the CDFs of $P_{\hat{\phi}_1}$ and $P_{\h respectively. Specific choices of $\mathcal{F}$ (Gaussian, Beta, KDE) are discussed in \Cref{sec:roll-instantiations}. -Using this notation, at a threshold $\alpha$: +Using this notation, at a threshold $\tau$: \begin{align} - \operatorname{TPR}(\alpha) &= 1 - \hat{F}_1(\alpha), \label{eq:tpr-cdf} \\ - \operatorname{FPR}(\alpha) &= \hat{F}_0(\alpha). \label{eq:fpr-cdf} -\end{align} + \operatorname{TPR}(\tau) &= 1 - \hat{F}_1(\tau), \label{eq:tpr-cdf} \\ + \operatorname{FPR}(\tau) &= 1 - \hat{F}_0(\tau). \label{eq:fpr-cdf} +\end{align}t Let $\hat{F}_1^{-1}$ and $\hat{F}_0^{-1}$ denote the quantile functions of $P_{\hat{\phi}_1}$ and $P_{\hat{\phi}_0}$, respectively. The threshold achieving a target TPR of $\alpha$ follows directly @@ -172,34 +173,35 @@ from \eqref{eq:tpr-cdf}: \] and similarly for a target FPR of $\alpha$, from \eqref{eq:fpr-cdf}: \[ - \operatorname{FPR}(\tau) = \alpha \;\Longrightarrow\; \hat{F}_0(\tau) = \alpha - \;\Longrightarrow\; \tau = \hat{F}_0^{-1}(\alpha) + \operatorname{FPR}(\tau) = \alpha \;\Longrightarrow\; 1 - \hat{F}_0(\tau) = \alpha + \;\Longrightarrow\; \tau = \hat{F}_0^{-1}(1 - \alpha) \] This yields two versions of our objective. Substituting the ICDF threshold into the rate -expressions, our estimated TPR at a fixed FPR of $\alpha$ is $1 - \hat{F}_1(\hat{F}_0^{-1}(\alpha))$. +expressions, our estimated TPR at a fixed FPR of $\alpha$ is $1 - \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))$. Therefore, to maximise TPR we minimise: \begin{equation} - \mathcal{L}_{\text{ROLL-TPR@FPR}}(f_{\theta}(\mathcal{B}) ; \alpha) = \hat{F}_1(\hat{F}_0^{-1}(\alpha)) + \mathcal{L}_{\text{ROLL-TPR@FPR}}(f_{\theta}(\mathcal{B}) ; \alpha) = \hat{F}_1(\hat{F}_0^{-1}(1-\alpha)) \label{eq:roll-tpr-at-fpr} \end{equation} -Our estimated FPR at a fixed TPR of $\alpha$ is $\hat{F}_0(\hat{F}_1^{-1}(1 - \alpha))$. +Our estimated FPR at a fixed TPR of $\alpha$ is $1 - \hat{F}_0(\hat{F}_1^{-1}(1 - \alpha))$. Therefore, to minimise FPR: \begin{equation} - \mathcal{L}_{\text{ROLL-FPR@TPR}}(f_{\theta}(\mathbf{X}) ; \alpha) = \hat{F}_0(\hat{F}_1^{-1}(1 - \alpha)) + \mathcal{L}_{\text{ROLL-FPR@TPR}}(f_{\theta}(\mathbf{X}) ; \alpha) = 1 - \hat{F}_0(\hat{F}_1^{-1}(1 - \alpha)) \label{eq:roll-fpr-at-tpr} \end{equation} Observe that \eqref{eq:roll-tpr-at-fpr} and \eqref{eq:roll-fpr-at-tpr} share the same -functional structure: each evaluates one empirical CDF at the quantile of the other. This -symmetry means \eqref{eq:roll-fpr-at-tpr} can be reduced to \eqref{eq:roll-tpr-at-fpr} by -negating the model scores and exchanging the class labels. Concretely, replacing +inner structure: each evaluates one empirical CDF at the $(1-\alpha)$-quantile of the other. +The two objectives are interchangeable at the implementation level: replacing $f_\theta(\mathbf{x})$ with $-f_\theta(\mathbf{x})$ and $y$ with $1 - y$ swaps the roles -of the two populations, turning a TPR@FPR objective into a FPR@TPR one. Because the -two objectives are therefore interchangeable at the implementation level, all derivations +of the two populations, and passing target rate $1-\alpha$ to the resulting +TPR@FPR objective recovers the FPR@TPR objective at rate $\alpha$. Because +the two objectives are therefore interchangeable at the implementation level, all derivations and implementation details below are given for \eqref{eq:roll-tpr-at-fpr} only; -\eqref{eq:roll-fpr-at-tpr} follows by the same transformation applied to the inputs. +\eqref{eq:roll-fpr-at-tpr} follows by the same transformation applied to the inputs, with +the target rate complemented to $1-\alpha$. \Cref{fig:roll-principle} provides a geometric view of \eqref{eq:roll-tpr-at-fpr}. \begin{figure}[H] @@ -221,20 +223,20 @@ and implementation details below are given for \eqref{eq:roll-tpr-at-fpr} only; We now derive the gradient of \eqref{eq:roll-tpr-at-fpr} with respect to $f_\theta(\mathbf{x}_i)$. If $y_i = 1$, then $(\mathbf{x}_i, y_i) \in \mathcal{B}_1$ and $f_\theta(\mathbf{x}_i)$ has no -effect on $\hat{F}_0^{-1}(\alpha)$. Therefore: +effect on $\hat{F}_0^{-1}(1-\alpha)$. Therefore: \begin{equation} \left.\frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}(f_\theta(\mathcal{B}) ; \alpha)} {\partial f_\theta(\mathbf{x}_i)}\right|_{y_i = 1} - = \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_\theta(\mathbf{x}_i)} + = \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial f_\theta(\mathbf{x}_i)} \end{equation} If $y_i = 0$, then $(\mathbf{x}_i, y_i) \in \mathcal{B}_0$ and $f_\theta(\mathbf{x}_i)$ affects -$\hat{F}_0^{-1}(\alpha)$ instead. Applying the chain rule: +$\hat{F}_0^{-1}(1-\alpha)$ instead. Applying the chain rule: \begin{equation} \left.\frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}(f_\theta(\mathbf{X}) ; \alpha)} {\partial f_\theta(\mathbf{x}_i)}\right|_{y_i = 0} - = \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial \hat{F}_0^{-1}(\alpha)} - \cdot \frac{\partial \hat{F}_0^{-1}(\alpha)}{\partial f_\theta(\mathbf{x}_i)} + = \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial \hat{F}_0^{-1}(1-\alpha)} + \cdot \frac{\partial \hat{F}_0^{-1}(1-\alpha)}{\partial f_\theta(\mathbf{x}_i)} \end{equation} Unifying both cases, the general gradient applicable to all ROLL instantiations is: @@ -242,10 +244,10 @@ Unifying both cases, the general gradient applicable to all ROLL instantiations \frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}(f_\theta(\mathbf{X}) ; \alpha)} {\partial f_\theta(\mathbf{x}_i)} = \begin{cases} - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_\theta(\mathbf{x}_i)} + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial f_\theta(\mathbf{x}_i)} & \text{if } y_i = 1 \\[10pt] - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial \hat{F}_0^{-1}(\alpha)} - \cdot \dfrac{\partial \hat{F}_0^{-1}(\alpha)}{\partial f_\theta(\mathbf{x}_i)} + \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(1-\alpha))}{\partial \hat{F}_0^{-1}(1-\alpha)} + \cdot \dfrac{\partial \hat{F}_0^{-1}(1-\alpha)}{\partial f_\theta(\mathbf{x}_i)} & \text{if } y_i = 0 \end{cases} \label{eq:roll-gradient} @@ -253,6 +255,49 @@ Unifying both cases, the general gradient applicable to all ROLL instantiations The concrete form of each partial derivative depends on the choice of distribution family $\mathcal{F}$, and is derived for each instantiation in \Cref{sec:roll-instantiations}. +\subsection{ROLL variant - direct AUC optimisation} + +In addition to optimising for a specific rate, ROLL provides us an opportunity to +optimize the AUC of the ROC directly. + +The AUC is defined as the area under the curve of the ROC. The ROC is a function that +for every FPR gives us the performing TPR of the model we have fitted. + +Formally, for the function $TPR(\alpha)$ as defined above, we may define AUC as: + +\begin{equation} + \operatorname{AUC} = \int_{0}^{1}\operatorname{TPR}(\alpha) d \alpha +\end{equation} + +The AUC is something we would like to maximize. In order to do so, we would like to +minimize the area over the curve, which is $1-AUC$. + +We note that $1-\operatorname{TPR}(\alpha) = \mathcal{L}(TPR@FPR)$. + +From here, we would like to minimize: + +\begin{equation} + \mathcal{L}_{AOC} = \int_0^1\mathcal{L}_{\text{ROLL-TPR@FPR}}(\alpha) d \alpha +\end{equation} + +A direct integration is not part of this work. However, integration can be approximated. Instead +of integrating directly, it is possible to evaluate the loss for every FPR between 0 and 1, sum them, and re-normalize. + +Therefor, subdividing the interval $(0, 1)$ to 99 steps (every alpha starting from $0.01$ and ending with $0.99$, since a value of $0$ or $1$ would be illegal), our loss for minimizing AOC becomes: + +\begin{equation} + \mathcal{L}_{ROLL-AOC} = \frac{1}{99}\sum_{i=1}^{99}\mathcal{L}_{ROLL-TPR@FPR}\left(\frac{i}{100}\right) + \label{eq:roll-aoc} +\end{equation} + +The gradient per score then simply becomes the average gradient over every threshold. + +\begin{equation} + \frac{\partial \mathcal{L}_{ROLL-AOC}(f_\theta(\mathbf{X}))} + {\partial f_\theta(\mathbf{x}_i)} = \frac{1}{99}\sum_{i=1}^{99}\left(\frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}\left(f_\theta(\mathbf{X}) ; \frac{i}{100}\right)} + {\partial f_\theta(\mathbf{x}_i)} \right) + \label{eq:roll-aoc-gradient} +\end{equation} %------------------------------------------------ @@ -322,7 +367,7 @@ available in standard numerical libraries (e.g.\ \texttt{torch.erf} and \texttt{torch.erfinv}). Plugging into the general ROLL framework, the threshold $\tau$ achieving FPR $= \alpha$ and the resulting loss are: \begin{align} - \tau &= \mu_0 + \sigma_0\sqrt{2}\,\text{ierf}(2\alpha - 1) \nonumber \\ + \tau &= \mu_0 + \sigma_0\sqrt{2}\,\text{ierf}(1 - 2\alpha) \nonumber \\ \mathcal{L}_{\text{ROLL-TPR@FPR}}^{\text{GAUSSIAN}}(f_{\theta}(\mathcal{B}) ; \alpha) &= \frac{1}{2}\left[1 + \text{erf}\!\left(\frac{\tau - \mu_1}{\sigma_1\sqrt{2}}\right)\right] \label{eq:roll-tpr-at-fpr-gaussian} @@ -331,87 +376,8 @@ $\tau$ achieving FPR $= \alpha$ and the resulting loss are: \subsubsection{Gradient Derivation} \label{sec:roll-gaussian-backward} -% Differentiate the Gaussian loss with respect to $f_\theta(\mathbf{x}_i)$. -% Gradients flow through $\mu_k$ and $\sigma_k^2$ (which are differentiable -% functions of the scores), and through $\Phi$ and $\Phi^{-1}$, which have -% simple closed-form derivatives. - -In order to compute the gradient derivation for the gaussian estimates we must first compute the gradient to each of the parameters. -Firstly, for $y_i = 1$. - -\[ - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial \mu_1} = - \frac{\partial \frac{1}{2}\left[1 + \text{erf}\!\left(\frac{\hat{F}_0^{-1}(\alpha) - \mu_1}{\sigma_1\sqrt{2}}\right)\right]}{\partial \mu_1} -\] - -\[ - = -\frac{1}{\sigma_1\sqrt{2\pi}}\exp\!\left(-\frac{(\hat{F}_0^{-1}(\alpha) - \mu_1)^2}{2\sigma_1^2}\right) -\] - -\[ - \frac{\partial \mu_1}{\partial f_{\theta}(\mathbf{x}_i)} = \frac{1}{|\mathcal{B}_1|} -\] - -\[ - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial \sigma_1} = - \frac{\partial \frac{1}{2}\left[1 + \text{erf}\!\left(\frac{\hat{F}_0^{-1}(\alpha) - \mu_1}{\sigma_1\sqrt{2}}\right)\right]}{\partial \sigma_1} -\] - -\[ - = \frac{\mu_1 - \hat{F}_0^{-1}(\alpha)}{\sigma_1^2\sqrt{2\pi}} \exp\!\left( -\frac{(\hat{F}_0^{-1}(\alpha) - \mu_1)^2}{2\sigma_1^2} \right) -\] -\[ - \frac{\partial \sigma_1}{\partial f_{\theta}(\mathbf{x}_i)} = \frac{f_\theta(\mathbf{x}_i) - \mu_1}{|\mathcal{B}_1| \sigma_1} -\] - -Combining via the chain rule, the gradient for $y_i = 1$ is: -\begin{equation} - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_{\theta}(\mathbf{x}_i)} - = -\frac{1}{|\mathcal{B}_1|\,\sigma_1\sqrt{2\pi}} - \exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) - \left(1 + \frac{(\tau - \mu_1)(f_\theta(\mathbf{x}_i) - \mu_1)}{\sigma_1^2}\right) - \label{eq:gauss-grad-y1} -\end{equation} -where $\tau = \hat{F}_0^{-1}(\alpha) = \mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(2\alpha - 1)$. - -Given $y_i = 0$, the score $f_\theta(\mathbf{x}_i)$ affects the loss only through the threshold -$\tau = \hat{F}_0^{-1}(\alpha)$, which depends on $\mu_0$ and $\sigma_0$. -Applying the chain rule: -\[ - \frac{\partial \hat{F}_1(\tau)}{\partial f_\theta(\mathbf{x}_i)} - = \underbrace{\frac{\partial \hat{F}_1(\tau)}{\partial \tau}}_{\text{PDF of class 1 at }\tau} - \cdot \frac{\partial \tau}{\partial f_\theta(\mathbf{x}_i)} -\] - -The first factor is the Gaussian PDF evaluated at $\tau$: -\[ - \frac{\partial \hat{F}_1(\tau)}{\partial \tau} - = \frac{1}{\sigma_1\sqrt{2\pi}}\exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) -\] - -For the second factor, $\tau = \mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(2\alpha - 1)$, so -$\frac{\partial \tau}{\partial \mu_0} = 1$ and -$\frac{\partial \tau}{\partial \sigma_0} = \sqrt{2}\,\operatorname{ierf}(2\alpha - 1) = \frac{\tau - \mu_0}{\sigma_0}$. -Combined with $\frac{\partial \mu_0}{\partial f_\theta(\mathbf{x}_i)} = \frac{1}{|\mathcal{B}_0|}$ and -$\frac{\partial \sigma_0}{\partial f_\theta(\mathbf{x}_i)} = \frac{f_\theta(\mathbf{x}_i) - \mu_0}{|\mathcal{B}_0|\sigma_0}$: -\[ - \frac{\partial \tau}{\partial f_\theta(\mathbf{x}_i)} - = \frac{1}{|\mathcal{B}_0|}\left(1 + \frac{(\tau - \mu_0)(f_\theta(\mathbf{x}_i) - \mu_0)}{\sigma_0^2}\right) -\] - -Therefore, the gradient for $y_i = 0$ is: -\begin{equation} - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_\theta(\mathbf{x}_i)} - = \frac{1}{|\mathcal{B}_0|\,\sigma_1\sqrt{2\pi}} - \exp\!\left(-\frac{(\tau - \mu_1)^2}{2\sigma_1^2}\right) - \left(1 + \frac{(\tau - \mu_0)(f_\theta(\mathbf{x}_i) - \mu_0)}{\sigma_0^2}\right) - \label{eq:gauss-grad-y0} -\end{equation} - -\paragraph{Combined gradient.} - -Substituting \Cref{eq:gauss-grad-y1} and \Cref{eq:gauss-grad-y0} into \Cref{eq:roll-gradient}, -and letting $\tau = \hat{F}_0^{-1}(\alpha) = \mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(2\alpha-1)$: +The full derivation is given in Appendix~\ref{appendix:gauss-grad}. +Letting $\tau = \hat{F}_0^{-1}(1-\alpha) = \mu_0 + \sigma_0\sqrt{2}\,\operatorname{ierf}(1-2\alpha)$, the gradient is: \begin{equation} \frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}^{\text{GAUSSIAN}}}{\partial f_\theta(\mathbf{x}_i)} = @@ -476,10 +442,10 @@ Substituting into the general ROLL framework \eqref{eq:roll-tpr-at-fpr}: \mathcal{L}_{\text{ROLL-TPR@FPR}}^{\text{BETA}}(f_\theta(\mathcal{B});\,\alpha) = I_{\hat\tau}(\hat{a}_1,\hat{b}_1), \qquad - \hat\tau = I^{-1}_\alpha(\hat{a}_0,\hat{b}_0) + \hat\tau = I^{-1}_{1-\alpha}(\hat{a}_0,\hat{b}_0) \label{eq:roll-tpr-at-fpr-beta} \end{equation} -where $I^{-1}_\alpha(a,b)$ denotes the $\alpha$-quantile of $\operatorname{Beta}(a,b)$. +where $I^{-1}_{1-\alpha}(a,b)$ denotes the $(1-\alpha)$-quantile of $\operatorname{Beta}(a,b)$. \subsubsection{Gradient Derivation} \label{sec:roll-beta-backward} @@ -492,12 +458,6 @@ Gradients of \eqref{eq:roll-tpr-at-fpr-beta} with respect to $f_\theta(\mathbf{x are therefore propagated via automatic differentiation through the estimator \eqref{eq:beta-params}, the CDF evaluation, and the quantile inversion. -Note that the gradient balance property (\Cref{prop:gradient-balance}) does not hold -for Beta ROLL: the sigmoid activation that maps raw scores into $(0,1)$ is nonlinear, -so a uniform additive shift of the raw scores produces a non-uniform shift of the -transformed inputs, violating the translation-invariance assumption required by the -proof. - \subsection{KDE ROLL} \label{sec:roll-kde} @@ -522,7 +482,7 @@ As before, to calculate the loss, we calculate: \[ - \mathcal{L}_{\text{ROLL-TPR@FPR}}^{\text{KDE}}(f_{\theta}(\mathcal{B}) ; \alpha) = \hat{F}_1(\hat{F}_0^{-1}(\alpha)) + \mathcal{L}_{\text{ROLL-TPR@FPR}}^{\text{KDE}}(f_{\theta}(\mathcal{B}) ; \alpha) = \hat{F}_1(\hat{F}_0^{-1}(1-\alpha)) \] To calculate this, we first define the kernel function as $\sigma '$, and the CDF of the kernel function as $\sigma$. The approach used here is to define $\sigma$ as a sigmoid function,. @@ -542,24 +502,10 @@ The CDF of the KDE function then becomes: \hat{F}_{KDE}(\tau ; \mathbf{X}) = \frac{1}{|X|}\sum_i \sigma(\tau - x_i) \] -While the CDF has a nice formula, the inverse CDF has no known closed formula. It instead must be calculated numerically. Thus, the calculation of the decision threshold $\tau$ must be achevied -using a numerical calculation algorithm. In this work, the Newton--Raphson method~\cite{press2007numerical} is chosen. - -Firstly we must calculate $\hat{F}_0^{-1}(\alpha)$ = \tau. We start with our initial guess, $\tau_0$, and for each step, calculate: - -\[ - \tau_{n+1} = \tau_n - \frac{\hat{F}_0(\tau_n ; \mathcal{X}_0) - \alpha}{\frac{\partial \hat{F}_0(\tau_n ; \mathcal{X}_0)}{\partial \tau}} -\] - -This step is taken until $\hat{F}_0(\tau_n ; \mathcal{B}_0) \approx \alpha$ within some acceptable error (in our case $1e-4$). - -Our derivative w.r.t. $\tau$ is - -\[ % - \frac{\partial \hat{F}_0(\tau_n ; \mathcal{X}_0)}{\partial \tau} = \frac{1}{|\mathcal{X}_0|}\sum_i \sigma'(\tau - x_i) -\] - -At this point, we have succesfully calculated $\tau$ for which $\tau = \hat{F}_0^{-1}(\alpha ; \mathbf{X}_0)$. +While the CDF has a closed form, its inverse has none and must be found numerically. +We use bisection, which requires no derivative evaluation and is guaranteed to converge +for any strictly monotone CDF; the bracket construction and iteration are detailed in +Appendix~\ref{appendix:kde-bisection}. We can now relatively easily calculate $\hat{F}_1(\tau ; \mathbf{X}_1)$ using the formulat for $\hat{F}_{KDE}(\tau ; \mathbf{X})$ above. @@ -574,144 +520,7 @@ Importantly, we must save the calculation of $\tau$ for the backward derivation, % Gradients flow through the kernel evaluations back to the model scores. % This is the section that connects to \Cref{sec:roll-backward} motivation. -We derive the concrete form of the two terms from \Cref{eq:roll-gradient} for the KDE instantiation, -where $\tau = \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)$. - -\paragraph{Case $y_i = 1$ (positive class).} - -When $\mathbf{x}_i \in \mathcal{B}_1$, the score $f_\theta(\mathbf{x}_i)$ appears directly in $\hat{F}_1$ -and has no effect on $\tau$ (which depends only on $\mathcal{B}_0$). Therefore: - -\[ - \dfrac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_{\theta}(\mathbf{x}_i)} = - \frac{\partial \frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1} \sigma_1(\tau - f_{\theta}(\mathbf{x}_j))}{\partial f_{\theta}(\mathbf{x}_i)} -\] - -\[ - = \frac{\partial \left(\sum_{\mathbf{x}_j \in \mathcal{B}_1 ; j \neq i} \frac{1}{|\mathcal{B}_1|}\sigma_1(\tau - f_{\theta}(\mathbf{x}_j)) + \frac{1}{|\mathcal{B}_1|}\sigma_1(\tau - f_{\theta}(\mathbf{x}_i))\right)}{\partial f_{\theta}(\mathbf{x}_i)} -\] - -Applying the chain rule to the only $f_\theta(\mathbf{x}_i)$-dependent term, -$\frac{\partial}{\partial f_\theta(\mathbf{x}_i)}(\tau - f_\theta(\mathbf{x}_i)) = -1$: - -\begin{equation} - \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial f_{\theta}(\mathbf{x}_i)} = -\frac{1}{|\mathcal{B}_1|}\sigma_1'(\tau - f_{\theta}(\mathbf{x}_i)) - \label{eq:kde-grad-y1} -\end{equation} - -\paragraph{Case $y_i = 0$ (negative class).} - -When $\mathbf{x}_i \in \mathcal{B}_0$, the score $f_\theta(\mathbf{x}_i)$ does not appear directly in -$\hat{F}_1$, but influences it through the threshold $\tau$. Per \Cref{eq:roll-gradient}, we compute -each factor of the chain rule separately. - -\medskip\noindent\textit{Derivative of $\hat{F}_1$ with respect to $\tau$.} - -\[ - \frac{\partial \hat{F}_1(\hat{F}_0^{-1}(\alpha))}{\partial \hat{F}_0^{-1}(\alpha)} = \frac{\partial \frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1} \sigma_1(\tau - f_{\theta}(\mathbf{x}_j))}{\partial \tau} -\] - -Applying the chain rule, $\frac{\partial}{\partial\tau}(\tau - f_\theta(\mathbf{x}_j)) = +1$: - -\begin{equation} - = +\frac{1}{|\mathcal{B}_1|}\sum_{\mathbf{x}_j \in \mathcal{B}_1}\sigma_1'(\tau - f_{\theta}(\mathbf{x}_j)) - \label{eq:kde-dF1-dtau} -\end{equation} - -\medskip\noindent\textit{Derivative of $\tau$ with respect to $f_\theta(\mathbf{x}_i)$.} - -This requires differentiating a quantity computed numerically --- $\tau = \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)$ -is found via Newton's method rather than in closed form. - -We apply the inverse derivative rule: - -\[ - f'(x) = \frac{1}{f^{-1}'(f(x))} -\] - -This allows us to use the derivative of the inverse function instead. We need the inverse of -$\hat{F}_0^{-1}$ viewed as a function of $f_\theta(\mathbf{x}_i)$ --- that is, an expression for -$f_\theta(\mathbf{x}_i)$ in terms of $\tau$, $\alpha$, and $\mathcal{B}_0 \setminus \{\mathbf{x}_i\}$. -Solving $|\mathcal{B}_0|\cdot\alpha = \sum_{\mathbf{x}_j \in \mathcal{B}_0}\sigma_0(\tau - f_\theta(\mathbf{x}_j))$ -for $f_\theta(\mathbf{x}_i)$ gives: - -\[ - f_\theta(\mathbf{x}_i) = \tau - \sigma_0^{-1}\left( |\mathcal{B}_0|\cdot\alpha - \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0(\tau - f_{\theta}(\mathbf{x}_j))\right) -\] - -Applying the inverse derivative rule to this inverse: - -\[ - \frac{\partial \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} = \frac{1}{\frac{\partial \left(\tau - \sigma_0^{-1}\left( |\mathcal{B}_0|\cdot \alpha - \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0(\tau - f_{\theta}(\mathbf{x}_j))\right)\right)}{\partial \tau}} -\] - -Applying the chain rule: - -\[ - = \frac{1}{\sigma_0^{-1}{}'\left( |\mathcal{B}_0|\cdot \alpha - \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0(\tau - f_{\theta}(\mathbf{x}_j))\right)\cdot\left( \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0'(\tau - f_{\theta}(\mathbf{x}_j))\right) + 1} -\] - -Since $|\mathcal{B}_0|\cdot\alpha = \sum_{\mathbf{x}_j \in \mathcal{B}_0}\sigma_0(\tau - f_\theta(\mathbf{x}_j))$, -the argument of $\sigma_0^{-1}{}'$ simplifies: - -\[ - |\mathcal{B}_0|\cdot \alpha - \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0(\tau - f_{\theta}(\mathbf{x}_j)) = \sigma_0(\tau - f_{\theta}(\mathbf{x}_i)) -\] - -Therefore: - -\[ - \frac{\partial \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} = \frac{1}{\sigma_0^{-1}{}'\!\left( \sigma_0(\tau - f_{\theta}(\mathbf{x}_i)) \right)\cdot\left( \sum_{\mathbf{x}_j \in \mathcal{B}_0 ; j \neq i}\sigma_0'(\tau - f_{\theta}(\mathbf{x}_j))\right) + 1 } -\] - -Substituting $\sigma_0^{-1}{}'(\sigma_0(u)) = \frac{1}{\sigma_0'(u)}$ and multiplying numerator and denominator -by $\sigma_0'(\tau - f_{\theta}(\mathbf{x}_i))$: - -\begin{equation} - \frac{\partial \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} = - \frac{\sigma_0'(\tau - f_{\theta}(\mathbf{x}_i))}{\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0}\sigma_0'(\tau - f_{\theta}(\mathbf{x}_j))} - \label{eq:kde-grad-tau} -\end{equation} - -\medskip\noindent\textit{Efficient computation via the sigmoid identity.} - -Direct evaluation of \eqref{eq:kde-grad-tau} requires computing $\sigma_0'$ for every -point, then dividing by the per-point value — potentially unstable when a point is far -from $\tau$. For the sigmoid kernel, we can avoid this by exploiting the identity - -\begin{equation} - \sigma(u;\,v)\,\bigl(1 - \sigma(u;\,v)\bigr) = \frac{\sigma'(u;\,v)}{v} - \label{eq:sigmoid-identity} -\end{equation} - -which holds for all $u \in \mathbb{R}$ (proved by direct substitution: both sides equal -$\exp(-v|u|)/(1+\exp(-v|u|))^2$). Applying this with $u = \tau - f_\theta(\mathbf{x}_j)$: - -\[ - \sigma_0'(\tau - f_\theta(\mathbf{x}_j)) = v_0\,\sigma_0(\tau - f_\theta(\mathbf{x}_j)) - \,\bigl(1-\sigma_0(\tau - f_\theta(\mathbf{x}_j))\bigr) -\] - -Since $v_0$ cancels between numerator and denominator of \eqref{eq:kde-grad-tau}, -the ratio can be written entirely in terms of the sigmoid values already computed -during the forward pass: - -\begin{equation} - \frac{\partial \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)}{\partial f_\theta(\mathbf{x}_i)} - = - \frac{\sigma_0(\tau-f_\theta(\mathbf{x}_i))\,\bigl(1-\sigma_0(\tau-f_\theta(\mathbf{x}_i))\bigr)} - {\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0} - \sigma_0(\tau-f_\theta(\mathbf{x}_j))\,\bigl(1-\sigma_0(\tau-f_\theta(\mathbf{x}_j))\bigr)} - \label{eq:kde-grad-tau-efficient} -\end{equation} - -This avoids recomputing $\sigma_0'$ (which requires an extra exponential), instead -reusing the sigmoid activations cached from the CDF computation. - -\paragraph{Combined gradient.} - -Substituting \Cref{eq:kde-grad-y1}, \Cref{eq:kde-dF1-dtau}, and \Cref{eq:kde-grad-tau} -into \Cref{eq:roll-gradient}: +The derivation is given in Appendix~\ref{appendix:kde-grad}; letting $\tau = \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)$, the gradient is: \begin{equation} \frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}}{\partial f_\theta(\mathbf{x}_i)} = @@ -726,87 +535,10 @@ into \Cref{eq:roll-gradient}: \label{eq:kde-grad-combined} \end{equation} -where $\tau = \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)$. +where $\tau = \hat{F}_0^{-1}(1-\alpha ; \mathcal{B}_0)$. -\subsubsection{Sigmoid Kernel: Explicit Equations} -\label{sec:roll-kde-sigmoid} - -The derivations above hold for any differentiable CDF kernel $\sigma$. -In our implementation we choose the logistic sigmoid: -% -\begin{equation} - \sigma(x ; v) = \frac{1}{1 + \exp(-vx)}, - \qquad - \sigma'(x ; v) = \frac{v\,\exp(-v|x|)}{\bigl(1 + \exp(-v|x|)\bigr)^{2}} - \label{eq:sigmoid-kernel} -\end{equation} -% -where $v > 0$ is the bandwidth parameter. The derivative formula evaluates at -$|x|$ rather than $x$: since $\sigma'$ is an even function -($\sigma'(x) = \sigma'(-x)$ for any symmetric logistic), both forms are -mathematically identical, but $\exp(-v|x|) \to 0$ as $|x| \to \infty$ while -$\exp(-vx) \to \infty$ for $x \to -\infty$, so the $|x|$ form avoids -floating-point overflow when scores fall well below the threshold. - -\paragraph{Forward pass.} - -Substituting \eqref{eq:sigmoid-kernel} into the KDE CDF: -% -\begin{equation} - \hat{F}_{k}(\tau ; \mathbf{s}^{(k)}) = - \frac{1}{|\mathcal{B}_k|} - \sum_{\mathbf{x}_j \in \mathcal{B}_k} - \frac{1}{1 + \exp\!\bigl(-v_k\bigl(\tau - f_\theta(\mathbf{x}_j)\bigr)\bigr)} - \label{eq:kde-sigmoid-cdf} -\end{equation} -% -and its derivative with respect to $\tau$ — used both in the Newton--Raphson -inversion and in the gradient computation below — is: -% -\begin{equation} - \frac{\partial \hat{F}_{k}(\tau)}{\partial \tau} - = - \frac{1}{|\mathcal{B}_k|} - \sum_{\mathbf{x}_j \in \mathcal{B}_k} - \frac{v_k\,\exp\!\bigl(-v_k\bigl|\tau - f_\theta(\mathbf{x}_j)\bigr|\bigr)} - {\Bigl(1 + \exp\!\bigl(-v_k\bigl|\tau - f_\theta(\mathbf{x}_j)\bigr|\bigr)\Bigr)^{2}} - \label{eq:kde-sigmoid-pdf} -\end{equation} - -\paragraph{Gradient.} - -Define the sigmoid kernel PDF shorthand: -\begin{equation} - \varphi_k(u) \;=\; - \frac{v_k\,\exp(-v_k|u|)}{\bigl(1+\exp(-v_k|u|)\bigr)^{2}} - \label{eq:sigmoid-phi} -\end{equation} -This is simply $\sigma'(u ; v_k)$ from \eqref{eq:sigmoid-kernel}, a bell-shaped function -centred at zero with width controlled by bandwidth $v_k$. -Substituting \eqref{eq:sigmoid-kernel} into \eqref{eq:kde-grad-combined} and using this -notation, the explicit sigmoid-kernel gradient is: - -\begin{equation} - \frac{\partial \mathcal{L}_{\text{ROLL-TPR@FPR}}}{\partial f_\theta(\mathbf{x}_i)} = - \begin{cases} - -\dfrac{\varphi_1\!\left(\tau - f_\theta(\mathbf{x}_i)\right)}{|\mathcal{B}_1|} - & \text{if } y_i = 1\\[14pt] - +\,\dfrac{\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_1} - \varphi_1\!\left(\tau - f_\theta(\mathbf{x}_j)\right)}{|\mathcal{B}_1|} - \;\cdot\; - \dfrac{\varphi_0\!\left(\tau-f_\theta(\mathbf{x}_i)\right)} - {\displaystyle\sum_{\mathbf{x}_j \in \mathcal{B}_0} - \varphi_0\!\left(\tau-f_\theta(\mathbf{x}_j)\right)} - & \text{if } y_i = 0 - \end{cases} - \label{eq:kde-sigmoid-grad} -\end{equation} - -where $\tau = \hat{F}_0^{-1}(\alpha ; \mathcal{B}_0)$. -The signs reflect the direction of each class's effect on the loss: raising a -positive-class score pushes $\hat{F}_1(\tau)$ down (gradient negative), while -raising a negative-class score shifts $\tau$ right, also lowering $\hat{F}_1(\tau)$ -(gradient positive). Positive-class samples are weighted by their individual kernel +The explicit sigmoid-kernel form of \eqref{eq:kde-grad-combined} — forward pass CDF, efficient gradient, and implementation notes — is given in Appendix~\ref{appendix:kde-sigmoid}. +Positive-class samples are weighted by their individual kernel PDF at $\tau$; negative-class samples are weighted by the mean positive-class kernel PDF scaled by each sample's share of the negative-class kernel mass. @@ -859,7 +591,7 @@ From \Cref{eq:roll-gradient}, for $y_i = 0$: We claim $\sum_{\mathbf{x}_i \in \mathcal{B}_0}\frac{\partial \tau}{\partial f_\theta(\mathbf{x}_i)} = 1$. Shift all negative scores uniformly: $f_\theta(\mathbf{x}_i) \to f_\theta(\mathbf{x}_i) + \delta$ for $\mathbf{x}_i \in \mathcal{B}_0$. By translation invariance, $\hat{F}_0$ simply translates, so -$\tau = \hat{F}_0^{-1}(\alpha)$ shifts by exactly $\delta$. Differentiating with respect to $\delta$ at +$\tau = \hat{F}_0^{-1}(1-\alpha)$ shifts by exactly $\delta$. Differentiating with respect to $\delta$ at $\delta = 0$: \[ 1 = \frac{\mathrm{d}\tau}{\mathrm{d}\delta}\bigg|_{\delta=0} @@ -887,25 +619,25 @@ Differentiating at $\delta = 0$: Combining with \eqref{eq:grad-balance-b0} gives \eqref{eq:grad-balance}. \end{proof} -The translation-invariance assumption holds for all distribution families considered in this -work: for Gaussian MLE, a uniform shift in scores moves $\mu_k$ by the same amount while +The translation-invariance assumption holds for both the Gaussian distribution, +as well as the KDE-based distribution, but not for the Beta distribution. +For Gaussian MLE, a uniform shift in scores moves $\mu_k$ by the same amount while leaving $\sigma_k$ unchanged, which translates $\hat{F}_k$; for KDE, each kernel term is evaluated at $\tau - f_\theta(\mathbf{x}_j)$, so a uniform shift in the $f_\theta(\mathbf{x}_j)$ is equivalent to an equal shift in $\tau$. The condition is necessary: without it, a uniform score shift need not produce a rigid translation of $\hat{F}_k$, so the shift argument in the -proof breaks down and the gradient sums need not be equal. A natural example where this fails -is a family that first maps scores through a nonlinear link function before fitting, such as -passing scores through a sigmoid into $[0,1]$ before fitting a Beta distribution. A uniform -additive shift of the raw scores then produces a non-uniform shift of the transformed inputs, -changing the shape of the fitted distribution rather than merely translating it, and the -balance property no longer holds. +proof breaks down and the gradient sums need not be equal. + +The Beta distribution only accepts values in the interval $\[0, 1\]$. Since it +is mapped only over an interval, the translation-invariance assumption does not hold +for this distribution. \paragraph{Gradient locality.} \label{para:gradient-locality} -A second structural consequence of the ROLL formulation is that gradient mass is +A second structural consequence of the ROLL-KDE formulation is that gradient mass is \emph{concentrated near the operating threshold $\tau$}. Samples whose scores lie -close to $\tau$ receive disproportionately large gradient updates, while samples +close to $\tau$ receive larger gradient updates, while samples already far on the correct side contribute very little. This follows directly from \Cref{eq:kde-grad-combined}. For the positive class ($y_i = 1$), @@ -922,15 +654,14 @@ again bell-shaped and centred on $\tau$. The effect is that each gradient step focuses the model's attention on the region that directly determines the operating-point performance: samples that could plausibly be -re-ranked relative to the threshold at the current step. Samples comfortably classified -on the correct side contribute negligible signal, not because they are deemed unimportant, -but because their contribution to the CDF estimate at $\tau$ is already saturated. +re-ranked relative to the threshold at the current step. Samples classified with strong +confidence relative to the threshold, with scores far enough away from said threshold, +receive small gradient updates, since a small change to the score of these samples will not +bring any change to the placement of the threshold itself, or the performance at said threshold. This stands in contrast to standard losses such as cross-entropy, where the per-sample gradient is determined by the predicted probability, with no direct dependence on an -operating threshold. Under heavy class imbalance this can cause the dominant class to -``push'' the threshold away from the intended operating point, a problem that gradient -locality avoids by construction. +operating threshold. \begin{observation}[Gradient locality] \label{obs:gradient-locality} @@ -958,32 +689,34 @@ concentration of gradient mass around $\tau$, with smooth decay on either side. \label{fig:threshold-locality} \end{figure} - -\subsection{Gradient Computation and the Custom Backward Pass} -\label{sec:roll-backward} - -% Because the distribution parameters are themselves functions of model scores -% (not fixed), the backward pass must differentiate through the distribution -% fitting step. Describe the custom autograd implementation: how gradients flow -% from the ROLL loss back through the distribution parameters to the model -% weights. Highlight where standard autograd would fail and what the manual -% backward pass does differently. - %------------------------------------------------ \section{Implementation Considerations} \label{sec:roll-implementation} -\subsection{Numerical Stability and the Scaling Trick} +\subsection{Combatting Numerical Instability With Score Scaling} \label{sec:roll-numerical-stability} -% The KDE loss involves sums of kernel evaluations that can span many orders of -% magnitude, leading to floating-point underflow or overflow during training. -% Describe the scaling trick that normalizes these sums to a numerically stable -% range without changing the gradient direction, and show that it is equivalent -% to computing in log-space with a max-subtraction stabilizer (analogous to the -% log-sum-exp trick). +Before computing the KDE, all batch scores are divided by their overall standard +deviation: +\[ + \tilde{s}_i = \frac{f_\theta(\mathbf{x}_i)}{\hat\sigma_{\mathcal{B}}}, + \qquad + \hat\sigma_{\mathcal{B}} = \sqrt{\operatorname{Var}(f_\theta(\mathbf{x}_i) : (\mathbf{x}_i, y_i) \in \mathcal{B})}. +\] +This keeps the values given to the sigmoid kernel ($v(\tau - \tilde{s}_j)$) +near unit scale, preventing floating-point overflow and underflow in the exponential +evaluations. +The scaling has no effect on the loss value itself or derived gradients. +Silverman's rule derives the bandwidth proportionally to the data standard deviation, +$h \propto \hat\sigma \cdot n^{-1/5}$, so dividing all scores by $\hat\sigma_\mathcal{B}$ +causes the bandwidth to scale by the same factor. +The product $v \cdot (\tau - s_j)$ — the only quantity entering the sigmoid — is +therefore invariant under the rescaling. +In the backward pass, gradients with respect to the normalised scores are multiplied +by $1/\hat\sigma_\mathcal{B}$ to apply the chain rule, providing gradients mathematically +identical to those that would have been obtained without normalisation. \subsection{Bandwidth Estimation for KDE} \label{sec:kde-bandwidth} @@ -996,17 +729,33 @@ concentration of gradient mass around $\tau$, with smooth decay on either side. % NOTE - not silverman's rule, we do use scheduling, but we also use different % estimator - see impl. -When computing KDE, kernel selection and bandwidth estimation affect the final result greatly. Large bandwidths -don't accurately track the probability distribution, while small kernels result in a very jagged CDF, which for us means very low gradient values unless unless a point is very close to the decision threshold. +When computing KDE, bandwidth estimation strongly affects the result. Large bandwidths +produce an overly smooth CDF that fails to track the true score distribution; small +bandwidths produce a jagged CDF, yielding negligible gradients for all but the +nearest-threshold samples. -Use of the Improved Sheather-Jones (ISJ) method~\cite{botev2010kde} of bandwidth selection worked reliably well at creating very close-tracking, yet smooth CDFs. +We estimate the bandwidth using the Improved Sheather-Jones (ISJ) +method~\cite{botev2010kde}, which minimises the asymptotic mean integrated squared +error via an iterative plug-in procedure. ISJ tracks the true score distribution more +closely than closed-form rules, as illustrated in \Cref{fig:density-fit-comparison}. +Because ISJ is iterative, it can fail to converge on small or degenerate batches early +in training. In those cases we fall back to Silverman's rule of +thumb~\cite{silverman1986density}, +\[ + h = 1.06\,\hat{\sigma}\,n^{-1/5}, +\] +which is closed-form and always produces a valid bandwidth. +The kernel parameter is then set to $v = 1/h$. \subsubsection{Bandwidth Scaling for KDE} \label{sec:kde-bandwidth-scaling} -While the ISJ method worked very well for selecting an acceptable bandwidth, this wasn't necessarily wanted during training. Near the start of the training session, scores tended to be all low. This naturally made the selected bandwidth to be too low. This caused very low training performance near the start of a training session, which could result in non-convergence of the model even after significant training epochs elapsed. +Although we may select a valid bandwidth at each step, it tends to be +too small near the start of training, when scores are not yet +spread out and $\hat{\sigma}$ is small. This causes the KDE to undersmooth the score +distribution, producing very low gradient magnitudes and stalling convergence. -The solution was to use a bandwidth scheduler. Starting with large bandwidths resulted in gradients that spread out more evenly across all scores, and less non-convergence runs occurred. The bandwidth scheduler artificially scales up the bandwidth at the beginning to speed up initial training, and then tapers back to restore the intended bandwidth in order to maximize resuslts. +The solution was to use a bandwidth scheduler. Starting with large bandwidths resulted in gradients that spread out more evenly across all scores, and fewer non-convergence runs occurred. The bandwidth scheduler artificially scales up the bandwidth at the beginning to speed up initial training, and then tapers back to restore the intended bandwidth in order to maximise results. % TODO: algorithm box — full training loop (forward → ROLL loss → custom backward → weight update) diff --git a/content/related_work/related_work.tex b/content/related_work/related_work.tex index dd1bb4e..23b9288 100644 --- a/content/related_work/related_work.tex +++ b/content/related_work/related_work.tex @@ -84,10 +84,130 @@ TODO finish this section % ============================================================ -% PLACEMENT: near the END of Ch. 2, after KDE and AUC/lit -% review sections, just before the chapter summary. This -% section bridges from prior work to the method chapter by -% framing ROLL as a learnable, gradient-based NP test. +% PLACEMENT: Section 2.5, AFTER the KDE background section +% (sec:kde-background) and BEFORE the Neyman-Pearson bridge +% (sec:neyman-pearson, which becomes 2.6). +% +% Purpose: establish that existing pointwise losses are +% fragile under label corruption, motivating both the +% practical robustness of ROLL and the poisoning experiment +% results in Ch. 4. +% +% Narrative arc: +% 1. Define label noise types: symmetric (uniform flip), +% asymmetric / class-conditional (only certain class +% transitions occur), instance-dependent. Our poisoning +% experiment is asymmetric: P(\tilde{y}=0 \mid y=1)>0, +% P(\tilde{y}=1 \mid y=0)=0. +% 2. Why BCE is fragile: the symmetry condition (Ghosh +% et al., AAAI 2017) — a loss \ell is noise-tolerant +% iff \sum_k \ell(f(x),k) = C (constant). CE fails +% this; MAE satisfies it but converges slowly. Cite +% Feng et al. (IJCAI 2020) for "Can CE be robust?" +% (only under very strict conditions). Implication: +% mislabeled samples produce large unmitigated +% gradients; DNNs memorize noise late in training +% (memorization effect). +% 3. Family of existing fixes — keep brief; these are what +% ROLL sidesteps structurally: +% (a) Robust loss functions: MAE (noise-tolerant, +% slow), GCE (Zhang & Sabuncu, NeurIPS 2018; +% interpolates MAE↔CE via q), asymmetric losses +% (Zhou et al., ICML 2021), symmetrization +% (arXiv:2605.20347). +% (b) Label correction via noise transition matrix +% (Patrini et al., CVPR 2017): estimate +% T[i,j]=P(\tilde{y}=j|y=i), correct logits by +% T^{-1}. Hard for asymmetric noise without a +% clean reference set. +% (c) Sample selection / co-teaching (Han et al., +% NeurIPS 2018): two networks select small-loss +% examples for each other, exploiting the +% memorization effect. Requires dual-model +% training. +% 4. Ranking / distributional objectives and noise +% robustness: pairwise losses depend on score +% differences, not absolute labels — one mislabeled +% sample affects O(n) pairs, each with a small gradient +% weight. Wang et al. (arXiv:2305.14258) formally show +% noise robustness of partial-AUC objectives. +% 5. Bridge (observation, not oversell): ROLL's KDE-based +% distributional objective shares this structural +% property. Fake negatives (copies of positives with +% flipped labels) shift the estimated negative density +% but do not erase distributional separation when true +% positive scores remain clustered. ROLL achieves this +% without any explicit noise-handling mechanism; the +% poisoning experiment in Ch. 4 provides empirical +% evidence. +% ============================================================ +\section{Learning with Noisy Labels} +\label{sec:noisy-labels} + +% SUBSECTION STRUCTURE: +% +% \subsection{Types of Label Noise} +% - Symmetric / uniform: each label flipped with +% probability \varepsilon across all classes. +% - Asymmetric / class-conditional: only certain class +% transitions occur. Our poisoning experiment is of +% this type: P(\tilde{y}=0 \mid y=1)>0, +% P(\tilde{y}=1 \mid y=0)=0. +% - Instance-dependent: flip probability varies per +% sample (hardest to handle; mention only briefly). +% - Note: even moderate noise rates significantly hurt +% pointwise losses in the imbalanced setting, because +% mislabeled positives are rare to begin with. +% +% \subsection{Why Cross-Entropy Is Fragile Under Label Noise} +% - Introduce symmetry condition \cite{ghosh2017robust}: +% a loss is noise-tolerant iff +% \sum_k \ell(f(\mathbf{x}), k) = C (constant). +% - CE does NOT satisfy this; MAE does (but is slow). +% - Memorization effect: DNNs learn clean patterns early, +% then memorize noisy labels late in training. +% - Cite: \cite{ghosh2017robust}, \cite{feng2020can}. +% +% \subsection{Approaches to Robust Learning} +% - Paragraph 1 — Robust loss functions: +% MAE \cite{ghosh2017robust}, +% GCE \cite{zhang2018generalized} (L_q interpolation), +% asymmetric losses \cite{zhou2021asymmetric}. +% Key tradeoff: noise-tolerance vs.\ convergence speed. +% - Paragraph 2 — Transition matrix correction +% \cite{patrini2017making}: forward correction +% multiplies logits by T^{-1}. Canonical method but +% requires estimating T, which is hard for asymmetric +% noise without a clean anchor set. +% - Paragraph 3 — Sample selection / co-teaching +% \cite{han2018coteaching}: two nets select small-loss +% samples for each other each epoch. Bypasses T +% estimation but requires dual-model training. +% +% \subsection{Ranking Objectives and Noise Robustness} +% - Pairwise ranking losses are structurally more +% noise-robust: a single mislabeled sample affects O(n) +% pairs, each with small gradient weight, vs.\ one large +% pointwise gradient in BCE. +% - Cite Wang et al.\ \cite{wang2023weakly} for formal +% treatment in the partial-AUC setting. +% - Close with bridge sentence: ROLL's distributional +% threshold objective operates in the same structural +% regime — not pairwise, but also not pointwise — +% conferring noise robustness without explicit correction. +% Empirical evidence deferred to the Experiments chapter. + +TODO write this section. + +% ============================================================ +% PLACEMENT: Section 2.6 (was 2.5), near the END of Ch. 2, +% after KDE and Noisy Labels sections, just before the +% chapter summary. This section bridges from prior work to +% the method chapter by framing ROLL as a learnable, +% gradient-based NP test. +% NOTE: the label sec:neyman-pearson is unchanged; existing +% \Cref references in Ch. 3 (sec:problem-formulation) still +% work without modification. % ============================================================ \section{Connection to Neyman-Pearson} \label{sec:neyman-pearson} diff --git a/main.tex b/main.tex index 421ceaa..f62904f 100644 --- a/main.tex +++ b/main.tex @@ -236,10 +236,35 @@ \begin{appendices} \chapter{Some title for apendix A} -\label[appendix]{appendix:numerically_distinguished_comp} +\label{appendix:numerically_distinguished_comp} \addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח א}{\quad\qquadדרישת תאימות כלשהי}}{{\beginL\thepage\endL}}} \input{content/appendixs/appendix_a} +\chapter{Gaussian ROLL: Gradient Derivation} +\label{appendix:gauss-grad} +\addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח ב}{\quad\qquadנגזרת גאוסיאנית של ROLL}}{{\beginL\thepage\endL}}} +\input{content/appendixs/appendix_gauss_grad} + +\chapter{KDE ROLL: Gradient Derivation} +\label{appendix:kde-grad} +\addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח ג}{\quad\qquadנגזרת KDE של ROLL}}{{\beginL\thepage\endL}}} +\input{content/appendixs/appendix_kde_grad} + +\chapter{KDE ROLL: Sigmoid Kernel — Explicit Equations} +\label{appendix:kde-sigmoid} +\addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח ד}{\quad\qquadKDE ROLL: ניסוח מפורש עם גרעין סיגמואיד}}{{\beginL\thepage\endL}}} +\input{content/appendixs/appendix_kde_sigmoid} + +\chapter{KDE ROLL: Bisection for CDF Inversion} +\label{appendix:kde-bisection} +\addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח ה}{\quad\qquadKDE ROLL: היפוך CDF בשיטת חצייה}}{{\beginL\thepage\endL}}} +\input{content/appendixs/appendix_kde_bisection} + +\chapter{KDE ROLL: Newton--Raphson Inversion (Superseded)} +\label{appendix:kde-nr} +\addtocontents{tocheb}{\contentsline{chapter}{\protect\numberline{נספח ו}{\quad\qquadKDE ROLL: היפוך ניוטון-רפסון}}{{\beginL\thepage\endL}}} +\input{content/appendixs/appendix_kde_nr} + \end{appendices} %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%