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}