Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Section 2.1 — Discrete random variables

This notebook contains all the code examples from Section 2.1 Discrete random variables of the No Bullshit Guide to Statistics.

Topics covered in this notebook:

  • Definitions of discrete random variables

  • Examples of random variables

  • Cumulative probability distribution

  • Expectation calculations

  • Computer models for random variables

    • Overview of scipy.stats methods

  • Real-world scenario involving probability calculations

  • Discussion topics:

    • Bulk and tails of a distribution

    • Illustration of the frequentist interpretation of probability

Notebook setup

We’ll start by importing the Python modules we need for this notebook.

Note: you may need to restart the kernel to use updated packages.
<Figure size 640x480 with 0 Axes>

Definitions

Random variables

  • random variable XX: a quantity that can take on different values

  • outcome: a particular value {X=x}\{X = x\} or range of values {a≤X≤b}\{a \leq X \leq b\} that can occur as a result of observing the random variable XX

  • sample space X\mathcal{X}: describes the set of all possible outcomes of the random variable.

  • fXf_X: the probability mass function is a function that assigns probabilities to the different outcomes in the sample space of a discrete random variable. The probability mass function of the random variable XX is a function of the form fX:X→[0,1]f_X: \mathcal{X} \to [0,1].

Example 1: coin toss

Consider the random variable CC that describes the outcome of a coin toss for a balanced (fair) coin. The sample space for the random variable CC is {heads,tails}\{\texttt{heads}, \texttt{tails}\}.

The probability mass function is

fC(heads)=0.5andfC(tails)=0.5.f_C(\texttt{heads}) = 0.5 \quad \textrm{and} \quad f_C(\texttt{tails}) = 0.5.

The following code defines the Python function fC that corresponds to the probability mass function fCf_C for the random variable CC.

0.5
0.5

Let’s print the values of the probability mass function for the two values in the sample space: heads and tails.

The probability of getting heads is 0.5
The probability of getting tails is 0.5

Example 2: rolling a six-sided die

The random outcome that occurs when we roll a six-sided die can be described as a random variable DD which has the sample space {1,2,3,4,5,6}\{1, 2, 3, 4, 5, 6\}. If we assume the die is fair, then each of the outcomes will have equal weight, so the probability mass function fDf_D has the following values:

fD(1) ⁣= ⁣16, fD(2) ⁣= ⁣16, fD(3) ⁣= ⁣16, fD(4) ⁣= ⁣16, fD(5) ⁣= ⁣16, fD(6) ⁣= ⁣16.f_D(1)\!=\!\tfrac{1}{6}, \ f_D(2)\!=\!\tfrac{1}{6}, \ f_D(3)\!=\!\tfrac{1}{6}, \ f_D(4)\!=\!\tfrac{1}{6}, \ f_D(5)\!=\!\tfrac{1}{6}, \ f_D(6)\!=\!\tfrac{1}{6}.

Let’s define the probability mass function fDf_D for the random variable DD as a Python function ...

... and print the values of fD for all individual outcomes in the sample space {1,2,3,4,5,6}\{1,2,3,4,5,6\}:

The probability of rolling a 1 is 0.16666666666666666
The probability of rolling a 2 is 0.16666666666666666
The probability of rolling a 3 is 0.16666666666666666
The probability of rolling a 4 is 0.16666666666666666
The probability of rolling a 5 is 0.16666666666666666
The probability of rolling a 6 is 0.16666666666666666

Note the Python function range(a,b) is equivalent to the list of values [a,a+1,a+2,...,b-1], which does not include the upper limit b. If we want to have a range of values that includes b we use range(a,b+1) which produces [a,a+1,a+2,...,b-1,b]. You’ll see this +1 added in code examples whenever we use the Python function range to iterate over a list of values.

The probability of the event E={2,4,6}E = \{2,4,6\} is as follows:

0.5

Example 3: hard disk failures

We can model the number of hard disk failures expected to occur in a given data centre as a random variable HH distributed according to the Poisson model. The probability mass function of the Poisson distribution is described by the following equation:

fH(h)=λhe−λh!,  for h∈{0,1,2,3,…},f_H(h) = \frac{\lambda^{h}e^{-\lambda }}{h!}, \ \ \textrm{for } h \in \{0, 1, 2, 3, \ldots \},

where λ\lambda is a parameter of the distribution.

In this example, we know parameter is λ=20\lambda = 20, which we’ll denote as lam = 20 in Python.

The probability mass function for the random variable H∼Pois(λ=20)H \sim \textrm{Pois}(\lambda=20) is computed using the following Python function fH.

The code above uses the function np.exp from the NumPy module to do the exe^x calculation, and math.factorial for the n!n! calculation.

We can use the function fH to compute the probability of simple outcomes like {H=23}\{H=23\}, the probability of getting exactly 23 hard disc failures in a month.

0.06688147366240181

The probability of an event is the sum of the probabilities of the individual outcomes. To compute the probability of the event {18≤H≤22}\{18 \leq H \leq 22\}, we must find the probability of getting either 18, 19, 20, 21, and 22 hard disk failures, and sum together the probabilities of the individual outcomes, to find the the probability of the event.

0.42358294520135187

We can write the above steps more succinctly and find the event in a single line of code using python’s list-comprehension syntax:

0.42358294520135187

The code below verifies that the Python function fH satisfies Kolmogorov’s second axiom, which demands that the total probability must be one: ∑h=0h=∞fH(h)=1\sum_{h=0}^{h=\infty} f_H(h) = 1.

1.0

Note we calculated the summation only until h=100h=100 and not until h=∞h=\infty. In general, it’s it’s not possible to do summation until infinity on computers. Stopping the summation at h=100h=100 is okay in this case, because the probability values fH(101)f_H(101), fH(102)f_H(102), etc. are very small numbers, fH(101) = 5.544e-38 which is a negligible number, when added to the answer 1.0.

1.0

Plotting the probability mass function

We use the stem plot from the Matplotlib library to plot the probability mass functions of discrete random variables. To create a stem-plot of the probability mass function fHf_H, we follow a three-step procedure:

  1. Create a range of inputs hs for the plot.

  2. Compute the value of fHf_H for each of the inputs and store as list of values fHs.

  3. Plot the values fHs by calling the function plt.stem.

We’ll use this three-step procedure whenever we want to generate plots in Python. For more details about this, check out the section “Plotting function graphs” in the Python tutorial notebook, which whos other examples.

<Figure size 700x400 with 1 Axes>

Note the graph of the probability mass function corresponds to a discrete set of points, and is not defined for values in between the integers. This makes sense, since we can’t have 20.3 hard disk failures—only integers are allowed.

Cumulative distribution function and its inverse

We’ll now discuss two other functions associated with a random variable XX, which are obtained from its probability mass function fXf_X.

Cumulative distribution function

The cumulative distribution function FXF_X of the random variable XX describes the probability of outcomes that are smaller than or equal to some value bb:

FX(b)=Pr({X≤b}).F_X(b) = \textrm{Pr}(\{X \leq b\}).

The cumulative distribution function is often abbreviated as CDF.

For example, the cumulative distribution function of the random variable HH is given by:

FH(b)=Pr({H≤b})=∑h=0h=bfH(h).F_H(b) = \textrm{Pr}(\{H \leq b\}) = \sum_{h=0}^{h=b} f_H(h).

The code below compute the CDF using a summation.

Evaluating the function FH(21)=F_H(21) = FH(21) ...

0.6436976484142636

... is equivalent to computing the summation ∑h=0h=21fH(h)\sum_{h=0}^{h=21} f_H(h).

0.6436976484142636

The cumulative distribution function is defined for non-integer values, with it’s value staying constant for all fractional values all the way until the next integers value:

FH(21)=FH(21.1)=FH(21.9)=FH(21.9999).F_H(21) = F_H(21.1) = F_H(21.9) = F_H(21.9999).
(0.6436976484142636, 0.6436976484142636, 0.6436976484142636, 0.6436976484142636)

Plotting the cumulative distribution function

We can use the seaborn function lineplot to plot the graph of the function FHF_H. Recall the three-step procedure we use when plotting functions in Python:

  1. Create a range of inputs hs for the plot.
    For this plot, we’ll use a continuous range of inputs obtained from the NumPy linspace function.

  2. Compute the value of FH=F_H = FH for each of the inputs and store the results as list of values FHs.

  3. Plot the values FHs by calling the sns.lineplot.

<Figure size 700x400 with 1 Axes>

Inverse of the cumulative distribution function

The inverse cumulative distribution function (inverse-CDF) FX−1F^{-1}_X tells us the positions of the quantiles of the random variable XX. The value FX−1(q)=xqF_X^{-1}(q)=x_q tells how far you need to go in the sample space so that the outcome {X≤xq}\{ X \leq x_q \} contains at least proportion qq of the total probability: FX(xq)≥qF_X(x_q) \geq q.

The code below shows how to calculate the inverse of the cumulative distribution function FH−1(q)F_H^{-1}(q) for the random variable HH, by searching for the first value bb that satisfies the requirement FH(b)≥qF_H(b) \geq q.

For example, let’s compute FX−1(0.5)F^{-1}_X(0.5) (the median of HH):

20

We can check this answer by computing the value of the cumulative distribution function FH(20)F_H(20), and verifying that it is indeed greater than 0.5.

0.5590925842313252

Plotting the inverse-CDF

<Figure size 700x400 with 1 Axes>

Note the graph of the inverse-CDF FH−1F_H^{-1} corresponds to a flipped version of the graph of the CDF FHF_H. Indeed, FHF_H and FH−1F_H^{-1} contain the same information.

Expectation calculations

Definitions

Suppose we’re interested in calculating some value w(X)w(X), which depends on the random variable XX. The function w ⁣:X→Rw \colon \mathcal{X} \to \mathbb{R} assigns different “winning” amounts to the different outcomes of the random variable XX.

The expected value of w(X)w(X) is obtained by computing the average of w(X)w(X) over all the possible outcomes xx of the random variable XX:

EX[w(X)]=∑x∈Xw(x)fX(x).\mathbb{E}_X[w(X)] = \sum_{x \in \mathcal{X}} w(x)f_X(x).

The math shorthand symbol EX\mathbb{E}_X describes the expected value of a quantity that depends on the random variable XX.

Example 4: expected winnings from the die game

Consider the game of chance with a six-sided die that costs $1\$1 to play per round. You win $5\$5 if you roll a 6{6} and you win nothing if you roll any other number. In other words, the winnings function ww for this game is

w(1)=w(2)=w(3)=w(4)=w(5)=$0andw(6)=$5.w({1}) = w({2}) = w({3}) = w({4}) = w({5}) = \$0 \quad \textrm{and} \quad w({6}) = \$5.

Let’s encode encode this winning (payout) as a Python function.

The expected value of w(D)w(D) is computed as follows:

0.8333333333333333

Measures of centre and dispersion

The mean of the discrete random variable XX with probability mass function fXf_X is defined as:

μX=EX[X]=∑x∈Xx⋅fX(x).\mu_X = \mathbb{E}_X[X] = \sum_{x \in \mathcal{X}} x \cdot f_{X}(x).

The variance of a discrete random variable is defined as follows:

σX2=EX[(X−μX)2]=∑x∈X(X−μX)2⋅fX(x).\sigma_X^2 = \mathbb{E}_X[(X-\mu_X)^2] = \sum_{x \in \mathcal{X}} (X-\mu_X)^2 \cdot f_{X}(x).

The variance formula calculates the average squared distance of the outcomes from the mean, which is a measure of the dispersion of the distribution.

Example 5: mean and variance of six-sided die

The formula for the mean of DD is given by:

μD = ED[D]=∑d=1d=6d⋅fD(d).\mu_D \ = \ \mathbb{E}_D[D] = \sum_{d=1}^{d=6} d \cdot f_{D}(d).

In code, this gives:

3.5

So the mean of the random variable DD is μD=216=3.5\mu_D = \frac{21}{6} = 3.5.

The formula for the variance of DD is

σD2=ED ⁣[(D−μD)2]=∑d=1d=6  (d−3.5)2⋅fD(d).\sigma_D^2 = \mathbb{E}_D\!\left[ (D-\mu_D)^2 \right] = \sum_{d=1}^{d=6} \; (d-3.5)^2 \cdot f_D(d).
2.9166666666666665

So the variance of DD is σD2=2.916‾\sigma_D^2 = 2.91\overline{6}.

We can compute the standard deviation σD\sigma_D by taking the square root of the variance.

1.707825127659933

Example 6: mean and variance of hard disks failures

The formula for the mean of HH is given by:

μH = EH[H]=∑h=0h=∞h⋅fH(h).\mu_H \ = \ \mathbb{E}_H[H] = \sum_{h=0}^{h=\infty} h \cdot f_{H}(h).

In code, we’ll use the upper limit of h=100h=100 instead of h=∞h=\infty since the answer is the same (values h⋅fH(h)h\cdot f_H(h) for h≥101h \geq 101 are negligibly small).

20.0

So the mean of the random variable HH is μH=20.0\mu_H = 20.0. Indeed, this is what we expect since we constructed this random variable with parameter λ=20\lambda=20.

The formula for the variance of HH is

σH2=EH ⁣[(H−μH)2]=∑h=0h=∞(h−20)2⋅fH(h).\sigma_H^2 = \mathbb{E}_H\!\left[ (H-\mu_H)^2 \right] = \sum_{h=0}^{h=\infty} (h-20)^2 \cdot f_H(h).
19.999999999999996

Due to numerical rounding errors in the above computation, we end up with a number that differs (in the 15th decimal) from the correct answer 20. The variance of HH is σH2=20.0\sigma_H^2 = 20.0.

We can compute the standard deviation σH\sigma_H by taking the square root of the variance.

4.47213595499958

Intuitively, the standard deviation σH\sigma_H tells us the width of the distribution is approximately 5, and the most likely outcomes will be in the interval [μH−σH,μH+σH]=[15,25][\mu_H - \sigma_H, \mu_H + \sigma_H] = [15, 25].

Computer models for random variables

We saw in the above examples how to define Python functions fC, fD, fH, which correspond to the probability mass functions fCf_C, fDf_D, fHf_H of the random variables CC, DD, HH. But we don’t have to create all our computer models by ourselves! The Python module scipy.stats contains pre-defined code for all the probability distributions that we’ll use in this book.

Here is the general terminology we use initializing on of these pre-defined models:

  • <model>: the family of probability distributions

    • Examples: randint, poisson, norm, etc., which we import from scipy.stats.

  • <params>: parameters of the model—specific value of the control knobs we choose to create a particular distribution:

    • Examples: alpha, beta, lam, mu, sigma, etc.

  • <model>(<params>): the probability model from the family <model> initialized with parameters <params>

    • Examples: randint(1,6+1), poisson(20), normal(10,3)

The math shorthand symbol “∼\sim” stands for “is distributed according to.” For example, X∼M(θ)X \sim \mathcal{M}(\theta) means the random variable XX is distributed according to the probability model M\mathcal{M} with parameters θ\theta.

Examples of probability models and their computer implementations

  • The discrete uniform family of distribution Ud(α,β)\mathcal{U}_d(\alpha,\beta) assigns equal probabilities to all outcomes in the range [α,α+1,…,β][\alpha, \alpha+1, \ldots, \beta]. To create a computer model for a discrete uniform distribution, use the code randint(alpha,beta+1), where alpha and beta are two integers.

    • Examples 2: we can model the outcome of a six-sided die roll D∼Ud(1,6)D \sim \mathcal{U}_d(1,6) as rvD = randint(1,6+1).

  • The Poisson family of distribution Pois(λ)\textrm{Pois}(\lambda) describes the count of occurrences when the average rate is λ\lambda. To create a computer model for a Poisson random variable use the code poisson(lam), where lam (short for lambda) describes the average number of occurrences.

    • Examples 3: we can represent the number of hard disk failures H∼Pois(20)H \sim \textrm{Pois}(20) using the computer model rvH = poisson(20).

  • The normal family of distribution N(μ,σ)\mathcal{N}(\mu,\sigma) corresponds to a bell-shaped curve centred at μ\mu whose width is proportional to σ\sigma. To create a computer model for a normal random variable N(μ,σ)\mathcal{N}(\mu,\sigma), use the code norm(mu,sigma), where mu = μ\mu is the mean and sigma = σ\sigma is the standard deviation.

TODO: table of methods

Hard disks example

Let’s now look at a a real-world scenario in which we’ll use the computer model for the Poisson variable to do all kinds of computations with relevance to the real-world.

The first thing we’ll do is import the poisson model from scipy.stats:

Next, create a random variable object rvH by initializing the Poisson model with parameter λ=20\lambda = 20.

The methods on the random variable object rvH allow us to do anything we might want to do with the random variable HH, as we’ll now see below...

Compute probabilities of simple outcomes

To compute the value of fHf_H, we simply call the pmf method on the random variable object rvH.

0.0888353173920848
0.0846050641829373
0.07691369471176195

Properties of the distribution

The mean μH\mu_H of the distribution is obtained using:

20.0

The standard deviation σH\sigma_H is obtained using:

4.47213595499958

Alternatively, we can compute the standard deviation σH\sigma_H by taking the square root of the variance:

4.47213595499958

The median of the distribution is the position of the q=0.5q=0.5 quantile, FH−1(12)F_H^{-1}\big(\frac{1}{2}\big):

20.0

The sample space the random variable is described by:

(0, inf)

The concept of support (of a probability distribution) is a fancy math way to talk about “the interval of values where the probability distribution is non-zero.” The above result tells us the support of the random variable rvH is all integers between 0 and ∞\infty.

Computing probabilities of events

Suppose you want to compute the probability of the event {a≤N≤b}\{ a \leq N \leq b \} for the random variable HH.

For example,

Pr({15≤H≤25})=∑h=15h=25fH(h),\textrm{Pr}(\{15 \leq H \leq 25\}) = \sum_{h=15}^{h=25} f_H(h),

is the sum of f_H between 15 and 25:

0.7829507461740415

An alternative approach

Pr({15≤H≤25})=FH(25)−FH(15−1).\textrm{Pr}(\{15 \leq H \leq 25\}) = F_H(25) - F_H(15-1).
0.7829507461740454

Plotting the probability mass function

Let’s create a stem plot of the probability mass function fHf_H. Recall the three-step procedure for plotting:

  1. Create a range of inputs hs for the plot.

  2. Compute the value of fHf_H for the hs inputs and store result in an array fHs.

  3. Plot the fHs values using plt.stem.

Instead of using ordinary list of values as we did previously, we’ll use the NumPy arrays for the calculations, which are much more efficient.

<Figure size 700x400 with 1 Axes>

Some comments on the code we used to produce graph:

  1. The command range(a,b+1) produces a list of inputs from a until b.

  2. Note we call the method rvH.pmf with the entire list of inputs, and rvH.pmf computes the outputs for each element in the list in one step. This is a common pattern in scientific computing: most of the functions in NumPy and SciPy can be called with array inputs (vectors) and return array outputs, which makes them very efficient when doing large-scale calculations (e.g. computations with millions of inputs).

The helper method plot_pmf defined in the ministats module can also be used to generate this graph. To use it, just pass any random variable object as input, and the function will figure out an appropriate settings for the plot.

Note: you may need to restart the kernel to use updated packages.
<Figure size 700x400 with 1 Axes>

You can control the resulting plot by passing optional arguments like xlims, ylims, rv_name (default to X), etc. Type in help(plot_pmf) so learn about all these options.

Computing quantiles

Recall the inverse cumulative distribution function FX−1F^{-1}_X, which tells us the positions of the quantiles of the random variable XX. The value FX−1(q)=xqF_X^{-1}(q)=x_q tells the smallest xqx_q such that FX(xq)≥qF_X(x_q) \geq q. We use the method rvH.ppf(q) (short for percentile point function) to obtain values of inverse-CDF.

Let’s try to find the smallest interval [0,hq][0, h_q] that contains at least proportion qq of the total probability. For example, the q=0.95q=0.95 quantile corresponds to the value hh such that Pr({H≤h})≥0.95\textrm{Pr}(\{H \leq h\}) \geq 0.95.

28.0

We can verify that answer is correct by computing Pr({H≤28})=FH(28)\textrm{Pr}(\{H \leq 28\}) = F_H(28):

0.9656664781059899

Note by choosing h=28h=28 we’re overshooting the target 0.95 a little bit. This is often the case when calling the ppf methods of discrete random variables. The previous value at h=27h=27 gives rvH.cdf(27) =FH(27)=0.9475=F_H(27) = 0.9475, which is less than 0.95, so we pick h=28h=28 as the smallest value that satisfies FH(h)≥0.95F_H(h) \geq 0.95.

Generating random observations

Let’s say you want to generate n=12n=12 observations from the random variable HH. You can do this by calling the method rvH.rvs(12).

array([23, 15, 21, 25, 15, 17, 19, 21, 17, 19, 16, 21])

If you rerun the above code cell another time, you’ll see 12 different numbers. This is the whole point of the rvs method (random variates generator): each time you call it, you’ll see a different set of observations.

Computing expectations

Let’s say we want to estimate of the total cost we should budget for replacement hard disks, given a base price of \200/diskandabulkdiscountof200/disk and a bulk discount of \\150/disk when buying 20 or more disks.

The replacement cost for h disks is described by the following Python function.

To calculate the expected cost of replacement disks, we compute the sum of cost(h)*h for all possible outcomes h.

3381.421949447139

Another option for computing the expected value is to use the method rvH.expect(). If we try calling rvH.expect(cost), we’ll get an error “ValueError: The truth value of an array with more than one element is ambiguous.”

This error occurs because the Python function w chokes if we pass it an array of inputs to evaluate, which is what the method rvD.expect does (for efficiency reasons).

We can easily solve this by “vectorizing” the function using the NumPy helper method vectorize, which makes any Python function work with vector inputs (arrays of numbers). The code below shows how to convert the function cost to a vector-friendly equivalent function vcost, which we can ten use in the rvH.expect method.

3381.42194944714

Additional visualizations (bonus topic)

We already saw how to plot the probability mass function fHf_H above, but what about plotting cumulative distribution function FHF_H and its inverse FH−1F_H^{-1}?

Plotting the cumulative distribution function

The cumulative distribution function FH(b)=F_H(b) = rvH.cdf(b) is a continuous function (defined for all inputs bb), so we can use the seaborn function lineplot to graph it.

<Figure size 700x400 with 1 Axes>

Plotting the inverse of the cumulative distribution function

The inverse of the cumulative distribution FH−1(q)=F_H^{-1}(q) = rvH.ppf(q) is a also a continuous function, so we’ll use a similar approach as for the CDF.

<Figure size 700x400 with 1 Axes>

Discussion

Bulk of the distribution

We want to find an interval [a,b][a,b] (a subset of the sample space H\mathcal{H}) that contains the most likely observations of the random variable HH. Recall the math interval notation [a,b][a,b] describes all numbers between aa and bb, including the endpoints aa and bb. Specifically, we’ll find an interval that contains the middle 95% of the observations of the random variable HH, which means we’re looking for the integers a and b such that:

Pr({a≤H≤b})=∑h=ah=bfH(h)=fH(a)+fH(a+1)+⋯+fH(b)≥0.95.\textrm{Pr}(\{a \leq H \leq b\}) = \sum_{h=a}^{h=b} f_H(h) = f_H(a) + f_H(a+1) + \cdots + f_H(b) \geq 0.95.

We can obtain this upper and lower limits by calling the ppf method on the rvH object.

[12.0, 29.0]

The logic is as follows: if we want the interval to contain the middle 0.95 of the probability, we can split the remaining 0.05 into left and right “tails” accounting for 0.025 of the probability each.

  • We can obtain the left-boundary of the interval from the value FX−1(0.025)F_X^{-1}(0.025), which reports the interval [0,a][0,a] that contains at least 0.025 of the probability.

  • To find the right boundary b we compute the value FX−1(0.975)F_X^{-1}(0.975).

We’ll convert the limits to integers, so we can use them in summation calculations.

[12, 29]

The interval [a,b][a,b] should contain at least 0.95 of the probability (the bulk of the distribution). Let’s verify this by computing the sum of fHf_H for all the values in that interval: fH(a)+fH(a+1)+⋯+fH(b)f_H(a) + f_H(a+1) + \cdots + f_H(b).

0.9567949608871579

Another way to verify that the interval [a,b][a,b] contains 95% of the probability is to use the cumulative distribution function FH=F_H = rvH.cdf, since

Pr({a≤H≤b})=FH(b)−FH(a−1).\textrm{Pr}(\{a \leq H \leq b\}) = F_H(b) - F_H(a-1).
0.9567949608871623

Visualizing the interval [a,b][a,b]

The code below generates a stem plot for the subset of fHf_H values within the interval [a,b][a,b].

The bulk of the distibution:
<Figure size 700x400 with 1 Axes>

Tails of the distribution

Conversely, the “tails” of the distribution contain the unlikely outcomes for the random variable. The complement of the interval [a,b] contains at most 5% of the probability.

Left tail

The left tail of the distribution fHf_H is the interval [0,a-1], which contains less than 2.5% of the probability.

0.021386821587280218

Right tail

The right tail of the distribution fHf_H is the interval [b+1,np.inf], which contains less than 2.5% of the probability.

0.021818217525557397

We can verify the combined weight of the two tails is less than 5%.

0.043205039112837615

Visualizing the tails of the distribution

The code below generates a stem plot for tails of the distribution fHf_H, which consists of values outside the interval I_95.

The tails of the distibution:
<Figure size 700x400 with 1 Axes>

Frequentist interpretation of probability theory

Recall the random variable CC that describes a coin toss. We can interpret the probability values that the probability mass function fCf_C assigns to different outcomes in terms of relative frequencies of observed outcomes in a hypothetical experiment in which we toss the coin many, many times.

Consider a sequence of nn observations from a coin toss: (c1,c2,c3,…,cn)(c_1, c_2, c_3, \ldots, c_n). Each cic_i is either heads or tails.

RelFreq(heads)=count of ci=headsnandRelFreq(tails)=count of ci=tailsn.\textrm{RelFreq}(\texttt{heads}) = \frac{ \textrm{count of } c_i = \texttt{heads} }{ n } \qquad \textrm{and} \qquad \textrm{RelFreq}(\texttt{tails}) = \frac{ \textrm{count of } c_i = \texttt{tails} }{ n }.

If we generate larger and larger sets of observations, for example n=100n=100, n=1000n=1000, or n=10 000n=10\,000, we will observe that the relative frequencies of the two outcomes get close to 12\frac{1}{2} and 12\frac{1}{2}.

So when we say fC(heads)=12f_C(\texttt{heads}) = \frac{1}{2} and fC(tails)=12f_C(\texttt{tails}) = \frac{1}{2}, what we are saying is that if were to perform the hypothetical experiment infinitely many times, we’ll observe:

fC(heads)=count of ci=headsn as n goes to infinity=12.f_C(\texttt{heads}) = \frac{ \textrm{count of } c_i = \texttt{heads} }{ n } \textrm{ as } n \textrm{ goes to infinity} = \tfrac{1}{2}.

and

fC(tails)=count of ci=tailsn as n goes to infinity=12.f_C(\texttt{tails}) = \frac{ \textrm{count of } c_i = \texttt{tails} }{ n } \textrm{ as } n \textrm{ goes to infinity} = \tfrac{1}{2}.

Bayesian interpretation of probability theory

TODO?

state of knowledge