# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['bootstrap_stat']

package_data = \
{'': ['*'], 'bootstrap_stat': ['data/*']}

install_requires = \
['numpy>=1.17', 'pandas>=0.25.1', 'pathos>=0.2.5', 'scipy>=1.3']

setup_kwargs = {
    'name': 'bootstrap-stat',
    'version': '0.2.4',
    'description': 'Bootstrap method for standard errors, confidence intervals, and more!',
    'long_description': '# bootstrap-stat\n\n![](https://github.com/rwilson4/bootstrap-stat/workflows/build/badge.svg)\n\nMethods relating to the Bootstrap.\n\nEstimates of standard errors, bias, confidence intervals, prediction\nerrors, and more!\n\n## Getting Started\nBootstrap-Stat is hosted on PyPI. Install as you would any other\nlibrary, e.g.: `poetry add bootstrap-stat`.\n\nDocumentation is available at\n[Convex Analytics](https://www.convexanalytics.com/bootstrap-stat/index.html)\nbut I also recommend reviewing the rest of this README.\n\n## Brief Overview\n\nQuoting [ET93], "The bootstrap is a data-based simulation method for\nstatistical inference...The use of the term bootstrap derives from the\nphrase *to pull oneself up by one\'s bootstrap*..."\n\nThe bootstrap is a collection of methodologies for estimating errors\nand uncertainties associated with estimates and predictions. For\nexample, it can be used to compute the bias and standard error of a\nparticular estimator. It can be used to estimate the prediction error\nof a particular ML model (as a competitor to Cross Validation). And it\ncan be used to compute confidence intervals. Most of the techniques\ndescribed in [ET93] have now been implemented. (Notable exceptions\ninclude importance resampling, likelihood-based methods, and better\nsupport for the parametric bootstrap.)\n\n### Basic Terminology\n\nTo apply bootstrap techniques, it is important to understand the\nfollowing terminology.\n\n* Distribution: an entity assigning probabilities to observations or\n  sets of observations.\n* Population: the complete set of data, typically only partially observed.\n* Sample: the observed data, assumed to be drawn with replacement from\n  the population. In real life, samples are usually drawn *without*\n  replacement from the population, but provided the sample is a small\n  fraction of the population, this is a negligible concern.\n* Empirical Distribution: the distribution assigning probability 1/n\n  to each observation in a sample of size n.\n* Parameter: some function of a distribution. See `statistic`.\n* Statistic: some function of a collection of observations. We will\n  assume all statistics are real-valued scalars, such as mean, median,\n  or variance. Parameters and statistics are similar: it makes sense\n  to talk about the mean of a distribution, which is a parameter of\n  that distribution, and it also makes sense to talk about the mean of\n  a collection of numbers, which is a statistic. For this reason, it\n  is important to keep it straight whether we are talking about a\n  parameter or a statistic! For example, it makes sense to talk about\n  the bias of a statistic, but it does not make sense to talk about\n  the bias of a parameter.\n* Plug-in estimate of a parameter: an estimate of a parameter\n  calculated by "plugging-in" the Empirical Distribution. For example,\n  to estimate the mean of an unobserved distribution, simply calculate\n  the mean of the (observed) Empirical Distribution. The plug-in\n  estimate is a *statistic*.\n* Bootstrap sample: a sample drawn with replacement from the Empirical\n  Distribution, having size equal to the size of the original dataset.\n* Standard Error: the square root of the variance of a statistic,\n  typically used to quantify accuracy.\n* Bias: the difference between the expected value of a statistic and\n  the parameter it purports to estimate.\n* Confidence Interval: a range of plausible values of a parameter\n  consistent with the data.\n\n## Examples\nThis library includes some datasets that can be used for trying out\nmethods. The test cases themselves (in `tests/`) contain many\npractical examples.\n\n```\n>>> import numpy as np\n>>> from bootstrap_stat import bootstrap_stat as bp\n>>> from bootstrap_stat import datasets as d\n>>>\n>>> df = d.law_data()\n>>> print(df)\n    LSAT   GPA\n0    576  3.39\n1    635  3.30\n2    558  2.81\n3    578  3.03\n4    666  3.44\n5    580  3.07\n6    555  3.00\n7    661  3.43\n8    651  3.36\n9    605  3.13\n10   653  3.12\n11   575  2.74\n12   545  2.76\n13   572  2.88\n14   594  2.96\n```\n\nThe law data are a collection of N = 82 American law schools\nparticipating in a large study of admissions practices. Two\nmeasurements were made on the entering classes of each school in 1973:\nLSAT, the average score for the class on a national law test, and GPA,\nthe average undergraduate grade-point average for the class. Both the\nfull data set, and a sample are available. The above is a sample of 15\nschools. The law data are taken from [EF93].\n\nSuppose we are interested in the correlation between LSAT and\nGPA. Numpy can be used to compute the observed correlation for the\nsample (a *statistic*), but we hope to draw inferences about the\npopulation (all 82 schools) correlation coefficient (a *parameter*)\nbased just on the sample. In this case, the entire population is\navailable, and we could just compute the parameter directly. In most\ncases, the entire population is not available.\n\nTo use the bootrap method, we need to specify the statistic as well as\nthe dataset. Specifically, we need to be able to sample with\nreplacement from the Empirical Distribution. `bootstrap_stat` has a class\nfacilitating just that.\n\n```\n>>> dist = bp.EmpiricalDistribution(df)\n>>> dist.sample(reset_index=False)\n    LSAT   GPA\n14   594  2.96\n3    578  3.03\n0    576  3.39\n6    555  3.00\n10   653  3.12\n12   545  2.76\n6    555  3.00\n0    576  3.39\n10   653  3.12\n8    651  3.36\n3    578  3.03\n4    666  3.44\n13   572  2.88\n5    580  3.07\n8    651  3.36\n```\n\nGenerating the Empirical Distribution is as simple as feeding either\nan array, pandas Series, or pandas DataFrame into the\nconstructor. Under the hood, the bootstrap methods make frequent use\nof the `sample` method, which samples with replacement from the\noriginal dataset. Such samples are called *bootstrap samples*. Notice\nin the example above how school 0 makes multiple appearances in the\nbootstrap sample. Since the sampling is random, if you run the above\nyou will likely get different results than in this example. (In some\nof the more exotic use cases, we need to reset the index for technical\nreasons relating to pandas indexing, so the default behavior is to\nreset, hence the `reset_index=False` in this example.)\n\nNext we need to implement the statistic, which will be applied to\nbootstrap samples.\n\n```\n>>> def statistic(df):\n...     return np.corrcoef(df["LSAT"], df["GPA"])[0, 1]\n...\n>>> obs_correlation = statistic(df)  # Observed correlation coefficient\n>>> print(obs_correlation)\n0.776374491289407\n```\n\nNotice how we can apply the statistic to the original dataset to\ncalculate the observed value. The statistic should take as input\neither an array or a pandas Series or DataFrame, whatever was used to\ngenerate the Empirical Distribution. It should output a single\nnumber. Other than that, it can be anything: a simple calculation like\na mean, a parameter from a linear regression model, or even a\nprediction from a neural network.\n\nNow we can compute the standard error, which is a way of quantifying\nthe variability of a statistic:\n\n```\n>>> se = bp.standard_error(dist, statistic)\n>>> print(se)\n0.13826565276176475\n```\n\nSince the bootstrap involves random sampling, you will likely get a\nslightly different answer than above, but it should be within 1% or\nso.\n\nOr we can compute a confidence interval, a range of plausible values\nfor the parameter consistent with the data.\n\n```\n>>> ci_low, ci_high = bp.bcanon_interval(dist, statistic, df)\n>>> print(ci_low, ci_high)\n0.44968698948896413 0.9230026418265834\n```\n\nThese represent lower and upper bounds on a 90% confidence interval,\nthe default behavior of `bcanon_interval`. We can do a 95% confidence\ninterval by specifying `alpha`:\n\n```\n>>> ci_low, ci_high = bp.bcanon_interval(dist, statistic, df, alpha=0.025)\n>>> print(ci_low, ci_high)\n0.3120414479586675 0.9425059323691073\n```\n\nIn general, `bcanon_interval` returns a 100(1-2`alpha`)% confidence\ninterval. The `bcanon` terminology is a nod to the S implementation\ndiscussed in [ETF93]. (BCa is an algorithm for Bias-Corrected and\nAccelerated confidence intervals, and the function is NONparametric.)\n\nBasic multicore functionality is implemented, allowing parallel\ncalculation of bootstrap samples. Simply specify the `num_threads`\nargument in applicable functions. See the function documentation for\ndetails.\n\n\n## Running the test cases\n\n```\n$ poetry shell\n$ python -m pytest\n```\n\n## Documentation\nDocumentation is built using Sphinx and is hosted at\n[Convex Analytics](https://www.convexanalytics.com/bootstrap-stat/index.html).\n\nTo update the docs (e.g. after updating the code), just change\ndirectory to `docs` and type `make html`. You\'ll need to be in a\npoetry shell.\n\n## Architecture\nWe use Poetry to manage dependencies, pytest as our test runner, black\nfor code formatting, and sphinx for generating documentation.\n\nBasic multicore functionality is implemented, using the\n[pathos](https://pathos.readthedocs.io/en/latest/) version of\nmultiprocessing. We chose this version over the official python\nmultiprocessing library since pathos uses `dill` instead of `pickle`\nto manage shared memory, and `pickle` cannot be used with locally\ndefined functions. For users of this library, hopefully that\nimplementation detail is irrelevant.\n\n## Licensing\nBootstrap-Stat is licensed under the Apache License, Version 2.0. See\n`LICENSE.txt` for the full license text.\n\n## References\n\n[ET93] Bradley Efron and Robert J. Tibshirani, "An Introduction to the\n       Bootstrap". Chapman & Hall, 1993.\n',
    'author': 'Bob Wilson',
    'author_email': 'bob@convexanalytics.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': None,
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.6',
}


setup(**setup_kwargs)
