From 61e3d15010277f634ad249902ded93ffbb9cc1da Mon Sep 17 00:00:00 2001 From: thomassargent30 Date: Mon, 23 Jun 2025 17:06:15 +0800 Subject: [PATCH 01/29] Tom's June 23 edits of two Wald lectures and rearranging order of lectures --- lectures/_toc.yml | 37 +- lectures/wald_friedman.md | 830 ++++++++++-------------------------- lectures/wald_friedman_2.md | 758 ++++++++++++++++++++++++++++++++ 3 files changed, 1006 insertions(+), 619 deletions(-) create mode 100644 lectures/wald_friedman_2.md diff --git a/lectures/_toc.yml b/lectures/_toc.yml index c64a7f344..4681e02d6 100644 --- a/lectures/_toc.yml +++ b/lectures/_toc.yml @@ -23,6 +23,23 @@ parts: - file: back_prop - file: rand_resp - file: util_rand_resp +- caption: Bayes Law + numbered: true + chapters: + - file: bayes_nonconj + - file: ar1_bayes + - file: ar1_turningpts +- caption: Statistics and Information + numbered: true + chapters: + - file: likelihood_ratio_process + - file: imp_sample + - file: wald_friedman + - file: wald_friedman_2 + - file: exchangeable + - file: likelihood_bayes + - file: mix_model + - file: navy_captain - caption: Linear Programming numbered: true chapters: @@ -49,6 +66,7 @@ parts: - file: career - file: jv - file: mccall_q + - file: odu - caption: Consumption, Savings and Capital numbered: true chapters: @@ -64,25 +82,6 @@ parts: - file: egm_policy_iter - file: ifp - file: ifp_advanced - -- caption: Bayes Law - numbered: true - chapters: - - file: bayes_nonconj - - file: ar1_bayes - - file: ar1_turningpts - -- caption: Information - numbered: true - chapters: - - file: odu - - file: likelihood_ratio_process - - file: imp_sample - - file: wald_friedman - - file: exchangeable - - file: likelihood_bayes - - file: mix_model - - file: navy_captain - caption: LQ Control numbered: true chapters: diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 48a751fa4..ed29ab4d5 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -40,12 +40,10 @@ the U.S. Government's Statistical Research Group at Columbia University. This problem led Abraham Wald {cite}`Wald47` to formulate **sequential analysis**, an approach to statistical decision problems intimately related to dynamic programming. -In this lecture, we apply dynamic programming algorithms to Friedman and Wallis and Wald's problem. +In this lecture, we describe elements of Wald's formulation of the problem. Key ideas in play will be: -- Bayes' Law -- Dynamic programming - Type I and type II statistical errors - a type I error occurs when you reject a null hypothesis that is true - a type II error occures when you accept a null hypothesis that is false @@ -64,8 +62,7 @@ from numba.experimental import jitclass from math import gamma ``` -This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `. -and {doc}`this lecture `. +This lecture uses ideas studied in {doc}`this lecture ` and {doc}`this lecture `. ## Origin of the Problem @@ -112,66 +109,176 @@ they were not able to solve it, described the problem to Abraham Wald. That started Wald on the path that led him to *Sequential Analysis* {cite}`Wald47`. -We'll formulate the problem using dynamic programming. -## A Dynamic Programming Approach -The following presentation of the problem closely follows Dmitri -Berskekas's treatment in **Dynamic Programming and Stochastic Control** {cite}`Bertekas75`. +## Neyman-Pearson Formulation -A decision-maker can observe a sequence of draws of a random variable $z$. +It is useful to begin by describing the theory underlying the test +that Navy Captain G. S. Schuyler had been told to use and that led him +to approach Milton Friedman and Allan Wallis to convey his conjecture +that superior practical procedures existed. -He (or she) wants to know which of two probability distributions $f_0$ or $f_1$ governs $z$. +Evidently, the Navy had told Captail Schuyler to use what was then the state-of-the-art +Neyman-Pearson test. -Conditional on knowing that successive observations are drawn from distribution $f_0$, the sequence of -random variables is independently and identically distributed (IID). +We'll rely on Abraham Wald's {cite}`Wald47` elegant summary of Neyman-Pearson theory. -Conditional on knowing that successive observations are drawn from distribution $f_1$, the sequence of -random variables is also independently and identically distributed (IID). +Watch for these features of the setup: -But the observer does not know which of the two distributions generated the sequence. +- the assumption of a *fixed* sample size $n$ +- the application of laws of large numbers, conditioned on alternative + probability models, to interpret the probabilities $\alpha$ and + $\beta$ defined in the Neyman-Pearson theory -For reasons explained in [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html), this means that the sequence is not -IID. -The observer has something to learn, namely, whether the observations are drawn from $f_0$ or from $f_1$. +In chapter 1 of **Sequential Analysis** {cite}`Wald47` Abraham Wald summarizes the +Neyman-Pearson approach to hypothesis testing. -The decision maker wants to decide -which of the two distributions is generating outcomes. +Wald frames the problem as making a decision about a probability +distribution that is partially known. -We adopt a Bayesian formulation. +(You have to assume that *something* is already known in order to state a well-posed +problem -- usually, *something* means *a lot*) -The decision maker begins with a prior probability +By limiting what is unknown, Wald uses the following simple structure +to illustrate the main ideas: -$$ -\pi_{-1} = -\mathbb P \{ f = f_0 \mid \textrm{ no observations} \} \in (0, 1) -$$ +- A decision-maker wants to decide which of two distributions + $f_0$, $f_1$ govern an IID random variable $z$. +- The null hypothesis $H_0$ is the statement that $f_0$ + governs the data. +- The alternative hypothesis $H_1$ is the statement that + $f_1$ governs the data. +- The problem is to devise and analyze a test of hypothesis + $H_0$ against the alternative hypothesis $H_1$ on the + basis of a sample of a fixed number $n$ independent + observations $z_1, z_2, \ldots, z_n$ of the random variable + $z$. -After observing $k+1$ observations $z_k, z_{k-1}, \ldots, z_0$, he updates his personal probability that the observations are described by distribution $f_0$ to +To quote Abraham Wald, -$$ -\pi_k = \mathbb P \{ f = f_0 \mid z_k, z_{k-1}, \ldots, z_0 \} -$$ +> A test procedure leading to the acceptance or rejection of the [null] +> hypothesis in question is simply a rule specifying, for each possible +> sample of size $n$, whether the [null] hypothesis should be accepted +> or rejected on the basis of the sample. This may also be expressed as +> follows: A test procedure is simply a subdivision of the totality of +> all possible samples of size $n$ into two mutually exclusive +> parts, say part 1 and part 2, together with the application of the +> rule that the [null] hypothesis be accepted if the observed sample is +> contained in part 2. Part 1 is also called the critical region. Since +> part 2 is the totality of all samples of size $n$ which are not +> included in part 1, part 2 is uniquely determined by part 1. Thus, +> choosing a test procedure is equivalent to determining a critical +> region. -which is calculated recursively by applying Bayes' law: +Let's listen to Wald longer: -$$ -\pi_{k+1} = \frac{ \pi_k f_0(z_{k+1})}{ \pi_k f_0(z_{k+1}) + (1-\pi_k) f_1 (z_{k+1}) }, -\quad k = -1, 0, 1, \ldots -$$ +> As a basis for choosing among critical regions the following +> considerations have been advanced by Neyman and Pearson: In accepting +> or rejecting $H_0$ we may commit errors of two kinds. We commit +> an error of the first kind if we reject $H_0$ when it is true; +> we commit an error of the second kind if we accept $H_0$ when +> $H_1$ is true. After a particular critical region $W$ has +> been chosen, the probability of committing an error of the first +> kind, as well as the probability of committing an error of the second +> kind is uniquely determined. The probability of committing an error +> of the first kind is equal to the probability, determined by the +> assumption that $H_0$ is true, that the observed sample will be +> included in the critical region $W$. The probability of +> committing an error of the second kind is equal to the probability, +> determined on the assumption that $H_1$ is true, that the +> probability will fall outside the critical region $W$. For any +> given critical region $W$ we shall denote the probability of an +> error of the first kind by $\alpha$ and the probability of an +> error of the second kind by $\beta$. -After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker believes -that $z_{k+1}$ has probability distribution +Let's listen carefully to how Wald applies law of large numbers to +interpret $\alpha$ and $\beta$: -$$ -f_{{\pi}_k} (v) = \pi_k f_0(v) + (1-\pi_k) f_1 (v) , -$$ +> The probabilities $\alpha$ and $\beta$ have the +> following important practical interpretation: Suppose that we draw a +> large number of samples of size $n$. Let $M$ be the +> number of such samples drawn. Suppose that for each of these +> $M$ samples we reject $H_0$ if the sample is included in +> $W$ and accept $H_0$ if the sample lies outside +> $W$. In this way we make $M$ statements of rejection or +> acceptance. Some of these statements will in general be wrong. If +> $H_0$ is true and if $M$ is large, the probability is +> nearly $1$ (i.e., it is practically certain) that the +> proportion of wrong statements (i.e., the number of wrong statements +> divided by $M$) will be approximately $\alpha$. If +> $H_1$ is true, the probability is nearly $1$ that the +> proportion of wrong statements will be approximately $\beta$. +> Thus, we can say that in the long run [ here Wald applies law of +> large numbers by driving $M \rightarrow \infty$ (our comment, +> not Wald's) ] the proportion of wrong statements will be +> $\alpha$ if $H_0$is true and $\beta$ if +> $H_1$ is true. + +The quantity $\alpha$ is called the *size* of the critical region, +and the quantity $1-\beta$ is called the *power* of the critical +region. + +Wald notes that + +> one critical region $W$ is more desirable than another if it +> has smaller values of $\alpha$ and $\beta$. Although +> either $\alpha$ or $\beta$ can be made arbitrarily small +> by a proper choice of the critical region $W$, it is possible +> to make both $\alpha$ and $\beta$ arbitrarily small for a +> fixed value of $n$, i.e., a fixed sample size. + +Wald summarizes Neyman and Pearson's setup as follows: + +> Neyman and Pearson show that a region consisting of all samples +> $(z_1, z_2, \ldots, z_n)$ which satisfy the inequality +> +> $$ + \frac{ f_1(z_1) \cdots f_1(z_n)}{f_0(z_1) \cdots f_0(z_n)} \geq k + $$ +> +> is a most powerful critical region for testing the hypothesis +> $H_0$ against the alternative hypothesis $H_1$. The term +> $k$ on the right side is a constant chosen so that the region +> will have the required size $\alpha$. + +Wald goes on to discuss Neyman and Pearson's concept of *uniformly most +powerful* test. + +Here is how Wald introduces the notion of a sequential test + +> A rule is given for making one of the following three decisions at any stage of +> the experiment (at the m th trial for each integral value of m ): (1) to +> accept the hypothesis H , (2) to reject the hypothesis H , (3) to +> continue the experiment by making an additional observation. Thus, such +> a test procedure is carried out sequentially. On the basis of the first +> observation, one of the aforementioned decision is made. If the first or +> second decision is made, the process is terminated. If the third +> decision is made, a second trial is performed. Again, on the basis of +> the first two observations, one of the three decision is made. If the +> third decision is made, a third trial is performed, and so on. The +> process is continued until either the first or the second decisions is +> made. The number n of observations required by such a test procedure is +> a random variable, since the value of n depends on the outcome of the +> observations. + +## Wald's sequential formulation + +In contradistinction to Neyman-Pearson formulation of the problemm, in Wald's formulation -which is a mixture of distributions $f_0$ and $f_1$, with the weight -on $f_0$ being the posterior probability that $f = f_0$ [^f1]. -To illustrate such a distribution, let's inspect some mixtures of beta distributions. +- The sample size $n$ is not fixed but rather an object to be + chosen; technically $n$ is a random variable. +- Two parameters $A$ and $B$ that are related to but distinct from Neyman and Pearson's $\alpha$ and $\beta$, characterize cut-off rules that Wald uses to determine the random variable $n$. + +Here is how Wald sets up the problem. + +A decision-maker can observe a sequence of draws of a random variable $z$. + +He (or she) wants to know which of two probability distributions $f_0$ or $f_1$ governs $z$. + + +To illustrate, let's inspect some beta distributions. The density of a beta probability distribution with parameters $a$ and $b$ is @@ -181,9 +288,16 @@ f(z; a, b) = \frac{\Gamma(a+b) z^{a-1} (1-z)^{b-1}}{\Gamma(a) \Gamma(b)} \Gamma(t) := \int_{0}^{\infty} x^{t-1} e^{-x} dx $$ -The next figure shows two beta distributions in the top panel. +The next figure shows two beta distributions. + +## Request for Humphrey. + +The bottom panel presents mixtures of these distributions, with various mixing probabilities $\pi_k$ -- +that is inherited from the Bayesian lecture. -The bottom panel presents mixtures of these distributions, with various mixing probabilities $\pi_k$ +Please remove the bottom panel and just leave the top panel. + +This is the end of the "message" ```{code-cell} ipython3 @jit @@ -214,417 +328,128 @@ plt.tight_layout() plt.show() ``` -### Losses and Costs - -After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker -chooses among three distinct actions: +Conditional on knowing that successive observations are drawn from distribution $f_0$, the sequence of +random variables is independently and identically distributed (IID). -- He decides that $f = f_0$ and draws no more $z$'s -- He decides that $f = f_1$ and draws no more $z$'s -- He postpones deciding now and instead chooses to draw a - $z_{k+1}$ +Conditional on knowing that successive observations are drawn from distribution $f_1$, the sequence of +random variables is also independently and identically distributed (IID). -Associated with these three actions, the decision-maker can suffer three -kinds of losses: +But the observer does not know which of the two distributions generated the sequence. -- A loss $L_0$ if he decides $f = f_0$ when actually - $f=f_1$ -- A loss $L_1$ if he decides $f = f_1$ when actually - $f=f_0$ -- A cost $c$ if he postpones deciding and chooses instead to draw - another $z$ +For reasons explained in [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html), this means that the sequence is not +IID. -### Digression on Type I and Type II Errors +The observer has something to learn, namely, whether the observations are drawn from $f_0$ or from $f_1$. -If we regard $f=f_0$ as a null hypothesis and $f=f_1$ as an alternative hypothesis, -then $L_1$ and $L_0$ are losses associated with two types of statistical errors +The decision maker wants to decide which of the two distributions is generating outcomes. -- a type I error is an incorrect rejection of a true null hypothesis (a "false positive") -- a type II error is a failure to reject a false null hypothesis (a "false negative") -So when we treat $f=f_0$ as the null hypothesis -- We can think of $L_1$ as the loss associated with a type I - error. -- We can think of $L_0$ as the loss associated with a type II - error. -### Intuition -Before proceeding, let's try to guess what an optimal decision rule might look like. +### Type I and Type II Errors -Suppose at some given point in time that $\pi$ is close to 1. +If we regard $f=f_0$ as a null hypothesis and $f=f_1$ as an alternative hypothesis, +then -Then our prior beliefs and the evidence so far point strongly to $f = f_0$. +- a type I error is an incorrect rejection of a true null hypothesis (a "false positive") +- a type II error is a failure to reject a false null hypothesis (a "false negative") -If, on the other hand, $\pi$ is close to 0, then $f = f_1$ is strongly favored. +To repeat ourselves -Finally, if $\pi$ is in the middle of the interval $[0, 1]$, then we are confronted with more uncertainty. +- $\alpha$ is the probability of a type I error +- $\beta$ is the probability of a type II error -This reasoning suggests a decision rule such as the one shown in the figure +**note to Humphrey -- please leave the alpha and beta as they are in this section! -```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png +### Choices -``` +After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker +chooses among three distinct actions: -As we'll see, this is indeed the correct form of the decision rule. +- He decides that $f = f_0$ and draws no more $z$'s +- He decides that $f = f_1$ and draws no more $z$'s +- He postpones deciding now and instead chooses to draw a + $z_{k+1}$ -Our problem is to determine threshold values $\alpha, \beta$ that somehow depend on the parameters described above. -You might like to pause at this point and try to predict the impact of a -parameter such as $c$ or $L_0$ on $\alpha$ or $\beta$. +### Message to Humphrey -### A Bellman Equation +We want to redraw this figure with $A$ and $B$ replacing $\alpha$ and $\beta$. I suspect that we +used the notebook to generate the figure. -Let $J(\pi)$ be the total loss for a decision-maker with current belief $\pi$ who chooses optimally. -With some thought, you will agree that $J$ should satisfy the Bellman equation -```{math} -:label: new1 +```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png -J(\pi) = - \min - \left\{ - (1-\pi) L_0, \; \pi L_1, \; - c + \mathbb E [ J (\pi') ] - \right\} ``` -where $\pi'$ is the random variable defined by Bayes' Law - -$$ -\pi' = \kappa(z', \pi) = \frac{ \pi f_0(z')}{ \pi f_0(z') + (1-\pi) f_1 (z') } -$$ - -when $\pi$ is fixed and $z'$ is drawn from the current best guess, which is the distribution $f$ defined by - -$$ -f_{\pi}(v) = \pi f_0(v) + (1-\pi) f_1 (v) -$$ -In the Bellman equation, minimization is over three actions: -1. Accept the hypothesis that $f = f_0$ -1. Accept the hypothesis that $f = f_1$ -1. Postpone deciding and draw again -We can represent the Bellman equation as -```{math} -:label: optdec - -J(\pi) = -\min \left\{ (1-\pi) L_0, \; \pi L_1, \; h(\pi) \right\} -``` +Wald proceeds as follows. -where $\pi \in [0,1]$ and +He defines -- $(1-\pi) L_0$ is the expected loss associated with accepting - $f_0$ (i.e., the cost of making a type II error). -- $\pi L_1$ is the expected loss associated with accepting - $f_1$ (i.e., the cost of making a type I error). -- $h(\pi) := c + \mathbb E [J(\pi')]$; this is the continuation value; i.e., - the expected cost associated with drawing one more $z$. - -The optimal decision rule is characterized by two numbers $\alpha, \beta \in (0,1) \times (0,1)$ that satisfy - -$$ -(1- \pi) L_0 < \min \{ \pi L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq \alpha -$$ +- $p_{0m} = f_0(z_0) \cdots f_0(z_k)$ +- $p_{1m} = f_1(z_0) \cdots f_1(z_k)$ +- $L_{m} = \frac{p_{1m}}{p_{0m}}$ -and +Here $\{L_m\}_{m=0}^\infty$ is a **likelihood ratio process**. -$$ -\pi L_1 < \min \{ (1-\pi) L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq \beta -$$ +One of Wald's sequential decision rule is parameterized by two real numbers $B < A$. -The optimal decision rule is then +For a given pair $A, B$ the decision rule is $$ \begin{aligned} -\textrm { accept } f=f_0 \textrm{ if } \pi \geq \alpha \\ -\textrm { accept } f=f_1 \textrm{ if } \pi \leq \beta \\ -\textrm { draw another } z \textrm{ if } \beta \leq \pi \leq \alpha +\textrm { accept } f=f_0 \textrm{ if } L_m \geq A \\ +\textrm { accept } f=f_1 \textrm{ if } L_m \leq B \\ +\textrm { draw another } z \textrm{ if } B < L_m < A \end{aligned} $$ -Our aim is to compute the cost function $J$, and from it the associated cutoffs $\alpha$ -and $\beta$. - -To make our computations manageable, using {eq}`optdec`, we can write the continuation cost $h(\pi)$ as - -```{math} -:label: optdec2 - -\begin{aligned} -h(\pi) &= c + \mathbb E [J(\pi')] \\ -&= c + \mathbb E_{\pi'} \min \{ (1 - \pi') L_0, \pi' L_1, h(\pi') \} \\ -&= c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' -\end{aligned} -``` - -The equality - -```{math} -:label: funceq - -h(\pi) = -c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' -``` - -is a **functional equation** in an unknown function $h$. - -Using the functional equation, {eq}`funceq`, for the continuation cost, we can back out -optimal choices using the right side of {eq}`optdec`. +### Links between $A,B$ and $\alpha, \beta$ -This functional equation can be solved by taking an initial guess and iterating -to find a fixed point. +In chapter 3 of **Sequential Analysis** {cite}`Wald47` Wald establishes the inequalities -Thus, we iterate with an operator $Q$, where - -$$ -Q h(\pi) = -c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' +$$ +\begin{align} + \frac{\alpha}{1 -\beta} & \leq \frac{1}{A} \\ + \frac{\beta}{1 - \alpha} & \leq B +\end{align} $$ -## Implementation - -First, we will construct a `jitclass` to store the parameters of the model - -```{code-cell} ipython3 -wf_data = [('a0', float64), # Parameters of beta distributions - ('b0', float64), - ('a1', float64), - ('b1', float64), - ('c', float64), # Cost of another draw - ('π_grid_size', int64), - ('L0', float64), # Cost of selecting f0 when f1 is true - ('L1', float64), # Cost of selecting f1 when f0 is true - ('π_grid', float64[:]), - ('mc_size', int64), - ('z0', float64[:]), - ('z1', float64[:])] -``` - -```{code-cell} ipython3 -@jitclass(wf_data) -class WaldFriedman: - - def __init__(self, - c=1.25, - a0=1, - b0=1, - a1=3, - b1=1.2, - L0=25, - L1=25, - π_grid_size=200, - mc_size=1000): - - self.a0, self.b0 = a0, b0 - self.a1, self.b1 = a1, b1 - self.c, self.π_grid_size = c, π_grid_size - self.L0, self.L1 = L0, L1 - self.π_grid = np.linspace(0, 1, π_grid_size) - self.mc_size = mc_size - - self.z0 = np.random.beta(a0, b0, mc_size) - self.z1 = np.random.beta(a1, b1, mc_size) - - def f0(self, x): - - return p(x, self.a0, self.b0) - - def f1(self, x): +His analysis of these inequalities leads Wald to recommend the following as rules for setting +$A$ and $B$ that come close to attaining a decision maker's target values for probabilities $\alpha$ of +a type I and $\beta$ of a type II error: - return p(x, self.a1, self.b1) - - def f0_rvs(self): - return np.random.beta(self.a0, self.b0) - - def f1_rvs(self): - return np.random.beta(self.a1, self.b1) - - def κ(self, z, π): - """ - Updates π using Bayes' rule and the current observation z - """ - - f0, f1 = self.f0, self.f1 - - π_f0, π_f1 = π * f0(z), (1 - π) * f1(z) - π_new = π_f0 / (π_f0 + π_f1) - - return π_new -``` - -As in the {doc}`optimal growth lecture `, to approximate a continuous value function - -* We iterate at a finite grid of possible values of $\pi$. -* When we evaluate $\mathbb E[J(\pi')]$ between grid points, we use linear interpolation. - -We define the operator function `Q` below. - -```{code-cell} ipython3 -@jit(nopython=True, parallel=True) -def Q(h, wf): - - c, π_grid = wf.c, wf.π_grid - L0, L1 = wf.L0, wf.L1 - z0, z1 = wf.z0, wf.z1 - mc_size = wf.mc_size - - κ = wf.κ - - h_new = np.empty_like(π_grid) - h_func = lambda p: np.interp(p, π_grid, h) - - for i in prange(len(π_grid)): - π = π_grid[i] - - # Find the expected value of J by integrating over z - integral_f0, integral_f1 = 0, 0 - for m in range(mc_size): - π_0 = κ(z0[m], π) # Draw z from f0 and update π - integral_f0 += min((1 - π_0) * L0, π_0 * L1, h_func(π_0)) - - π_1 = κ(z1[m], π) # Draw z from f1 and update π - integral_f1 += min((1 - π_1) * L0, π_1 * L1, h_func(π_1)) - - integral = (π * integral_f0 + (1 - π) * integral_f1) / mc_size - - h_new[i] = c + integral - - return h_new -``` - -To solve the key functional equation, we will iterate using `Q` to find the fixed point - -```{code-cell} ipython3 -@jit -def solve_model(wf, tol=1e-4, max_iter=1000): - """ - Compute the continuation cost function - - * wf is an instance of WaldFriedman - """ - - # Set up loop - h = np.zeros(len(wf.π_grid)) - i = 0 - error = tol + 1 - - while i < max_iter and error > tol: - h_new = Q(h, wf) - error = np.max(np.abs(h - h_new)) - i += 1 - h = h_new - - if error > tol: - print("Failed to converge!") - - return h_new -``` - -## Analysis - -Let's inspect outcomes. - -We will be using the default parameterization with distributions like so - -```{code-cell} ipython3 -wf = WaldFriedman() - -fig, ax = plt.subplots(figsize=(10, 6)) -ax.plot(wf.f0(wf.π_grid), label="$f_0$") -ax.plot(wf.f1(wf.π_grid), label="$f_1$") -ax.set(ylabel="probability of $z_k$", xlabel="$z_k$", title="Distributions") -ax.legend() - -plt.show() -``` - -### Value Function - -To solve the model, we will call our `solve_model` function - -```{code-cell} ipython3 -h_star = solve_model(wf) # Solve the model -``` - -We will also set up a function to compute the cutoffs $\alpha$ and $\beta$ -and plot these on our cost function plot - -```{code-cell} ipython3 -@jit -def find_cutoff_rule(wf, h): - - """ - This function takes a continuation cost function and returns the - corresponding cutoffs of where you transition between continuing and - choosing a specific model - """ - - π_grid = wf.π_grid - L0, L1 = wf.L0, wf.L1 - - # Evaluate cost at all points on grid for choosing a model - payoff_f0 = (1 - π_grid) * L0 - payoff_f1 = π_grid * L1 - - # The cutoff points can be found by differencing these costs with - # The Bellman equation (J is always less than or equal to p_c_i) - β = π_grid[np.searchsorted( - payoff_f1 - np.minimum(h, payoff_f0), - 1e-10) - - 1] - α = π_grid[np.searchsorted( - np.minimum(h, payoff_f1) - payoff_f0, - 1e-10) - - 1] - - return (β, α) - -β, α = find_cutoff_rule(wf, h_star) -cost_L0 = (1 - wf.π_grid) * wf.L0 -cost_L1 = wf.π_grid * wf.L1 - -fig, ax = plt.subplots(figsize=(10, 6)) +$$ +\begin{align} +A(\alpha,\beta) & = \frac{1-\beta}{\alpha} \\ +B(\alpha,\beta) & = \frac{\beta}{1-\alpha} +\end{align} +$$ (eq:Waldrule) -ax.plot(wf.π_grid, h_star, label='sample again') -ax.plot(wf.π_grid, cost_L1, label='choose f1') -ax.plot(wf.π_grid, cost_L0, label='choose f0') -ax.plot(wf.π_grid, - np.amin(np.column_stack([h_star, cost_L0, cost_L1]),axis=1), - lw=15, alpha=0.1, color='b', label=r'$J(\pi)$') + For small values of $\alpha $ and $\beta$, Wald shows that {eq}`eq:Waldrule` provides good ways to set $A$ and $B$. -ax.annotate(r"$\beta$", xy=(β + 0.01, 0.5), fontsize=14) -ax.annotate(r"$\alpha$", xy=(α + 0.01, 0.5), fontsize=14) -plt.vlines(β, 0, β * wf.L0, linestyle="--") -plt.vlines(α, 0, (1 - α) * wf.L1, linestyle="--") +## Message to Humphrey -ax.set(xlim=(0, 1), ylim=(0, 0.5 * max(wf.L0, wf.L1)), ylabel="cost", - xlabel=r"$\pi$", title="Cost function $J(\pi)$") +I want drastically to edit the following section. We want instead to create some examples along the following lines. -plt.legend(borderpad=1.1) -plt.show() -``` +- we'll set a pair of target $\alpha, \beta$ (size, power parameters) +- we'll use formulas {eq}`eq:Waldrule` for $A(\alpha,\beta), B(\alpha, \beta)$ +- we'll set beta distributions for $f_1$ and $f_2$ that have lots of overlap and are more or less challenging to distinguish. +- we'll then simulate Wald's decision rule and generate distributions of + - stopping times $n$ + - probabilities of making type I and type II errors that we'll compare with our target $\alpha, \beta$ -The cost function $J$ equals $\pi L_1$ for $\pi \leq \beta$, and $(1-\pi )L_0$ for $\pi -\geq \alpha$. +I welcome your suggestions for improvements and more interesting experiments. -The slopes of the two linear pieces of the cost function $J(\pi)$ are determined by $L_1$ -and $- L_0$. +## Simulations -The cost function $J$ is smooth in the interior region, where the posterior -probability assigned to $f_0$ is in the indecisive region $\pi \in (\beta, \alpha)$. - -The decision-maker continues to sample until the probability that he attaches to -model $f_0$ falls below $\beta$ or above $\alpha$. - -### Simulations The next figure shows the outcomes of 500 simulations of the decision process. @@ -729,213 +554,18 @@ def simulation_plot(wf): simulation_plot(wf) ``` -### Comparative Statics - -Now let's consider the following exercise. - -We double the cost of drawing an additional observation. - -Before you look, think about what will happen: - -- Will the decision-maker be correct more or less often? -- Will he make decisions sooner or later? - -```{code-cell} ipython3 -wf = WaldFriedman(c=2.5) -simulation_plot(wf) -``` - -Increased cost per draw has induced the decision-maker to take fewer draws before deciding. - -Because he decides with fewer draws, the percentage of time he is correct drops. - -This leads to him having a higher expected loss when he puts equal weight on both models. - -### A Notebook Implementation - -To facilitate comparative statics, we provide -a [Jupyter notebook](https://nbviewer.org/github/QuantEcon/lecture-python.notebooks/blob/main/wald_friedman.ipynb) that -generates the same plots, but with sliders. - -With these sliders, you can adjust parameters and immediately observe - -* effects on the smoothness of the value function in the indecisive middle range - as we increase the number of grid points in the piecewise linear approximation. -* effects of different settings for the cost parameters $L_0, L_1, c$, the - parameters of two beta distributions $f_0$ and $f_1$, and the number - of points and linear functions $m$ to use in the piece-wise continuous approximation to the value function. -* various simulations from $f_0$ and associated distributions of waiting times to making a decision. -* associated histograms of correct and incorrect decisions. - -## Comparison with Neyman-Pearson Formulation - -For several reasons, it is useful to describe the theory underlying the test -that Navy Captain G. S. Schuyler had been told to use and that led him -to approach Milton Friedman and Allan Wallis to convey his conjecture -that superior practical procedures existed. - -Evidently, the Navy had told -Captail Schuyler to use what it knew to be a state-of-the-art -Neyman-Pearson test. - -We'll rely on Abraham Wald's {cite}`Wald47` elegant summary of Neyman-Pearson theory. -For our purposes, watch for there features of the setup: -- the assumption of a *fixed* sample size $n$ -- the application of laws of large numbers, conditioned on alternative - probability models, to interpret the probabilities $\alpha$ and - $\beta$ defined in the Neyman-Pearson theory - -Recall that in the sequential analytic formulation above, that - -- The sample size $n$ is not fixed but rather an object to be - chosen; technically $n$ is a random variable. -- The parameters $\beta$ and $\alpha$ characterize cut-off - rules used to determine $n$ as a random variable. -- Laws of large numbers make no appearances in the sequential - construction. - -In chapter 1 of **Sequential Analysis** {cite}`Wald47` Abraham Wald summarizes the -Neyman-Pearson approach to hypothesis testing. - -Wald frames the problem as making a decision about a probability -distribution that is partially known. - -(You have to assume that *something* is already known in order to state a well-posed -problem -- usually, *something* means *a lot*) - -By limiting what is unknown, Wald uses the following simple structure -to illustrate the main ideas: - -- A decision-maker wants to decide which of two distributions - $f_0$, $f_1$ govern an IID random variable $z$. -- The null hypothesis $H_0$ is the statement that $f_0$ - governs the data. -- The alternative hypothesis $H_1$ is the statement that - $f_1$ governs the data. -- The problem is to devise and analyze a test of hypothesis - $H_0$ against the alternative hypothesis $H_1$ on the - basis of a sample of a fixed number $n$ independent - observations $z_1, z_2, \ldots, z_n$ of the random variable - $z$. - -To quote Abraham Wald, - -> A test procedure leading to the acceptance or rejection of the [null] -> hypothesis in question is simply a rule specifying, for each possible -> sample of size $n$, whether the [null] hypothesis should be accepted -> or rejected on the basis of the sample. This may also be expressed as -> follows: A test procedure is simply a subdivision of the totality of -> all possible samples of size $n$ into two mutually exclusive -> parts, say part 1 and part 2, together with the application of the -> rule that the [null] hypothesis be accepted if the observed sample is -> contained in part 2. Part 1 is also called the critical region. Since -> part 2 is the totality of all samples of size $n$ which are not -> included in part 1, part 2 is uniquely determined by part 1. Thus, -> choosing a test procedure is equivalent to determining a critical -> region. - -Let's listen to Wald longer: - -> As a basis for choosing among critical regions the following -> considerations have been advanced by Neyman and Pearson: In accepting -> or rejecting $H_0$ we may commit errors of two kinds. We commit -> an error of the first kind if we reject $H_0$ when it is true; -> we commit an error of the second kind if we accept $H_0$ when -> $H_1$ is true. After a particular critical region $W$ has -> been chosen, the probability of committing an error of the first -> kind, as well as the probability of committing an error of the second -> kind is uniquely determined. The probability of committing an error -> of the first kind is equal to the probability, determined by the -> assumption that $H_0$ is true, that the observed sample will be -> included in the critical region $W$. The probability of -> committing an error of the second kind is equal to the probability, -> determined on the assumption that $H_1$ is true, that the -> probability will fall outside the critical region $W$. For any -> given critical region $W$ we shall denote the probability of an -> error of the first kind by $\alpha$ and the probability of an -> error of the second kind by $\beta$. - -Let's listen carefully to how Wald applies law of large numbers to -interpret $\alpha$ and $\beta$: - -> The probabilities $\alpha$ and $\beta$ have the -> following important practical interpretation: Suppose that we draw a -> large number of samples of size $n$. Let $M$ be the -> number of such samples drawn. Suppose that for each of these -> $M$ samples we reject $H_0$ if the sample is included in -> $W$ and accept $H_0$ if the sample lies outside -> $W$. In this way we make $M$ statements of rejection or -> acceptance. Some of these statements will in general be wrong. If -> $H_0$ is true and if $M$ is large, the probability is -> nearly $1$ (i.e., it is practically certain) that the -> proportion of wrong statements (i.e., the number of wrong statements -> divided by $M$) will be approximately $\alpha$. If -> $H_1$ is true, the probability is nearly $1$ that the -> proportion of wrong statements will be approximately $\beta$. -> Thus, we can say that in the long run [ here Wald applies law of -> large numbers by driving $M \rightarrow \infty$ (our comment, -> not Wald's) ] the proportion of wrong statements will be -> $\alpha$ if $H_0$is true and $\beta$ if -> $H_1$ is true. - -The quantity $\alpha$ is called the *size* of the critical region, -and the quantity $1-\beta$ is called the *power* of the critical -region. - -Wald notes that - -> one critical region $W$ is more desirable than another if it -> has smaller values of $\alpha$ and $\beta$. Although -> either $\alpha$ or $\beta$ can be made arbitrarily small -> by a proper choice of the critical region $W$, it is possible -> to make both $\alpha$ and $\beta$ arbitrarily small for a -> fixed value of $n$, i.e., a fixed sample size. - -Wald summarizes Neyman and Pearson's setup as follows: - -> Neyman and Pearson show that a region consisting of all samples -> $(z_1, z_2, \ldots, z_n)$ which satisfy the inequality -> -> $$ - \frac{ f_1(z_1) \cdots f_1(z_n)}{f_0(z_1) \cdots f_0(z_n)} \geq k - $$ -> -> is a most powerful critical region for testing the hypothesis -> $H_0$ against the alternative hypothesis $H_1$. The term -> $k$ on the right side is a constant chosen so that the region -> will have the required size $\alpha$. - -Wald goes on to discuss Neyman and Pearson's concept of *uniformly most -powerful* test. - -Here is how Wald introduces the notion of a sequential test - -> A rule is given for making one of the following three decisions at any stage of -> the experiment (at the m th trial for each integral value of m ): (1) to -> accept the hypothesis H , (2) to reject the hypothesis H , (3) to -> continue the experiment by making an additional observation. Thus, such -> a test procedure is carried out sequentially. On the basis of the first -> observation, one of the aforementioned decision is made. If the first or -> second decision is made, the process is terminated. If the third -> decision is made, a second trial is performed. Again, on the basis of -> the first two observations, one of the three decision is made. If the -> third decision is made, a third trial is performed, and so on. The -> process is continued until either the first or the second decisions is -> made. The number n of observations required by such a test procedure is -> a random variable, since the value of n depends on the outcome of the -> observations. [^f1]: The decision maker acts as if he believes that the sequence of random variables $[z_{0}, z_{1}, \ldots]$ is *exchangeable*. See [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html) and {cite}`Kreps88` chapter 11, for discussions of exchangeability. -## Sequels +## Related lectures -We'll dig deeper into some of the ideas used here in the following lectures: +We'll dig deeper into some of the ideas used here in the following earlier and later lectures: * {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** -* {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule +* {doc}`this lecture ` takes up the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md new file mode 100644 index 000000000..0664cca8d --- /dev/null +++ b/lectures/wald_friedman_2.md @@ -0,0 +1,758 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.11.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +(wald_friedman_2)= +```{raw} jupyter + +``` + +# {index}`A Bayesian Formulation of Friedman's Problem ` + + + +```{index} single: Models; Sequential analysis +``` + +```{contents} Contents +:depth: 2 +``` + +## Overview + +This lecture revisits the statistical decision problem presented to Milton +Friedman and W. Allen Wallis during World War II when they were analysts at +the U.S. Government's Statistical Research Group at Columbia University. + +This problem led Abraham Wald {cite}`Wald47` to formulate **sequential analysis**, +an approach to statistical decision problems intimately related to dynamic programming. + +In this lecture, we apply dynamic programming algorithms to Friedman and Wallis and Wald's problem. + +In our previous lecture, key ideas in play were: + +- Type I and type II statistical errors + - a type I error occurs when you reject a null hypothesis that is true + - a type II error occures when you accept a null hypothesis that is false +- Abraham Wald's **sequential probability ratio test** +- The **power** of a statistical test +- The **critical region** of a statistical test +- A **uniformly most powerful test** + +In this lecture, additional key ideas are + +- Bayes' Law +- Dynamic programming + +We'll begin with some imports: + +```{code-cell} ipython3 +import numpy as np +import matplotlib.pyplot as plt +from numba import jit, prange, float64, int64 +from numba.experimental import jitclass +from math import gamma +``` + +This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `, and {doc}`this lecture `. + +We'll formulate the problem using dynamic programming. + +## Message/request for Humphrey + +Below in order to remove some bad recycling of notation, I ask you everywhre in the Dynamic programming presentation below please to + +* change $\alpha$ to $A$ +* change $\beta$ to $B$ + +However, if there are places where $\alpha$ is used to be the probability of a type I error +and $\beta$ is used to be the probability of a type II error, please don't change them. There might be a few such cases. + +This request applies to the + +* written text +* the graphs +* the Python code I suppose + +this is the end of the "message" + + +## A Dynamic Programming Approach + +The following presentation of the problem closely follows Dmitri +Berskekas's treatment in **Dynamic Programming and Stochastic Control** {cite}`Bertekas75`. + +A decision-maker can observe a sequence of draws of a random variable $z$. + +He (or she) wants to know which of two probability distributions $f_0$ or $f_1$ governs $z$. + +Conditional on knowing that successive observations are drawn from distribution $f_0$, the sequence of +random variables is independently and identically distributed (IID). + +Conditional on knowing that successive observations are drawn from distribution $f_1$, the sequence of +random variables is also independently and identically distributed (IID). + +But the observer does not know which of the two distributions generated the sequence. + +For reasons explained in [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html), this means that the sequence is not +IID. + +The observer has something to learn, namely, whether the observations are drawn from $f_0$ or from $f_1$. + +The decision maker wants to decide +which of the two distributions is generating outcomes. + +We adopt a Bayesian formulation. + +The decision maker begins with a prior probability + +$$ +\pi_{-1} = +\mathbb P \{ f = f_0 \mid \textrm{ no observations} \} \in (0, 1) +$$ + +After observing $k+1$ observations $z_k, z_{k-1}, \ldots, z_0$, he updates his personal probability that the observations are described by distribution $f_0$ to + +$$ +\pi_k = \mathbb P \{ f = f_0 \mid z_k, z_{k-1}, \ldots, z_0 \} +$$ + +which is calculated recursively by applying Bayes' law: + +$$ +\pi_{k+1} = \frac{ \pi_k f_0(z_{k+1})}{ \pi_k f_0(z_{k+1}) + (1-\pi_k) f_1 (z_{k+1}) }, +\quad k = -1, 0, 1, \ldots +$$ + +After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker believes +that $z_{k+1}$ has probability distribution + +$$ +f_{{\pi}_k} (v) = \pi_k f_0(v) + (1-\pi_k) f_1 (v) , +$$ + +which is a mixture of distributions $f_0$ and $f_1$, with the weight +on $f_0$ being the posterior probability that $f = f_0$ [^f1]. + +To illustrate such a distribution, let's inspect some mixtures of beta distributions. + +The density of a beta probability distribution with parameters $a$ and $b$ is + +$$ +f(z; a, b) = \frac{\Gamma(a+b) z^{a-1} (1-z)^{b-1}}{\Gamma(a) \Gamma(b)} +\quad \text{where} \quad +\Gamma(t) := \int_{0}^{\infty} x^{t-1} e^{-x} dx +$$ + +The next figure shows two beta distributions in the top panel. + +The bottom panel presents mixtures of these distributions, with various mixing probabilities $\pi_k$ + +```{code-cell} ipython3 +@jit +def p(x, a, b): + r = gamma(a + b) / (gamma(a) * gamma(b)) + return r * x**(a-1) * (1 - x)**(b-1) + +f0 = lambda x: p(x, 1, 1) +f1 = lambda x: p(x, 9, 9) +grid = np.linspace(0, 1, 50) + +fig, axes = plt.subplots(2, figsize=(10, 8)) + +axes[0].set_title("Original Distributions") +axes[0].plot(grid, f0(grid), lw=2, label="$f_0$") +axes[0].plot(grid, f1(grid), lw=2, label="$f_1$") + +axes[1].set_title("Mixtures") +for π in 0.25, 0.5, 0.75: + y = π * f0(grid) + (1 - π) * f1(grid) + axes[1].plot(y, lw=2, label=rf"$\pi_k$ = {π}") + +for ax in axes: + ax.legend() + ax.set(xlabel="$z$ values", ylabel="probability of $z_k$") + +plt.tight_layout() +plt.show() +``` + +### Losses and Costs + +After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker +chooses among three distinct actions: + +- He decides that $f = f_0$ and draws no more $z$'s +- He decides that $f = f_1$ and draws no more $z$'s +- He postpones deciding now and instead chooses to draw a + $z_{k+1}$ + +Associated with these three actions, the decision-maker can suffer three +kinds of losses: + +- A loss $L_0$ if he decides $f = f_0$ when actually + $f=f_1$ +- A loss $L_1$ if he decides $f = f_1$ when actually + $f=f_0$ +- A cost $c$ if he postpones deciding and chooses instead to draw + another $z$ + +### Digression on Type I and Type II Errors + +If we regard $f=f_0$ as a null hypothesis and $f=f_1$ as an alternative hypothesis, +then $L_1$ and $L_0$ are losses associated with two types of statistical errors + +- a type I error is an incorrect rejection of a true null hypothesis (a "false positive") +- a type II error is a failure to reject a false null hypothesis (a "false negative") + +So when we treat $f=f_0$ as the null hypothesis + +- We can think of $L_1$ as the loss associated with a type I + error. +- We can think of $L_0$ as the loss associated with a type II + error. + +### Intuition + +Before proceeding, let's try to guess what an optimal decision rule might look like. + +Suppose at some given point in time that $\pi$ is close to 1. + +Then our prior beliefs and the evidence so far point strongly to $f = f_0$. + +If, on the other hand, $\pi$ is close to 0, then $f = f_1$ is strongly favored. + +Finally, if $\pi$ is in the middle of the interval $[0, 1]$, then we are confronted with more uncertainty. + +This reasoning suggests a decision rule such as the one shown in the figure + +```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png + +``` + +As we'll see, this is indeed the correct form of the decision rule. + +Our problem is to determine threshold values $\alpha, \beta$ that somehow depend on the parameters described above. + +You might like to pause at this point and try to predict the impact of a +parameter such as $c$ or $L_0$ on $\alpha$ or $\beta$. + +### A Bellman Equation + +Let $J(\pi)$ be the total loss for a decision-maker with current belief $\pi$ who chooses optimally. + +With some thought, you will agree that $J$ should satisfy the Bellman equation + +```{math} +:label: new1 + +J(\pi) = + \min + \left\{ + (1-\pi) L_0, \; \pi L_1, \; + c + \mathbb E [ J (\pi') ] + \right\} +``` + +where $\pi'$ is the random variable defined by Bayes' Law + +$$ +\pi' = \kappa(z', \pi) = \frac{ \pi f_0(z')}{ \pi f_0(z') + (1-\pi) f_1 (z') } +$$ + +when $\pi$ is fixed and $z'$ is drawn from the current best guess, which is the distribution $f$ defined by + +$$ +f_{\pi}(v) = \pi f_0(v) + (1-\pi) f_1 (v) +$$ + +In the Bellman equation, minimization is over three actions: + +1. Accept the hypothesis that $f = f_0$ +1. Accept the hypothesis that $f = f_1$ +1. Postpone deciding and draw again + +We can represent the Bellman equation as + +```{math} +:label: optdec + +J(\pi) = +\min \left\{ (1-\pi) L_0, \; \pi L_1, \; h(\pi) \right\} +``` + +where $\pi \in [0,1]$ and + +- $(1-\pi) L_0$ is the expected loss associated with accepting + $f_0$ (i.e., the cost of making a type II error). +- $\pi L_1$ is the expected loss associated with accepting + $f_1$ (i.e., the cost of making a type I error). +- $h(\pi) := c + \mathbb E [J(\pi')]$; this is the continuation value; i.e., + the expected cost associated with drawing one more $z$. + +The optimal decision rule is characterized by two numbers $\alpha, \beta \in (0,1) \times (0,1)$ that satisfy + +$$ +(1- \pi) L_0 < \min \{ \pi L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq \alpha +$$ + +and + +$$ +\pi L_1 < \min \{ (1-\pi) L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq \beta +$$ + +The optimal decision rule is then + +$$ +\begin{aligned} +\textrm { accept } f=f_0 \textrm{ if } \pi \geq \alpha \\ +\textrm { accept } f=f_1 \textrm{ if } \pi \leq \beta \\ +\textrm { draw another } z \textrm{ if } \beta \leq \pi \leq \alpha +\end{aligned} +$$ + +Our aim is to compute the cost function $J$, and from it the associated cutoffs $\alpha$ +and $\beta$. + +To make our computations manageable, using {eq}`optdec`, we can write the continuation cost $h(\pi)$ as + +```{math} +:label: optdec2 + +\begin{aligned} +h(\pi) &= c + \mathbb E [J(\pi')] \\ +&= c + \mathbb E_{\pi'} \min \{ (1 - \pi') L_0, \pi' L_1, h(\pi') \} \\ +&= c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' +\end{aligned} +``` + +The equality + +```{math} +:label: funceq + +h(\pi) = +c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' +``` + +is a **functional equation** in an unknown function $h$. + +Using the functional equation, {eq}`funceq`, for the continuation cost, we can back out +optimal choices using the right side of {eq}`optdec`. + +This functional equation can be solved by taking an initial guess and iterating +to find a fixed point. + +Thus, we iterate with an operator $Q$, where + +$$ +Q h(\pi) = +c + \int \min \{ (1 - \kappa(z', \pi) ) L_0, \kappa(z', \pi) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' +$$ + +## Implementation + +First, we will construct a `jitclass` to store the parameters of the model + +```{code-cell} ipython3 +wf_data = [('a0', float64), # Parameters of beta distributions + ('b0', float64), + ('a1', float64), + ('b1', float64), + ('c', float64), # Cost of another draw + ('π_grid_size', int64), + ('L0', float64), # Cost of selecting f0 when f1 is true + ('L1', float64), # Cost of selecting f1 when f0 is true + ('π_grid', float64[:]), + ('mc_size', int64), + ('z0', float64[:]), + ('z1', float64[:])] +``` + +```{code-cell} ipython3 +@jitclass(wf_data) +class WaldFriedman: + + def __init__(self, + c=1.25, + a0=1, + b0=1, + a1=3, + b1=1.2, + L0=25, + L1=25, + π_grid_size=200, + mc_size=1000): + + self.a0, self.b0 = a0, b0 + self.a1, self.b1 = a1, b1 + self.c, self.π_grid_size = c, π_grid_size + self.L0, self.L1 = L0, L1 + self.π_grid = np.linspace(0, 1, π_grid_size) + self.mc_size = mc_size + + self.z0 = np.random.beta(a0, b0, mc_size) + self.z1 = np.random.beta(a1, b1, mc_size) + + def f0(self, x): + + return p(x, self.a0, self.b0) + + def f1(self, x): + + return p(x, self.a1, self.b1) + + def f0_rvs(self): + return np.random.beta(self.a0, self.b0) + + def f1_rvs(self): + return np.random.beta(self.a1, self.b1) + + def κ(self, z, π): + """ + Updates π using Bayes' rule and the current observation z + """ + + f0, f1 = self.f0, self.f1 + + π_f0, π_f1 = π * f0(z), (1 - π) * f1(z) + π_new = π_f0 / (π_f0 + π_f1) + + return π_new +``` + +As in the {doc}`optimal growth lecture `, to approximate a continuous value function + +* We iterate at a finite grid of possible values of $\pi$. +* When we evaluate $\mathbb E[J(\pi')]$ between grid points, we use linear interpolation. + +We define the operator function `Q` below. + +```{code-cell} ipython3 +@jit(nopython=True, parallel=True) +def Q(h, wf): + + c, π_grid = wf.c, wf.π_grid + L0, L1 = wf.L0, wf.L1 + z0, z1 = wf.z0, wf.z1 + mc_size = wf.mc_size + + κ = wf.κ + + h_new = np.empty_like(π_grid) + h_func = lambda p: np.interp(p, π_grid, h) + + for i in prange(len(π_grid)): + π = π_grid[i] + + # Find the expected value of J by integrating over z + integral_f0, integral_f1 = 0, 0 + for m in range(mc_size): + π_0 = κ(z0[m], π) # Draw z from f0 and update π + integral_f0 += min((1 - π_0) * L0, π_0 * L1, h_func(π_0)) + + π_1 = κ(z1[m], π) # Draw z from f1 and update π + integral_f1 += min((1 - π_1) * L0, π_1 * L1, h_func(π_1)) + + integral = (π * integral_f0 + (1 - π) * integral_f1) / mc_size + + h_new[i] = c + integral + + return h_new +``` + +To solve the key functional equation, we will iterate using `Q` to find the fixed point + +```{code-cell} ipython3 +@jit +def solve_model(wf, tol=1e-4, max_iter=1000): + """ + Compute the continuation cost function + + * wf is an instance of WaldFriedman + """ + + # Set up loop + h = np.zeros(len(wf.π_grid)) + i = 0 + error = tol + 1 + + while i < max_iter and error > tol: + h_new = Q(h, wf) + error = np.max(np.abs(h - h_new)) + i += 1 + h = h_new + + if error > tol: + print("Failed to converge!") + + return h_new +``` + +## Analysis + +Let's inspect outcomes. + +We will be using the default parameterization with distributions like so + +```{code-cell} ipython3 +wf = WaldFriedman() + +fig, ax = plt.subplots(figsize=(10, 6)) +ax.plot(wf.f0(wf.π_grid), label="$f_0$") +ax.plot(wf.f1(wf.π_grid), label="$f_1$") +ax.set(ylabel="probability of $z_k$", xlabel="$z_k$", title="Distributions") +ax.legend() + +plt.show() +``` + +### Value Function + +To solve the model, we will call our `solve_model` function + +```{code-cell} ipython3 +h_star = solve_model(wf) # Solve the model +``` + +We will also set up a function to compute the cutoffs $\alpha$ and $\beta$ +and plot these on our cost function plot + +```{code-cell} ipython3 +@jit +def find_cutoff_rule(wf, h): + + """ + This function takes a continuation cost function and returns the + corresponding cutoffs of where you transition between continuing and + choosing a specific model + """ + + π_grid = wf.π_grid + L0, L1 = wf.L0, wf.L1 + + # Evaluate cost at all points on grid for choosing a model + payoff_f0 = (1 - π_grid) * L0 + payoff_f1 = π_grid * L1 + + # The cutoff points can be found by differencing these costs with + # The Bellman equation (J is always less than or equal to p_c_i) + β = π_grid[np.searchsorted( + payoff_f1 - np.minimum(h, payoff_f0), + 1e-10) + - 1] + α = π_grid[np.searchsorted( + np.minimum(h, payoff_f1) - payoff_f0, + 1e-10) + - 1] + + return (β, α) + +β, α = find_cutoff_rule(wf, h_star) +cost_L0 = (1 - wf.π_grid) * wf.L0 +cost_L1 = wf.π_grid * wf.L1 + +fig, ax = plt.subplots(figsize=(10, 6)) + +ax.plot(wf.π_grid, h_star, label='sample again') +ax.plot(wf.π_grid, cost_L1, label='choose f1') +ax.plot(wf.π_grid, cost_L0, label='choose f0') +ax.plot(wf.π_grid, + np.amin(np.column_stack([h_star, cost_L0, cost_L1]),axis=1), + lw=15, alpha=0.1, color='b', label=r'$J(\pi)$') + +ax.annotate(r"$\beta$", xy=(β + 0.01, 0.5), fontsize=14) +ax.annotate(r"$\alpha$", xy=(α + 0.01, 0.5), fontsize=14) + +plt.vlines(β, 0, β * wf.L0, linestyle="--") +plt.vlines(α, 0, (1 - α) * wf.L1, linestyle="--") + +ax.set(xlim=(0, 1), ylim=(0, 0.5 * max(wf.L0, wf.L1)), ylabel="cost", + xlabel=r"$\pi$", title="Cost function $J(\pi)$") + +plt.legend(borderpad=1.1) +plt.show() +``` + +The cost function $J$ equals $\pi L_1$ for $\pi \leq \beta$, and $(1-\pi )L_0$ for $\pi +\geq \alpha$. + +The slopes of the two linear pieces of the cost function $J(\pi)$ are determined by $L_1$ +and $- L_0$. + +The cost function $J$ is smooth in the interior region, where the posterior +probability assigned to $f_0$ is in the indecisive region $\pi \in (\beta, \alpha)$. + +The decision-maker continues to sample until the probability that he attaches to +model $f_0$ falls below $\beta$ or above $\alpha$. + +### Simulations + +The next figure shows the outcomes of 500 simulations of the decision process. + +On the left is a histogram of **stopping times**, i.e., the number of draws of $z_k$ required to make a decision. + +The average number of draws is around 6.6. + +On the right is the fraction of correct decisions at the stopping time. + +In this case, the decision-maker is correct 80% of the time + +```{code-cell} ipython3 +def simulate(wf, true_dist, h_star, π_0=0.5): + + """ + This function takes an initial condition and simulates until it + stops (when a decision is made) + """ + + f0, f1 = wf.f0, wf.f1 + f0_rvs, f1_rvs = wf.f0_rvs, wf.f1_rvs + π_grid = wf.π_grid + κ = wf.κ + + if true_dist == "f0": + f, f_rvs = wf.f0, wf.f0_rvs + elif true_dist == "f1": + f, f_rvs = wf.f1, wf.f1_rvs + + # Find cutoffs + β, α = find_cutoff_rule(wf, h_star) + + # Initialize a couple of useful variables + decision_made = False + π = π_0 + t = 0 + + while decision_made is False: + # Maybe should specify which distribution is correct one so that + # the draws come from the "right" distribution + z = f_rvs() + t = t + 1 + π = κ(z, π) + if π < β: + decision_made = True + decision = 1 + elif π > α: + decision_made = True + decision = 0 + + if true_dist == "f0": + if decision == 0: + correct = True + else: + correct = False + + elif true_dist == "f1": + if decision == 1: + correct = True + else: + correct = False + + return correct, π, t + +def stopping_dist(wf, h_star, ndraws=250, true_dist="f0"): + + """ + Simulates repeatedly to get distributions of time needed to make a + decision and how often they are correct + """ + + tdist = np.empty(ndraws, int) + cdist = np.empty(ndraws, bool) + + for i in range(ndraws): + correct, π, t = simulate(wf, true_dist, h_star) + tdist[i] = t + cdist[i] = correct + + return cdist, tdist + +def simulation_plot(wf): + h_star = solve_model(wf) + ndraws = 500 + cdist, tdist = stopping_dist(wf, h_star, ndraws) + + fig, ax = plt.subplots(1, 2, figsize=(16, 5)) + + ax[0].hist(tdist, bins=np.max(tdist)) + ax[0].set_title(f"Stopping times over {ndraws} replications") + ax[0].set(xlabel="time", ylabel="number of stops") + ax[0].annotate(f"mean = {np.mean(tdist)}", xy=(max(tdist) / 2, + max(np.histogram(tdist, bins=max(tdist))[0]) / 2)) + + ax[1].hist(cdist.astype(int), bins=2) + ax[1].set_title(f"Correct decisions over {ndraws} replications") + ax[1].annotate(f"% correct = {np.mean(cdist)}", + xy=(0.05, ndraws / 2)) + + plt.show() + +simulation_plot(wf) +``` + +### Comparative Statics + +Now let's consider the following exercise. + +We double the cost of drawing an additional observation. + +Before you look, think about what will happen: + +- Will the decision-maker be correct more or less often? +- Will he make decisions sooner or later? + +```{code-cell} ipython3 +wf = WaldFriedman(c=2.5) +simulation_plot(wf) +``` + +Increased cost per draw has induced the decision-maker to take fewer draws before deciding. + +Because he decides with fewer draws, the percentage of time he is correct drops. + +This leads to him having a higher expected loss when he puts equal weight on both models. + +### A Notebook Implementation + +To facilitate comparative statics, we provide +a [Jupyter notebook](https://nbviewer.org/github/QuantEcon/lecture-python.notebooks/blob/main/wald_friedman.ipynb) that +generates the same plots, but with sliders. + +With these sliders, you can adjust parameters and immediately observe + +* effects on the smoothness of the value function in the indecisive middle range + as we increase the number of grid points in the piecewise linear approximation. +* effects of different settings for the cost parameters $L_0, L_1, c$, the + parameters of two beta distributions $f_0$ and $f_1$, and the number + of points and linear functions $m$ to use in the piece-wise continuous approximation to the value function. +* various simulations from $f_0$ and associated distributions of waiting times to making a decision. +* associated histograms of correct and incorrect decisions. + + +[^f1]: The decision maker acts as if he believes that the sequence of random variables +$[z_{0}, z_{1}, \ldots]$ is *exchangeable*. See [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html) and +{cite}`Kreps88` chapter 11, for discussions of exchangeability. + +## Sequels + +We'll dig deeper into some of the ideas used here in the following lectures: + +* {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning +* {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories +* {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** +* {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule From c4e5c3f2de8835766dfdd3b20ec0cf3c111b259e Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 09:43:40 +0800 Subject: [PATCH 02/29] updates --- .../wald_friedman/wald_dec_rule.pdf | Bin 0 -> 8458 bytes .../wald_friedman/wald_dec_rule.png | Bin 28643 -> 25698 bytes .../wald_friedman/wald_dec_rule.tex | 4 +- lectures/wald_friedman.md | 488 ++++++++++++------ 4 files changed, 336 insertions(+), 156 deletions(-) create mode 100644 lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f4383cf06f185f805e8340eed829349179e72ec0 GIT binary patch literal 8458 zcmchcWmFv9+NKFk2Z9F)L4y+-r*RAJ9$XuDXk3B^cM0wg2u^Ts+}$+DA_p_;$K1jT0W#$A>|2#eV1z=?%XCb#YwgT|;10^hN zT)<912^%99@CUGoy(t(d2evbJu^?w9+@{!_gpNxQJp+#AA`vT$d($oc@zX+<9FlB}NaSKh2P$LIa?Rfudu9uINA~O0wS|x8YGuPK z1b$M@)O1KY&-`vRp}2L_?=J8t*THHCU&=Gg4=E6?U`@ijKS3-BNgMbynws$Gby?Ox z7rHgtj(SSzs6%=@TB6LE4{M)HYM}eqCTs27Ak9zeof)g~RCvQlxRQ|vne^!rshyJNwJNU4U;50>}X5+mUjS3kB!?=434tVK###X4!POr_G)Qud_h;JRG#nJQ;$*Yym0G*P5Us%vKo0xZ^C1Sev zrqha_-&TE~y0okp{R(`z--R#I>myD$Db?S_s)sE>8Hfiy831aLdvaTTOC-5XDJ$Q9 zV-dGeTS-FoK0zzxq8Amh*Bw7f<=r;@OMHC_KH=T2#q`-+Ik^;kq3jt=gZ z_G8niVwt(n(ji;edSwyN&u?wRFP~fT7(cg(IKv>YaL07G)-AmQ#WG~I1G5EAY~9JG z+MSscMK81>MIcllGE<@b8^g-5Sl~0J#7VOsN`o6k7MRCk%{_Wt#Mr!BKFu)`=L&Id z;+5+u$8I~A|K&aL2225?>t#9Bn>_cZ%WD^_33F8_{fw8)etci92>bSzz0s-x?(pv_ z)(KZCQ&;EV#)9e5>C=Za_>nR@$aNoS!Z@K5yy=c1k53w&S$PL5JDq%0z79I_+;!~g zT;ea7bk`DnTm~6leUJ9~pvE*l`|Y8%#*YUGb{=#zcDw}Z=%Wuu69j)li$;0&P}K#j zDOhc7QXeS5TJzFIN~S1Alcg<3C$8s-%oa{;KSH=AXL-hQ-7FqY>zC}@%}Z^gw_Yrz z*Tp1VyH9Bh0+X+|J*4@f!yVHYla?M~HmTdWHdy^_3IoIbF>wXm*`MeV03QE%yq#EaT~#ob(@33wD!-fCkV*?BD*4eRL@RsHg}jwz{u+BaYS!rkWJp74`5h<X{x6&PJ^IU-SULU^hhk@A`O~2Erj)G%S+L+X-2B8z`6MP6=4{Bj z&1gY$km+l%y`>XxE)B(j*z=>D!X1mqW`tY6hk0tsy$Xa1t>fEk&d7rO#5$I}K>#^{ z1t0!I>VQII#DnVP3Zjwk#!kYGaQDrD%fpk$14ylTH(UY+SlS;ty7OkR5Pio%=+jI@ ze)hx3U_Au;PK7hAz*1NWR1ASy*qdHaULldLEKbT)Wm*j$WXwMmWJNZKVp_dZjs>@q z^j-%gvk)?OI?am4N?atx)umQ4!BIcA6{AlxNB!EK3!e6V6_Xcarf|k+7095ZQz;+0 zluO7U^4?>_y5)mlewGrCRgCAwlCqlrl4tb*W0(>vz?$vQhWRKsllo(Vk-5zvbZjBM z{{fVI;u`4qrVXejH#fF*WqlLj%zliw@{FDzHGF) zRS*kS+b-iyV<8@H3n~(JxJK1R{mkl`3EPseyy#4z-}<{DQctO!QPZ`pZECP8r}q0; zZ(b^1T|*^p-i*-$MA4Z1sh~pgq>s_eYsNp4-+_mZf))1`PiAknkE(5!Lne!tznc+B zkz6Oi%&@2O?Mv;_2{MQU2nU?uW4%3kJsjU;=ojvvQH%&?d?>y|E!J7=m2S|!kH9@Z zqN5L|>vvV`mdbcfu-8Z$_cQTz>^ww7Y1q$xH**s6M<`!>EkTELwybvS!w7s)yL-kl z=n6DUc}>0db|i;{tx=L(W4E<|Q0)Q2Qo^xTTi1uI!S6R~>;n87{kZ?3pDM)I#lry% zRQr8l75g`TT^<&WKjoy3^|8T)5cZ$UU4vvalO`Ie9o$5sR&^zah%>Yzhkt^5n8}rm ze=tD=EPLB0*5+U3twy#3p2J8iB1z<<9V`mZ*KC(B8=Wz%9qsl{=VC(swZJ`qc2uI?Wi67?EDo+Nt%zRz#s;*)!nTW{&X<U5<chuMc&q13}KE8CG*xyJct<3~;Z8zA3Fc+`Rj#u0D?bTJ; zp@eLPOMJuiD@zNiT3s+%ppa7!-Au*7J)`k19AggtK80x_erZS~`DPxUj@EXT0{^W3 z8)iljlm)S(;HXs^T>(LhZU?~eP8ikfZP}^72sG*|uoo!x0qYCn>Et~^=kz)6Bqmd; zeuMVdWw#a^z@H-t(TFXs^$Es?_vs-G^nSjBay}hnOAN~&E#A+bU(5$}@bhi=1TCi^OO$)rhWBQnVSfm>q&&QUG z0Fo#ML@P0?f_7QxLG`xTS>;2U&MAsV**%|@*x(z)4xTT?NCQy0cLdVnMu?)54(^E= zaY(BTbji(3J(VIv*ZsJokw%-n) z;=ytnn6o@71nf-T!Q3>o7Z#<9*5Qcq=q^b?U(gS+{;>J*?258)9!5z?6S0_$yWgkg zYu1dK;PB#HP<6mQm?C~SY6qyxq^Ea~>61{?B`eq>2*SGd`g!zIB!CRTw{FKU*nLy* z$eNTR<5M42qyPB(UR6!Qw2Z65TlQ$*>!@-5h#Ae(eeR~Rm)z#cJ~rVq*C_?e$|K}n zVX>n>UdxoP7);n?PL-IX*@CYQ>YIWj0_R*GP#oJ*5dMa3&_CGz?;|uDJNKV3>nT;+ zLCLXJZ^PfHswZ{DEg@;ikZ7I9)86OO%7!9d;W@-ql5M}PaNWvi|DhM5tjYU}dp za9C&2@RP!uZO6KV6x8?EOIXQ)Q*1VR&D-Q8gG03r1gzwyp(iF+&ff3G=VKb~%Z*QR zs&rm7EK>Z`G00ByKnKkf)pqi{7^sL?BYZ$_39NbF-m_S&x%YkF$PJjzVM(*=>nM!- zDLzli$p-SSyn7NYOh1(rt+)Nv)H+~DRHW$4QG?F<^h>qOgCq{<9}6*?T<~zf9!@FTx@>|Xkuz;WMpV+`qL5J z#p$KEGvt}UF)=q=b5fTx8WB~0Hy#~|J z?$H0DNj5Fmp-G10;Q@5r4u1Jcodh7}BBG{7(zv_Z-rn{MYwGp972kJF;{|Mgp(X-| zeC_=z4*p6Hu)Fo32Ka_GeFc!y!u(NpA65dU;%6w4)*ljQ^7wNS2r+)ogh&)bm`X&X z1#o@Z+qieE_r6t(-j2M__A$7LyzP%XNfB@9V4qzLZ%eJ6cB_SO_n)L4ughj;w)l-d z>tD1L-QPb9pLbaMX1|U)y4KO~ZMgn;vwB>%s@YsQ&Re%Jw~wULjOltZp7sXBSJ&UP zT(DfdTs;<=ztY*p(Ugv0p?PyhCOc=JJ^ssQ>g~=+j33}LGwg6M<>H!kPv&4p%G_YZ zr~ZDzDOxCDp|%+|v#m0{xO45jd$L@0(4y2YN}6=__3&VoeQw|)Y5aMUALg|-Lw~X8 zORHdFFb;|Ex-})u(y8@u-){UkvU}n1goXVA?#`*2`)?|Q^*>{Z^Uspd`<*v>$g$e) z@ts#x!qY?*ap<(*dEUKGU&UnMl@6BZO%;1;p9~VX%o&S35mR0!B7XoCw+hnzxISst{M^aUm31y&eFH?cQy z)6`UbKb*m9w>?9?k5OsBRadC+;_ZLwdaA>JC&&T(( zcYlvmD;{E;;xCb(2>*qY8|r@{r2!%S|A~|#H_Tu9|3)hRpO8vZ_zS5?<>u4k9??Ge zn|8(a{s*efd;H1cW!nb!ioW*xjLe0j^&_>^f|R2S!EP zkj!H4sgT6ath(53=FJdzx2hcGHPhyCk$()~XDF*##NaEkjooF``vvtFyJ@w=C8&8+ zNE>Sphr!=;)AREa>|C4K=ch)I8tu(xyhE10tU zyI{)32KuLVkgbM?5}qdMu~D?dTjk=+55?bG1dM0sLiIr zzT4y7P5a4B``ub)Hfn+tOPo}}LcLFle%YM3c*R<;SsJI67z=SfaDxDzr&pCwF~XfD z$l%=$f$RiZ)2~F`b8_NLeR9Y{P{B)9IW;auP*w(lK{8xhh56zdohhwM`sKt18h$n>y+}ds@z~5SVB@(D5*2#*B;2f% znWjVet$uYmX$nm{K6xO${a8ZAsNL*LxE9$Z|_OEvsWf0RWc z8C)Y*v|>(0DYrA?&_=;dDK@|=VNnzxiQVN^!&i?h+oMvY#`I>|xG7bHNs3Mv zAcu{o8lZ0CCjNSofP(c0UA5{%yJ`N_7}ZvMYM{ z?C!cVm~UQegLi(bg;b{-u}t~BEtNi?Js8v9f5g{{+{Yf8{s@dkHq= z>ARcf#WyyKJm8!%H9tZ0i`46zPdeA-wha_E$k2UvXbVlMW-lJ&QvKkf?Gbv%wCH)e zu*>0j+#2st9zM8sBVl#Ya)P<~DV?E&<*7kK=>-s~W0t zkkbv(iC`O8wN`{)IY0@-2udqK>|Xn7USI2#AUT6mi)&L0k0~k0`X8Jru|mx9o7|G2 zN+keckEl;RT?e&J1U$dmG0hy(D1wD2`6a3z_!J%7ZKSt((mFzMF)Y5Smv%jCLoP9h zEl&mYWV~>~ih%n5iJyP@@+9iL<-tCk)^Yd&E=m0PB9t?m5_xUrn7ugmo^4r?cpo9~ zS~jrM_lB%lg0AAqbll7IWMb2YL@yna#G~{pwUv%ho#KoK!t0pF);=6Jt?K-`9+CH> z;qa0JZI-K#G}?TCzB@G*@(T}PSZ2Yp#VbJ6M~28!G7V9ZkSJkC_BNz3%{(f$#=IZ0 z&uHiCoS)^2p&Ox}whBpfZ@@{4h}0(QzSJSOxV4FoL;@`)ezjiM!Kb^Neqz}_?!S>| zO>HRc#AWfmJS?_2CU0Lp?d?_Vf$!>_! zM|9sYj_(W$%5yOS>hrjebnjWQj+=}b{dI2neVb~k>0<4qndQ}05o@kXW=YwJNC|F? zYhtd*3SMIF9*wJ59%zk;wk2mL#21A(C7?n#F1>bzVDCX4#R&&1ZMcWz81$Wx#4&oI z0VK8Uobu}6DNOXG^ud$9exW13mh}mV>^;~8S6okmh7uaT!jKhX?dz}Sun1zSG{$AR zOF(yG(^v)+xwNFGK#^+R->)9h2;cw6;W(?UIXmYO{s7>&%`+MZBpNEvysr58+U=?P zOTr_R^gwL!J>3f!l6;f2Jg1nFi-F@szj;5Z5MqE^{X#1O2e2m)F}dTn<)XTu0d<%XjPAV6KE^*PQzgvc=hHh*?-j@6mcqJ_voo5#A~{4BB~) zz}@O#`5D+JnPVKI=5T2$qLB?B5-H}IvG)U^duARZXIUDG`0#pz!$-}e>nSWuJb04(q8BQW-t6*8YtlFudu|PpEVfU)y{OqC$zT?Le$fi+bWG6jG0xc}bE%ql8 zq-IexYP08v-m*eHnPwWZh7_OvOn85*kUvIq%ib$AUXWrl(raCey6p^&gWVOn!%+`r zNnx-+s(6jh@uO$uLT|TuEMXp4DXzjBX>h8vbZ>HFkBuI4=A8IKUQ@=!%vvx})z1B*Lj~E%7fJ0`Rh5GV1X$Nt;H#$eTk+BGEag;QD`IM{ zZWM=#^MLx6lISHesY(^iV49h}dB2~?iuqe1Q_zG*LeUIRRF>~ICzAH#QO$hrg|VkB%Acn+3g`+xkLU~Y z6Bg7@@SlUqm|wX)RY!#55W5hbRPqc+I^>zP3y*l+7RtPGOLbAeZ5pE*IdGdxd-XL) zC}LDbAhtVWv8fVMO!=2fF3wIGwnbhFckoB(-P1!(AQH{ zfYNT7&)P;6_v>CjY1k0Cu-!6nIpu9$E54IE`vOtO-9oy(%V_7%EX4y20lrG9wdv;6 z&ho74tM|iMVDBX_6l$;H>G%caSA|?B&si~ImP>*!G`e0}YQ1$x5gNglN$>G)7|T+X z6hpdG*50^ELGekshrR;V#`Tl8g`C%aNWOuxUM!oW%YizczL{3Yk6V(e1jcD-m%Da6x*A2oVF&q3l5`_t z?O?t7g~Lp3)T129B8|8eblY=QF)euqU z-Oz5(E*ixgPW^FFMg$^t^{0&5hlV|{-*bAxn@aS1Xl&i3=87{q*IClO(yqnzcXgP8 zO~Tj=#vpGeV3VoLm#Xr#FuF;o86gMs-Qm?*&LCwIaOmf&r2OVNu!Q6ttKPw4XqSRf zQJJ?YGbA{7A^r8TXuhkluT17FGI_1w2QuYv@W>KtZ-p#0OR89xE-N`I;Js)HRNod) zlKTNhh&Bh9^I%^qHd?lzDv}WW`T_2?iFK*=uMzT5AjgK6HN%;18IH4D6#eOi%sPr^ zCfYqWFxvC{U~PC32fw=Is7#J=3FUH~e78P0spHh?0KHG1FHh@NbuBYjQNXKY5|Fwf z+?7|l4X)LQMl-Fe9?nQiy^GLE)aGLr@~O5vHcNq+0jzp=Za2svc;tv_UKQ}7zU zs|sjng1V1*o5XytRWpUS=Z;T}A7|m#GL;;wrN1w`AjF&@(57dqIjQ~3?I~fBQNh7g zQxr@H;!KXeiO9jE_cXHO^%~$K+rPK@(w~a#Su@v(FS#db#~Wl5?icr*Sy)nz9kK4w zrSLr+m8m(&vakL{5m+6QjB=z*R!Fji2f^3n`EGh|=isr|fj5)Iy$|{7c~OW)lfir( zDQsV8tJ{)>PtL_i5i{oG{Gbbsh$LFK6S-5EZW^sSfxo&4n$E(a{9e1DP7&p@-Dl)l zOBg7jn3=o#9F(Obc^TV?a(ZWgvX%Z~jq@T)WVeIMrAl&CNDYe3QDB2W4E0;f7T$7r zwItL$Vwts%JD~vYL2sIoDH_tyj$X4rJ8R0z%`H%zj^GDizhxXjJPbpAVjsy^H+CgP zyL$k#D5cT=t4*-~(JlF(Ht|sfYzCD6pu=x!#LCUZ&BMuR#tt@SV=-d|v$LDBvauO) zaB{O5|K7#@zn{5Z?DX9QeEj_{H>})_y9oFA>*!2FL3-SEv zeeZ|bu!V&QgEm($#vP@Qnw35qtL41@@>@l|l`&cmv-K}Xr|qvuzeok+;_1)i;ftVu zfUE1=uS;TSGv0{+j~PcSeoIDrB(3FRk`3wCfL7P3JKl|F?)47bA`8+K0g(PxAZHgN WCl_}ouo(cv$^imUQ;RD~0R9I}YWZXU literal 0 HcmV?d00001 diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.png b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.png index a7276d9cb544336ca3caffb17de061a29c56aa92..6868041cabcf49540b459a1287766f12d39102bf 100644 GIT binary patch literal 25698 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

W*RktMbuHJhd1hKzI_(qH8 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�R`x!4bT)Q z5>btiDV*rAHRMvW)9z9mPxO{M8ee;q07OyycgS1dXaCDBAMn5Sh|!TQy3eq#)`u*# z8?U#OzsQ%LbRF^Bs7BKlsvnPf+-y7OosE9!oG+`VTj!ywk8~#TKPeg*zFHQg8+DYt znmgO}ajg8}lQq}LbP$h4`w>L6>j=!LARF}-$6Fxzj4WE@pfP{sUYN2%1w=W51IZ}`(g;&Vo(uSn!?1D1_W;D7c99Ol<=Nv`*X1e3# zb9%gv{dPqGE4OCYd%)Lwy^ zCnUtv>Mp<7at!{PZ_P&%=!B|>C?6(&^3iVV7&?a><*32~FLt*6Zdvel!U-N1=%UI_ z^~3Sr*$Vo9c6Z3>uH#clDJ8%ZnC zOu4ozhqL$Mf7MI~2(Kp}T}{d4{{zGi(lfs&sXHAfMx3d)*~1I?2%Mce#Rcmf4K zsb>w}yk48T6jdp(PC)uZwQ6=A9t``VZNgU`qTsN4?@d|I1}gs|v-$U+CL~y0^FA!3 zkGzdA%#YhoFG@VI8Lp4H^_!)GHW>{)8No_i`R06tIrI71!o<8U5{Q`J;Nw zfQew5LKuX1Y0k#t`K%#R+S3-ly2(rLC)ZQ>iEChVoPg8_5U)p&7Wm$DpE$@bcPc8V zKNW#4jMuAvS^k_wr;+%sw(Z}y>qaslo2%Zj&>82w``L$>D<=+v7r11Sm%<0?=cYw@ zzZo(w1XGW_d^$95t&pewJAu9p#zEc10jqoz$!$1uOgy)i^^ z#07FA8VGqHNDrv97ExD5p5gMGbE7RUc7L9gU!u`wJO-?lZoHIo*|3oS!ZvNCYr04* z8{9xOa(CF(I&`&i{@x?NmMD9g1>Wg(S4LT z2eaf8`t#Cce+k~kAe6FG+euwfn;VA!CgMIiLKU!Rvn5$;A#-G}ZH5(WxvC5IHYb+I z+TVwp>wAWEB6USXkQm)$MGRiNNLFXu2#Emzz`u}gT3q4T&5Cd0kL8n_8wc*t&zTmkU_^;x}?8K}y1D1?~h)c&JZ zV6qAcK`!n5G)E6PQ7Rvz9zhO_T4-M#oZn{C?jVcWs|HEaY+Uj3mykIpsKjM^igmmM z$O~i3&qIe?pW%$$*@iIFPBSIB<-578pj0NN?MI?nry}_!(-wZmk&0gm@~CR}VQK(m z5$H@o;+wCMz-!El^_%fx3Yg}n1dKHZ2&?egWsL0w?B4to{tR;9^vp&tZG`hO8Y(g6 zJ+wDfxs$hUJ7iM(MKS0pQw}z!c&?Y@2p=p*xDOZ^=9NR;H)3u zmFdOhY6#VR09Ce{2T`rgaIjXZ=cvNkmXhr(`$BM?4bb+UMVD-GTji;Bw~i!*+l5wr z9UGME@d^Z)6Z1e(k@$TzLgY_vxO7`b+&R0Fy$NvxAS#g>x}pqU&_8p6W4EJ5?~I$! z*$2Pf6-vxclb|+%an$x0YX18taeEOh*~^CDbzmi@Q@-6?B`lYBk|`QAj5JIMte0;- ze{42Lmtgv)PbkMO;KxfmXs&=#ZqM3tbjLzrVndB^jz^rfl{T)`s2zG=qv zBJt#fYwbuDYCShR9m}FjJ^UY~iq}a1 literal 28643 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 PM{Zs` and {doc}`this lecture `. @@ -109,8 +111,6 @@ they were not able to solve it, described the problem to Abraham Wald. That started Wald on the path that led him to *Sequential Analysis* {cite}`Wald47`. - - ## Neyman-Pearson Formulation It is useful to begin by describing the theory underlying the test @@ -235,7 +235,7 @@ Wald summarizes Neyman and Pearson's setup as follows: > > $$ \frac{ f_1(z_1) \cdots f_1(z_n)}{f_0(z_1) \cdots f_0(z_n)} \geq k - $$ + $$ > > is a most powerful critical region for testing the hypothesis > $H_0$ against the alternative hypothesis $H_1$. The term @@ -278,9 +278,9 @@ A decision-maker can observe a sequence of draws of a random variable $z$. He (or she) wants to know which of two probability distributions $f_0$ or $f_1$ governs $z$. -To illustrate, let's inspect some beta distributions. +To illustrate, let's inspect some Beta distributions. -The density of a beta probability distribution with parameters $a$ and $b$ is +The density of a Beta probability distribution with parameters $a$ and $b$ is $$ f(z; a, b) = \frac{\Gamma(a+b) z^{a-1} (1-z)^{b-1}}{\Gamma(a) \Gamma(b)} @@ -288,16 +288,7 @@ f(z; a, b) = \frac{\Gamma(a+b) z^{a-1} (1-z)^{b-1}}{\Gamma(a) \Gamma(b)} \Gamma(t) := \int_{0}^{\infty} x^{t-1} e^{-x} dx $$ -The next figure shows two beta distributions. - -## Request for Humphrey. - -The bottom panel presents mixtures of these distributions, with various mixing probabilities $\pi_k$ -- -that is inherited from the Bayesian lecture. - -Please remove the bottom panel and just leave the top panel. - -This is the end of the "message" +The next figure shows two Beta distributions. ```{code-cell} ipython3 @jit @@ -309,20 +300,14 @@ f0 = lambda x: p(x, 1, 1) f1 = lambda x: p(x, 9, 9) grid = np.linspace(0, 1, 50) -fig, axes = plt.subplots(2, figsize=(10, 8)) - -axes[0].set_title("Original Distributions") -axes[0].plot(grid, f0(grid), lw=2, label="$f_0$") -axes[0].plot(grid, f1(grid), lw=2, label="$f_1$") +fig, ax = plt.subplots(figsize=(10, 8)) -axes[1].set_title("Mixtures") -for π in 0.25, 0.5, 0.75: - y = π * f0(grid) + (1 - π) * f1(grid) - axes[1].plot(y, lw=2, label=rf"$\pi_k$ = {π}") +ax.set_title("Original Distributions") +ax.plot(grid, f0(grid), lw=2, label="$f_0$") +ax.plot(grid, f1(grid), lw=2, label="$f_1$") -for ax in axes: - ax.legend() - ax.set(xlabel="$z$ values", ylabel="probability of $z_k$") +ax.legend() +ax.set(xlabel="$z$ values", ylabel="probability of $z_k$") plt.tight_layout() plt.show() @@ -344,9 +329,6 @@ The observer has something to learn, namely, whether the observations are drawn The decision maker wants to decide which of the two distributions is generating outcomes. - - - ### Type I and Type II Errors If we regard $f=f_0$ as a null hypothesis and $f=f_1$ as an alternative hypothesis, @@ -360,8 +342,6 @@ To repeat ourselves - $\alpha$ is the probability of a type I error - $\beta$ is the probability of a type II error -**note to Humphrey -- please leave the alpha and beta as they are in this section! - ### Choices After observing $z_k, z_{k-1}, \ldots, z_0$, the decision-maker @@ -372,22 +352,10 @@ chooses among three distinct actions: - He postpones deciding now and instead chooses to draw a $z_{k+1}$ - -### Message to Humphrey - -We want to redraw this figure with $A$ and $B$ replacing $\alpha$ and $\beta$. I suspect that we -used the notebook to generate the figure. - - - ```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png ``` - - - - Wald proceeds as follows. He defines @@ -434,132 +402,344 @@ $$ (eq:Waldrule) For small values of $\alpha $ and $\beta$, Wald shows that {eq}`eq:Waldrule` provides good ways to set $A$ and $B$. +## Simulations -## Message to Humphrey +In this section, we experiment with different distributions $f_0$ and $f_1$ to examine how Wald's test performs under various conditions. -I want drastically to edit the following section. We want instead to create some examples along the following lines. +The goal of these simulations is to understand the trade-offs between decision speed and accuracy in sequential hypothesis testing. -- we'll set a pair of target $\alpha, \beta$ (size, power parameters) -- we'll use formulas {eq}`eq:Waldrule` for $A(\alpha,\beta), B(\alpha, \beta)$ -- we'll set beta distributions for $f_1$ and $f_2$ that have lots of overlap and are more or less challenging to distinguish. -- we'll then simulate Wald's decision rule and generate distributions of - - stopping times $n$ - - probabilities of making type I and type II errors that we'll compare with our target $\alpha, \beta$ +Specifically, we will see how: -I welcome your suggestions for improvements and more interesting experiments. +- The decision thresholds $A$ and $B$ (or equivalently the target error rates $\alpha$ and $\beta$) affect the average stopping time +- The separability between distributions affects the average stopping time -## Simulations +We will focus on the case where $f_0$ and $f_1$ are beta distributions since it is easy to control the overlapping regions of the two densities by adjusting their shape parameters. +First, we define a namedtuple to store all the parameters we need for our simulation studies. -The next figure shows the outcomes of 500 simulations of the decision process. +```{code-cell} ipython3 +SPRTParams = namedtuple('SPRTParams', ['α', 'β', # Target type I and type II errors + 'a0', 'b0', # Shape parameters for f_0 + 'a1', 'b1', # Shape parameters for f_1 + 'N', # Number of simulations to run + 'seed']) +``` -On the left is a histogram of **stopping times**, i.e., the number of draws of $z_k$ required to make a decision. +Now we can run the simulation following Wald's recommendation. -The average number of draws is around 6.6. +We use the log-likelihood ratio and compare it to the logarithms of the thresholds $\log(A)$ and $\log(B)$. -On the right is the fraction of correct decisions at the stopping time. +```{code-cell} ipython3 +def run_sprt_simulation(params): + """Run SPRT simulation with given parameters.""" + + A = (1 - params.β) / params.α + B = params.β / (1 - params.α) + logA, logB = np.log(A), np.log(B) + + f0 = beta(params.a0, params.b0) + f1 = beta(params.a1, params.b1) + + rng = np.random.default_rng(seed=params.seed) + + def sprt(true_f0): + """Run one SPRT until a decision is reached.""" + log_L = 0.0 + n = 0 + while True: + z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) + n += 1 + log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) + + if log_L >= logA: + return n, False + elif log_L <= logB: + return n, True + + # Monte Carlo experiment + stopping_times = [] + decisions = [] + truth = [] + + for i in range(params.N): + # Alternate true distribution for each simulation + true_f0 = (i % 2 == 0) + n, decide_f0 = sprt(true_f0) + stopping_times.append(n) + decisions.append(decide_f0) + truth.append(true_f0) + + stopping_times = np.asarray(stopping_times) + decisions = np.asarray(decisions) + truth = np.asarray(truth) + + # Calculate error rates + type_I = np.mean(truth & (~decisions)) + type_II = np.mean((~truth) & decisions) + accuracy = np.mean(decisions == truth) + + return { + 'stopping_times': stopping_times, + 'decisions': decisions, + 'truth': truth, + 'type_I': type_I, + 'type_II': type_II, + 'accuracy': accuracy, + 'f0': f0, + 'f1': f1 + } + +# Run simulation +params = SPRTParams(α=0.05, β=0.10, a0=2, b0=5, a1=5, b1=2, N=15000, seed=1) +results = run_sprt_simulation(params) + +print(f"Average stopping time: {results['stopping_times'].mean():.2f}") +print(f"Empirical type I error: {results['type_I']:.3f} (target = {params.α})") +print(f"Empirical type II error: {results['type_II']:.3f} (target = {params.β})") +``` -In this case, the decision-maker is correct 80% of the time +We visualize the two distributions and the distribution of stopping times to reach a decision. ```{code-cell} ipython3 -def simulate(wf, true_dist, h_star, π_0=0.5): - - """ - This function takes an initial condition and simulates until it - stops (when a decision is made) - """ - - f0, f1 = wf.f0, wf.f1 - f0_rvs, f1_rvs = wf.f0_rvs, wf.f1_rvs - π_grid = wf.π_grid - κ = wf.κ - - if true_dist == "f0": - f, f_rvs = wf.f0, wf.f0_rvs - elif true_dist == "f1": - f, f_rvs = wf.f1, wf.f1_rvs - - # Find cutoffs - β, α = find_cutoff_rule(wf, h_star) - - # Initialize a couple of useful variables - decision_made = False - π = π_0 - t = 0 - - while decision_made is False: - # Maybe should specify which distribution is correct one so that - # the draws come from the "right" distribution - z = f_rvs() - t = t + 1 - π = κ(z, π) - if π < β: - decision_made = True - decision = 1 - elif π > α: - decision_made = True - decision = 0 - - if true_dist == "f0": - if decision == 0: - correct = True - else: - correct = False - - elif true_dist == "f1": - if decision == 1: - correct = True - else: - correct = False - - return correct, π, t - -def stopping_dist(wf, h_star, ndraws=250, true_dist="f0"): - - """ - Simulates repeatedly to get distributions of time needed to make a - decision and how often they are correct - """ - - tdist = np.empty(ndraws, int) - cdist = np.empty(ndraws, bool) - - for i in range(ndraws): - correct, π, t = simulate(wf, true_dist, h_star) - tdist[i] = t - cdist[i] = correct - - return cdist, tdist - -def simulation_plot(wf): - h_star = solve_model(wf) - ndraws = 500 - cdist, tdist = stopping_dist(wf, h_star, ndraws) - - fig, ax = plt.subplots(1, 2, figsize=(16, 5)) - - ax[0].hist(tdist, bins=np.max(tdist)) - ax[0].set_title(f"Stopping times over {ndraws} replications") - ax[0].set(xlabel="time", ylabel="number of stops") - ax[0].annotate(f"mean = {np.mean(tdist)}", xy=(max(tdist) / 2, - max(np.histogram(tdist, bins=max(tdist))[0]) / 2)) - - ax[1].hist(cdist.astype(int), bins=2) - ax[1].set_title(f"Correct decisions over {ndraws} replications") - ax[1].annotate(f"% correct = {np.mean(cdist)}", - xy=(0.05, ndraws / 2)) - - plt.show() - -simulation_plot(wf) +fig, axes = plt.subplots(1, 2, figsize=(14, 5)) + +z_grid = np.linspace(0, 1, 200) +axes[0].plot(z_grid, results['f0'].pdf(z_grid), 'b-', + lw=2, label=f'$f_0 = \\text{{Beta}}({params.a0},{params.b0})$') +axes[0].plot(z_grid, results['f1'].pdf(z_grid), 'r-', + lw=2, label=f'$f_1 = \\text{{Beta}}({params.a1},{params.b1})$') +axes[0].fill_between(z_grid, 0, + np.minimum(results['f0'].pdf(z_grid), + results['f1'].pdf(z_grid)), + alpha=0.3, color='purple', label='Overlap region') +axes[0].set_xlabel('z') +axes[0].set_ylabel('Density') +axes[0].legend() + +axes[1].hist(results['stopping_times'], + bins=np.arange(1, results['stopping_times'].max() + 1.5) - 0.5, + color="steelblue", alpha=0.8, edgecolor="black") +axes[1].set_title("distribution of stopping times $n$") +axes[1].set_xlabel("$n$") +axes[1].set_ylabel("Frequency") + +plt.show() ``` +In this simple case, the stopping time stays below 10. + +We can also examine the confusion matrix for this decision problem. + +The diagonal elements show the number of times when Wald's rule results in correct acceptance/rejection of the null hypothesis. + +```{code-cell} ipython3 +f0_correct = np.sum(results['truth'] & results['decisions']) +f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) +f1_correct = np.sum((~results['truth']) & (~results['decisions'])) +f1_incorrect = np.sum((~results['truth']) & results['decisions']) + +confusion_data = np.array([[f0_correct, f0_incorrect], + [f1_incorrect, f1_correct]]) + +fig, ax = plt.subplots() +ax.imshow(confusion_data, cmap='Blues', aspect='equal') +ax.set_xticks([0, 1]) +ax.set_xticklabels(['accept $H_0$', 'reject $H_0$']) +ax.set_yticks([0, 1]) +ax.set_yticklabels(['true $f_0$', 'true $f_1$']) + +for i in range(2): + for j in range(2): + color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' + ax.text(j, i, f'{confusion_data[i, j]}\n({confusion_data[i, j]/params.N:.1%})', + ha="center", va="center", color=color, fontweight='bold') + +plt.tight_layout() +plt.show() +``` + +Now we compare three different scenarios with varying degrees of overlap between the distributions: + +```{code-cell} ipython3 +params_1 = SPRTParams(α=0.05, β=0.10, a0=2, b0=8, a1=8, b1=2, N=5000, seed=42) +results_1 = run_sprt_simulation(params_1) + +params_2 = SPRTParams(α=0.05, β=0.10, a0=4, b0=5, a1=5, b1=4, N=5000, seed=42) +results_2 = run_sprt_simulation(params_2) + +params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, b1=0.5, N=5000, seed=42) +results_3 = run_sprt_simulation(params_3) + +# Create comparison plots +fig, axes = plt.subplots(3, 3, figsize=(18, 18)) + +scenarios = [ + (results_1, params_1, "Well-separated", 0), + (results_2, params_2, "Moderate overlap", 1), + (results_3, params_3, "Highly overlapping", 2) +] + +for results, params, title, row in scenarios: + + # Distribution plots + z_grid = np.linspace(0, 1, 200) + axes[row, 0].plot(z_grid, results['f0'].pdf(z_grid), 'b-', lw=2, + label=f'$f_0 = \\text{{Beta}}({params.a0},{params.b0})$') + axes[row, 0].plot(z_grid, results['f1'].pdf(z_grid), 'r-', lw=2, + label=f'$f_1 = \\text{{Beta}}({params.a1},{params.b1})$') + axes[row, 0].fill_between(z_grid, 0, + np.minimum(results['f0'].pdf(z_grid), results['f1'].pdf(z_grid)), + alpha=0.3, color='purple', label='Overlap') + axes[row, 0].set_title(f'{title}') + axes[row, 0].set_xlabel('z') + axes[row, 0].set_ylabel('Density') + axes[row, 0].legend() + + # Stopping times + max_n = max(results['stopping_times'].max(), 101) + bins = np.arange(1, min(max_n, 101)) - 0.5 + axes[row, 1].hist(results['stopping_times'], bins=bins, + color="steelblue", alpha=0.8, edgecolor="black") + axes[row, 1].set_title(f'Stopping times (mean={results["stopping_times"].mean():.1f})') + axes[row, 1].set_xlabel('n') + axes[row, 1].set_ylabel('Frequency') + axes[row, 1].set_xlim(0, 100) + + # Confusion matrix + f0_correct = np.sum(results['truth'] & results['decisions']) + f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) + f1_correct = np.sum((~results['truth']) & (~results['decisions'])) + f1_incorrect = np.sum((~results['truth']) & results['decisions']) + + confusion_data = np.array([[f0_correct, f0_incorrect], + [f1_incorrect, f1_correct]]) + + im = axes[row, 2].imshow(confusion_data, cmap='Blues', aspect='equal') + axes[row, 2].set_title(f'Errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}') + axes[row, 2].set_xlabel('Decision') + axes[row, 2].set_ylabel('Truth') + axes[row, 2].set_xticks([0, 1]) + axes[row, 2].set_xticklabels(['Accept $H_0$', 'Reject $H_0$']) + axes[row, 2].set_yticks([0, 1]) + axes[row, 2].set_yticklabels(['True $f_0$', 'True $f_1$']) + + for i in range(2): + for j in range(2): + color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' + axes[row, 2].text(j, i, f'{confusion_data[i, j]}\n({confusion_data[i, j]/params.N:.1%})', + ha="center", va="center", color=color, fontweight='bold') + +plt.tight_layout() +plt.show() +``` + +Next, let's adjust the decision thresholds $A$ and $B$ and examine how the mean stopping time and the type I and type II error rates change. + +```{code-cell} ipython3 +def run_with_adjusted_thresholds(params, A_factor=1.0, B_factor=1.0): + """Wrapper to run SPRT with adjusted A and B thresholds.""" + + # Calculate original thresholds + A_original = (1 - params.β) / params.α + B_original = params.β / (1 - params.α) + + # Apply adjustment factors + A_adj = A_original * A_factor + B_adj = B_original * B_factor + logA, logB = np.log(A_adj), np.log(B_adj) + + f0 = beta(params.a0, params.b0) + f1 = beta(params.a1, params.b1) + rng = np.random.default_rng(seed=params.seed) + + def sprt_adjusted(true_f0): + log_L = 0.0 + n = 0 + while True: + z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) + n += 1 + log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) + + if log_L >= logA: + return n, False + elif log_L <= logB: + return n, True + + # Run simulation + stopping_times = [] + decisions = [] + truth = [] + + for i in range(params.N): + true_f0 = (i % 2 == 0) + n, decide_f0 = sprt_adjusted(true_f0) + stopping_times.append(n) + decisions.append(decide_f0) + truth.append(true_f0) + + stopping_times = np.asarray(stopping_times) + decisions = np.asarray(decisions) + truth = np.asarray(truth) + + type_I = np.mean(truth & (~decisions)) + type_II = np.mean((~truth) & decisions) + + return { + 'stopping_times': stopping_times, + 'type_I': type_I, + 'type_II': type_II, + 'A_used': A_adj, + 'B_used': B_adj + } + +adjustments = [ + (5.0, 0.5), + (1.0, 1.0), + (0.3, 3.0), + (0.2, 5.0), + (0.15, 7.0), +] + +results_table = [] +for A_factor, B_factor in adjustments: + result = run_with_adjusted_thresholds(params_2, A_factor, B_factor) + results_table.append([ + A_factor, B_factor, + f"{result['stopping_times'].mean():.1f}", + f"{result['type_I']:.3f}", + f"{result['type_II']:.3f}" + ]) + +# Generate markdown table +from IPython.display import Markdown, display + +table_header = """ +| A factor | B factor | Mean Stop Time | Type I Error | Type II Error | +|----------|----------|----------------|--------------|---------------| +""" + +table_rows = "" +for row in results_table: + table_rows += f"| {row[0]} | {row[1]} | {row[2]} | {row[3]} | {row[4]} |\n" + +markdown_table = table_header + table_rows + +display(Markdown(markdown_table)) +``` + +Let's pause and think about the table more carefully by referring back to {eq}`eq:Waldrule`. + +Recall that $A = \frac{1-\beta}{\alpha}$ and $B = \frac{\beta}{1-\alpha}$. + +When we multiply $A$ by a factor less than 1 (making $A$ smaller), we are effectively making it easier to reject the null hypothesis $H_0$. This increases the probability of Type I errors. + +When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are making it easier to accept the null hypothesis $H_0$. This increases the probability of Type II errors. +The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. +This demonstrates the trade-off in sequential testing between speed and accuracy. -[^f1]: The decision maker acts as if he believes that the sequence of random variables -$[z_{0}, z_{1}, \ldots]$ is *exchangeable*. See [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html) and -{cite}`Kreps88` chapter 11, for discussions of exchangeability. ++++ ## Related lectures @@ -568,4 +748,4 @@ We'll dig deeper into some of the ideas used here in the following earlier and l * {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** -* {doc}`this lecture ` takes up the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule +* {doc}`this lecture ` takes up the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule From 5b9fbe850c137f0e87e6332948a19972c17670bb Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 10:51:37 +0800 Subject: [PATCH 03/29] updates --- lectures/wald_friedman.md | 4 +-- lectures/wald_friedman_2.md | 64 +++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 6a0d1194d..83c2f00de 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -278,7 +278,7 @@ A decision-maker can observe a sequence of draws of a random variable $z$. He (or she) wants to know which of two probability distributions $f_0$ or $f_1$ governs $z$. -To illustrate, let's inspect some Beta distributions. +To illustrate, let's inspect some beta distributions. The density of a Beta probability distribution with parameters $a$ and $b$ is @@ -288,7 +288,7 @@ f(z; a, b) = \frac{\Gamma(a+b) z^{a-1} (1-z)^{b-1}}{\Gamma(a) \Gamma(b)} \Gamma(t) := \int_{0}^{\infty} x^{t-1} e^{-x} dx $$ -The next figure shows two Beta distributions. +The next figure shows two beta distributions. ```{code-cell} ipython3 @jit diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 0664cca8d..308c1954d 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.11.5 + jupytext_version: 1.17.2 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -245,10 +245,10 @@ This reasoning suggests a decision rule such as the one shown in the figure As we'll see, this is indeed the correct form of the decision rule. -Our problem is to determine threshold values $\alpha, \beta$ that somehow depend on the parameters described above. +Our problem is to determine threshold values $A, B$ that somehow depend on the parameters described above. You might like to pause at this point and try to predict the impact of a -parameter such as $c$ or $L_0$ on $\alpha$ or $\beta$. +parameter such as $c$ or $L_0$ on $A$ or $B$. ### A Bellman Equation @@ -303,30 +303,30 @@ where $\pi \in [0,1]$ and - $h(\pi) := c + \mathbb E [J(\pi')]$; this is the continuation value; i.e., the expected cost associated with drawing one more $z$. -The optimal decision rule is characterized by two numbers $\alpha, \beta \in (0,1) \times (0,1)$ that satisfy +The optimal decision rule is characterized by two numbers $A, B \in (0,1) \times (0,1)$ that satisfy $$ -(1- \pi) L_0 < \min \{ \pi L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq \alpha +(1- \pi) L_0 < \min \{ \pi L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq A $$ and $$ -\pi L_1 < \min \{ (1-\pi) L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq \beta +\pi L_1 < \min \{ (1-\pi) L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq B $$ The optimal decision rule is then $$ \begin{aligned} -\textrm { accept } f=f_0 \textrm{ if } \pi \geq \alpha \\ -\textrm { accept } f=f_1 \textrm{ if } \pi \leq \beta \\ -\textrm { draw another } z \textrm{ if } \beta \leq \pi \leq \alpha +\textrm { accept } f=f_0 \textrm{ if } \pi \geq A \\ +\textrm { accept } f=f_1 \textrm{ if } \pi \leq B \\ +\textrm { draw another } z \textrm{ if } B \leq \pi \leq A \end{aligned} $$ -Our aim is to compute the cost function $J$, and from it the associated cutoffs $\alpha$ -and $\beta$. +Our aim is to compute the cost function $J$, and from it the associated cutoffs $A$ +and $B$. To make our computations manageable, using {eq}`optdec`, we can write the continuation cost $h(\pi)$ as @@ -529,7 +529,7 @@ To solve the model, we will call our `solve_model` function h_star = solve_model(wf) # Solve the model ``` -We will also set up a function to compute the cutoffs $\alpha$ and $\beta$ +We will also set up a function to compute the cutoffs $A$ and $B$ and plot these on our cost function plot ```{code-cell} ipython3 @@ -551,18 +551,16 @@ def find_cutoff_rule(wf, h): # The cutoff points can be found by differencing these costs with # The Bellman equation (J is always less than or equal to p_c_i) - β = π_grid[np.searchsorted( + B = π_grid[np.searchsorted( payoff_f1 - np.minimum(h, payoff_f0), - 1e-10) - - 1] - α = π_grid[np.searchsorted( + 1e-10) - 1] + A = π_grid[np.searchsorted( np.minimum(h, payoff_f1) - payoff_f0, - 1e-10) - - 1] + 1e-10) - 1] - return (β, α) + return (B, A) -β, α = find_cutoff_rule(wf, h_star) +B, A = find_cutoff_rule(wf, h_star) cost_L0 = (1 - wf.π_grid) * wf.L0 cost_L1 = wf.π_grid * wf.L1 @@ -575,11 +573,11 @@ ax.plot(wf.π_grid, np.amin(np.column_stack([h_star, cost_L0, cost_L1]),axis=1), lw=15, alpha=0.1, color='b', label=r'$J(\pi)$') -ax.annotate(r"$\beta$", xy=(β + 0.01, 0.5), fontsize=14) -ax.annotate(r"$\alpha$", xy=(α + 0.01, 0.5), fontsize=14) +ax.annotate(r"$B$", xy=(B + 0.01, 0.5), fontsize=14) +ax.annotate(r"$A$", xy=(A + 0.01, 0.5), fontsize=14) -plt.vlines(β, 0, β * wf.L0, linestyle="--") -plt.vlines(α, 0, (1 - α) * wf.L1, linestyle="--") +plt.vlines(B, 0, B * wf.L1, linestyle="--") +plt.vlines(A, 0, (1 - A) * wf.L0, linestyle="--") ax.set(xlim=(0, 1), ylim=(0, 0.5 * max(wf.L0, wf.L1)), ylabel="cost", xlabel=r"$\pi$", title="Cost function $J(\pi)$") @@ -588,17 +586,17 @@ plt.legend(borderpad=1.1) plt.show() ``` -The cost function $J$ equals $\pi L_1$ for $\pi \leq \beta$, and $(1-\pi )L_0$ for $\pi -\geq \alpha$. +The cost function $J$ equals $\pi L_1$ for $\pi \leq B$, and $(1-\pi )L_0$ for $\pi +\geq A$. The slopes of the two linear pieces of the cost function $J(\pi)$ are determined by $L_1$ and $- L_0$. The cost function $J$ is smooth in the interior region, where the posterior -probability assigned to $f_0$ is in the indecisive region $\pi \in (\beta, \alpha)$. +probability assigned to $f_0$ is in the indecisive region $\pi \in (B, A)$. The decision-maker continues to sample until the probability that he attaches to -model $f_0$ falls below $\beta$ or above $\alpha$. +model $f_0$ falls below $B$ or above $A$. ### Simulations @@ -631,7 +629,7 @@ def simulate(wf, true_dist, h_star, π_0=0.5): f, f_rvs = wf.f1, wf.f1_rvs # Find cutoffs - β, α = find_cutoff_rule(wf, h_star) + B, A = find_cutoff_rule(wf, h_star) # Initialize a couple of useful variables decision_made = False @@ -639,15 +637,13 @@ def simulate(wf, true_dist, h_star, π_0=0.5): t = 0 while decision_made is False: - # Maybe should specify which distribution is correct one so that - # the draws come from the "right" distribution z = f_rvs() t = t + 1 π = κ(z, π) - if π < β: + if π < B: decision_made = True decision = 1 - elif π > α: + elif π > A: decision_made = True decision = 0 @@ -755,4 +751,4 @@ We'll dig deeper into some of the ideas used here in the following lectures: * {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** -* {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule +* {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule From 9c87b8b9201e6157afa7d714a172df06513c932a Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 11:17:52 +0800 Subject: [PATCH 04/29] updates --- lectures/wald_friedman.md | 31 ++++++++++--------------------- lectures/wald_friedman_2.md | 4 ++-- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 83c2f00de..92295bdb5 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -62,6 +62,8 @@ from numba.experimental import jitclass from math import gamma from scipy.stats import beta from collections import namedtuple +import pandas as pd +from IPython.display import display ``` This lecture uses ideas studied in {doc}`this lecture ` and {doc}`this lecture `. @@ -589,7 +591,7 @@ for results, params, title, row in scenarios: label=f'$f_1 = \\text{{Beta}}({params.a1},{params.b1})$') axes[row, 0].fill_between(z_grid, 0, np.minimum(results['f0'].pdf(z_grid), results['f1'].pdf(z_grid)), - alpha=0.3, color='purple', label='Overlap') + alpha=0.3, color='purple', label='overlap') axes[row, 0].set_title(f'{title}') axes[row, 0].set_xlabel('z') axes[row, 0].set_ylabel('Density') @@ -636,7 +638,7 @@ plt.show() Next, let's adjust the decision thresholds $A$ and $B$ and examine how the mean stopping time and the type I and type II error rates change. ```{code-cell} ipython3 -def run_with_adjusted_thresholds(params, A_factor=1.0, B_factor=1.0): +def run_adjusted_thresholds(params, A_factor=1.0, B_factor=1.0): """Wrapper to run SPRT with adjusted A and B thresholds.""" # Calculate original thresholds @@ -702,7 +704,7 @@ adjustments = [ results_table = [] for A_factor, B_factor in adjustments: - result = run_with_adjusted_thresholds(params_2, A_factor, B_factor) + result = run_adjusted_thresholds(params_2, A_factor, B_factor) results_table.append([ A_factor, B_factor, f"{result['stopping_times'].mean():.1f}", @@ -710,21 +712,11 @@ for A_factor, B_factor in adjustments: f"{result['type_II']:.3f}" ]) -# Generate markdown table -from IPython.display import Markdown, display - -table_header = """ -| A factor | B factor | Mean Stop Time | Type I Error | Type II Error | -|----------|----------|----------------|--------------|---------------| -""" - -table_rows = "" -for row in results_table: - table_rows += f"| {row[0]} | {row[1]} | {row[2]} | {row[3]} | {row[4]} |\n" - -markdown_table = table_header + table_rows - -display(Markdown(markdown_table)) +df = pd.DataFrame(results_table, + columns=["A factor", "B factor", "Mean Stop Time", + "Type I Error", "Type II Error"]) +df = df.set_index(["A factor", "B factor"]) +df ``` Let's pause and think about the table more carefully by referring back to {eq}`eq:Waldrule`. @@ -736,9 +728,6 @@ When we multiply $A$ by a factor less than 1 (making $A$ smaller), we are effect When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are making it easier to accept the null hypothesis $H_0$. This increases the probability of Type II errors. The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. - -This demonstrates the trade-off in sequential testing between speed and accuracy. - +++ ## Related lectures diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 308c1954d..c57357148 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -180,7 +180,7 @@ axes[0].plot(grid, f1(grid), lw=2, label="$f_1$") axes[1].set_title("Mixtures") for π in 0.25, 0.5, 0.75: y = π * f0(grid) + (1 - π) * f1(grid) - axes[1].plot(y, lw=2, label=rf"$\pi_k$ = {π}") + axes[1].plot(y, lw=2, label=fr"$\pi_k$ = {π}") for ax in axes: ax.legend() @@ -580,7 +580,7 @@ plt.vlines(B, 0, B * wf.L1, linestyle="--") plt.vlines(A, 0, (1 - A) * wf.L0, linestyle="--") ax.set(xlim=(0, 1), ylim=(0, 0.5 * max(wf.L0, wf.L1)), ylabel="cost", - xlabel=r"$\pi$", title="Cost function $J(\pi)$") + xlabel=r"$\pi$", title=r"Cost function $J(\pi)$") plt.legend(borderpad=1.1) plt.show() From b42ccf2066ffd761615485fabe7d1fc68138c2a6 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 14:34:14 +0800 Subject: [PATCH 05/29] updates --- .../wald_friedman/wald_dec_rule.pdf | Bin 8458 -> 7355 bytes .../wald_friedman/wald_dec_rule.png | Bin 25698 -> 23656 bytes .../wald_friedman/wald_dec_rule.tex | 8 +- lectures/wald_friedman.md | 121 ++++++++++++++++-- 4 files changed, 112 insertions(+), 17 deletions(-) diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf index f4383cf06f185f805e8340eed829349179e72ec0..4db6649ae2d7aa1db9752ad5a74057f13c9db094 100644 GIT binary patch delta 4051 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 Y2fu(2Ke!7(1^|(g1@Q7}8EXUn0SsT8p8x;= delta 4957 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

W*RktMbuHJhd1hKzI_(qH8 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�R`x!4bT)Q z5>btiDV*rAHRMvW)9z9mPxO{M8ee;q07OyycgS1dXaCDBAMn5Sh|!TQy3eq#)`u*# z8?U#OzsQ%LbRF^Bs7BKlsvnPf+-y7OosE9!oG+`VTj!ywk8~#TKPeg*zFHQg8+DYt znmgO}ajg8}lQq}LbP$h4`w>L6>j=!LARF}-$6Fxzj4WE@pfP{sUYN2%1w=W51IZ}`(g;&Vo(uSn!?1D1_W;D7c99Ol<=Nv`*X1e3# zb9%gv{dPqGE4OCYd%)Lwy^ zCnUtv>Mp<7at!{PZ_P&%=!B|>C?6(&^3iVV7&?a><*32~FLt*6Zdvel!U-N1=%UI_ z^~3Sr*$Vo9c6Z3>uH#clDJ8%ZnC zOu4ozhqL$Mf7MI~2(Kp}T}{d4{{zGi(lfs&sXHAfMx3d)*~1I?2%Mce#Rcmf4K zsb>w}yk48T6jdp(PC)uZwQ6=A9t``VZNgU`qTsN4?@d|I1}gs|v-$U+CL~y0^FA!3 zkGzdA%#YhoFG@VI8Lp4H^_!)GHW>{)8No_i`R06tIrI71!o<8U5{Q`J;Nw zfQew5LKuX1Y0k#t`K%#R+S3-ly2(rLC)ZQ>iEChVoPg8_5U)p&7Wm$DpE$@bcPc8V zKNW#4jMuAvS^k_wr;+%sw(Z}y>qaslo2%Zj&>82w``L$>D<=+v7r11Sm%<0?=cYw@ zzZo(w1XGW_d^$95t&pewJAu9p#zEc10jqoz$!$1uOgy)i^^ z#07FA8VGqHNDrv97ExD5p5gMGbE7RUc7L9gU!u`wJO-?lZoHIo*|3oS!ZvNCYr04* z8{9xOa(CF(I&`&i{@x?NmMD9g1>Wg(S4LT z2eaf8`t#Cce+k~kAe6FG+euwfn;VA!CgMIiLKU!Rvn5$;A#-G}ZH5(WxvC5IHYb+I z+TVwp>wAWEB6USXkQm)$MGRiNNLFXu2#Emzz`u}gT3q4T&5Cd0kL8n_8wc*t&zTmkU_^;x}?8K}y1D1?~h)c&JZ zV6qAcK`!n5G)E6PQ7Rvz9zhO_T4-M#oZn{C?jVcWs|HEaY+Uj3mykIpsKjM^igmmM z$O~i3&qIe?pW%$$*@iIFPBSIB<-578pj0NN?MI?nry}_!(-wZmk&0gm@~CR}VQK(m z5$H@o;+wCMz-!El^_%fx3Yg}n1dKHZ2&?egWsL0w?B4to{tR;9^vp&tZG`hO8Y(g6 zJ+wDfxs$hUJ7iM(MKS0pQw}z!c&?Y@2p=p*xDOZ^=9NR;H)3u zmFdOhY6#VR09Ce{2T`rgaIjXZ=cvNkmXhr(`$BM?4bb+UMVD-GTji;Bw~i!*+l5wr z9UGME@d^Z)6Z1e(k@$TzLgY_vxO7`b+&R0Fy$NvxAS#g>x}pqU&_8p6W4EJ5?~I$! z*$2Pf6-vxclb|+%an$x0YX18taeEOh*~^CDbzmi@Q@-6?B`lYBk|`QAj5JIMte0;- ze{42Lmtgv)PbkMO;KxfmXs&=#ZqM3tbjLzrVndB^jz^rfl{T)`s2zG=qv zBJt#fYwbuDYCShR9m}FjJ^UY~iq}a1 diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.tex b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.tex index 88ed18a4d..3e4a41e4f 100644 --- a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.tex +++ b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.tex @@ -22,14 +22,10 @@ node [midway, anchor=south, outer sep=10pt]{draw again}; \draw [decorate, very thick] (s2) -- (s3) node [midway, anchor=south, outer sep=10pt]{accept $f_0$}; - \node[circle, draw, thin, blue, fill=white!10, scale=0.45] at (a0){}; - \node[below, outer sep=5pt] at (a0){$0$}; \node[circle, draw, thin, blue, fill=white!10, scale=0.45] at (a1){}; - \node[below, outer sep=5pt] at (a1){$A$}; + \node[below, outer sep=5pt] at (a1){$B$}; \node[circle, draw, thin, blue, fill=white!10, scale=0.45] at (a2){}; - \node[below, outer sep=5pt] at (a2){$B$}; - \node[circle, draw, thin, blue, fill=white!10, scale=0.45] at (a3){}; - \node[below, outer sep=5pt] at (a3){$1$}; + \node[below, outer sep=5pt] at (a2){$A$}; \node[below, outer sep=25pt] at (1.5, 0){values of $\pi$}; \end{tikzpicture} diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 92295bdb5..5a77e5f2b 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -431,6 +431,28 @@ Now we can run the simulation following Wald's recommendation. We use the log-likelihood ratio and compare it to the logarithms of the thresholds $\log(A)$ and $\log(B)$. +Below is the algorithm for the simulation. + +1. Compute thresholds $A = \frac{1-\beta}{\alpha}$, $B = \frac{\beta}{1-\alpha}$ and work with $\log A$, $\log B$. + +2. Given true distribution (either $f_0$ or $f_1$): + - Initialize log-likelihood ratio $\log L = 0$ and observation counter $n = 0$ + - Repeat: + - Draw observation $z$ from the true distribution + - Update: $\log L \leftarrow \log L + \log f_1(z) - \log f_0(z)$, $n \leftarrow n + 1$ + - If $\log L \geq \log A$: stop, reject $H_0$ (decide $f_1$) + - If $\log L \leq \log B$: stop, accept $H_0$ (decide $f_0$) + +3. Monte Carlo: Repeat step 2 for $N$ replications with $N/2$ replications for each distribution, compute the empirical type I and type II error rates with + +$$ +\hat{\alpha} = \frac{\text{# of times reject } H_0 \text{ when } f_0 \text{ is true}}{\text{# of replications with } f_0 \text{ true}} +$$ + +$$ +\hat{\beta} = \frac{\text{# of times accept } H_0 \text{ when } f_1 \text{ is true}}{\text{# of replications with } f_1 \text{ true}} +$$ + ```{code-cell} ipython3 def run_sprt_simulation(params): """Run SPRT simulation with given parameters.""" @@ -443,7 +465,7 @@ def run_sprt_simulation(params): f1 = beta(params.a1, params.b1) rng = np.random.default_rng(seed=params.seed) - + def sprt(true_f0): """Run one SPRT until a decision is reached.""" log_L = 0.0 @@ -457,7 +479,7 @@ def run_sprt_simulation(params): return n, False elif log_L <= logB: return n, True - + # Monte Carlo experiment stopping_times = [] decisions = [] @@ -476,9 +498,8 @@ def run_sprt_simulation(params): truth = np.asarray(truth) # Calculate error rates - type_I = np.mean(truth & (~decisions)) - type_II = np.mean((~truth) & decisions) - accuracy = np.mean(decisions == truth) + type_I = np.sum(truth & ~decisions) / np.sum(truth) + type_II = np.sum(~truth & decisions) / np.sum(~truth) return { 'stopping_times': stopping_times, @@ -486,7 +507,6 @@ def run_sprt_simulation(params): 'truth': truth, 'type_I': type_I, 'type_II': type_II, - 'accuracy': accuracy, 'f0': f0, 'f1': f1 } @@ -542,6 +562,7 @@ f1_incorrect = np.sum((~results['truth']) & results['decisions']) confusion_data = np.array([[f0_correct, f0_incorrect], [f1_incorrect, f1_correct]]) +row_totals = confusion_data.sum(axis=1, keepdims=True) fig, ax = plt.subplots() ax.imshow(confusion_data, cmap='Blues', aspect='equal') @@ -552,8 +573,9 @@ ax.set_yticklabels(['true $f_0$', 'true $f_1$']) for i in range(2): for j in range(2): + percent = confusion_data[i, j] / row_totals[i, 0] if row_totals[i, 0] > 0 else 0 color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' - ax.text(j, i, f'{confusion_data[i, j]}\n({confusion_data[i, j]/params.N:.1%})', + ax.text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', ha="center", va="center", color=color, fontweight='bold') plt.tight_layout() @@ -573,7 +595,7 @@ params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, b1=0.5, N=5000, results_3 = run_sprt_simulation(params_3) # Create comparison plots -fig, axes = plt.subplots(3, 3, figsize=(18, 18)) +fig, axes = plt.subplots(3, 3, figsize=(18, 20)) scenarios = [ (results_1, params_1, "Well-separated", 0), @@ -615,6 +637,7 @@ for results, params, title, row in scenarios: confusion_data = np.array([[f0_correct, f0_incorrect], [f1_incorrect, f1_correct]]) + row_totals = confusion_data.sum(axis=1, keepdims=True) im = axes[row, 2].imshow(confusion_data, cmap='Blues', aspect='equal') axes[row, 2].set_title(f'Errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}') @@ -627,14 +650,91 @@ for results, params, title, row in scenarios: for i in range(2): for j in range(2): + percent = confusion_data[i, j] / row_totals[i, 0] if row_totals[i, 0] > 0 else 0 color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' - axes[row, 2].text(j, i, f'{confusion_data[i, j]}\n({confusion_data[i, j]/params.N:.1%})', + axes[row, 2].text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', ha="center", va="center", color=color, fontweight='bold') plt.tight_layout() plt.show() ``` +Let's visualize individual likelihood ratio processes to see how they evolve toward the decision boundaries. + +```{code-cell} ipython3 +def plot_likelihood_paths(params, n_highlight=10, n_background=200): + """Plot likelihood ratio paths""" + + A = (1 - params.β) / params.α + B = params.β / (1 - params.α) + logA, logB = np.log(A), np.log(B) + + f0 = beta(params.a0, params.b0) + f1 = beta(params.a1, params.b1) + + fig, axes = plt.subplots(1, 2, figsize=(14, 7)) + + stopping_times_f0 = [] + stopping_times_f1 = [] + decisions_f0 = [] + decisions_f1 = [] + + # Generate and plot paths for each distribution + for dist_idx, (true_f0, ax, title, color_main) in enumerate([ + (True, axes[0], 'true distribution: $f_0$', 'blue'), + (False, axes[1], 'true distribution: $f_1$', 'red') + ]): + rng = np.random.default_rng(seed=42 + dist_idx) + paths_data = [] + + for path in range(n_background + n_highlight): + log_L_path = [0.0] # Start at 0 + log_L = 0.0 + n = 0 + + while True: + z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) + n += 1 + log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) + log_L_path.append(log_L) + + # Check stopping conditions + if log_L >= logA or log_L <= logB: + decision = log_L >= logA # True = reject H0, False = accept H0 + break + + paths_data.append((log_L_path, n, decision)) + + for i, (path, n, decision) in enumerate(paths_data[:n_background]): + color = 'C1' if decision else 'C0' + ax.plot(range(len(path)), path, color=color, alpha=0.2, linewidth=0.5) + + for i, (path, n, decision) in enumerate(paths_data[n_background:]): + # Color code by decision + color = 'C1' if decision else 'C0' + ax.plot(range(len(path)), path, color=color, alpha=0.8, linewidth=1.5, + label='reject $H_0$' if decision and i == 0 else ('accept $H_0$' if not decision and i == 0 else '')) + + ax.axhline(y=logA, color='C1', linestyle='--', linewidth=2, + label=f'$\\log A = {logA:.2f}$') + ax.axhline(y=logB, color='C0', linestyle='--', linewidth=2, + label=f'$\\log B = {logB:.2f}$') + ax.axhline(y=0, color='black', linestyle='-', alpha=0.5, linewidth=1) + + ax.set_xlabel('observation number') + ax.set_ylabel('log-likelihood ratio') + ax.set_title(title) + ax.legend() + + y_margin = max(abs(logA), abs(logB)) * 0.2 + ax.set_ylim(logB - y_margin, logA + y_margin) + + plt.tight_layout() + plt.show() + +plot_likelihood_paths(params_3, n_highlight=10, n_background=100) +``` + Next, let's adjust the decision thresholds $A$ and $B$ and examine how the mean stopping time and the type I and type II error rates change. ```{code-cell} ipython3 @@ -727,8 +827,7 @@ When we multiply $A$ by a factor less than 1 (making $A$ smaller), we are effect When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are making it easier to accept the null hypothesis $H_0$. This increases the probability of Type II errors. -The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. -+++ +The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. ## Related lectures From 4ea6914b7a3b09f378964186722645e2ccdfb2a9 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 14:46:14 +0800 Subject: [PATCH 06/29] updates --- lectures/wald_friedman.md | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 5a77e5f2b..3718af0f7 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -598,9 +598,9 @@ results_3 = run_sprt_simulation(params_3) fig, axes = plt.subplots(3, 3, figsize=(18, 20)) scenarios = [ - (results_1, params_1, "Well-separated", 0), - (results_2, params_2, "Moderate overlap", 1), - (results_3, params_3, "Highly overlapping", 2) + (results_1, params_1, "well-separated", 0), + (results_2, params_2, "moderate overlap", 1), + (results_3, params_3, "highly overlapping", 2) ] for results, params, title, row in scenarios: @@ -616,7 +616,7 @@ for results, params, title, row in scenarios: alpha=0.3, color='purple', label='overlap') axes[row, 0].set_title(f'{title}') axes[row, 0].set_xlabel('z') - axes[row, 0].set_ylabel('Density') + axes[row, 0].set_ylabel('density') axes[row, 0].legend() # Stopping times @@ -626,7 +626,7 @@ for results, params, title, row in scenarios: color="steelblue", alpha=0.8, edgecolor="black") axes[row, 1].set_title(f'Stopping times (mean={results["stopping_times"].mean():.1f})') axes[row, 1].set_xlabel('n') - axes[row, 1].set_ylabel('Frequency') + axes[row, 1].set_ylabel('frequency') axes[row, 1].set_xlim(0, 100) # Confusion matrix @@ -641,12 +641,10 @@ for results, params, title, row in scenarios: im = axes[row, 2].imshow(confusion_data, cmap='Blues', aspect='equal') axes[row, 2].set_title(f'Errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}') - axes[row, 2].set_xlabel('Decision') - axes[row, 2].set_ylabel('Truth') axes[row, 2].set_xticks([0, 1]) - axes[row, 2].set_xticklabels(['Accept $H_0$', 'Reject $H_0$']) + axes[row, 2].set_xticklabels(['accept $H_0$', 'reject $H_0$']) axes[row, 2].set_yticks([0, 1]) - axes[row, 2].set_yticklabels(['True $f_0$', 'True $f_1$']) + axes[row, 2].set_yticklabels(['true $f_0$', 'true $f_1$']) for i in range(2): for j in range(2): @@ -721,8 +719,8 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): label=f'$\\log B = {logB:.2f}$') ax.axhline(y=0, color='black', linestyle='-', alpha=0.5, linewidth=1) - ax.set_xlabel('observation number') - ax.set_ylabel('log-likelihood ratio') + ax.set_xlabel(r'$n$') + ax.set_ylabel(r'$log(L_m)$') ax.set_title(title) ax.legend() From 0d86e73e5948010e452859b437a06d84b186307f Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 24 Jun 2025 18:09:30 +0800 Subject: [PATCH 07/29] update code --- .../wald_friedman/wald_dec_rule.pdf | Bin 7355 -> 9692 bytes .../wald_friedman/wald_dec_rule.png | Bin 23656 -> 26557 bytes .../wald_friedman/wald_dec_rule.tex | 2 +- .../wald_friedman_2/wald_dec_rule.pdf | Bin 0 -> 7355 bytes .../wald_friedman_2/wald_dec_rule.png | Bin 0 -> 23656 bytes .../wald_friedman_2/wald_dec_rule.tex | 32 +++ lectures/wald_friedman.md | 193 +++++++++++++----- lectures/wald_friedman_2.md | 21 +- 8 files changed, 173 insertions(+), 75 deletions(-) create mode 100644 lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.pdf create mode 100644 lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.png create mode 100644 lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.tex diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf index 4db6649ae2d7aa1db9752ad5a74057f13c9db094..532dbd63f509fd73275158f21c9d625608d02d8b 100644 GIT binary patch delta 6209 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 literal 0 HcmV?d00001 diff --git a/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.png b/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.png new file mode 100644 index 0000000000000000000000000000000000000000..c221201659ebd5493a79863c23d85f09232de9d6 GIT binary patch literal 23656 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 and {doc}`this lecture `. @@ -362,8 +361,8 @@ Wald proceeds as follows. He defines -- $p_{0m} = f_0(z_0) \cdots f_0(z_k)$ -- $p_{1m} = f_1(z_0) \cdots f_1(z_k)$ +- $p_{0m} = f_0(z_0) \cdots f_0(z_m)$ +- $p_{1m} = f_1(z_0) \cdots f_1(z_m)$ - $L_{m} = \frac{p_{1m}}{p_{0m}}$ Here $\{L_m\}_{m=0}^\infty$ is a **likelihood ratio process**. @@ -488,9 +487,9 @@ def run_sprt_simulation(params): for i in range(params.N): # Alternate true distribution for each simulation true_f0 = (i % 2 == 0) - n, decide_f0 = sprt(true_f0) + n, accept_f0 = sprt(true_f0) stopping_times.append(n) - decisions.append(decide_f0) + decisions.append(accept_f0) truth.append(true_f0) stopping_times = np.asarray(stopping_times) @@ -511,13 +510,93 @@ def run_sprt_simulation(params): 'f1': f1 } +def run_sprt_single_distribution(params, use_f0=True): + """ + Run SPRT simulation drawing from only one distribution. + + This is a version of the function above except the previous + function alternates between the two distributions automatically. + """ + + A = (1 - params.β) / params.α + B = params.β / (1 - params.α) + logA, logB = np.log(A), np.log(B) + + f0 = beta(params.a0, params.b0) + f1 = beta(params.a1, params.b1) + + rng = np.random.default_rng(seed=params.seed) + + def sprt(true_f0): + """Run one SPRT until a decision is reached.""" + log_L = 0.0 + n = 0 + while True: + z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) + n += 1 + log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) + + if log_L >= logA: + return n, False # Reject H0 (decide f1) + elif log_L <= logB: + return n, True # Accept H0 (decide f0) + + # Monte Carlo experiment - all draws from same distribution + stopping_times = [] + decisions = [] + truth = [] + + for i in range(params.N): + # Use the same distribution for all simulations + true_f0 = use_f0 + n, accept_f0 = sprt(true_f0) + stopping_times.append(n) + decisions.append(accept_f0) + truth.append(true_f0) + + stopping_times = np.asarray(stopping_times) + decisions = np.asarray(decisions) + truth = np.asarray(truth) + + # Calculate error rates based on which distribution was used + if use_f0: + # All samples from f0, so we can only calculate type I error + type_I = np.sum(~decisions) / len(decisions) # Rejecting H0 when f0 is true + type_II = None + else: + # All samples from f1, so we can only calculate type II error + type_I = None + type_II = np.sum(decisions) / len(decisions) # Accepting H0 when f1 is true + + return { + 'stopping_times': stopping_times, + 'decisions': decisions, + 'truth': truth, + 'type_I': type_I, + 'type_II': type_II, + 'f0': f0, + 'f1': f1, + 'distribution_used': 'f0' if use_f0 else 'f1' + } + # Run simulation -params = SPRTParams(α=0.05, β=0.10, a0=2, b0=5, a1=5, b1=2, N=15000, seed=1) +params = SPRTParams(α=0.05, β=0.10, a0=2, b0=5, a1=5, b1=2, N=20000, seed=1) results = run_sprt_simulation(params) print(f"Average stopping time: {results['stopping_times'].mean():.2f}") print(f"Empirical type I error: {results['type_I']:.3f} (target = {params.α})") print(f"Empirical type II error: {results['type_II']:.3f} (target = {params.β})") + +print("\nDrawing only from f0 (null hypothesis):") +results_f0 = run_sprt_single_distribution(params, use_f0=True) +print(f"Average stopping time: {results_f0['stopping_times'].mean():.2f}") +print(f"Empirical type I error: {results_f0['type_I']:.3f} (target = {params.α})") + + +print("\nDrawing only from f1 (alternative hypothesis):") +results_f1 = run_sprt_single_distribution(params, use_f0=False) +print(f"Average stopping time: {results_f1['stopping_times'].mean():.2f}") +print(f"Empirical type II error: {results_f1['type_II']:.3f} (target = {params.β})") ``` We visualize the two distributions and the distribution of stopping times to reach a decision. @@ -594,40 +673,36 @@ results_2 = run_sprt_simulation(params_2) params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, b1=0.5, N=5000, seed=42) results_3 = run_sprt_simulation(params_3) -# Create comparison plots -fig, axes = plt.subplots(3, 3, figsize=(18, 20)) - -scenarios = [ - (results_1, params_1, "well-separated", 0), - (results_2, params_2, "moderate overlap", 1), - (results_3, params_3, "highly overlapping", 2) -] - -for results, params, title, row in scenarios: +def plot_sprt_results(results, params, title=""): + """Plot SPRT simulation results with distributions, stopping times, and confusion matrix.""" + fig, axes = plt.subplots(1, 3, figsize=(22, 8)) # Distribution plots z_grid = np.linspace(0, 1, 200) - axes[row, 0].plot(z_grid, results['f0'].pdf(z_grid), 'b-', lw=2, + axes[0].plot(z_grid, results['f0'].pdf(z_grid), 'b-', lw=2, label=f'$f_0 = \\text{{Beta}}({params.a0},{params.b0})$') - axes[row, 0].plot(z_grid, results['f1'].pdf(z_grid), 'r-', lw=2, + axes[0].plot(z_grid, results['f1'].pdf(z_grid), 'r-', lw=2, label=f'$f_1 = \\text{{Beta}}({params.a1},{params.b1})$') - axes[row, 0].fill_between(z_grid, 0, + axes[0].fill_between(z_grid, 0, np.minimum(results['f0'].pdf(z_grid), results['f1'].pdf(z_grid)), alpha=0.3, color='purple', label='overlap') - axes[row, 0].set_title(f'{title}') - axes[row, 0].set_xlabel('z') - axes[row, 0].set_ylabel('density') - axes[row, 0].legend() + if title: + axes[0].set_title(title, fontsize=25) + axes[0].set_xlabel('z', fontsize=25) + axes[0].set_ylabel('density', fontsize=25) + axes[0].legend(fontsize=18) + axes[0].tick_params(axis='both', which='major', labelsize=18) # Stopping times max_n = max(results['stopping_times'].max(), 101) bins = np.arange(1, min(max_n, 101)) - 0.5 - axes[row, 1].hist(results['stopping_times'], bins=bins, + axes[1].hist(results['stopping_times'], bins=bins, color="steelblue", alpha=0.8, edgecolor="black") - axes[row, 1].set_title(f'Stopping times (mean={results["stopping_times"].mean():.1f})') - axes[row, 1].set_xlabel('n') - axes[row, 1].set_ylabel('frequency') - axes[row, 1].set_xlim(0, 100) + axes[1].set_title(f'stopping times (mean={results["stopping_times"].mean():.1f})', fontsize=25) + axes[1].set_xlabel('n', fontsize=25) + axes[1].set_ylabel('frequency', fontsize=25) + axes[1].set_xlim(0, 100) + axes[1].tick_params(axis='both', which='major', labelsize=18) # Confusion matrix f0_correct = np.sum(results['truth'] & results['decisions']) @@ -639,22 +714,36 @@ for results, params, title, row in scenarios: [f1_incorrect, f1_correct]]) row_totals = confusion_data.sum(axis=1, keepdims=True) - im = axes[row, 2].imshow(confusion_data, cmap='Blues', aspect='equal') - axes[row, 2].set_title(f'Errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}') - axes[row, 2].set_xticks([0, 1]) - axes[row, 2].set_xticklabels(['accept $H_0$', 'reject $H_0$']) - axes[row, 2].set_yticks([0, 1]) - axes[row, 2].set_yticklabels(['true $f_0$', 'true $f_1$']) + im = axes[2].imshow(confusion_data, cmap='Blues', aspect='equal') + axes[2].set_title(f'errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}', fontsize=25) + axes[2].set_xticks([0, 1]) + axes[2].set_xticklabels(['accept $H_0$', 'reject $H_0$'], fontsize=22) + axes[2].set_yticks([0, 1]) + axes[2].set_yticklabels(['true $f_0$', 'true $f_1$'], fontsize=22) + axes[2].tick_params(axis='both', which='major', labelsize=18) + for i in range(2): for j in range(2): percent = confusion_data[i, j] / row_totals[i, 0] if row_totals[i, 0] > 0 else 0 color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' - axes[row, 2].text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', - ha="center", va="center", color=color, fontweight='bold') + axes[2].text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', + ha="center", va="center", color=color, fontweight='bold', fontsize=18) -plt.tight_layout() -plt.show() + plt.tight_layout() + plt.show() +``` + +```{code-cell} ipython3 +plot_sprt_results(results_1, params_1) +``` + +```{code-cell} ipython3 +plot_sprt_results(results_2, params_2) +``` + +```{code-cell} ipython3 +plot_sprt_results(results_3, params_3) ``` Let's visualize individual likelihood ratio processes to see how they evolve toward the decision boundaries. @@ -672,15 +761,10 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): fig, axes = plt.subplots(1, 2, figsize=(14, 7)) - stopping_times_f0 = [] - stopping_times_f1 = [] - decisions_f0 = [] - decisions_f1 = [] - # Generate and plot paths for each distribution - for dist_idx, (true_f0, ax, title, color_main) in enumerate([ - (True, axes[0], 'true distribution: $f_0$', 'blue'), - (False, axes[1], 'true distribution: $f_1$', 'red') + for dist_idx, (true_f0, ax, title) in enumerate([ + (True, axes[0], 'true distribution: $f_0$'), + (False, axes[1], 'true distribution: $f_1$') ]): rng = np.random.default_rng(seed=42 + dist_idx) paths_data = [] @@ -702,7 +786,7 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): break paths_data.append((log_L_path, n, decision)) - + for i, (path, n, decision) in enumerate(paths_data[:n_background]): color = 'C1' if decision else 'C0' ax.plot(range(len(path)), path, color=color, alpha=0.2, linewidth=0.5) @@ -711,7 +795,8 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): # Color code by decision color = 'C1' if decision else 'C0' ax.plot(range(len(path)), path, color=color, alpha=0.8, linewidth=1.5, - label='reject $H_0$' if decision and i == 0 else ('accept $H_0$' if not decision and i == 0 else '')) + label='reject $H_0$' if decision and i == 0 else ( + 'accept $H_0$' if not decision and i == 0 else '')) ax.axhline(y=logA, color='C1', linestyle='--', linewidth=2, label=f'$\\log A = {logA:.2f}$') @@ -721,8 +806,8 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): ax.set_xlabel(r'$n$') ax.set_ylabel(r'$log(L_m)$') - ax.set_title(title) - ax.legend() + ax.set_title(title, fontsize=20) + ax.legend(fontsize=18, loc='center right') y_margin = max(abs(logA), abs(logB)) * 0.2 ax.set_ylim(logB - y_margin, logA + y_margin) @@ -772,17 +857,17 @@ def run_adjusted_thresholds(params, A_factor=1.0, B_factor=1.0): for i in range(params.N): true_f0 = (i % 2 == 0) - n, decide_f0 = sprt_adjusted(true_f0) + n, accept_f0 = sprt_adjusted(true_f0) stopping_times.append(n) - decisions.append(decide_f0) + decisions.append(accept_f0) truth.append(true_f0) stopping_times = np.asarray(stopping_times) decisions = np.asarray(decisions) truth = np.asarray(truth) - type_I = np.mean(truth & (~decisions)) - type_II = np.mean((~truth) & decisions) + type_I = np.sum(truth & (~decisions)) / np.sum(truth) + type_II = np.sum((~truth) & decisions) / np.sum(~truth) return { 'stopping_times': stopping_times, diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index c57357148..d5348afd3 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -71,25 +71,6 @@ This lecture uses ideas studied in {doc}`this lecture We'll formulate the problem using dynamic programming. -## Message/request for Humphrey - -Below in order to remove some bad recycling of notation, I ask you everywhre in the Dynamic programming presentation below please to - -* change $\alpha$ to $A$ -* change $\beta$ to $B$ - -However, if there are places where $\alpha$ is used to be the probability of a type I error -and $\beta$ is used to be the probability of a type II error, please don't change them. There might be a few such cases. - -This request applies to the - -* written text -* the graphs -* the Python code I suppose - -this is the end of the "message" - - ## A Dynamic Programming Approach The following presentation of the problem closely follows Dmitri @@ -239,7 +220,7 @@ Finally, if $\pi$ is in the middle of the interval $[0, 1]$, then we are confron This reasoning suggests a decision rule such as the one shown in the figure -```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png +```{figure} /_static/lecture_specific/wald_friedman_2/wald_dec_rule.png ``` From 350741ff72905b10280a11a823b543b4d039f9b4 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 09:45:36 +0800 Subject: [PATCH 08/29] updates --- .../wald_friedman/wald_dec_rule.pdf | Bin 9692 -> 9760 bytes .../wald_friedman/wald_dec_rule.png | Bin 26557 -> 26484 bytes .../wald_friedman/wald_dec_rule.tex | 6 +- lectures/wald_friedman.md | 71 +++++++++++++----- 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf index 532dbd63f509fd73275158f21c9d625608d02d8b..20d8d5c84328b3c413b9aa5be110c0496ecfb25a 100644 GIT binary patch delta 5589 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 delta 5374 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%0AJ>E4+Alu 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 U>t9E= logA: return n, False + + # If the log-likelihood ratio is less than the threshold, accept the null hypothesis elif log_L <= logB: return n, True @@ -485,7 +496,10 @@ def run_sprt_simulation(params): truth = [] for i in range(params.N): - # Alternate true distribution for each simulation + # H0 is true for half of the simulations and H1 is true for the other half + # Later we will calculate the type I and type II errors by counting the number of times + # we reject H0 when H0 is true and accept H0 when H0 is false divided by the number of simulations + # for each distribution true_f0 = (i % 2 == 0) n, accept_f0 = sprt(true_f0) stopping_times.append(n) @@ -497,8 +511,12 @@ def run_sprt_simulation(params): truth = np.asarray(truth) # Calculate error rates - type_I = np.sum(truth & ~decisions) / np.sum(truth) - type_II = np.sum(~truth & decisions) / np.sum(~truth) + + # For type I error: P(reject H0 | H0 is true) = P(H0 is true and reject H0) / P(H0 is true) + type_I = np.mean(truth & ~decisions) / np.mean(truth) + + # For type II error: P(accept H0 | H0 is false) = P(H0 is false and accept H0) / P(H0 is false) + type_II = np.mean(~truth & decisions) / np.mean(~truth) return { 'stopping_times': stopping_times, @@ -517,14 +535,16 @@ def run_sprt_single_distribution(params, use_f0=True): This is a version of the function above except the previous function alternates between the two distributions automatically. """ - + # Define the thresholds A = (1 - params.β) / params.α B = params.β / (1 - params.α) logA, logB = np.log(A), np.log(B) + # Define the two distributions f0 = beta(params.a0, params.b0) f1 = beta(params.a1, params.b1) + # Set the random number generator rng = np.random.default_rng(seed=params.seed) def sprt(true_f0): @@ -532,14 +552,20 @@ def run_sprt_single_distribution(params, use_f0=True): log_L = 0.0 n = 0 while True: + # Draw a random variable from the true distribution z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) n += 1 + + # Update the log-likelihood ratio log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) + # If the log-likelihood ratio is greater than the threshold, reject the null hypothesis if log_L >= logA: - return n, False # Reject H0 (decide f1) + return n, False + + # If the log-likelihood ratio is less than the threshold, accept the null hypothesis elif log_L <= logB: - return n, True # Accept H0 (decide f0) + return n, True # Monte Carlo experiment - all draws from same distribution stopping_times = [] @@ -599,6 +625,9 @@ print(f"Average stopping time: {results_f1['stopping_times'].mean():.2f}") print(f"Empirical type II error: {results_f1['type_II']:.3f} (target = {params.β})") ``` +We can see that the single distribution simulations are the same as the two distribution simulations +subject to Monte Carlo sampling differences. + We visualize the two distributions and the distribution of stopping times to reach a decision. ```{code-cell} ipython3 @@ -631,13 +660,14 @@ In this simple case, the stopping time stays below 10. We can also examine the confusion matrix for this decision problem. -The diagonal elements show the number of times when Wald's rule results in correct acceptance/rejection of the null hypothesis. +The diagonal elements show the number of times when Wald's rule results in +correct acceptance/rejection of the null hypothesis. ```{code-cell} ipython3 -f0_correct = np.sum(results['truth'] & results['decisions']) -f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) -f1_correct = np.sum((~results['truth']) & (~results['decisions'])) -f1_incorrect = np.sum((~results['truth']) & results['decisions']) +f0_correct = np.sum(results['truth'] & results['decisions']) # Accept H0 when H0 is true +f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) # Reject H0 when H0 is true +f1_correct = np.sum((~results['truth']) & (~results['decisions'])) # Accept H0 when H1 is true +f1_incorrect = np.sum((~results['truth']) & results['decisions']) # Reject H0 when H1 is true confusion_data = np.array([[f0_correct, f0_incorrect], [f1_incorrect, f1_correct]]) @@ -661,7 +691,8 @@ plt.tight_layout() plt.show() ``` -Now we compare three different scenarios with varying degrees of overlap between the distributions: +Now we compare three different scenarios with varying degrees of overlap between the distributions +using the three plots we have just seen ```{code-cell} ipython3 params_1 = SPRTParams(α=0.05, β=0.10, a0=2, b0=8, a1=8, b1=2, N=5000, seed=42) From 120870757b93ef6eece7a5eeb93c49c8ad525914 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 09:47:31 +0800 Subject: [PATCH 09/29] updates --- lectures/wald_friedman.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 6277899cb..fccbebe88 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -439,8 +439,8 @@ Below is the algorithm for the simulation. - Repeat: - Draw observation $z$ from the true distribution - Update: $\log L_{n+1} \leftarrow \log L_n + (\log f_1(z) - \log f_0(z))$ - - If $\log L_{n+1} \geq \log A$: stop, reject $H_0$ (decide $f_1$) - - If $\log L_{n+1} \leq \log B$: stop, accept $H_0$ (decide $f_0$) + - If $\log L_{n+1} \geq \log A$: stop, reject $H_0$ + - If $\log L_{n+1} \leq \log B$: stop, accept $H_0$ 3. Monte Carlo: Repeat step 2 for $N$ replications with $N/2$ replications for each distribution, compute the empirical type I and type II error rates with From e3c35ce4cc1f9663b3760d0869787d542d7207ff Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 09:53:06 +0800 Subject: [PATCH 10/29] minor update --- lectures/_static/quant-econ.bib | 9 ++++++++- lectures/wald_friedman.md | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lectures/_static/quant-econ.bib b/lectures/_static/quant-econ.bib index f0ae49852..1b6e4dbd2 100644 --- a/lectures/_static/quant-econ.bib +++ b/lectures/_static/quant-econ.bib @@ -2568,4 +2568,11 @@ @article{hall1971dynamic pages={229--244}, year={1971}, publisher={Wiley-Blackwell} -} \ No newline at end of file +} + +@article{fischer2024improving, + title={Improving the (approximate) sequential probability ratio test by avoiding overshoot}, + author={Fischer, Lasse and Ramdas, Aaditya}, + journal={arXiv preprint arXiv:2410.16076}, + year={2024} +} diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index fccbebe88..afe1f3651 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -628,6 +628,11 @@ print(f"Empirical type II error: {results_f1['type_II']:.3f} (target = {params We can see that the single distribution simulations are the same as the two distribution simulations subject to Monte Carlo sampling differences. +We find that the algorithm "overshoots" the error rates by giving us a +lower type I and type II error rates than the target values. + +This has been documented in the literature (see, e.g., {cite}`fischer2024improving`). + We visualize the two distributions and the distribution of stopping times to reach a decision. ```{code-cell} ipython3 From db6e9af1d667ad5aa90081fcaa7b15895d1e8a3e Mon Sep 17 00:00:00 2001 From: thomassargent30 Date: Wed, 25 Jun 2025 13:19:24 +0800 Subject: [PATCH 11/29] Tom's June 25 edits of first Wald-Friedman lecture --- lectures/wald_friedman.md | 89 ++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 34 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index afe1f3651..64cfdb21a 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -48,9 +48,11 @@ Key ideas in play will be: - a type I error occurs when you reject a null hypothesis that is true - a type II error occures when you accept a null hypothesis that is false - Abraham Wald's **sequential probability ratio test** -- The **power** of a statistical test +- The **power** of a frequentist statistical test +- The **size** of a frequentist statistical test - The **critical region** of a statistical test - A **uniformly most powerful test** +- The role of a Law of Large Numbers (LLN) in interpreting **power** and **size** of a frequentist statistical test We'll begin with some imports: @@ -67,7 +69,7 @@ import pandas as pd This lecture uses ideas studied in {doc}`this lecture ` and {doc}`this lecture `. -## Origin of the Problem +## Source of the Problem On pages 137-139 of his 1998 book *Two Lucky People* with Rose Friedman {cite}`Friedman98`, Milton Friedman described a problem presented to him and Allen Wallis @@ -107,8 +109,8 @@ Let's listen to Milton Friedman tell us what happened > because it is obviously superior beyond what was hoped for > $\ldots$. -Friedman and Wallis struggled with the problem but, after realizing that -they were not able to solve it, described the problem to Abraham Wald. +Friedman and Wallis worked on the problem but, after realizing that +they were not able to solve it, they described the problem to Abraham Wald. That started Wald on the path that led him to *Sequential Analysis* {cite}`Wald47`. @@ -119,8 +121,8 @@ that Navy Captain G. S. Schuyler had been told to use and that led him to approach Milton Friedman and Allan Wallis to convey his conjecture that superior practical procedures existed. -Evidently, the Navy had told Captail Schuyler to use what was then the state-of-the-art -Neyman-Pearson test. +Evidently, the Navy had told Captain Schuyler to use what was then a state-of-the-art +Neyman-Pearson hypothesis test. We'll rely on Abraham Wald's {cite}`Wald47` elegant summary of Neyman-Pearson theory. @@ -128,8 +130,8 @@ Watch for these features of the setup: - the assumption of a *fixed* sample size $n$ - the application of laws of large numbers, conditioned on alternative - probability models, to interpret the probabilities $\alpha$ and - $\beta$ defined in the Neyman-Pearson theory + probability models, to interpret probabilities $\alpha$ and + $\beta$ of the type I and type II errors defined in the Neyman-Pearson theory In chapter 1 of **Sequential Analysis** {cite}`Wald47` Abraham Wald summarizes the @@ -263,14 +265,14 @@ Here is how Wald introduces the notion of a sequential test > a random variable, since the value of n depends on the outcome of the > observations. -## Wald's sequential formulation +## Wald's Sequential Formulation -In contradistinction to Neyman-Pearson formulation of the problemm, in Wald's formulation +In contradistinction to Neyman and Pearson's formulation of the problemm, in Wald's formulation -- The sample size $n$ is not fixed but rather an object to be - chosen; technically $n$ is a random variable. -- Two parameters $A$ and $B$ that are related to but distinct from Neyman and Pearson's $\alpha$ and $\beta$, characterize cut-off rules that Wald uses to determine the random variable $n$. +- The sample size $n$ is not fixed but rather a random variable. +- Two parameters $A$ and $B$ that are related to but distinct from Neyman and Pearson's $\alpha$ and $\beta$; +$A$ and $B$ characterize cut-off rules that Wald uses to determine the random variable $n$ as a function of random outcomes. Here is how Wald sets up the problem. @@ -353,9 +355,6 @@ chooses among three distinct actions: - He postpones deciding now and instead chooses to draw a $z_{k+1}$ -```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png - -``` Wald proceeds as follows. @@ -379,7 +378,14 @@ $$ \end{aligned} $$ -### Links between $A,B$ and $\alpha, \beta$ + +The following figure illustrates aspects of Wald's procedure. + +```{figure} /_static/lecture_specific/wald_friedman/wald_dec_rule.png + +``` + +## Links Between $A,B$ and $\alpha, \beta$ In chapter 3 of **Sequential Analysis** {cite}`Wald47` Wald establishes the inequalities @@ -390,31 +396,47 @@ $$ \end{align} $$ -His analysis of these inequalities leads Wald to recommend the following as rules for setting +His analysis of these inequalities leads Wald to recommend the following approximations as rules for setting $A$ and $B$ that come close to attaining a decision maker's target values for probabilities $\alpha$ of a type I and $\beta$ of a type II error: $$ \begin{align} -A(\alpha,\beta) & = \frac{1-\beta}{\alpha} \\ -B(\alpha,\beta) & = \frac{\beta}{1-\alpha} +A \approx a(\alpha,\beta) & \equiv \frac{1-\beta}{\alpha} \\ +B \approx b(\alpha,\beta) & \equiv \frac{\beta}{1-\alpha} \end{align} $$ (eq:Waldrule) - For small values of $\alpha $ and $\beta$, Wald shows that {eq}`eq:Waldrule` provides good ways to set $A$ and $B$. +For small values of $\alpha $ and $\beta$, Wald shows that approximation {eq}`eq:Waldrule` provides a good way to set $A$ and $B$. + +In particular, Wald constructs a mathematical argument that leads him to conclude that the use of approximation + {eq}`eq:Waldrule` rather than the true functions $A (\alpha, \beta), B(\alpha,\beta)$ for setting $A$ and $B$ + + > $\ldots$ cannot result in any appreciable increase in the value of either $\alpha$ or $\beta$. In other words, + > for all practical purposes the test corresponding to $A = a(\alpha, \beta), B = b(\alpha,\beta)$ provides as + > least the same protection against wrong decisions as the test corresponding to $A = A(\alpha, \beta)$ and + > $B = b(\alpha, \beta)$. + + > Thus, the only disadvantage that may arise from using $ a(\alpha, \beta), b(\alpha,\beta)$ instead of + > $ A(\alpha, \beta), B(\alpha,\beta)$, respectively, is that it may result in an appreciable increase in + > the number of observations required by the test. + + ## Simulations In this section, we experiment with different distributions $f_0$ and $f_1$ to examine how Wald's test performs under various conditions. -The goal of these simulations is to understand the trade-offs between decision speed and accuracy in sequential hypothesis testing. +The goal of these simulations is to understand trade-offs between decision speed and accuracy associated with Wald's **sequential probability ratio test**. -Specifically, we will see how: +Specifically, we will watch how: - The decision thresholds $A$ and $B$ (or equivalently the target error rates $\alpha$ and $\beta$) affect the average stopping time -- The separability between distributions affects the average stopping time +- The discrepancy between distributions $f_0$ and $f_1$ affects average stopping times + +We will focus on the case where $f_0$ and $f_1$ are beta distributions since it is easy to control the overlapping regions of the two densities by adjusting their shape parameters. -We will focus on the case where $f_0$ and $f_1$ are beta distributions since it is easy to control the overlapping regions of the two densities by adjusting their shape parameters. +**Tom and Humphrey: maybe we should compute relative entropies of $f_0, f_1$ and make a graph of mean stoppcing times versus relative entropy. We could link nicely to the lecture in the series that talks about relative entropy.** First, we define a namedtuple to store all the parameters we need for our simulation studies. @@ -628,12 +650,14 @@ print(f"Empirical type II error: {results_f1['type_II']:.3f} (target = {params We can see that the single distribution simulations are the same as the two distribution simulations subject to Monte Carlo sampling differences. -We find that the algorithm "overshoots" the error rates by giving us a +As anticipated in the passage above in which Wald discussed the quality of $a(\alpha), \beta), b(\alpha, \beta)$ given in approximation {eq}`eq:Waldrule`, we find that the algorithm "overshoots" the error rates by giving us a lower type I and type II error rates than the target values. -This has been documented in the literature (see, e.g., {cite}`fischer2024improving`). +```{note} +For recent work on the quality of approximation {eq}`eq:Waldrule`, see, e.g., {cite}`fischer2024improving`. +``` -We visualize the two distributions and the distribution of stopping times to reach a decision. +The following code constructs a graph that lets us visualize two distributions and the distribution of stimes to reach a decision. ```{code-cell} ipython3 fig, axes = plt.subplots(1, 2, figsize=(14, 5)) @@ -663,10 +687,7 @@ plt.show() In this simple case, the stopping time stays below 10. -We can also examine the confusion matrix for this decision problem. - -The diagonal elements show the number of times when Wald's rule results in -correct acceptance/rejection of the null hypothesis. +We can also examine a $2 \times 2$ "confusion matrix" whose diagonal elements show the number of times when Wald's rule results in correct acceptance and rejection of the null hypothesis. ```{code-cell} ipython3 f0_correct = np.sum(results['truth'] & results['decisions']) # Accept H0 when H0 is true @@ -696,8 +717,8 @@ plt.tight_layout() plt.show() ``` -Now we compare three different scenarios with varying degrees of overlap between the distributions -using the three plots we have just seen +Next we use our code to study three different $f_0, f_1$ pairs having different discrepancies between distributions. + ```{code-cell} ipython3 params_1 = SPRTParams(α=0.05, β=0.10, a0=2, b0=8, a1=8, b1=2, N=5000, seed=42) From d7cc97cfcc344916c18c6c3bba5be825104f4893 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 15:46:51 +0800 Subject: [PATCH 12/29] updates --- lectures/wald_friedman.md | 414 ++++++++++++++++++++------------------ 1 file changed, 222 insertions(+), 192 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 64cfdb21a..c3109f1c5 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -59,7 +59,7 @@ We'll begin with some imports: ```{code-cell} ipython3 import numpy as np import matplotlib.pyplot as plt -from numba import jit, prange, float64, int64 +from numba import njit, prange from numba.experimental import jitclass from math import gamma from scipy.stats import beta @@ -294,13 +294,13 @@ $$ The next figure shows two beta distributions. ```{code-cell} ipython3 -@jit -def p(x, a, b): +@njit +def beta_pdf(x, a, b): r = gamma(a + b) / (gamma(a) * gamma(b)) return r * x**(a-1) * (1 - x)**(b-1) -f0 = lambda x: p(x, 1, 1) -f1 = lambda x: p(x, 9, 9) +f0 = lambda x: beta_pdf(x, 1, 1) +f1 = lambda x: beta_pdf(x, 9, 9) grid = np.linspace(0, 1, 50) fig, ax = plt.subplots(figsize=(10, 8)) @@ -476,175 +476,105 @@ $$ $$ ```{code-cell} ipython3 -def run_sprt_simulation(params): - """Run SPRT simulation with given parameters.""" - - # Define the thresholds - A = (1 - params.β) / params.α - B = params.β / (1 - params.α) - logA, logB = np.log(A), np.log(B) - - # Define the two distributions - f0 = beta(params.a0, params.b0) - f1 = beta(params.a1, params.b1) - - # Set the random number generator - rng = np.random.default_rng(seed=params.seed) - - def sprt(true_f0): - """Run one SPRT until a decision is reached.""" - log_L = 0.0 - n = 0 - while True: - - # Draw a random variable from the true distribution - z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) - n += 1 - - # Update the log-likelihood ratio - log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) - - # If the log-likelihood ratio is greater than the threshold, reject the null hypothesis - if log_L >= logA: - return n, False +@njit +def beta_pdf(x, a, b): + r = gamma(a + b) / (gamma(a) * gamma(b)) + return r * x**(a-1) * (1 - x)**(b-1) - # If the log-likelihood ratio is less than the threshold, accept the null hypothesis - elif log_L <= logB: - return n, True +@njit +def sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed): + """Run a single SPRT until a decision is reached.""" + log_L = 0.0 + n = 0 + + # Set seed for this run + np.random.seed(seed) + + while True: + # Draw a random variable from the appropriate distribution + if true_f0: + z = np.random.beta(a0, b0) + else: + z = np.random.beta(a1, b1) + + n += 1 - # Monte Carlo experiment - stopping_times = [] - decisions = [] - truth = [] - - for i in range(params.N): - # H0 is true for half of the simulations and H1 is true for the other half - # Later we will calculate the type I and type II errors by counting the number of times - # we reject H0 when H0 is true and accept H0 when H0 is false divided by the number of simulations - # for each distribution + # Update the log-likelihood ratio + log_f1_z = np.log(beta_pdf(z, a1, b1)) + log_f0_z = np.log(beta_pdf(z, a0, b0)) + log_L += log_f1_z - log_f0_z + + # Check stopping conditions + if log_L >= logA: + return n, False # Reject H0 + elif log_L <= logB: + return n, True # Accept H0 + +@njit(parallel=True) +def run_sprt_simulation(a0, b0, a1, b1, alpha, βs, N, seed): + """SPRT simulation.""" + + # Calculate thresholds + A = (1 - βs) / alpha + B = βs / (1 - alpha) + logA = np.log(A) + logB = np.log(B) + + # Pre-allocate arrays + stopping_times = np.zeros(N, dtype=np.int64) + decisions = np.zeros(N, dtype=np.bool_) + truth = np.zeros(N, dtype=np.bool_) + + # Run simulations in parallel + for i in prange(N): true_f0 = (i % 2 == 0) - n, accept_f0 = sprt(true_f0) - stopping_times.append(n) - decisions.append(accept_f0) - truth.append(true_f0) + truth[i] = true_f0 + + n, accept_f0 = sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed + i) + stopping_times[i] = n + decisions[i] = accept_f0 - stopping_times = np.asarray(stopping_times) - decisions = np.asarray(decisions) - truth = np.asarray(truth) + return stopping_times, decisions, truth + +def run_sprt(params): + """Wrapper to run SPRT simulation with given parameters.""" + + stopping_times, decisions, truth = run_sprt_simulation( + params.a0, params.b0, params.a1, params.b1, + params.α, params.β, params.N, params.seed + ) # Calculate error rates - - # For type I error: P(reject H0 | H0 is true) = P(H0 is true and reject H0) / P(H0 is true) - type_I = np.mean(truth & ~decisions) / np.mean(truth) + truth_bool = truth.astype(bool) + decisions_bool = decisions.astype(bool) - # For type II error: P(accept H0 | H0 is false) = P(H0 is false and accept H0) / P(H0 is false) - type_II = np.mean(~truth & decisions) / np.mean(~truth) + # For type I error: P(reject H0 | H0 is true) + type_I = np.sum(truth_bool & ~decisions_bool) / np.sum(truth_bool) - return { - 'stopping_times': stopping_times, - 'decisions': decisions, - 'truth': truth, - 'type_I': type_I, - 'type_II': type_II, - 'f0': f0, - 'f1': f1 - } - -def run_sprt_single_distribution(params, use_f0=True): - """ - Run SPRT simulation drawing from only one distribution. - - This is a version of the function above except the previous - function alternates between the two distributions automatically. - """ - # Define the thresholds - A = (1 - params.β) / params.α - B = params.β / (1 - params.α) - logA, logB = np.log(A), np.log(B) + # For type II error: P(accept H0 | H0 is false) + type_II = np.sum(~truth_bool & decisions_bool) / np.sum(~truth_bool) - # Define the two distributions + # Create scipy distributions for compatibility f0 = beta(params.a0, params.b0) f1 = beta(params.a1, params.b1) - # Set the random number generator - rng = np.random.default_rng(seed=params.seed) - - def sprt(true_f0): - """Run one SPRT until a decision is reached.""" - log_L = 0.0 - n = 0 - while True: - # Draw a random variable from the true distribution - z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) - n += 1 - - # Update the log-likelihood ratio - log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) - - # If the log-likelihood ratio is greater than the threshold, reject the null hypothesis - if log_L >= logA: - return n, False - - # If the log-likelihood ratio is less than the threshold, accept the null hypothesis - elif log_L <= logB: - return n, True - - # Monte Carlo experiment - all draws from same distribution - stopping_times = [] - decisions = [] - truth = [] - - for i in range(params.N): - # Use the same distribution for all simulations - true_f0 = use_f0 - n, accept_f0 = sprt(true_f0) - stopping_times.append(n) - decisions.append(accept_f0) - truth.append(true_f0) - - stopping_times = np.asarray(stopping_times) - decisions = np.asarray(decisions) - truth = np.asarray(truth) - - # Calculate error rates based on which distribution was used - if use_f0: - # All samples from f0, so we can only calculate type I error - type_I = np.sum(~decisions) / len(decisions) # Rejecting H0 when f0 is true - type_II = None - else: - # All samples from f1, so we can only calculate type II error - type_I = None - type_II = np.sum(decisions) / len(decisions) # Accepting H0 when f1 is true - return { 'stopping_times': stopping_times, - 'decisions': decisions, - 'truth': truth, + 'decisions': decisions_bool, + 'truth': truth_bool, 'type_I': type_I, 'type_II': type_II, 'f0': f0, - 'f1': f1, - 'distribution_used': 'f0' if use_f0 else 'f1' + 'f1': f1 } - + # Run simulation params = SPRTParams(α=0.05, β=0.10, a0=2, b0=5, a1=5, b1=2, N=20000, seed=1) -results = run_sprt_simulation(params) +results = run_sprt(params) print(f"Average stopping time: {results['stopping_times'].mean():.2f}") print(f"Empirical type I error: {results['type_I']:.3f} (target = {params.α})") print(f"Empirical type II error: {results['type_II']:.3f} (target = {params.β})") - -print("\nDrawing only from f0 (null hypothesis):") -results_f0 = run_sprt_single_distribution(params, use_f0=True) -print(f"Average stopping time: {results_f0['stopping_times'].mean():.2f}") -print(f"Empirical type I error: {results_f0['type_I']:.3f} (target = {params.α})") - - -print("\nDrawing only from f1 (alternative hypothesis):") -results_f1 = run_sprt_single_distribution(params, use_f0=False) -print(f"Average stopping time: {results_f1['stopping_times'].mean():.2f}") -print(f"Empirical type II error: {results_f1['type_II']:.3f} (target = {params.β})") ``` We can see that the single distribution simulations are the same as the two distribution simulations @@ -719,16 +649,15 @@ plt.show() Next we use our code to study three different $f_0, f_1$ pairs having different discrepancies between distributions. - ```{code-cell} ipython3 params_1 = SPRTParams(α=0.05, β=0.10, a0=2, b0=8, a1=8, b1=2, N=5000, seed=42) -results_1 = run_sprt_simulation(params_1) +results_1 = run_sprt(params_1) params_2 = SPRTParams(α=0.05, β=0.10, a0=4, b0=5, a1=5, b1=4, N=5000, seed=42) -results_2 = run_sprt_simulation(params_2) +results_2 = run_sprt(params_2) params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, b1=0.5, N=5000, seed=42) -results_3 = run_sprt_simulation(params_3) +results_3 = run_sprt(params_3) def plot_sprt_results(results, params, title=""): """Plot SPRT simulation results with distributions, stopping times, and confusion matrix.""" @@ -803,6 +732,109 @@ plot_sprt_results(results_2, params_2) plot_sprt_results(results_3, params_3) ``` +We can see a clear pattern in the stopping times and how close "separated" the two distributions are. + +We can link this to the discussion of [Kullback–Leibler divergence](rel_entropy) in {doc}`this lecture `. + +Intuitively, KL divergence is large from one distribution is large, it should be easier to distinguish between them with shorter stopping times. + +We use a metric called [Jensen-Shannon distance](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) and plot it against the average stopping times. + +```{code-cell} ipython3 +def kl_div(h, f): + """KL divergence""" + integrand = lambda w: f(w) * np.log(f(w) / h(w)) + val, _ = quad(integrand, 0, 1) + return val + +def js_dist(a0, b0, a1, b1): + """Jensen–Shannon distance""" + f0 = lambda w: p(w, a0, b0) + f1 = lambda w: p(w, a1, b1) + # mixture + m = lambda w: 0.5*(f0(w) + f1(w)) + return np.sqrt(0.5*kl_div(m, f0) + 0.5*kl_div(m, f1)) + +def generate_linspace_beta_pairs(N=100, T=10.0, d_min=0.5, d_max=9.5): + ds = np.linspace(d_min, d_max, N) + a0 = (T - ds) / 2 + b0 = (T + ds) / 2 + return list(zip(a0, b0, b0, a0)) + +param_comb = generate_linspace_beta_pairs() + +# Run simulations for each parameter combination +js_dists = [] +mean_stopping_times = [] +param_list = [] + +for a0, b0, a1, b1 in param_comb: + # Compute KL divergence + js_div = js_dist(a1, b1, a0, b0) + + # Run SPRT simulation + params = SPRTParams(α=0.05, β=0.10, a0=a0, b0=b0, + a1=a1, b1=b1, N=5000, seed=42) + results = run_sprt(params) + + js_dists.append(js_div) + mean_stopping_times.append(results['stopping_times'].mean()) + param_list.append((a0, b0, a1, b1)) + +# Create the plot +fig, ax = plt.subplots(figsize=(6, 6)) + +scatter = ax.scatter(kl_divergences, mean_stopping_times, + s=80, alpha=0.7, c=range(len(kl_divergences)), + linewidth=0.5) + +ax.set_xlabel('Jensen–Shannon distance', fontsize=14) +ax.set_ylabel('mean stopping time', fontsize=14) + +plt.tight_layout() +plt.show() +``` + +The plot demonstrates a clear negative correlation between relative entropy and mean stopping time. + +As the KL divergence increases (distributions become more separated), the mean stopping time decreases exponentially. + +Below are sampled examples from the experiments we have above + +```{code-cell} ipython3 +selected_indices = [0, len(param_comb)//4, len(param_comb)//2, + 3*len(param_comb)//4, -1] + +fig, axes = plt.subplots(1, len(selected_indices), figsize=(20, 4)) + +for i, idx in enumerate(selected_indices): + a0, b0, a1, b1 = param_list[idx] + kl_div = kl_divergences[idx] + mean_time = mean_stopping_times[idx] + + # Plot the distributions + z_grid = np.linspace(0, 1, 200) + f0_dist = beta(a0, b0) + f1_dist = beta(a1, b1) + + axes[i].plot(z_grid, f0_dist.pdf(z_grid), 'b-', lw=2, label='$f_0$') + axes[i].plot(z_grid, f1_dist.pdf(z_grid), 'r-', lw=2, label='$f_1$') + axes[i].fill_between(z_grid, 0, + np.minimum(f0_dist.pdf(z_grid), f1_dist.pdf(z_grid)), + alpha=0.3, color='purple') + + axes[i].set_title(f'KL div: {kl_div:.3f}\nMean time: {mean_time:.1f}', fontsize=12) + axes[i].set_xlabel('z', fontsize=10) + if i == 0: + axes[i].set_ylabel('Density', fontsize=10) + axes[i].legend(fontsize=10) +plt.tight_layout() +plt.show() +``` + +Again, we find that the stopping time is shorter when the distributions are more separated +measured by Jensen-Shannon distance. + Let's visualize individual likelihood ratio processes to see how they evolve toward the decision boundaries. ```{code-cell} ipython3 @@ -878,53 +910,51 @@ plot_likelihood_paths(params_3, n_highlight=10, n_background=100) Next, let's adjust the decision thresholds $A$ and $B$ and examine how the mean stopping time and the type I and type II error rates change. ```{code-cell} ipython3 -def run_adjusted_thresholds(params, A_factor=1.0, B_factor=1.0): - """Wrapper to run SPRT with adjusted A and B thresholds.""" +@njit(parallel=True) +def run_adjusted_thresholds(a0, b0, a1, b1, alpha, βs, N, seed, A_factor, B_factor): + """SPRT simulation with adjusted thresholds.""" - # Calculate original thresholds - A_original = (1 - params.β) / params.α - B_original = params.β / (1 - params.α) + # Calculate original thresholds + A_original = (1 - βs) / alpha + B_original = βs / (1 - alpha) # Apply adjustment factors A_adj = A_original * A_factor B_adj = B_original * B_factor - logA, logB = np.log(A_adj), np.log(B_adj) + logA = np.log(A_adj) + logB = np.log(B_adj) - f0 = beta(params.a0, params.b0) - f1 = beta(params.a1, params.b1) - rng = np.random.default_rng(seed=params.seed) - - def sprt_adjusted(true_f0): - log_L = 0.0 - n = 0 - while True: - z = f0.rvs(random_state=rng) if true_f0 else f1.rvs(random_state=rng) - n += 1 - log_L += np.log(f1.pdf(z)) - np.log(f0.pdf(z)) - - if log_L >= logA: - return n, False - elif log_L <= logB: - return n, True - - # Run simulation - stopping_times = [] - decisions = [] - truth = [] + # Pre-allocate arrays + stopping_times = np.zeros(N, dtype=np.int64) + decisions = np.zeros(N, dtype=np.bool_) + truth = np.zeros(N, dtype=np.bool_) - for i in range(params.N): + # Run simulations in parallel + for i in prange(N): true_f0 = (i % 2 == 0) - n, accept_f0 = sprt_adjusted(true_f0) - stopping_times.append(n) - decisions.append(accept_f0) - truth.append(true_f0) + truth[i] = true_f0 + + n, accept_f0 = sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed + i) + stopping_times[i] = n + decisions[i] = accept_f0 - stopping_times = np.asarray(stopping_times) - decisions = np.asarray(decisions) - truth = np.asarray(truth) + return stopping_times, decisions, truth, A_adj, B_adj + +def run_adjusted(params, A_factor=1.0, B_factor=1.0): + """Wrapper to run SPRT with adjusted A and B thresholds.""" + + stopping_times, decisions, truth, A_adj, B_adj = run_adjusted_thresholds( + params.a0, params.b0, params.a1, params.b1, + params.α, params.β, params.N, params.seed, A_factor, B_factor + ) - type_I = np.sum(truth & (~decisions)) / np.sum(truth) - type_II = np.sum((~truth) & decisions) / np.sum(~truth) + # Convert to boolean arrays + truth_bool = truth.astype(bool) + decisions_bool = decisions.astype(bool) + + # Calculate error rates + type_I = np.sum(truth_bool & ~decisions_bool) / np.sum(truth_bool) + type_II = np.sum(~truth_bool & decisions_bool) / np.sum(~truth_bool) return { 'stopping_times': stopping_times, @@ -944,7 +974,7 @@ adjustments = [ results_table = [] for A_factor, B_factor in adjustments: - result = run_adjusted_thresholds(params_2, A_factor, B_factor) + result = run_adjusted(params_2, A_factor, B_factor) results_table.append([ A_factor, B_factor, f"{result['stopping_times'].mean():.1f}", From ef3d638592a6352cc7203504436cf783a736a3ec Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 16:13:15 +0800 Subject: [PATCH 13/29] updates --- lectures/wald_friedman.md | 40 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index c3109f1c5..452fef2f2 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -62,6 +62,7 @@ import matplotlib.pyplot as plt from numba import njit, prange from numba.experimental import jitclass from math import gamma +from scipy.integrate import quad from scipy.stats import beta from collections import namedtuple import pandas as pd @@ -749,8 +750,8 @@ def kl_div(h, f): def js_dist(a0, b0, a1, b1): """Jensen–Shannon distance""" - f0 = lambda w: p(w, a0, b0) - f1 = lambda w: p(w, a1, b1) + f0 = lambda w: beta_pdf(w, a0, b0) + f1 = lambda w: beta_pdf(w, a1, b1) # mixture m = lambda w: 0.5*(f0(w) + f1(w)) return np.sqrt(0.5*kl_div(m, f0) + 0.5*kl_div(m, f1)) @@ -784,8 +785,8 @@ for a0, b0, a1, b1 in param_comb: # Create the plot fig, ax = plt.subplots(figsize=(6, 6)) -scatter = ax.scatter(kl_divergences, mean_stopping_times, - s=80, alpha=0.7, c=range(len(kl_divergences)), +scatter = ax.scatter(js_dists, mean_stopping_times, + s=80, alpha=0.7, c=range(len(js_dists)), linewidth=0.5) ax.set_xlabel('Jensen–Shannon distance', fontsize=14) @@ -802,14 +803,17 @@ As the KL divergence increases (distributions become more separated), the mean s Below are sampled examples from the experiments we have above ```{code-cell} ipython3 -selected_indices = [0, len(param_comb)//4, len(param_comb)//2, - 3*len(param_comb)//4, -1] +selected_indices = [0, len(param_comb)//6, len(param_comb)//3, len(param_comb)//2, + 2*len(param_comb)//3, -1] -fig, axes = plt.subplots(1, len(selected_indices), figsize=(20, 4)) +fig, axes = plt.subplots(2, 3, figsize=(15, 8)) for i, idx in enumerate(selected_indices): + row = i // 3 + col = i % 3 + a0, b0, a1, b1 = param_list[idx] - kl_div = kl_divergences[idx] + kl_div = js_dists[idx] mean_time = mean_stopping_times[idx] # Plot the distributions @@ -817,17 +821,21 @@ for i, idx in enumerate(selected_indices): f0_dist = beta(a0, b0) f1_dist = beta(a1, b1) - axes[i].plot(z_grid, f0_dist.pdf(z_grid), 'b-', lw=2, label='$f_0$') - axes[i].plot(z_grid, f1_dist.pdf(z_grid), 'r-', lw=2, label='$f_1$') - axes[i].fill_between(z_grid, 0, + axes[row, col].plot(z_grid, f0_dist.pdf(z_grid), 'b-', lw=2, label='$f_0$') + axes[row, col].plot(z_grid, f1_dist.pdf(z_grid), 'r-', lw=2, label='$f_1$') + axes[row, col].fill_between(z_grid, 0, np.minimum(f0_dist.pdf(z_grid), f1_dist.pdf(z_grid)), alpha=0.3, color='purple') - axes[i].set_title(f'KL div: {kl_div:.3f}\nMean time: {mean_time:.1f}', fontsize=12) - axes[i].set_xlabel('z', fontsize=10) + axes[row, col].set_title(f'KL div: {kl_div:.3f}\nMean time: {mean_time:.1f}', fontsize=12) + axes[row, col].set_xlabel('z', fontsize=10) if i == 0: - axes[i].set_ylabel('Density', fontsize=10) - axes[i].legend(fontsize=10) + axes[row, col].set_ylabel('Density', fontsize=10) + axes[row, col].legend(fontsize=10) + +# Hide the last subplot since we only have 5 plots +axes[1, 2].axis('off') + plt.tight_layout() plt.show() ``` @@ -947,8 +955,6 @@ def run_adjusted(params, A_factor=1.0, B_factor=1.0): params.a0, params.b0, params.a1, params.b1, params.α, params.β, params.N, params.seed, A_factor, B_factor ) - - # Convert to boolean arrays truth_bool = truth.astype(bool) decisions_bool = decisions.astype(bool) From d4bc968e8b29c6ea6c668d8e9431a9a27a7686c2 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 17:43:34 +0800 Subject: [PATCH 14/29] update --- .../wald_friedman_2/wald_dec_rule.png | Bin 23656 -> 25678 bytes .../wald_friedman_2/wald_dec_rule.tex | 16 ++- lectures/wald_friedman.md | 8 +- lectures/wald_friedman_2.md | 108 ++++++++++-------- 4 files changed, 71 insertions(+), 61 deletions(-) diff --git a/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.png b/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.png index c221201659ebd5493a79863c23d85f09232de9d6..6664279d1b14da37dee074e8df08e8bc6ff72c7e 100644 GIT binary patch literal 25678 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 MUe6DU%j$lCvgS{V$)e6{R2IMS@mDP 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 literal 23656 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 A: decision_made = True - decision = 0 + decision = 1 if true_dist == "f0": if decision == 0: From a2ff759237b27b9f15d1c14c13ef84e78cbf6248 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 25 Jun 2025 17:51:56 +0800 Subject: [PATCH 15/29] minor updates --- .../wald_friedman_2/wald_dec_rule.pdf | Bin 7355 -> 8460 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman_2/wald_dec_rule.pdf index 4db6649ae2d7aa1db9752ad5a74057f13c9db094..903496aa527fa7dc7d9124ae7962403644332a28 100644 GIT binary patch delta 4958 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 Vp8zkoJuw(40VDAi)3fG9;u5C~NzD82V8pdct6 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 C51vc_ From ca3f8bad34e68033b645a21913267f74d51c1ec3 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 26 Jun 2025 09:07:55 +0800 Subject: [PATCH 16/29] updates --- lectures/wald_friedman.md | 19 +++++++------------ lectures/wald_friedman_2.md | 31 ++++++++++++++++++------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 91e79e0f8..70d97719e 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -296,12 +296,12 @@ The next figure shows two beta distributions. ```{code-cell} ipython3 @njit -def beta_pdf(x, a, b): +def p(x, a, b): r = gamma(a + b) / (gamma(a) * gamma(b)) return r * x**(a-1) * (1 - x)**(b-1) -f0 = lambda x: beta_pdf(x, 1, 1) -f1 = lambda x: beta_pdf(x, 9, 9) +f0 = lambda x: p(x, 1, 1) +f1 = lambda x: p(x, 9, 9) grid = np.linspace(0, 1, 50) fig, ax = plt.subplots(figsize=(10, 8)) @@ -477,11 +477,6 @@ $$ $$ ```{code-cell} ipython3 -@njit -def beta_pdf(x, a, b): - r = gamma(a + b) / (gamma(a) * gamma(b)) - return r * x**(a-1) * (1 - x)**(b-1) - @njit def sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed): """Run a single SPRT until a decision is reached.""" @@ -501,8 +496,8 @@ def sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed): n += 1 # Update the log-likelihood ratio - log_f1_z = np.log(beta_pdf(z, a1, b1)) - log_f0_z = np.log(beta_pdf(z, a0, b0)) + log_f1_z = np.log(p(z, a1, b1)) + log_f0_z = np.log(p(z, a0, b0)) log_L += log_f1_z - log_f0_z # Check stopping conditions @@ -750,8 +745,8 @@ def kl_div(h, f): def js_dist(a0, b0, a1, b1): """Jensen–Shannon distance""" - f0 = lambda w: beta_pdf(w, a0, b0) - f1 = lambda w: beta_pdf(w, a1, b1) + f0 = lambda w: p(w, a0, b0) + f1 = lambda w: p(w, a1, b1) # mixture m = lambda w: 0.5*(f0(w) + f1(w)) return np.sqrt(0.5*kl_div(m, f0) + 0.5*kl_div(m, f1)) diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 43fc71a4c..cb7e02f82 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -42,7 +42,7 @@ an approach to statistical decision problems intimately related to dynamic progr In this lecture, we apply dynamic programming algorithms to Friedman and Wallis and Wald's problem. -In our previous lecture, key ideas in play were: +In our {doc}`previous lecture `, key ideas in play were: - Type I and type II statistical errors - a type I error occurs when you reject a null hypothesis that is true @@ -74,7 +74,7 @@ We'll formulate the problem using dynamic programming. ## A Dynamic Programming Approach The following presentation of the problem closely follows Dmitri -Berskekas's treatment in **Dynamic Programming and Stochastic Control** {cite}`Bertekas75`. +Berskekas's treatment in **Dynamic Programming and Stochastic Control** {cite}`Bertekas75`. A decision-maker can observe a sequence of draws of a random variable $z$. @@ -105,6 +105,11 @@ $$ \mathbb P \{ f = f_1 \mid \textrm{ no observations} \} \in (0, 1) $$ +```{note} +In {cite:t}`Bertekas75`, the belief is associated with the distribution $f_0$, but here +we associate the belief with the distribution $f_1$ to match the discussions in {doc}`this lecture `. +``` + After observing $k+1$ observations $z_k, z_{k-1}, \ldots, z_0$, he updates his personal probability that the observations are described by distribution $f_1$ to $$ @@ -243,8 +248,8 @@ With some thought, you will agree that $J$ should satisfy the Bellman equation J(\pi) = \min \left\{ - \pi L_0, \; (1-\pi) L_1, \; - c + \mathbb E [ J (\pi') ] + \underbrace{\pi L_0}_{ \text{accept } f_0 } \; , \; \underbrace{(1-\pi) L_1}_{ \text{accept } f_1 } \; , \; + \underbrace{c + \mathbb E [ J (\pi') ]}_{ \text{draw again} } \right\} ``` @@ -287,13 +292,13 @@ where $\pi \in [0,1]$ and The optimal decision rule is characterized by two numbers $A, B \in (0,1) \times (0,1)$ that satisfy $$ -(1- \pi) L_1 < \min \{ \pi L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq B +\pi L_0 < \min \{ (1-\pi) L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \leq B $$ and $$ -\pi L_0 < \min \{ (1-\pi) L_1, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq A +(1- \pi) L_1 < \min \{ \pi L_0, c + \mathbb E [J(\pi')] \} \textrm { if } \pi \geq A $$ The optimal decision rule is then @@ -527,10 +532,10 @@ def find_cutoff_rule(wf, h): L0, L1 = wf.L0, wf.L1 # Evaluate cost at all points on grid for choosing a model - cost_f0 = π_grid * L0 # Cost of choosing f0 when π = P(f=f0) - cost_f1 = (1 - π_grid) * L1 # Cost of choosing f1 when π = P(f=f1) + cost_f0 = π_grid * L0 + cost_f1 = (1 - π_grid) * L1 - # Find B: largest π where cost_f0 ≤ min(cost_f1, h) + # Find B: largest π where cost_f0 <= min(cost_f1, h) optimal_cost = np.minimum(np.minimum(cost_f0, cost_f1), h) choose_f0 = (cost_f0 <= cost_f1) & (cost_f0 <= h) @@ -539,7 +544,7 @@ def find_cutoff_rule(wf, h): else: assert False, "No point where we choose f0" - # Find A: smallest π where cost_f1 ≤ min(cost_f0, h) + # Find A: smallest π where cost_f1 <= min(cost_f0, h) choose_f1 = (cost_f1 <= cost_f0) & (cost_f1 <= h) if np.any(choose_f1): @@ -575,11 +580,11 @@ plt.legend(borderpad=1.1) plt.show() ``` -The cost function $J$ equals $(1-\pi) L_1$ for $\pi \leq B$, and $\pi L_0$ for $\pi +The cost function $J$ equals $\pi L_0$ for $\pi \leq B$, and $(1-\pi) L_1$ for $\pi \geq A$. -The slopes of the two linear pieces of the cost function $J(\pi)$ are determined by $-L_1$ -and $L_0$. +The slopes of the two linear pieces of the cost function $J(\pi)$ are determined by $L_0$ +and $-L_1$. The cost function $J$ is smooth in the interior region, where the posterior probability assigned to $f_1$ is in the indecisive region $\pi \in (B, A)$. From edbe2e1fb0a7966e8e05db96c3b32cea930b42ba Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Thu, 26 Jun 2025 10:38:47 +0800 Subject: [PATCH 17/29] updates --- lectures/wald_friedman_2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index cb7e02f82..eb54b791a 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -46,7 +46,7 @@ In our {doc}`previous lecture `, key ideas in play were: - Type I and type II statistical errors - a type I error occurs when you reject a null hypothesis that is true - - a type II error occures when you accept a null hypothesis that is false + - a type II error occurs when you accept a null hypothesis that is false - Abraham Wald's **sequential probability ratio test** - The **power** of a statistical test - The **critical region** of a statistical test @@ -307,7 +307,7 @@ $$ \begin{aligned} \textrm { accept } f=f_1 \textrm{ if } \pi \geq A \\ \textrm { accept } f=f_0 \textrm{ if } \pi \leq B \\ -\textrm { draw another } z \textrm{ if } B \leq \pi \leq A +\textrm { draw another } z \textrm{ if } B < \pi < A \end{aligned} $$ From b6409098bf819b4b052126aa8f7da33ead1344ea Mon Sep 17 00:00:00 2001 From: thomassargent30 Date: Thu, 26 Jun 2025 14:09:12 +0800 Subject: [PATCH 18/29] Tom's June 26 first edits of two Wald lectures --- lectures/wald_friedman.md | 9 ++++---- lectures/wald_friedman_2.md | 44 +++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 70d97719e..8921e4443 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -437,7 +437,6 @@ Specifically, we will watch how: We will focus on the case where $f_0$ and $f_1$ are beta distributions since it is easy to control the overlapping regions of the two densities by adjusting their shape parameters. -**Tom and Humphrey: maybe we should compute relative entropies of $f_0, f_1$ and make a graph of mean stoppcing times versus relative entropy. We could link nicely to the lecture in the series that talks about relative entropy.** First, we define a namedtuple to store all the parameters we need for our simulation studies. @@ -583,7 +582,7 @@ lower type I and type II error rates than the target values. For recent work on the quality of approximation {eq}`eq:Waldrule`, see, e.g., {cite}`fischer2024improving`. ``` -The following code constructs a graph that lets us visualize two distributions and the distribution of stimes to reach a decision. +The following code constructs a graph that lets us visualize two distributions and the distribution of times to reach a decision. ```{code-cell} ipython3 fig, axes = plt.subplots(1, 2, figsize=(14, 5)) @@ -734,7 +733,7 @@ We can link this to the discussion of [Kullback–Leibler divergence](rel_entrop Intuitively, KL divergence is large from one distribution is large, it should be easier to distinguish between them with shorter stopping times. -We use a metric called [Jensen-Shannon distance](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) and plot it against the average stopping times. +To measure the discrepancy between two distributions, we use a metric called [Jensen-Shannon distance](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) and plot it against the average stopping times. ```{code-cell} ipython3 def kl_div(h, f): @@ -998,11 +997,11 @@ When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are maki The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. -## Related lectures +## Related Lectures We'll dig deeper into some of the ideas used here in the following earlier and later lectures: -* {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning +* {doc}`this lecture ` discusses the key concept of **exchangeability** that underlies statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** * {doc}`this lecture ` takes up the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index eb54b791a..1ca49186c 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -35,12 +35,21 @@ kernelspec: This lecture revisits the statistical decision problem presented to Milton Friedman and W. Allen Wallis during World War II when they were analysts at -the U.S. Government's Statistical Research Group at Columbia University. +the U.S. Government's Statistical Research Group at Columbia University. -This problem led Abraham Wald {cite}`Wald47` to formulate **sequential analysis**, -an approach to statistical decision problems intimately related to dynamic programming. +In {doc}`this lecture `, we described how Abraham Wald {cite}`Wald47` solved the problem by extending frequentist hypothesis testing techniques and formulating the problem sequentially. -In this lecture, we apply dynamic programming algorithms to Friedman and Wallis and Wald's problem. +```{note} +Wald's idea of formulating the problem sequentially created links to the **dynamic programming** that Richard Bellman developed in the 1950s. +``` + +In this lecture, we reformulate the problem in a way that invites us to apply dynamic programming. + +We'll do this by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to an explicitly 'subjective' perspective taken by a Bayesian decision maker who is equipped with + +- an initial prior subjective probability $\pi_{-1} \in (0,1)$ that nature is generating the $\{z_k\}$ sequence as a sequence of i.i.d. draws from $f_1$ rather than $f_0$. +- faith in Bayes' law as a way to revise his subjective beliefs as observations on $\{z_k\}$ sequence arrive each period. +- a loss function that tells how the decision maker values type I and type II errors. In our {doc}`previous lecture `, key ideas in play were: @@ -52,11 +61,16 @@ In our {doc}`previous lecture `, key ideas in play were: - The **critical region** of a statistical test - A **uniformly most powerful test** -In this lecture, additional key ideas are - +In this lecture, additional ideas are +- an initial prior probability $\pi_{-1}$ that +- a sequence of posterior probabilities - Bayes' Law - Dynamic programming + +This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `, and {doc}`this lecture `. + + We'll begin with some imports: ```{code-cell} ipython3 @@ -67,9 +81,7 @@ from numba.experimental import jitclass from math import gamma ``` -This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `, and {doc}`this lecture `. -We'll formulate the problem using dynamic programming. ## A Dynamic Programming Approach @@ -223,7 +235,7 @@ If, on the other hand, $\pi$ is close to 0, then $f = f_0$ is strongly favored. Finally, if $\pi$ is in the middle of the interval $[0, 1]$, then we are confronted with more uncertainty. -This reasoning suggests a decision rule such as the one shown in the figure +This reasoning suggests a sequential decision rule that we illustrate in the following figure: ```{figure} /_static/lecture_specific/wald_friedman_2/wald_dec_rule.png @@ -311,7 +323,7 @@ $$ \end{aligned} $$ -Our aim is to compute the cost function $J$, and from it the associated cutoffs $A$ +Our aim is to compute the cost function $J$ as well as the associated cutoffs $A$ and $B$. To make our computations manageable, using {eq}`optdec`, we can write the continuation cost $h(\pi)$ as @@ -335,7 +347,11 @@ h(\pi) = c + \int \min \{ \kappa(z', \pi) L_0, (1 - \kappa(z', \pi) ) L_1, h(\kappa(z', \pi) ) \} f_\pi (z') dz' ``` -is a **functional equation** in an unknown function $h$. +is an equation in an unknown function $h$. + +```{note} +Such an equation is called a **functional equation**. +``` Using the functional equation, {eq}`funceq`, for the continuation cost, we can back out optimal choices using the right side of {eq}`optdec`. @@ -507,7 +523,7 @@ ax.legend() plt.show() ``` -### Value Function +### Cost Function To solve the model, we will call our `solve_model` function @@ -738,11 +754,11 @@ With these sliders, you can adjust parameters and immediately observe $[z_{0}, z_{1}, \ldots]$ is *exchangeable*. See [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html) and {cite}`Kreps88` chapter 11, for discussions of exchangeability. -## Sequels +## Related Lectures We'll dig deeper into some of the ideas used here in the following lectures: -* {doc}`this lecture ` discusses the key concept of **exchangeability** that rationalizes statistical learning +* {doc}`this lecture ` discusses the key concept of **exchangeability** -- a notion of conditional independences associated with foundations of statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** * {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule From 9e26a719b424385f32ad604141a9e20838c3f00d Mon Sep 17 00:00:00 2001 From: thomassargent30 Date: Mon, 30 Jun 2025 10:45:16 +0800 Subject: [PATCH 19/29] Tom's June 30 edits of two Wald lectures --- lectures/wald_friedman.md | 22 ++++++++++++++++------ lectures/wald_friedman_2.md | 10 +++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 8921e4443..83ea3b050 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -33,16 +33,24 @@ kernelspec: ## Overview -This lecture describes a statistical decision problem presented to Milton -Friedman and W. Allen Wallis during World War II when they were analysts at -the U.S. Government's Statistical Research Group at Columbia University. +This is the first of two lectures about a statistical decision problem that a US Navy Captain presented to Milton +Friedman and W. Allen Wallis during World War II when they were analysts at the U.S. Government's Statistical Research Group at Columbia University. This problem led Abraham Wald {cite}`Wald47` to formulate **sequential analysis**, -an approach to statistical decision problems intimately related to dynamic programming. +an approach to statistical decision problems that is intimately related to dynamic programming. -In this lecture, we describe elements of Wald's formulation of the problem. +In the spirit of {doc}`this lecture `, the present lecture and its {doc}`sequel ` approach the problem from two distinct points of view. -Key ideas in play will be: +In this lecture, we describe Wald's formulation of the problem from the perspective of a statistician +working within the Neyman-Pearson tradition of a frequentist statistician who thinks about testing hypotheses and consequently use laws of large numbers to investigate limiting properties of particular statistics under a given **hypothesis**, i.e., a vector of **parameters** that pins down a particular member of a manifold of statistical models that interest the statistician. + + * From {doc}`this lecture `, please remember that a frequentist statistician routinely calculates functions of sequences of random variables, conditioning on a vector of parameters. + +In {doc}`this sequel ` we'll discuss another formulation that adopts the perspective of a **Bayesian statistician** who views +parameter vectors as vectors of random variables that are jointly distributed with observable variables that he is concerned about. + +Because we are taking a frequentist perspective that is concerned about relative frequencies conditioned on alternative parameter values, i.e., +alternative **hypotheses**, key ideas in this lecture - Type I and type II statistical errors - a type I error occurs when you reject a null hypothesis that is true @@ -1001,6 +1009,8 @@ The table confirms this intuition: as $A$ decreases and $B$ increases from their We'll dig deeper into some of the ideas used here in the following earlier and later lectures: +* {doc}`this sequel ` reformulates the problem from the perspective of a **Bayesian statistician** who views +parameters as vectors of random variables that are jointly distributed with the observable that he is concerned about. * {doc}`this lecture ` discusses the key concept of **exchangeability** that underlies statistical learning * {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories * {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 1ca49186c..b2c741007 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -20,7 +20,7 @@ kernelspec: ``` -# {index}`A Bayesian Formulation of Friedman's Problem ` +# {index}`A Bayesian Formulation of Friedman and Wald's Problem ` @@ -45,13 +45,13 @@ Wald's idea of formulating the problem sequentially created links to the **dynam In this lecture, we reformulate the problem in a way that invites us to apply dynamic programming. -We'll do this by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to an explicitly 'subjective' perspective taken by a Bayesian decision maker who is equipped with +We'll do this by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to the explicitly 'subjective' perspective taken by a Bayesian decision maker who is equipped with -- an initial prior subjective probability $\pi_{-1} \in (0,1)$ that nature is generating the $\{z_k\}$ sequence as a sequence of i.i.d. draws from $f_1$ rather than $f_0$. +- an initial prior subjective probability $\pi_{-1} \in (0,1)$ that nature uses to generate $\{z_k\}$ as a sequence of i.i.d. draws from $f_1$ rather than $f_0$. - faith in Bayes' law as a way to revise his subjective beliefs as observations on $\{z_k\}$ sequence arrive each period. - a loss function that tells how the decision maker values type I and type II errors. -In our {doc}`previous lecture `, key ideas in play were: +In our {doc}`previous frequentist version `, key ideas in play were: - Type I and type II statistical errors - a type I error occurs when you reject a null hypothesis that is true @@ -61,7 +61,7 @@ In our {doc}`previous lecture `, key ideas in play were: - The **critical region** of a statistical test - A **uniformly most powerful test** -In this lecture, additional ideas are +In this lecture about a Bayesian reformulation of the problem, additional ideas at work are - an initial prior probability $\pi_{-1}$ that - a sequence of posterior probabilities - Bayes' Law From 85183d494d057d692637c28f60f38f53b3ad0c3a Mon Sep 17 00:00:00 2001 From: thomassargent30 Date: Tue, 1 Jul 2025 12:44:32 +0800 Subject: [PATCH 20/29] Tom's July 1 edits of two Wald lectures --- lectures/wald_friedman.md | 2 +- lectures/wald_friedman_2.md | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 83ea3b050..29cf1c1fb 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -276,7 +276,7 @@ Here is how Wald introduces the notion of a sequential test ## Wald's Sequential Formulation -In contradistinction to Neyman and Pearson's formulation of the problemm, in Wald's formulation +In contradistinction to Neyman and Pearson's formulation of the problem, in Wald's formulation - The sample size $n$ is not fixed but rather a random variable. diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index b2c741007..2894e135c 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -43,9 +43,23 @@ In {doc}`this lecture `, we described how Abraham Wald {cite}`W Wald's idea of formulating the problem sequentially created links to the **dynamic programming** that Richard Bellman developed in the 1950s. ``` -In this lecture, we reformulate the problem in a way that invites us to apply dynamic programming. +As we learned in {doc}`probability with matrices ` and {doc}`two meanings of probability`, a frequentist statistician views a probability distribution as measuring relative frequencies of a statistic that he anticipates constructing from a very long sequence of i.i.d. draws from a known probability distribution. -We'll do this by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to the explicitly 'subjective' perspective taken by a Bayesian decision maker who is equipped with +That known probability distribution is his 'hypothesis'. + +A frequentist statistician studies the distribution of that statistic under that known probability distribution + +* when the distribution is a member of a set of parameterized probability distribution, his hypothesis takes the form of a particular parameter vector. +* this is what we mean when we say that the frequentist statistician 'conditions on the parameters' +* he regards the parameters that are fixed numbers, known to nature, but not to him. +* the statistician copes with his ignorane of those parameters by constructing the type I and type II errors associated with frequentist hypothesis testing. + +In this lecture, we reformulate Friedman and Wald's problem by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to an explicitly 'subjective' perspective taken by a Bayesian decision maker who regards parameters not as fixed numbers but as (hidden) random variables that are jointly distributed with the random variables that can be observed by sampling from that joint distribution. + +To form that joint distribution, the Bayesian statistician supplements the conditional distributions used by the frequentist statistician with +a prior probability distribution over the parameters that representive his personal, subjective opinion about those them. + +To proceed in the way, we endow our decision maker with - an initial prior subjective probability $\pi_{-1} \in (0,1)$ that nature uses to generate $\{z_k\}$ as a sequence of i.i.d. draws from $f_1$ rather than $f_0$. - faith in Bayes' law as a way to revise his subjective beliefs as observations on $\{z_k\}$ sequence arrive each period. @@ -62,10 +76,10 @@ In our {doc}`previous frequentist version `, key ideas in play we - A **uniformly most powerful test** In this lecture about a Bayesian reformulation of the problem, additional ideas at work are -- an initial prior probability $\pi_{-1}$ that -- a sequence of posterior probabilities +- an initial prior probability $\pi_{-1}$ that model $f_1$ generates the data - Bayes' Law -- Dynamic programming +- a sequence of posterior probabilities that model $f_1$ is generating the data +- dynamic programming This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `, and {doc}`this lecture `. From d0d1de39e16a03e39309e6f9d9ac2140c86e643e Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 1 Jul 2025 15:12:29 +1000 Subject: [PATCH 21/29] Update lectures/wald_friedman.md --- lectures/wald_friedman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 29cf1c1fb..b1de12cda 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -399,7 +399,7 @@ The following figure illustrates aspects of Wald's procedure. In chapter 3 of **Sequential Analysis** {cite}`Wald47` Wald establishes the inequalities $$ -\begin{align} +\begin{aligned} \frac{\alpha}{1 -\beta} & \leq \frac{1}{A} \\ \frac{\beta}{1 - \alpha} & \leq B \end{align} From 579dadfc74216a1681141e351482042043296d97 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 1 Jul 2025 15:12:34 +1000 Subject: [PATCH 22/29] Update lectures/wald_friedman.md --- lectures/wald_friedman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index b1de12cda..a1244d2cf 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -402,7 +402,7 @@ $$ \begin{aligned} \frac{\alpha}{1 -\beta} & \leq \frac{1}{A} \\ \frac{\beta}{1 - \alpha} & \leq B -\end{align} +\end{aligned} $$ His analysis of these inequalities leads Wald to recommend the following approximations as rules for setting From 7b768d166fed87909e0e479e35376e6cc4543bdc Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 1 Jul 2025 15:12:39 +1000 Subject: [PATCH 23/29] Update lectures/wald_friedman.md --- lectures/wald_friedman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index a1244d2cf..4cefe380b 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -410,7 +410,7 @@ $A$ and $B$ that come close to attaining a decision maker's target values for pr a type I and $\beta$ of a type II error: $$ -\begin{align} +\begin{aligned} A \approx a(\alpha,\beta) & \equiv \frac{1-\beta}{\alpha} \\ B \approx b(\alpha,\beta) & \equiv \frac{\beta}{1-\alpha} \end{align} From 4c4357bbedc5b5f17d8f3c1016b2993d9ddc7177 Mon Sep 17 00:00:00 2001 From: Matt McKay Date: Tue, 1 Jul 2025 15:12:43 +1000 Subject: [PATCH 24/29] Update lectures/wald_friedman.md --- lectures/wald_friedman.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 4cefe380b..810d440f7 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -413,7 +413,7 @@ $$ \begin{aligned} A \approx a(\alpha,\beta) & \equiv \frac{1-\beta}{\alpha} \\ B \approx b(\alpha,\beta) & \equiv \frac{\beta}{1-\alpha} -\end{align} +\end{aligned} $$ (eq:Waldrule) For small values of $\alpha $ and $\beta$, Wald shows that approximation {eq}`eq:Waldrule` provides a good way to set $A$ and $B$. From 3e7ef369ba3b39fe8292f54dfcc0a68fe25721c6 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 1 Jul 2025 16:36:48 +0800 Subject: [PATCH 25/29] update lecrture --- .../wald_friedman/wald_dec_rule.pdf | Bin 9760 -> 8167 bytes .../wald_friedman/wald_dec_rule.png | Bin 26484 -> 24195 bytes .../wald_friedman/wald_dec_rule.tex | 2 +- lectures/likelihood_ratio_process.md | 1 + lectures/wald_friedman.md | 248 +++++++++++------- lectures/wald_friedman_2.md | 7 +- 6 files changed, 161 insertions(+), 97 deletions(-) diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.pdf index 20d8d5c84328b3c413b9aa5be110c0496ecfb25a..a662e6f2804c401393afd41de6f6c4a4836d9f67 100644 GIT binary patch delta 6494 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 DVq#R? delta 8061 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 diff --git a/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.png b/lectures/_static/lecture_specific/wald_friedman/wald_dec_rule.png index ed599b770d02ecc287d5905f294a36230c4784d5..611eb781edc73a683930aa7d84ef82c6782359a7 100644 GIT binary patch literal 24195 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 literal 26484 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. +(rel_entropy)= ## Kullback–Leibler Divergence Now let’s consider a case in which neither $g$ nor $f$ diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 810d440f7..4e3cd135c 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -449,11 +449,12 @@ We will focus on the case where $f_0$ and $f_1$ are beta distributions since it First, we define a namedtuple to store all the parameters we need for our simulation studies. ```{code-cell} ipython3 -SPRTParams = namedtuple('SPRTParams', ['α', 'β', # Target type I and type II errors - 'a0', 'b0', # Shape parameters for f_0 - 'a1', 'b1', # Shape parameters for f_1 - 'N', # Number of simulations to run - 'seed']) +SPRTParams = namedtuple('SPRTParams', + ['α', 'β', # Target type I and type II errors + 'a0', 'b0', # Shape parameters for f_0 + 'a1', 'b1', # Shape parameters for f_1 + 'N', # Number of simulations + 'seed']) ``` Now we can run the simulation following Wald's recommendation. @@ -465,15 +466,15 @@ Below is the algorithm for the simulation. 1. Compute thresholds $A = \frac{1-\beta}{\alpha}$, $B = \frac{\beta}{1-\alpha}$ and work with $\log A$, $\log B$. 2. Given true distribution (either $f_0$ or $f_1$): - - Initialize log-likelihood ratio $\log L_0 = 0$ and observation counter $n = 0$ + - Initialize log-likelihood ratio $\log L_0 = 0$ - Repeat: - Draw observation $z$ from the true distribution - Update: $\log L_{n+1} \leftarrow \log L_n + (\log f_1(z) - \log f_0(z))$ - If $\log L_{n+1} \geq \log A$: stop, reject $H_0$ - If $\log L_{n+1} \leq \log B$: stop, accept $H_0$ -3. Monte Carlo: Repeat step 2 for $N$ replications with $N/2$ replications - for each distribution, compute the empirical type I and type II error rates with +3. Repeat step 2 for $N$ replications with $N/2$ replications + for each distribution, compute the empirical type I error $\hat{\alpha}$ and type II error $\hat{\beta}$ with $$ \hat{\alpha} = \frac{\text{# of times reject } H_0 \text{ when } f_0 \text{ is true}}{\text{# of replications with } f_0 \text{ true}} @@ -515,7 +516,7 @@ def sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed): @njit(parallel=True) def run_sprt_simulation(a0, b0, a1, b1, alpha, βs, N, seed): - """SPRT simulation.""" + """SPRT simulation described by the algorithm.""" # Calculate thresholds A = (1 - βs) / alpha @@ -525,37 +526,45 @@ def run_sprt_simulation(a0, b0, a1, b1, alpha, βs, N, seed): # Pre-allocate arrays stopping_times = np.zeros(N, dtype=np.int64) - decisions = np.zeros(N, dtype=np.bool_) - truth = np.zeros(N, dtype=np.bool_) + + # Store decision and ground truth as boolean arrays + decisions_h0 = np.zeros(N, dtype=np.bool_) + truth_h0 = np.zeros(N, dtype=np.bool_) # Run simulations in parallel for i in prange(N): true_f0 = (i % 2 == 0) - truth[i] = true_f0 + truth_h0[i] = true_f0 - n, accept_f0 = sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed + i) + n, accept_f0 = sprt_single_run( + a0, b0, a1, b1, + logA, logB, + true_f0, seed + i) + stopping_times[i] = n - decisions[i] = accept_f0 + decisions_h0[i] = accept_f0 - return stopping_times, decisions, truth + return stopping_times, decisions_h0, truth_h0 def run_sprt(params): - """Wrapper to run SPRT simulation with given parameters.""" + """Run SPRT simulations with given parameters.""" - stopping_times, decisions, truth = run_sprt_simulation( + stopping_times, decisions_h0, truth_h0 = run_sprt_simulation( params.a0, params.b0, params.a1, params.b1, params.α, params.β, params.N, params.seed ) # Calculate error rates - truth_bool = truth.astype(bool) - decisions_bool = decisions.astype(bool) - + truth_h0_bool = truth_h0.astype(bool) + decisions_h0_bool = decisions_h0.astype(bool) + # For type I error: P(reject H0 | H0 is true) - type_I = np.sum(truth_bool & ~decisions_bool) / np.sum(truth_bool) + type_I = np.sum(truth_h0_bool + & ~decisions_h0_bool) / np.sum(truth_h0_bool) # For type II error: P(accept H0 | H0 is false) - type_II = np.sum(~truth_bool & decisions_bool) / np.sum(~truth_bool) + type_II = np.sum(~truth_h0_bool + & decisions_h0_bool) / np.sum(~truth_h0_bool) # Create scipy distributions for compatibility f0 = beta(params.a0, params.b0) @@ -563,8 +572,8 @@ def run_sprt(params): return { 'stopping_times': stopping_times, - 'decisions': decisions_bool, - 'truth': truth_bool, + 'decisions_h0': decisions_h0_bool, + 'truth_h0': truth_h0_bool, 'type_I': type_I, 'type_II': type_II, 'f0': f0, @@ -580,10 +589,9 @@ print(f"Empirical type I error: {results['type_I']:.3f} (target = {params.α} print(f"Empirical type II error: {results['type_II']:.3f} (target = {params.β})") ``` -We can see that the single distribution simulations are the same as the two distribution simulations -subject to Monte Carlo sampling differences. - -As anticipated in the passage above in which Wald discussed the quality of $a(\alpha), \beta), b(\alpha, \beta)$ given in approximation {eq}`eq:Waldrule`, we find that the algorithm "overshoots" the error rates by giving us a +As anticipated in the passage above in which Wald discussed the quality of +$a(\alpha, \beta), b(\alpha, \beta)$ given in approximation {eq}`eq:Waldrule`, +we find that the algorithm "overshoots" the error rates by giving us a lower type I and type II error rates than the target values. ```{note} @@ -603,9 +611,9 @@ axes[0].plot(z_grid, results['f1'].pdf(z_grid), 'r-', axes[0].fill_between(z_grid, 0, np.minimum(results['f0'].pdf(z_grid), results['f1'].pdf(z_grid)), - alpha=0.3, color='purple', label='Overlap region') + alpha=0.3, color='purple', label='overlap region') axes[0].set_xlabel('z') -axes[0].set_ylabel('Density') +axes[0].set_ylabel('density') axes[0].legend() axes[1].hist(results['stopping_times'], @@ -613,25 +621,40 @@ axes[1].hist(results['stopping_times'], color="steelblue", alpha=0.8, edgecolor="black") axes[1].set_title("distribution of stopping times $n$") axes[1].set_xlabel("$n$") -axes[1].set_ylabel("Frequency") +axes[1].set_ylabel("frequency") plt.show() ``` In this simple case, the stopping time stays below 10. -We can also examine a $2 \times 2$ "confusion matrix" whose diagonal elements show the number of times when Wald's rule results in correct acceptance and rejection of the null hypothesis. +We can also examine a $2 \times 2$ "confusion matrix" whose diagonal elements +show the number of times when Wald's rule results in correct acceptance and +rejection of the null hypothesis. ```{code-cell} ipython3 -f0_correct = np.sum(results['truth'] & results['decisions']) # Accept H0 when H0 is true -f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) # Reject H0 when H0 is true -f1_correct = np.sum((~results['truth']) & (~results['decisions'])) # Accept H0 when H1 is true -f1_incorrect = np.sum((~results['truth']) & results['decisions']) # Reject H0 when H1 is true +# Accept H0 when H0 is true (correct) +f0_correct = np.sum(results['truth_h0'] & results['decisions_h0']) + +# Reject H0 when H0 is true (incorrect) +f0_incorrect = np.sum(results['truth_h0'] & (~results['decisions_h0'])) -confusion_data = np.array([[f0_correct, f0_incorrect], +# Reject H0 when H1 is true (correct) +f1_correct = np.sum((~results['truth_h0']) & (~results['decisions_h0'])) + +# Accept H0 when H1 is true (incorrect) +f1_incorrect = np.sum((~results['truth_h0']) & results['decisions_h0']) + +# First row is when f0 is the true distribution +# Second row is when f1 is true +confusion_data = np.array([[f0_correct, f0_incorrect], [f1_incorrect, f1_correct]]) + row_totals = confusion_data.sum(axis=1, keepdims=True) +print("Confusion Matrix:") +print(confusion_data) + fig, ax = plt.subplots() ax.imshow(confusion_data, cmap='Blues', aspect='equal') ax.set_xticks([0, 1]) @@ -644,13 +667,15 @@ for i in range(2): percent = confusion_data[i, j] / row_totals[i, 0] if row_totals[i, 0] > 0 else 0 color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' ax.text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', - ha="center", va="center", color=color, fontweight='bold') - + ha="center", va="center", + color=color, fontweight='bold') plt.tight_layout() plt.show() ``` -Next we use our code to study three different $f_0, f_1$ pairs having different discrepancies between distributions. +Next we use our code to study three different $f_0, f_1$ pairs having different discrepancies between distributions. + +We plot the same three graphs we used above for each pair of distributions ```{code-cell} ipython3 params_1 = SPRTParams(α=0.05, β=0.10, a0=2, b0=8, a1=8, b1=2, N=5000, seed=42) @@ -659,11 +684,18 @@ results_1 = run_sprt(params_1) params_2 = SPRTParams(α=0.05, β=0.10, a0=4, b0=5, a1=5, b1=4, N=5000, seed=42) results_2 = run_sprt(params_2) -params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, b1=0.5, N=5000, seed=42) +params_3 = SPRTParams(α=0.05, β=0.10, a0=0.5, b0=0.4, a1=0.4, + b1=0.5, N=5000, seed=42) results_3 = run_sprt(params_3) +``` + +```{code-cell} ipython3 +--- +tags: [hide-input] +--- def plot_sprt_results(results, params, title=""): - """Plot SPRT simulation results with distributions, stopping times, and confusion matrix.""" + """Plot SPRT simulation results.""" fig, axes = plt.subplots(1, 3, figsize=(22, 8)) # Distribution plots @@ -687,24 +719,26 @@ def plot_sprt_results(results, params, title=""): bins = np.arange(1, min(max_n, 101)) - 0.5 axes[1].hist(results['stopping_times'], bins=bins, color="steelblue", alpha=0.8, edgecolor="black") - axes[1].set_title(f'stopping times (mean={results["stopping_times"].mean():.1f})', fontsize=25) + axes[1].set_title(f'stopping times (mean={results["stopping_times"].mean():.1f})', + fontsize=25) axes[1].set_xlabel('n', fontsize=25) axes[1].set_ylabel('frequency', fontsize=25) axes[1].set_xlim(0, 100) axes[1].tick_params(axis='both', which='major', labelsize=18) # Confusion matrix - f0_correct = np.sum(results['truth'] & results['decisions']) - f0_incorrect = np.sum(results['truth'] & (~results['decisions'])) - f1_correct = np.sum((~results['truth']) & (~results['decisions'])) - f1_incorrect = np.sum((~results['truth']) & results['decisions']) + f0_correct = np.sum(results['truth_h0'] & results['decisions_h0']) + f0_incorrect = np.sum(results['truth_h0'] & (~results['decisions_h0'])) + f1_correct = np.sum((~results['truth_h0']) & (~results['decisions_h0'])) + f1_incorrect = np.sum((~results['truth_h0']) & results['decisions_h0']) confusion_data = np.array([[f0_correct, f0_incorrect], [f1_incorrect, f1_correct]]) row_totals = confusion_data.sum(axis=1, keepdims=True) im = axes[2].imshow(confusion_data, cmap='Blues', aspect='equal') - axes[2].set_title(f'errors: I={results["type_I"]:.3f}, II={results["type_II"]:.3f}', fontsize=25) + axes[2].set_title(f'errors: I={results["type_I"]:.3f} '+ + f'II={results["type_II"]:.3f}', fontsize=25) axes[2].set_xticks([0, 1]) axes[2].set_xticklabels(['accept $H_0$', 'reject $H_0$'], fontsize=22) axes[2].set_yticks([0, 1]) @@ -717,7 +751,9 @@ def plot_sprt_results(results, params, title=""): percent = confusion_data[i, j] / row_totals[i, 0] if row_totals[i, 0] > 0 else 0 color = 'white' if confusion_data[i, j] > confusion_data.max() * 0.5 else 'black' axes[2].text(j, i, f'{confusion_data[i, j]}\n({percent:.1%})', - ha="center", va="center", color=color, fontweight='bold', fontsize=18) + ha="center", va="center", + color=color, fontweight='bold', + fontsize=18) plt.tight_layout() plt.show() @@ -739,9 +775,17 @@ We can see a clear pattern in the stopping times and how close "separated" the t We can link this to the discussion of [Kullback–Leibler divergence](rel_entropy) in {doc}`this lecture `. -Intuitively, KL divergence is large from one distribution is large, it should be easier to distinguish between them with shorter stopping times. +Intuitively, KL divergence is large when the distribution from one distribution to another is +large. + +When two distributions are "far apart", it should not take long to decide which one is generating the data. -To measure the discrepancy between two distributions, we use a metric called [Jensen-Shannon distance](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) and plot it against the average stopping times. +When two distributions are "close" to each other, it takes longer to decide which one is generating the data. + +However, KL divergence is not symmetric, meaning that the divergence from one distribution to another is not necessarily the same as the reverse. + +To measure the discrepancy between two distributions, we use a metric +called [Jensen-Shannon distance](https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.jensenshannon.html) and plot it against the average stopping times. ```{code-cell} ipython3 def kl_div(h, f): @@ -754,17 +798,18 @@ def js_dist(a0, b0, a1, b1): """Jensen–Shannon distance""" f0 = lambda w: p(w, a0, b0) f1 = lambda w: p(w, a1, b1) - # mixture + + # Mixture m = lambda w: 0.5*(f0(w) + f1(w)) return np.sqrt(0.5*kl_div(m, f0) + 0.5*kl_div(m, f1)) -def generate_linspace_beta_pairs(N=100, T=10.0, d_min=0.5, d_max=9.5): +def generate_β_pairs(N=100, T=10.0, d_min=0.5, d_max=9.5): ds = np.linspace(d_min, d_max, N) a0 = (T - ds) / 2 b0 = (T + ds) / 2 return list(zip(a0, b0, b0, a0)) -param_comb = generate_linspace_beta_pairs() +param_comb = generate_β_pairs() # Run simulations for each parameter combination js_dists = [] @@ -775,7 +820,7 @@ for a0, b0, a1, b1 in param_comb: # Compute KL divergence js_div = js_dist(a1, b1, a0, b0) - # Run SPRT simulation + # Run SPRT simulation with a fixed set of parameters d d params = SPRTParams(α=0.05, β=0.10, a0=a0, b0=b0, a1=a1, b1=b1, N=5000, seed=42) results = run_sprt(params) @@ -805,8 +850,12 @@ As the KL divergence increases (distributions become more separated), the mean s Below are sampled examples from the experiments we have above ```{code-cell} ipython3 -selected_indices = [0, len(param_comb)//6, len(param_comb)//3, len(param_comb)//2, - 2*len(param_comb)//3, -1] +selected_indices = [0, + len(param_comb)//6, + len(param_comb)//3, + len(param_comb)//2, + 2*len(param_comb)//3, + -1] fig, axes = plt.subplots(2, 3, figsize=(15, 8)) @@ -823,13 +872,17 @@ for i, idx in enumerate(selected_indices): f0_dist = beta(a0, b0) f1_dist = beta(a1, b1) - axes[row, col].plot(z_grid, f0_dist.pdf(z_grid), 'b-', lw=2, label='$f_0$') - axes[row, col].plot(z_grid, f1_dist.pdf(z_grid), 'r-', lw=2, label='$f_1$') + axes[row, col].plot(z_grid, f0_dist.pdf(z_grid), 'b-', + lw=2, label='$f_0$') + axes[row, col].plot(z_grid, f1_dist.pdf(z_grid), 'r-', + lw=2, label='$f_1$') axes[row, col].fill_between(z_grid, 0, - np.minimum(f0_dist.pdf(z_grid), f1_dist.pdf(z_grid)), + np.minimum(f0_dist.pdf(z_grid), + f1_dist.pdf(z_grid)), alpha=0.3, color='purple') - axes[row, col].set_title(f'JS dist: {js_dist:.3f}\nMean time: {mean_time:.1f}', fontsize=12) + axes[row, col].set_title(f'JS dist: {js_dist:.3f}' + +f'\nMean time: {mean_time:.1f}', fontsize=12) axes[row, col].set_xlabel('z', fontsize=10) if i == 0: axes[row, col].set_ylabel('density', fontsize=10) @@ -879,30 +932,34 @@ def plot_likelihood_paths(params, n_highlight=10, n_background=200): # Check stopping conditions if log_L >= logA or log_L <= logB: - decision = log_L >= logA # True = reject H0, False = accept H0 + # True = reject H0, False = accept H0 + decision = log_L >= logA break paths_data.append((log_L_path, n, decision)) for i, (path, n, decision) in enumerate(paths_data[:n_background]): color = 'C1' if decision else 'C0' - ax.plot(range(len(path)), path, color=color, alpha=0.2, linewidth=0.5) + ax.plot(range(len(path)), path, + color=color, alpha=0.2, linewidth=0.5) for i, (path, n, decision) in enumerate(paths_data[n_background:]): # Color code by decision color = 'C1' if decision else 'C0' - ax.plot(range(len(path)), path, color=color, alpha=0.8, linewidth=1.5, - label='reject $H_0$' if decision and i == 0 else ( + ax.plot(range(len(path)), path, color=color, + alpha=0.8, linewidth=1.5, + label='reject $H_0$' if decision and i == 0 else ( 'accept $H_0$' if not decision and i == 0 else '')) ax.axhline(y=logA, color='C1', linestyle='--', linewidth=2, label=f'$\\log A = {logA:.2f}$') ax.axhline(y=logB, color='C0', linestyle='--', linewidth=2, label=f'$\\log B = {logB:.2f}$') - ax.axhline(y=0, color='black', linestyle='-', alpha=0.5, linewidth=1) + ax.axhline(y=0, color='black', linestyle='-', + alpha=0.5, linewidth=1) ax.set_xlabel(r'$n$') - ax.set_ylabel(r'$log(L_m)$') + ax.set_ylabel(r'$log(L_n)$') ax.set_title(title, fontsize=20) ax.legend(fontsize=18, loc='center right') @@ -917,9 +974,11 @@ plot_likelihood_paths(params_3, n_highlight=10, n_background=100) Next, let's adjust the decision thresholds $A$ and $B$ and examine how the mean stopping time and the type I and type II error rates change. +In the code below, we break Wald's rule by adjusting the thresholds $A$ and $B$ using factors $A_f$ and $B_f$. + ```{code-cell} ipython3 @njit(parallel=True) -def run_adjusted_thresholds(a0, b0, a1, b1, alpha, βs, N, seed, A_factor, B_factor): +def run_adjusted_thresholds(a0, b0, a1, b1, alpha, βs, N, seed, A_f, B_f): """SPRT simulation with adjusted thresholds.""" # Calculate original thresholds @@ -927,40 +986,43 @@ def run_adjusted_thresholds(a0, b0, a1, b1, alpha, βs, N, seed, A_factor, B_fac B_original = βs / (1 - alpha) # Apply adjustment factors - A_adj = A_original * A_factor - B_adj = B_original * B_factor + A_adj = A_original * A_f + B_adj = B_original * B_f logA = np.log(A_adj) logB = np.log(B_adj) # Pre-allocate arrays stopping_times = np.zeros(N, dtype=np.int64) - decisions = np.zeros(N, dtype=np.bool_) - truth = np.zeros(N, dtype=np.bool_) + decisions_h0 = np.zeros(N, dtype=np.bool_) + truth_h0 = np.zeros(N, dtype=np.bool_) # Run simulations in parallel for i in prange(N): true_f0 = (i % 2 == 0) - truth[i] = true_f0 + truth_h0[i] = true_f0 - n, accept_f0 = sprt_single_run(a0, b0, a1, b1, logA, logB, true_f0, seed + i) + n, accept_f0 = sprt_single_run(a0, b0, a1, b1, + logA, logB, true_f0, seed + i) stopping_times[i] = n - decisions[i] = accept_f0 + decisions_h0[i] = accept_f0 - return stopping_times, decisions, truth, A_adj, B_adj + return stopping_times, decisions_h0, truth_h0, A_adj, B_adj -def run_adjusted(params, A_factor=1.0, B_factor=1.0): +def run_adjusted(params, A_f=1.0, B_f=1.0): """Wrapper to run SPRT with adjusted A and B thresholds.""" - stopping_times, decisions, truth, A_adj, B_adj = run_adjusted_thresholds( + stopping_times, decisions_h0, truth_h0, A_adj, B_adj = run_adjusted_thresholds( params.a0, params.b0, params.a1, params.b1, - params.α, params.β, params.N, params.seed, A_factor, B_factor + params.α, params.β, params.N, params.seed, A_f, B_f ) - truth_bool = truth.astype(bool) - decisions_bool = decisions.astype(bool) + truth_h0_bool = truth_h0.astype(bool) + decisions_h0_bool = decisions_h0.astype(bool) # Calculate error rates - type_I = np.sum(truth_bool & ~decisions_bool) / np.sum(truth_bool) - type_II = np.sum(~truth_bool & decisions_bool) / np.sum(~truth_bool) + type_I = np.sum(truth_h0_bool + & ~decisions_h0_bool) / np.sum(truth_h0_bool) + type_II = np.sum(~truth_h0_bool + & decisions_h0_bool) / np.sum(~truth_h0_bool) return { 'stopping_times': stopping_times, @@ -979,19 +1041,19 @@ adjustments = [ ] results_table = [] -for A_factor, B_factor in adjustments: - result = run_adjusted(params_2, A_factor, B_factor) +for A_f, B_f in adjustments: + result = run_adjusted(params_2, A_f, B_f) results_table.append([ - A_factor, B_factor, + A_f, B_f, f"{result['stopping_times'].mean():.1f}", f"{result['type_I']:.3f}", f"{result['type_II']:.3f}" ]) df = pd.DataFrame(results_table, - columns=["A factor", "B factor", "Mean Stop Time", - "Type I Error", "Type II Error"]) -df = df.set_index(["A factor", "B factor"]) + columns=["A_f", "B_f", "mean stop time", + "Type I error", "Type II error"]) +df = df.set_index(["A_f", "B_f"]) df ``` @@ -999,9 +1061,13 @@ Let's pause and think about the table more carefully by referring back to {eq}`e Recall that $A = \frac{1-\beta}{\alpha}$ and $B = \frac{\beta}{1-\alpha}$. -When we multiply $A$ by a factor less than 1 (making $A$ smaller), we are effectively making it easier to reject the null hypothesis $H_0$. This increases the probability of Type I errors. +When we multiply $A$ by a factor less than 1 (making $A$ smaller), we are effectively making it easier to reject the null hypothesis $H_0$. + +This increases the probability of Type I errors. + +When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are making it easier to accept the null hypothesis $H_0$. -When we multiply $B$ by a factor greater than 1 (making $B$ larger), we are making it easier to accept the null hypothesis $H_0$. This increases the probability of Type II errors. +This increases the probability of Type II errors. The table confirms this intuition: as $A$ decreases and $B$ increases from their optimal Wald values, both Type I and Type II error rates increase, while the mean stopping time decreases. diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 2894e135c..0333e6856 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -749,11 +749,8 @@ This leads to him having a higher expected loss when he puts equal weight on bot ### A Notebook Implementation -To facilitate comparative statics, we provide -a [Jupyter notebook](https://nbviewer.org/github/QuantEcon/lecture-python.notebooks/blob/main/wald_friedman.ipynb) that -generates the same plots, but with sliders. - -With these sliders, you can adjust parameters and immediately observe +To facilitate comparative statics, we invite you to change the parameters of the model +and investigate * effects on the smoothness of the value function in the indecisive middle range as we increase the number of grid points in the piecewise linear approximation. From be93371d1033559c9f2df9ae401516d6ffbd53d5 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Tue, 1 Jul 2025 20:51:53 +0800 Subject: [PATCH 26/29] updates --- lectures/wald_friedman.md | 4 ++-- lectures/wald_friedman_2.md | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 4e3cd135c..0d70a780a 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -477,11 +477,11 @@ Below is the algorithm for the simulation. for each distribution, compute the empirical type I error $\hat{\alpha}$ and type II error $\hat{\beta}$ with $$ -\hat{\alpha} = \frac{\text{# of times reject } H_0 \text{ when } f_0 \text{ is true}}{\text{# of replications with } f_0 \text{ true}} +\hat{\alpha} = \frac{\text{\# of times reject } H_0 \text{ when } f_0 \text{ is true}}{\text{\# of replications with } f_0 \text{ true}} $$ $$ -\hat{\beta} = \frac{\text{# of times accept } H_0 \text{ when } f_1 \text{ is true}}{\text{# of replications with } f_1 \text{ true}} +\hat{\beta} = \frac{\text{\# of times accept } H_0 \text{ when } f_1 \text{ is true}}{\text{\# of replications with } f_1 \text{ true}} $$ ```{code-cell} ipython3 diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 0333e6856..f24701f5f 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -747,9 +747,7 @@ Because he decides with fewer draws, the percentage of time he is correct drops. This leads to him having a higher expected loss when he puts equal weight on both models. -### A Notebook Implementation - -To facilitate comparative statics, we invite you to change the parameters of the model +To facilitate comparative statics, we invite you to adjust the parameters of the model and investigate * effects on the smoothness of the value function in the indecisive middle range From 49fb80cad922cf4d10520bed3141c032d1040b82 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 2 Jul 2025 14:58:33 +0800 Subject: [PATCH 27/29] update according to John's suggestions --- lectures/wald_friedman.md | 11 +++++------ lectures/wald_friedman_2.md | 25 ++++++++----------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index 0d70a780a..f5f28b25c 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -1075,9 +1075,8 @@ The table confirms this intuition: as $A$ decreases and $B$ increases from their We'll dig deeper into some of the ideas used here in the following earlier and later lectures: -* {doc}`this sequel ` reformulates the problem from the perspective of a **Bayesian statistician** who views -parameters as vectors of random variables that are jointly distributed with the observable that he is concerned about. -* {doc}`this lecture ` discusses the key concept of **exchangeability** that underlies statistical learning -* {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories -* {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** -* {doc}`this lecture ` takes up the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule +* In {doc}`this sequel `, we reformulate the problem from the perspective of a **Bayesian statistician** who views parameters as vectors of random variables that are jointly distributed with the observables they are concerned about. +* The concept of **exchangeability**, which underlies much of statistical learning, is explored in depth in our {doc}`lecture on exchangeable random variables `. +* For a deeper understanding of likelihood ratio processes and their role in frequentist and Bayesian statistical theories, see {doc}`this lecture `. +* Building on that foundation, {doc}`this lecture ` examines the role of likelihood ratio processes in **Bayesian learning**. +* Finally, {doc}`this later lecture ` revisits the subject discussed here and examines whether the frequentist decision rule that the Navy ordered the captain to use would perform better or worse than the sequential decision rule we've developed. diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index f24701f5f..beee9e41a 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -37,13 +37,13 @@ This lecture revisits the statistical decision problem presented to Milton Friedman and W. Allen Wallis during World War II when they were analysts at the U.S. Government's Statistical Research Group at Columbia University. -In {doc}`this lecture `, we described how Abraham Wald {cite}`Wald47` solved the problem by extending frequentist hypothesis testing techniques and formulating the problem sequentially. +In {doc}`an earlier lecture`, we described how Abraham Wald {cite}`Wald47` solved the problem by extending frequentist hypothesis testing techniques and formulating the problem sequentially. ```{note} Wald's idea of formulating the problem sequentially created links to the **dynamic programming** that Richard Bellman developed in the 1950s. ``` -As we learned in {doc}`probability with matrices ` and {doc}`two meanings of probability`, a frequentist statistician views a probability distribution as measuring relative frequencies of a statistic that he anticipates constructing from a very long sequence of i.i.d. draws from a known probability distribution. +As we learned in {doc}`` and {doc}``, a frequentist statistician views a probability distribution as measuring relative frequencies of a statistic that he anticipates constructing from a very long sequence of i.i.d. draws from a known probability distribution. That known probability distribution is his 'hypothesis'. @@ -52,9 +52,9 @@ A frequentist statistician studies the distribution of that statistic under that * when the distribution is a member of a set of parameterized probability distribution, his hypothesis takes the form of a particular parameter vector. * this is what we mean when we say that the frequentist statistician 'conditions on the parameters' * he regards the parameters that are fixed numbers, known to nature, but not to him. -* the statistician copes with his ignorane of those parameters by constructing the type I and type II errors associated with frequentist hypothesis testing. +* the statistician copes with his ignorance of those parameters by constructing the type I and type II errors associated with frequentist hypothesis testing. -In this lecture, we reformulate Friedman and Wald's problem by transforming our point of view from the 'objective' frequentist perspective of {doc}`this lecture ` to an explicitly 'subjective' perspective taken by a Bayesian decision maker who regards parameters not as fixed numbers but as (hidden) random variables that are jointly distributed with the random variables that can be observed by sampling from that joint distribution. +In this lecture, we reformulate Friedman and Wald's problem by transforming our point of view from the 'objective' frequentist perspective of {doc}`the lecture on Wald's sequential analysis` to an explicitly 'subjective' perspective taken by a Bayesian decision maker who regards parameters not as fixed numbers but as (hidden) random variables that are jointly distributed with the random variables that can be observed by sampling from that joint distribution. To form that joint distribution, the Bayesian statistician supplements the conditional distributions used by the frequentist statistician with a prior probability distribution over the parameters that representive his personal, subjective opinion about those them. @@ -82,7 +82,7 @@ In this lecture about a Bayesian reformulation of the problem, additional ideas - dynamic programming -This lecture uses ideas studied in {doc}`this lecture `, {doc}`this lecture `, and {doc}`this lecture `. +This lecture uses ideas studied in the lectures on {doc}`likelihood ratio processes`, and {doc}` their roles in Bayesian learning`, and {doc}`this lecture on exchangeability`. We'll begin with some imports: @@ -132,8 +132,8 @@ $$ $$ ```{note} -In {cite:t}`Bertekas75`, the belief is associated with the distribution $f_0$, but here -we associate the belief with the distribution $f_1$ to match the discussions in {doc}`this lecture `. +In {cite:t}`Bertekas75`, the belief is associated with the distribution $f_0$, but here +we associate the belief with the distribution $f_1$ to match the discussions in {doc}`the lecture on Wald's sequential analysis`. ``` After observing $k+1$ observations $z_k, z_{k-1}, \ldots, z_0$, he updates his personal probability that the observations are described by distribution $f_1$ to @@ -761,13 +761,4 @@ and investigate [^f1]: The decision maker acts as if he believes that the sequence of random variables $[z_{0}, z_{1}, \ldots]$ is *exchangeable*. See [Exchangeability and Bayesian Updating](https://python.quantecon.org/exchangeable.html) and -{cite}`Kreps88` chapter 11, for discussions of exchangeability. - -## Related Lectures - -We'll dig deeper into some of the ideas used here in the following lectures: - -* {doc}`this lecture ` discusses the key concept of **exchangeability** -- a notion of conditional independences associated with foundations of statistical learning -* {doc}`this lecture ` describes **likelihood ratio processes** and their role in frequentist and Bayesian statistical theories -* {doc}`this lecture ` discusses the role of likelihood ratio processes in **Bayesian learning** -* {doc}`this lecture ` returns to the subject of this lecture and studies whether the Captain's hunch that the (frequentist) decision rule that the Navy had ordered him to use can be expected to be better or worse than our sequential decision rule +{cite}`Kreps88` chapter 11, for discussions of exchangeability. \ No newline at end of file From 0443996b6ccdf0e98f5cf35e0efa1ec40ffb9668 Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 2 Jul 2025 15:01:37 +0800 Subject: [PATCH 28/29] minor update --- lectures/wald_friedman_2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index beee9e41a..7d1d1676f 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -82,7 +82,7 @@ In this lecture about a Bayesian reformulation of the problem, additional ideas - dynamic programming -This lecture uses ideas studied in the lectures on {doc}`likelihood ratio processes`, and {doc}` their roles in Bayesian learning`, and {doc}`this lecture on exchangeability`. +This lecture uses ideas studied in the lectures on {doc}`likelihood ratio processes`, {doc}`their roles in Bayesian learning`, and {doc}`this lecture on exchangeability`. We'll begin with some imports: From d54b9e051a2467801a14b3744158481ca601dc5b Mon Sep 17 00:00:00 2001 From: Humphrey Yang Date: Wed, 2 Jul 2025 15:17:56 +0800 Subject: [PATCH 29/29] syntax updates --- lectures/wald_friedman.md | 12 ++++++------ lectures/wald_friedman_2.md | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lectures/wald_friedman.md b/lectures/wald_friedman.md index f5f28b25c..6f2f25682 100644 --- a/lectures/wald_friedman.md +++ b/lectures/wald_friedman.md @@ -39,12 +39,12 @@ Friedman and W. Allen Wallis during World War II when they were analysts at the This problem led Abraham Wald {cite}`Wald47` to formulate **sequential analysis**, an approach to statistical decision problems that is intimately related to dynamic programming. -In the spirit of {doc}`this lecture `, the present lecture and its {doc}`sequel ` approach the problem from two distinct points of view. +In the spirit of {doc}`this earlier lecture `, the present lecture and its {doc}`sequel ` approach the problem from two distinct points of view. In this lecture, we describe Wald's formulation of the problem from the perspective of a statistician working within the Neyman-Pearson tradition of a frequentist statistician who thinks about testing hypotheses and consequently use laws of large numbers to investigate limiting properties of particular statistics under a given **hypothesis**, i.e., a vector of **parameters** that pins down a particular member of a manifold of statistical models that interest the statistician. - * From {doc}`this lecture `, please remember that a frequentist statistician routinely calculates functions of sequences of random variables, conditioning on a vector of parameters. + * From {doc}`this earlier lecture on frequentist and bayesian statistics`, please remember that a frequentist statistician routinely calculates functions of sequences of random variables, conditioning on a vector of parameters. In {doc}`this sequel ` we'll discuss another formulation that adopts the perspective of a **Bayesian statistician** who views parameter vectors as vectors of random variables that are jointly distributed with observable variables that he is concerned about. @@ -76,7 +76,7 @@ from collections import namedtuple import pandas as pd ``` -This lecture uses ideas studied in {doc}`this lecture ` and {doc}`this lecture `. +This lecture uses ideas studied in {doc}`the lecture on likelihood ratio processes` and {doc}`the lecture on Bayesian learning`. ## Source of the Problem @@ -773,7 +773,7 @@ plot_sprt_results(results_3, params_3) We can see a clear pattern in the stopping times and how close "separated" the two distributions are. -We can link this to the discussion of [Kullback–Leibler divergence](rel_entropy) in {doc}`this lecture `. +We can link this to the discussion of [Kullback–Leibler divergence](rel_entropy) in {doc}`likelihood_ratio_process`. Intuitively, KL divergence is large when the distribution from one distribution to another is large. @@ -1077,6 +1077,6 @@ We'll dig deeper into some of the ideas used here in the following earlier and l * In {doc}`this sequel `, we reformulate the problem from the perspective of a **Bayesian statistician** who views parameters as vectors of random variables that are jointly distributed with the observables they are concerned about. * The concept of **exchangeability**, which underlies much of statistical learning, is explored in depth in our {doc}`lecture on exchangeable random variables `. -* For a deeper understanding of likelihood ratio processes and their role in frequentist and Bayesian statistical theories, see {doc}`this lecture `. -* Building on that foundation, {doc}`this lecture ` examines the role of likelihood ratio processes in **Bayesian learning**. +* For a deeper understanding of likelihood ratio processes and their role in frequentist and Bayesian statistical theories, see {doc}`likelihood_ratio_process`. +* Building on that foundation, {doc}`likelihood_bayes` examines the role of likelihood ratio processes in **Bayesian learning**. * Finally, {doc}`this later lecture ` revisits the subject discussed here and examines whether the frequentist decision rule that the Navy ordered the captain to use would perform better or worse than the sequential decision rule we've developed. diff --git a/lectures/wald_friedman_2.md b/lectures/wald_friedman_2.md index 7d1d1676f..1183ae506 100644 --- a/lectures/wald_friedman_2.md +++ b/lectures/wald_friedman_2.md @@ -43,7 +43,7 @@ In {doc}`an earlier lecture`, we described how Abraham Wald {ci Wald's idea of formulating the problem sequentially created links to the **dynamic programming** that Richard Bellman developed in the 1950s. ``` -As we learned in {doc}`` and {doc}``, a frequentist statistician views a probability distribution as measuring relative frequencies of a statistic that he anticipates constructing from a very long sequence of i.i.d. draws from a known probability distribution. +As we learned in {doc}`prob_matrix` and {doc}`prob_meaning`, a frequentist statistician views a probability distribution as measuring relative frequencies of a statistic that he anticipates constructing from a very long sequence of i.i.d. draws from a known probability distribution. That known probability distribution is his 'hypothesis'.