Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove resample.bootstrap.bias and resample.bootstrap.bias_corrected #181

Merged
merged 4 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions src/resample/_deprecated.py

This file was deleted.

124 changes: 12 additions & 112 deletions src/resample/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
from . import _util
from .empirical import quantile_function_gen
from .jackknife import jackknife
from ._deprecated import deprecated


def resample(
Expand Down Expand Up @@ -287,117 +286,6 @@ def bootstrap(
return np.array([fn(x) for x in gen])


@deprecated(
"bootstrap.bias is deprecated and will be removed in a future revision, "
"use jackknife.bias instead"
)
def bias(
fn: Callable[..., np.ndarray],
sample: "ArrayLike",
*args: "ArrayLike",
**kwargs: Any,
) -> np.ndarray:
"""
Calculate bias of the function estimate with the bootstrap.

Parameters
----------
fn : callable
Function to be bootstrapped.
sample : array-like
Original sample.
*args : array-like
Optional additional arrays of the same length to resample.
**kwargs
Keyword arguments forwarded to :func:`resample`.

Returns
-------
ndarray
Bootstrap estimate of bias (= expectation of estimator - true value).

Examples
--------
Compute bias of numpy.var with and without bias-correction.

>>> from resample.bootstrap import bias
>>> import numpy as np
>>> x = np.arange(10)
>>> round(bias(np.var, x, size=10000, random_state=1), 1)
-0.8
>>> round(bias(lambda x: np.var(x, ddof=1), x, size=10000, random_state=1), 1)
0.0

Notes
-----
This function has special space requirements, it needs to hold `size` replicates of
the original sample in memory at once. The balanced bootstrap is recommended over
the ordinary bootstrap for bias estimation, it tends to converge faster.

"""
thetas = []
if args:
replicates: List[List[np.ndarray]] = [[] for _ in range(len(args) + 1)]
for b in resample(sample, *args, **kwargs):
for ri, bi in zip(replicates, b):
ri.append(bi)
thetas.append(fn(*b))
population_theta = fn(*(np.concatenate(r) for r in replicates))
else:
replicates = []
for b in resample(sample, *args, **kwargs):
replicates.append(b)
thetas.append(fn(b))
population_theta = fn(np.concatenate(replicates))
return np.mean(thetas, axis=0) - population_theta


@deprecated(
"bootstrap.bias is deprecated and will be removed in a future revision, "
"use jackknife.bias instead"
)
def bias_corrected(
fn: Callable[..., np.ndarray],
sample: "ArrayLike",
*args: "ArrayLike",
**kwargs: Any,
) -> np.ndarray:
"""
Calculate bias-corrected estimate of the function with the bootstrap.

Parameters
----------
fn : callable
Estimator. Can be any mapping ℝⁿ → ℝᵏ, where n is the sample size
and k is the length of the output array.
sample : array-like
Original sample.
*args : array-like
Optional additional arrays of the same length to resample.
**kwargs
Keyword arguments forwarded to :func:`resample`.

Returns
-------
ndarray
Estimate with some bias removed.

Examples
--------
Compute bias-corrected estimate of numpy.var.

>>> from resample.bootstrap import bias_corrected
>>> import numpy as np
>>> x = np.arange(10)
>>> round(np.var(x), 1)
8.2
>>> round(bias_corrected(np.var, x, size=10000, random_state=1), 1)
9.1

"""
return fn(sample, *args) - bias(fn, sample, *args, **kwargs)


def variance(
fn: Callable[..., np.ndarray],
sample: "ArrayLike",
Expand Down Expand Up @@ -682,3 +570,15 @@ def _confidence_interval_bca(

quant = quantile_function_gen(thetas)
return quant(p_low), quant(p_high)


def __getattr__(key: str) -> Any:
for match in ("bias", "bias_corrected"):
if key == match:
msg = (
f"resample.bootstrap.{match} has been removed. The implementation was "
"discovered to be faulty, and a generic fix is not in sight. "
"Please use resample.jackknife.bias instead."
)
raise NotImplementedError(msg)
raise AttributeError
10 changes: 10 additions & 0 deletions tests/test_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,13 @@ def test_resample_extended_5():
mu2 = 3**2 * np.sum(x, axis=0)
assert_allclose(t1, (mu1, 3**2 * mu1), rtol=0.05)
assert_allclose(t2, (mu2, 3**2 * mu2), rtol=0.05)


def test_bias_error():
with pytest.raises(NotImplementedError):
from resample.bootstrap import bias # noqa

with pytest.raises(NotImplementedError):
import resample.bootstrap as b

b.bias_corrected # noqa
Loading