Skip to main content

bootstrap_ht/
prelude.rs

1// Copyright (c) 2022. Sebastien Soudan
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http:www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Bootstrap Hypothesis Testing
16//!
17//! In cases, where we have no idea what the distribution of the test statistic is, we
18//! still want to be able to perform hypothesis tests and we are willing to make the
19//! hypothesis that the samples we have are representative of the population.
20//!
21//! This is where the bootstrap hypothesis testing comes in. The idea is to generate a
22//! large number of samples from the null distribution (distribution the samples would
23//! have if H0 is true - i.e. if both samples are from the same population) and then
24//! compute the test statistic for each of these samples. This gives a test statistics
25//! sampling distribution under H0.
26//!
27//! We can then compute the p-value by counting the number of times the sampled test
28//! statistic is more 'extreme' than the test statistic for our initial samples.
29//!
30//! # References
31//! - [Bootstrap Hypothesis Testing](https://en.wikipedia.org/wiki/Bootstrapping_(statistics)#Bootstrap_hypothesis_testing)
32//! - [P-value](https://en.wikipedia.org/wiki/P-value)
33//! - [Stats 102A Lesson 9-2 Bootstrap Hypothesis Tests, Miles Chen](https://www.youtube.com/watch?v=s7do_F9LV-w)
34//!
35//! # Example
36//!
37//! ```rust
38//! use bootstrap_ht::prelude::bootstrap::{two_samples_non_parametric_ht, PValueType};
39//! use itertools::Itertools;
40//! use rand::prelude::Distribution;
41//! use rand::SeedableRng;
42//! use rand_chacha::ChaCha8Rng;
43//! use rand_distr::StandardNormal;
44//!
45//! let mut rng = &mut ChaCha8Rng::seed_from_u64(42);
46//!
47//! let a = StandardNormal
48//!     .sample_iter(&mut rng)
49//!     .take(100)
50//!     .collect::<Vec<f64>>();
51//! let b = StandardNormal
52//!     .sample_iter(&mut rng)
53//!     .take(100)
54//!     .map(|x: f64| x + 0.7)
55//!     .collect::<Vec<f64>>();
56//!
57//! // difference of the means
58//! let test_statistic_fn = |a: &[f64], b: &[f64]| {
59//!     let a_95percentile = a
60//!         .iter()
61//!         .sorted_by(|x, y| x.partial_cmp(y).unwrap())
62//!         .nth(95)
63//!         .unwrap();
64//!     let b_95percentile = b
65//!         .iter()
66//!         .sorted_by(|x, y| x.partial_cmp(y).unwrap())
67//!         .nth(95)
68//!         .unwrap();
69//!     (a_95percentile - b_95percentile).abs()
70//! };
71//!
72//! let p_value = two_samples_non_parametric_ht(
73//!     &mut rng,
74//!     &a,
75//!     &b,
76//!     test_statistic_fn,
77//!     PValueType::OneSidedRightTail,
78//!     10_000,
79//! )
80//! .unwrap();
81//! assert_eq!(p_value, 0.0236);
82//! // p_value is small enough to reject the null hypothesis that the 95-percentiles
83//! // are equal
84//! ```
85
86/// non-parametric bootstrap hypothesis test
87pub mod bootstrap {
88    pub use crate::bootstrap::{
89        one_sample_non_parametric_ht, two_samples_non_parametric_ht, PValueType,
90    };
91}