.. _sec_distributions: Distributions ============= Now that we have learned how to work with probability in both the discrete and the continuous setting, let’s get to know some of the common distributions encountered. Depending on the area of machine learning, we may need to be familiar with vastly more of these, or for some areas of deep learning potentially none at all. This is, however, a good basic list to be familiar with. Let’s first import some common libraries. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from math import erf, factorial import torch from IPython import display from d2l import torch as d2l torch.pi = torch.acos(torch.zeros(1)) * 2 # Define pi in torch .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from math import erf, factorial import numpy as np from IPython import display from d2l import mxnet as d2l .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python %matplotlib inline from math import erf, factorial import tensorflow as tf import tensorflow_probability as tfp from IPython import display from d2l import tensorflow as d2l tf.pi = tf.acos(tf.zeros(1)) * 2 # Define pi in TensorFlow .. raw:: html
.. raw:: html
Bernoulli --------- This is the simplest random variable usually encountered. This random variable encodes a coin flip which comes up :math:`1` with probability :math:`p` and :math:`0` with probability :math:`1-p`. If we have a random variable :math:`X` with this distribution, we will write .. math:: X \sim \textrm{Bernoulli}(p). The cumulative distribution function is .. math:: F(x) = \begin{cases} 0 & x < 0, \\ 1-p & 0 \le x < 1, \\ 1 & x >= 1 . \end{cases} :label: eq_bernoulli_cdf The probability mass function is plotted below. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.3 d2l.set_figsize() d2l.plt.stem([0, 1], [1 - p, p], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_15_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.3 d2l.set_figsize() d2l.plt.stem([0, 1], [1 - p, p], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_18_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.3 d2l.set_figsize() d2l.plt.stem([0, 1], [1 - p, p], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_21_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function :eq:`eq_bernoulli_cdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = torch.arange(-1, 2, 0.01) def F(x): return 0 if x < 0 else 1 if x > 1 else 1 - p d2l.plot(x, torch.tensor([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_27_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(-1, 2, 0.01) def F(x): return 0 if x < 0 else 1 if x > 1 else 1 - p d2l.plot(x, np.array([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_30_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = tf.range(-1, 2, 0.01) def F(x): return 0 if x < 0 else 1 if x > 1 else 1 - p d2l.plot(x, tf.constant([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_33_0.svg .. raw:: html
.. raw:: html
If :math:`X \sim \textrm{Bernoulli}(p)`, then: - :math:`\mu_X = p`, - :math:`\sigma_X^2 = p(1-p)`. We can sample an array of arbitrary shape from a Bernoulli random variable as follows. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python 1*(torch.rand(10, 10) < p) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[0, 1, 0, 0, 1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 1, 0, 0, 1, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 1, 1, 1, 1, 0], [1, 0, 0, 0, 1, 0, 1, 1, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [1, 0, 1, 1, 1, 1, 0, 1, 0, 0]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python 1*(np.random.rand(10, 10) < p) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[0, 0, 0, 1, 1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 1, 0, 1], [0, 1, 0, 0, 0, 0, 0, 1, 1, 0], [1, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 1, 1, 0, 0, 0, 0, 0], [1, 0, 0, 1, 1, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.cast(tf.random.uniform((10, 10)) < p, dtype=tf.float32) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Discrete Uniform ---------------- The next commonly encountered random variable is a discrete uniform. For our discussion here, we will assume that it is supported on the integers :math:`\{1, 2, \ldots, n\}`, however any other set of values can be freely chosen. The meaning of the word *uniform* in this context is that every possible value is equally likely. The probability for each value :math:`i \in \{1, 2, 3, \ldots, n\}` is :math:`p_i = \frac{1}{n}`. We will denote a random variable :math:`X` with this distribution as .. math:: X \sim U(n). The cumulative distribution function is .. math:: F(x) = \begin{cases} 0 & x < 1, \\ \frac{k}{n} & k \le x < k+1 \textrm{ with } 1 \le k < n, \\ 1 & x >= n . \end{cases} :label: eq_discrete_uniform_cdf Let’s first plot the probability mass function. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n = 5 d2l.plt.stem([i+1 for i in range(n)], n*[1 / n], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_51_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n = 5 d2l.plt.stem([i+1 for i in range(n)], n*[1 / n], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_54_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n = 5 d2l.plt.stem([i+1 for i in range(n)], n*[1 / n], use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_57_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function :eq:`eq_discrete_uniform_cdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = torch.arange(-1, 6, 0.01) def F(x): return 0 if x < 1 else 1 if x > n else torch.floor(x) / n d2l.plot(x, torch.tensor([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_63_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(-1, 6, 0.01) def F(x): return 0 if x < 1 else 1 if x > n else np.floor(x) / n d2l.plot(x, np.array([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_66_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = tf.range(-1, 6, 0.01) def F(x): return 0 if x < 1 else 1 if x > n else tf.floor(x) / n d2l.plot(x, [F(y) for y in x], 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_69_0.svg .. raw:: html
.. raw:: html
If :math:`X \sim U(n)`, then: - :math:`\mu_X = \frac{1+n}{2}`, - :math:`\sigma_X^2 = \frac{n^2-1}{12}`. We can sample an array of arbitrary shape from a discrete uniform random variable as follows. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python torch.randint(1, n, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[1, 4, 3, 2, 1, 1, 3, 1, 1, 4], [4, 1, 1, 4, 4, 1, 4, 3, 2, 4], [2, 4, 4, 1, 4, 2, 4, 3, 2, 1], [1, 2, 3, 1, 1, 4, 2, 4, 1, 3], [1, 2, 4, 1, 4, 3, 3, 2, 2, 1], [1, 2, 2, 4, 1, 3, 2, 4, 2, 3], [1, 2, 3, 4, 1, 3, 4, 1, 4, 3], [3, 1, 1, 4, 4, 1, 3, 1, 1, 2], [2, 2, 4, 3, 4, 2, 3, 4, 2, 4], [1, 4, 3, 3, 2, 3, 3, 4, 1, 3]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.random.randint(1, n, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[3, 4, 2, 1, 2, 1, 4, 4, 1, 4], [2, 3, 4, 2, 1, 4, 4, 2, 2, 4], [3, 4, 3, 4, 4, 4, 2, 4, 2, 4], [3, 4, 4, 4, 1, 3, 1, 2, 4, 1], [2, 2, 4, 1, 2, 4, 4, 3, 1, 2], [3, 4, 4, 3, 4, 1, 1, 1, 4, 2], [2, 1, 2, 1, 2, 2, 4, 4, 2, 2], [3, 4, 3, 3, 3, 3, 3, 4, 4, 1], [2, 1, 4, 2, 4, 2, 1, 2, 3, 1], [3, 4, 1, 2, 2, 4, 4, 4, 4, 3]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.random.uniform((10, 10), 1, n, dtype=tf.int32) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Continuous Uniform ------------------ Next, let’s discuss the continuous uniform distribution. The idea behind this random variable is that if we increase the :math:`n` in the discrete uniform distribution, and then scale it to fit within the interval :math:`[a, b]`, we will approach a continuous random variable that just picks an arbitrary value in :math:`[a, b]` all with equal probability. We will denote this distribution as .. math:: X \sim U(a, b). The probability density function is .. math:: p(x) = \begin{cases} \frac{1}{b-a} & x \in [a, b], \\ 0 & x \not\in [a, b].\end{cases} :label: eq_cont_uniform_pdf The cumulative distribution function is .. math:: F(x) = \begin{cases} 0 & x < a, \\ \frac{x-a}{b-a} & x \in [a, b], \\ 1 & x >= b . \end{cases} :label: eq_cont_uniform_cdf Let’s first plot the probability density function :eq:`eq_cont_uniform_pdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python a, b = 1, 3 x = torch.arange(0, 4, 0.01) p = (x > a).type(torch.float32)*(x < b).type(torch.float32)/(b-a) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_87_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python a, b = 1, 3 x = np.arange(0, 4, 0.01) p = (x > a)*(x < b)/(b - a) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_90_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python a, b = 1, 3 x = tf.range(0, 4, 0.01) p = tf.cast(x > a, tf.float32) * tf.cast(x < b, tf.float32) / (b - a) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_93_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function :eq:`eq_cont_uniform_cdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def F(x): return 0 if x < a else 1 if x > b else (x - a) / (b - a) d2l.plot(x, torch.tensor([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_99_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def F(x): return 0 if x < a else 1 if x > b else (x - a) / (b - a) d2l.plot(x, np.array([F(y) for y in x]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_102_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def F(x): return 0 if x < a else 1 if x > b else (x - a) / (b - a) d2l.plot(x, [F(y) for y in x], 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_105_0.svg .. raw:: html
.. raw:: html
If :math:`X \sim U(a, b)`, then: - :math:`\mu_X = \frac{a+b}{2}`, - :math:`\sigma_X^2 = \frac{(b-a)^2}{12}`. We can sample an array of arbitrary shape from a uniform random variable as follows. Note that it by default samples from a :math:`U(0,1)`, so if we want a different range we need to scale it. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python (b - a) * torch.rand(10, 10) + a .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[2.4857, 2.2461, 1.6809, 2.7434, 2.7072, 2.6190, 1.4883, 1.2517, 1.3454, 2.4754], [1.0974, 1.5680, 1.8788, 2.8231, 2.1695, 2.6461, 1.4914, 1.4887, 1.3860, 1.9090], [1.3746, 1.7773, 1.2412, 1.1950, 2.7281, 2.8356, 1.2266, 2.4724, 2.4641, 2.8991], [2.4018, 2.6727, 1.0308, 1.1951, 1.9390, 1.6486, 2.8314, 1.1025, 1.3354, 1.0130], [1.1281, 1.8000, 2.3788, 2.6580, 1.6750, 2.2081, 1.2705, 1.0757, 2.3311, 2.6557], [2.9912, 1.2263, 1.8115, 1.5940, 1.9321, 1.6469, 2.2990, 2.1473, 1.8165, 1.2806], [1.1672, 1.1536, 1.9649, 2.1655, 1.7170, 1.0284, 1.3305, 2.1904, 1.4036, 2.1958], [2.5891, 2.5840, 2.2679, 2.0687, 2.9249, 1.6741, 1.2238, 2.4463, 2.2235, 2.7038], [1.8697, 2.4965, 1.5785, 2.7890, 2.3319, 2.1434, 2.3333, 1.0286, 1.9245, 1.7640], [1.2504, 1.7558, 1.4322, 1.5226, 1.3380, 1.1388, 1.8707, 2.2330, 2.3818, 2.2087]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python (b - a) * np.random.rand(10, 10) + a .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[2.38360201, 1.42301059, 1.30828215, 2.23648218, 2.36792603, 1.91291633, 2.86068987, 1.82011582, 2.04179583, 1.60297964], [2.16824638, 1.57385641, 1.66921053, 1.43114352, 2.25602411, 2.87490344, 2.40876076, 1.7617666 , 2.02837681, 1.95209339], [2.10921523, 2.19732773, 1.59625198, 1.61302107, 1.27852537, 2.37811459, 2.29000406, 1.03847199, 1.56422557, 2.50686118], [1.7817774 , 1.62100143, 2.27307703, 2.05133929, 2.05104624, 2.96610051, 2.89734953, 1.21910903, 2.9754619 , 2.48726223], [2.56736775, 1.839721 , 2.95232472, 1.12483235, 2.5400353 , 2.29622885, 2.28849311, 2.52556794, 1.11539063, 1.49332251], [1.87762881, 2.0559545 , 1.62359339, 1.90967816, 2.98212587, 1.21525452, 2.68658767, 2.54676585, 1.1852055 , 2.45969756], [2.07266639, 2.95876653, 2.00955484, 1.55029107, 1.50520493, 1.88796762, 1.92171128, 2.02120858, 1.56685236, 2.6619405 ], [1.11606361, 1.40236782, 1.0776729 , 1.41579594, 2.87791721, 1.28461063, 1.91013181, 1.59194299, 2.97532135, 2.85899927], [2.06719995, 1.70292102, 2.4059567 , 1.61806169, 1.81718481, 2.92306811, 2.31158504, 1.05026323, 1.57910039, 1.83457301], [1.85492878, 1.84662898, 1.41416257, 1.05939756, 1.23999994, 2.11843352, 2.93857488, 1.05851556, 1.69802914, 2.87658077]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python (b - a) * tf.random.uniform((10, 10)) + a .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Binomial -------- Let’s make things a little more complex and examine the *binomial* random variable. This random variable originates from performing a sequence of :math:`n` independent experiments, each of which has probability :math:`p` of succeeding, and asking how many successes we expect to see. Let’s express this mathematically. Each experiment is an independent random variable :math:`X_i` where we will use :math:`1` to encode success, and :math:`0` to encode failure. Since each is an independent coin flip which is successful with probability :math:`p`, we can say that :math:`X_i \sim \textrm{Bernoulli}(p)`. Then, the binomial random variable is .. math:: X = \sum_{i=1}^n X_i. In this case, we will write .. math:: X \sim \textrm{Binomial}(n, p). To get the cumulative distribution function, we need to notice that getting exactly :math:`k` successes can occur in :math:`\binom{n}{k} = \frac{n!}{k!(n-k)!}` ways each of which has a probability of :math:`p^k(1-p)^{n-k}` of occurring. Thus the cumulative distribution function is .. math:: F(x) = \begin{cases} 0 & x < 0, \\ \sum_{m \le k} \binom{n}{m} p^m(1-p)^{n-m} & k \le x < k+1 \textrm{ with } 0 \le k < n, \\ 1 & x >= n . \end{cases} :label: eq_binomial_cdf Let’s first plot the probability mass function. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n, p = 10, 0.2 # Compute binomial coefficient def binom(n, k): comb = 1 for i in range(min(k, n - k)): comb = comb * (n - i) // (i + 1) return comb pmf = torch.tensor([p**i * (1-p)**(n - i) * binom(n, i) for i in range(n + 1)]) d2l.plt.stem([i for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_123_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n, p = 10, 0.2 # Compute binomial coefficient def binom(n, k): comb = 1 for i in range(min(k, n - k)): comb = comb * (n - i) // (i + 1) return comb pmf = np.array([p**i * (1-p)**(n - i) * binom(n, i) for i in range(n + 1)]) d2l.plt.stem([i for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_126_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python n, p = 10, 0.2 # Compute binomial coefficient def binom(n, k): comb = 1 for i in range(min(k, n - k)): comb = comb * (n - i) // (i + 1) return comb pmf = tf.constant([p**i * (1-p)**(n - i) * binom(n, i) for i in range(n + 1)]) d2l.plt.stem([i for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_129_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function :eq:`eq_binomial_cdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = torch.arange(-1, 11, 0.01) cmf = torch.cumsum(pmf, dim=0) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, torch.tensor([F(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_135_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(-1, 11, 0.01) cmf = np.cumsum(pmf) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, np.array([F(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_138_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = tf.range(-1, 11, 0.01) cmf = tf.cumsum(pmf) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, [F(y) for y in x.numpy().tolist()], 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_141_0.svg .. raw:: html
.. raw:: html
If :math:`X \sim \textrm{Binomial}(n, p)`, then: - :math:`\mu_X = np`, - :math:`\sigma_X^2 = np(1-p)`. This follows from the linearity of expected value over the sum of :math:`n` Bernoulli random variables, and the fact that the variance of the sum of independent random variables is the sum of the variances. This can be sampled as follows. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python m = torch.distributions.binomial.Binomial(n, p) m.sample(sample_shape=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[6., 3., 4., 3., 3., 1., 3., 3., 3., 3.], [3., 1., 2., 2., 3., 2., 1., 3., 1., 4.], [6., 1., 0., 3., 0., 3., 1., 0., 1., 1.], [1., 2., 3., 1., 2., 2., 2., 2., 3., 2.], [2., 2., 5., 4., 1., 3., 4., 3., 2., 0.], [2., 0., 2., 2., 3., 1., 1., 4., 3., 1.], [1., 1., 3., 2., 4., 2., 2., 2., 1., 0.], [0., 3., 2., 1., 1., 3., 2., 1., 1., 3.], [2., 3., 2., 3., 4., 3., 1., 2., 1., 2.], [1., 2., 1., 1., 3., 2., 4., 3., 3., 2.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.random.binomial(n, p, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[2, 1, 1, 2, 0, 3, 3, 1, 3, 4], [0, 2, 0, 2, 2, 1, 2, 1, 1, 2], [2, 2, 1, 1, 1, 2, 2, 3, 2, 3], [3, 2, 3, 2, 3, 2, 1, 1, 4, 1], [2, 2, 1, 2, 0, 2, 2, 1, 1, 2], [1, 1, 1, 0, 2, 0, 3, 3, 1, 0], [3, 3, 0, 3, 2, 2, 0, 1, 4, 4], [0, 1, 0, 1, 2, 5, 1, 3, 1, 0], [0, 3, 2, 4, 2, 1, 3, 3, 3, 3], [4, 3, 3, 2, 3, 2, 1, 3, 0, 1]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python m = tfp.distributions.Binomial(n, p) m.sample(sample_shape=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output WARNING:tensorflow:From /home/ci/.local/lib/python3.10/site-packages/tensorflow_probability/python/internal/batched_rejection_sampler.py:102: calling while_loop_v2 (from tensorflow.python.ops.control_flow_ops) with back_prop=False is deprecated and will be removed in a future version. Instructions for updating: back_prop=False is deprecated. Consider using tf.stop_gradient instead. Instead of: results = tf.while_loop(c, b, vars, back_prop=False) Use: results = tf.nest.map_structure(tf.stop_gradient, tf.while_loop(c, b, vars)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Poisson ------- Let’s now perform a thought experiment. We are standing at a bus stop and we want to know how many buses will arrive in the next minute. Let’s start by considering :math:`X^{(1)} \sim \textrm{Bernoulli}(p)` which is simply the probability that a bus arrives in the one minute window. For bus stops far from an urban center, this might be a pretty good approximation. We may never see more than one bus in a minute. However, if we are in a busy area, it is possible or even likely that two buses will arrive. We can model this by splitting our random variable into two parts for the first 30 seconds, or the second 30 seconds. In this case we can write .. math:: X^{(2)} \sim X^{(2)}_1 + X^{(2)}_2, where :math:`X^{(2)}` is the total sum, and :math:`X^{(2)}_i \sim \textrm{Bernoulli}(p/2)`. The total distribution is then :math:`X^{(2)} \sim \textrm{Binomial}(2, p/2)`. Why stop here? Let’s continue to split that minute into :math:`n` parts. By the same reasoning as above, we see that .. math:: X^{(n)} \sim \textrm{Binomial}(n, p/n). :label: eq_eq_poisson_approx Consider these random variables. By the previous section, we know that :eq:`eq_eq_poisson_approx` has mean :math:`\mu_{X^{(n)}} = n(p/n) = p`, and variance :math:`\sigma_{X^{(n)}}^2 = n(p/n)(1-(p/n)) = p(1-p/n)`. If we take :math:`n \rightarrow \infty`, we can see that these numbers stabilize to :math:`\mu_{X^{(\infty)}} = p`, and variance :math:`\sigma_{X^{(\infty)}}^2 = p`. This indicates that there *could be* some random variable we can define in this infinite subdivision limit. This should not come as too much of a surprise, since in the real world we can just count the number of bus arrivals, however it is nice to see that our mathematical model is well defined. This discussion can be made formal as the *law of rare events*. Following through this reasoning carefully, we can arrive at the following model. We will say that :math:`X \sim \textrm{Poisson}(\lambda)` if it is a random variable which takes the values :math:`\{0,1,2, \ldots\}` with probability .. math:: p_k = \frac{\lambda^ke^{-\lambda}}{k!}. :label: eq_poisson_mass The value :math:`\lambda > 0` is known as the *rate* (or the *shape* parameter), and denotes the average number of arrivals we expect in one unit of time. We may sum this probability mass function to get the cumulative distribution function. .. math:: F(x) = \begin{cases} 0 & x < 0, \\ e^{-\lambda}\sum_{m = 0}^k \frac{\lambda^m}{m!} & k \le x < k+1 \textrm{ with } 0 \le k. \end{cases} :label: eq_poisson_cdf Let’s first plot the probability mass function :eq:`eq_poisson_mass`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lam = 5.0 xs = [i for i in range(20)] pmf = torch.tensor([torch.exp(torch.tensor(-lam)) * lam**k / factorial(k) for k in xs]) d2l.plt.stem(xs, pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_159_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lam = 5.0 xs = [i for i in range(20)] pmf = np.array([np.exp(-lam) * lam**k / factorial(k) for k in xs]) d2l.plt.stem(xs, pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_162_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python lam = 5.0 xs = [i for i in range(20)] pmf = tf.constant([tf.exp(tf.constant(-lam)).numpy() * lam**k / factorial(k) for k in xs]) d2l.plt.stem(xs, pmf, use_line_collection=True) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.show() .. figure:: output_distributions_c7d568_165_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function :eq:`eq_poisson_cdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = torch.arange(-1, 21, 0.01) cmf = torch.cumsum(pmf, dim=0) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, torch.tensor([F(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_171_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = np.arange(-1, 21, 0.01) cmf = np.cumsum(pmf) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, np.array([F(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_174_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python x = tf.range(-1, 21, 0.01) cmf = tf.cumsum(pmf) def F(x): return 0 if x < 0 else 1 if x > n else cmf[int(x)] d2l.plot(x, [F(y) for y in x.numpy().tolist()], 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_177_0.svg .. raw:: html
.. raw:: html
As we saw above, the means and variances are particularly concise. If :math:`X \sim \textrm{Poisson}(\lambda)`, then: - :math:`\mu_X = \lambda`, - :math:`\sigma_X^2 = \lambda`. This can be sampled as follows. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python m = torch.distributions.poisson.Poisson(lam) m.sample((10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 1., 4., 6., 8., 4., 4., 4., 7., 6., 4.], [ 3., 6., 7., 7., 5., 7., 7., 3., 5., 4.], [ 4., 1., 3., 3., 10., 5., 5., 3., 7., 5.], [ 4., 3., 4., 10., 8., 6., 4., 6., 5., 5.], [ 5., 11., 1., 5., 7., 5., 2., 4., 3., 5.], [ 6., 6., 4., 4., 3., 1., 5., 8., 4., 5.], [ 2., 9., 7., 2., 6., 5., 2., 8., 6., 10.], [ 1., 4., 3., 7., 3., 1., 7., 5., 3., 6.], [ 5., 4., 6., 4., 9., 8., 3., 3., 1., 8.], [ 3., 12., 9., 13., 2., 14., 3., 2., 0., 3.]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.random.poisson(lam, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[ 5, 5, 4, 2, 13, 7, 8, 6, 6, 5], [ 6, 3, 4, 5, 4, 2, 1, 3, 6, 3], [ 6, 5, 3, 4, 4, 4, 2, 3, 2, 5], [ 2, 8, 4, 7, 7, 7, 5, 6, 2, 6], [ 3, 4, 3, 0, 7, 2, 6, 6, 7, 4], [ 4, 1, 5, 0, 3, 3, 3, 6, 4, 3], [ 4, 5, 4, 6, 4, 5, 3, 6, 9, 7], [ 4, 2, 5, 3, 5, 5, 2, 6, 10, 5], [ 5, 4, 5, 3, 6, 5, 2, 3, 6, 3], [ 8, 7, 9, 6, 3, 7, 11, 7, 13, 2]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python m = tfp.distributions.Poisson(lam) m.sample((10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
Gaussian -------- Now Let’s try a different, but related experiment. Let’s say we again are performing :math:`n` independent :math:`\textrm{Bernoulli}(p)` measurements :math:`X_i`. The distribution of the sum of these is :math:`X^{(n)} \sim \textrm{Binomial}(n, p)`. Rather than taking a limit as :math:`n` increases and :math:`p` decreases, Let’s fix :math:`p`, and then send :math:`n \rightarrow \infty`. In this case :math:`\mu_{X^{(n)}} = np \rightarrow \infty` and :math:`\sigma_{X^{(n)}}^2 = np(1-p) \rightarrow \infty`, so there is no reason to think this limit should be well defined. However, not all hope is lost! Let’s just make the mean and variance be well behaved by defining .. math:: Y^{(n)} = \frac{X^{(n)} - \mu_{X^{(n)}}}{\sigma_{X^{(n)}}}. This can be seen to have mean zero and variance one, and so it is plausible to believe that it will converge to some limiting distribution. If we plot what these distributions look like, we will become even more convinced that it will work. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.2 ns = [1, 10, 100, 1000] d2l.plt.figure(figsize=(10, 3)) for i in range(4): n = ns[i] pmf = torch.tensor([p**i * (1-p)**(n-i) * binom(n, i) for i in range(n + 1)]) d2l.plt.subplot(1, 4, i + 1) d2l.plt.stem([(i - n*p)/torch.sqrt(torch.tensor(n*p*(1 - p))) for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlim([-4, 4]) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.title("n = {}".format(n)) d2l.plt.show() .. figure:: output_distributions_c7d568_195_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.2 ns = [1, 10, 100, 1000] d2l.plt.figure(figsize=(10, 3)) for i in range(4): n = ns[i] pmf = np.array([p**i * (1-p)**(n-i) * binom(n, i) for i in range(n + 1)]) d2l.plt.subplot(1, 4, i + 1) d2l.plt.stem([(i - n*p)/np.sqrt(n*p*(1 - p)) for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlim([-4, 4]) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.title("n = {}".format(n)) d2l.plt.show() .. figure:: output_distributions_c7d568_198_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python p = 0.2 ns = [1, 10, 100, 1000] d2l.plt.figure(figsize=(10, 3)) for i in range(4): n = ns[i] pmf = tf.constant([p**i * (1-p)**(n-i) * binom(n, i) for i in range(n + 1)]) d2l.plt.subplot(1, 4, i + 1) d2l.plt.stem([(i - n*p)/tf.sqrt(tf.constant(n*p*(1 - p))) for i in range(n + 1)], pmf, use_line_collection=True) d2l.plt.xlim([-4, 4]) d2l.plt.xlabel('x') d2l.plt.ylabel('p.m.f.') d2l.plt.title("n = {}".format(n)) d2l.plt.show() .. figure:: output_distributions_c7d568_201_0.svg .. raw:: html
.. raw:: html
One thing to note: compared to the Poisson case, we are now dividing by the standard deviation which means that we are squeezing the possible outcomes into smaller and smaller areas. This is an indication that our limit will no longer be discrete, but rather continuous. A derivation of what occurs is beyond the scope of this document, but the *central limit theorem* states that as :math:`n \rightarrow \infty`, this will yield the Gaussian Distribution (or sometimes normal distribution). More explicitly, for any :math:`a, b`: .. math:: \lim_{n \rightarrow \infty} P(Y^{(n)} \in [a, b]) = P(\mathcal{N}(0,1) \in [a, b]), where we say a random variable is normally distributed with given mean :math:`\mu` and variance :math:`\sigma^2`, written :math:`X \sim \mathcal{N}(\mu, \sigma^2)` if :math:`X` has density .. math:: p_X(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}. :label: eq_gaussian_pdf Let’s first plot the probability density function :eq:`eq_gaussian_pdf`. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python mu, sigma = 0, 1 x = torch.arange(-3, 3, 0.01) p = 1 / torch.sqrt(2 * torch.pi * sigma**2) * torch.exp( -(x - mu)**2 / (2 * sigma**2)) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_207_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python mu, sigma = 0, 1 x = np.arange(-3, 3, 0.01) p = 1 / np.sqrt(2 * np.pi * sigma**2) * np.exp(-(x - mu)**2 / (2 * sigma**2)) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_210_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python mu, sigma = 0, 1 x = tf.range(-3, 3, 0.01) p = 1 / tf.sqrt(2 * tf.pi * sigma**2) * tf.exp( -(x - mu)**2 / (2 * sigma**2)) d2l.plot(x, p, 'x', 'p.d.f.') .. figure:: output_distributions_c7d568_213_0.svg .. raw:: html
.. raw:: html
Now, let’s plot the cumulative distribution function. It is beyond the scope of this appendix, but the Gaussian c.d.f. does not have a closed-form formula in terms of more elementary functions. We will use ``erf`` which provides a way to compute this integral numerically. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def phi(x): return (1.0 + erf((x - mu) / (sigma * torch.sqrt(torch.tensor(2.))))) / 2.0 d2l.plot(x, torch.tensor([phi(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_219_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def phi(x): return (1.0 + erf((x - mu) / (sigma * np.sqrt(2)))) / 2.0 d2l.plot(x, np.array([phi(y) for y in x.tolist()]), 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_222_0.svg .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python def phi(x): return (1.0 + erf((x - mu) / (sigma * tf.sqrt(tf.constant(2.))))) / 2.0 d2l.plot(x, [phi(y) for y in x.numpy().tolist()], 'x', 'c.d.f.') .. figure:: output_distributions_c7d568_225_0.svg .. raw:: html
.. raw:: html
Keen-eyed readers will recognize some of these terms. Indeed, we encountered this integral in :numref:`sec_integral_calculus`. Indeed we need exactly that computation to see that this :math:`p_X(x)` has total area one and is thus a valid density. Our choice of working with coin flips made computations shorter, but nothing about that choice was fundamental. Indeed, if we take any collection of independent identically distributed random variables :math:`X_i`, and form .. math:: X^{(N)} = \sum_{i=1}^N X_i. Then .. math:: \frac{X^{(N)} - \mu_{X^{(N)}}}{\sigma_{X^{(N)}}} will be approximately Gaussian. There are additional requirements needed to make it work, most commonly :math:`E[X^4] < \infty`, but the philosophy is clear. The central limit theorem is the reason why the Gaussian is fundamental to probability, statistics, and machine learning. Whenever we can say that something we measured is a sum of many small independent contributions, we can assume that the thing being measured will be close to Gaussian. There are many more fascinating properties of Gaussians, and we would like to discuss one more here. The Gaussian is what is known as a *maximum entropy distribution*. We will get into entropy more deeply in :numref:`sec_information_theory`, however all we need to know at this point is that it is a measure of randomness. In a rigorous mathematical sense, we can think of the Gaussian as the *most* random choice of random variable with fixed mean and variance. Thus, if we know that our random variable has some mean and variance, the Gaussian is in a sense the most conservative choice of distribution we can make. To close the section, let’s recall that if :math:`X \sim \mathcal{N}(\mu, \sigma^2)`, then: - :math:`\mu_X = \mu`, - :math:`\sigma_X^2 = \sigma^2`. We can sample from the Gaussian (or standard normal) distribution as shown below. .. raw:: html
pytorchmxnettensorflow
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python torch.normal(mu, sigma, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output tensor([[ 1.3588, 0.0473, -1.5805, -0.0108, 0.4253, 0.7924, -0.6547, 0.7313, -0.3038, 1.1935], [ 0.0089, 0.8951, 1.0055, 0.0956, -1.1109, -0.6342, 1.6772, 1.0314, 0.3819, -1.7822], [-0.0604, -1.0318, 0.9113, 1.3118, -1.8370, -0.9023, 1.0365, 0.9052, -0.6411, -0.8949], [-0.1713, -0.2347, 0.0767, -0.6375, -0.4612, -1.6875, -0.1570, 1.0591, 0.8377, 0.5097], [ 0.2762, -0.6213, -0.3422, 0.9449, -0.7544, -0.2150, 1.0240, 1.0253, -0.9182, 1.1536], [ 0.0614, 0.2758, -0.3610, -1.0577, -0.5513, -0.9158, 0.7539, 0.9204, -0.5908, 0.9113], [ 1.6190, -0.9213, -0.7944, -2.2621, 0.5826, -1.8287, 1.4097, -0.5744, -0.0668, 1.2074], [-0.0624, 0.1928, 1.3002, 0.6756, 1.1590, 1.0144, 1.1840, -0.5010, 0.6026, -0.7722], [-2.0148, 0.6958, 0.9940, 0.8477, 1.0957, -0.5253, 0.2353, -0.2663, 1.2275, 0.5993], [ 0.4651, -0.8218, -0.5441, -2.0338, -0.6930, -0.0674, -0.4448, -0.8397, 0.0360, -0.7089]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python np.random.normal(mu, sigma, size=(10, 10)) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output array([[-0.11992579, 0.11242172, -0.35572603, 0.58136987, 0.12435943, 0.75733951, -0.13772477, -0.10270837, -1.59153191, -0.94093858], [ 1.01421669, -0.64482199, -1.19968905, -0.29650658, 0.21354805, -0.233707 , -0.84922388, 0.38375312, -0.3886712 , -0.28680926], [ 0.26912722, 0.3832668 , -1.56047648, 1.55956818, -0.84004616, -0.35190349, -0.54684824, 0.83748666, -0.95408109, 0.61570842], [ 1.42284436, 1.47742409, 1.24482391, -0.85638551, -0.78176885, 0.78364858, 0.3804224 , 0.68402399, -1.51515355, 0.77536699], [ 0.80657544, -2.01318421, 0.0262837 , 0.14704248, -1.05968065, 0.09993582, 0.3437732 , 0.71795499, 2.40652949, -0.24287448], [ 0.60314452, 0.96139177, 0.42617912, -1.50385243, 1.89889768, -0.18784024, -0.29100909, -0.61710869, 1.00194018, 0.81604849], [ 0.27520902, -1.01320489, -1.32230684, 0.91961478, 1.08834228, 1.52541641, 0.83242223, -0.70249323, -1.41539373, 0.35746912], [-0.37485341, -0.81440897, 0.64964391, -2.64441164, 0.51285708, -0.00280402, -0.36267136, -0.89061862, -0.2587532 , 1.36505027], [ 0.30396154, -1.17431444, 0.3697711 , -0.58526674, -1.00467336, 1.80141639, 0.44061838, 0.66772324, 0.00462039, -1.1309502 ], [-0.28877008, 0.89796664, -0.80642533, -1.38372865, -0.72438918, 0.34978787, 0.9175374 , -0.43026127, -0.409859 , -1.43388418]]) .. raw:: html
.. raw:: html
.. raw:: latex \diilbookstyleinputcell .. code:: python tf.random.normal((10, 10), mu, sigma) .. raw:: latex \diilbookstyleoutputcell .. parsed-literal:: :class: output .. raw:: html
.. raw:: html
.. _subsec_exponential_family: Exponential Family ------------------ One shared property for all the distributions listed above is that they all belong to which is known as the *exponential family*. The exponential family is a set of distributions whose density can be expressed in the following form: .. math:: p(\mathbf{x} \mid \boldsymbol{\eta}) = h(\mathbf{x}) \cdot \exp \left( \boldsymbol{\eta}^{\top} \cdot T(\mathbf{x}) - A(\boldsymbol{\eta}) \right) :label: eq_exp_pdf As this definition can be a little subtle, let’s examine it closely. First, :math:`h(\mathbf{x})` is known as the *underlying measure* or the *base measure*. This can be viewed as an original choice of measure we are modifying with our exponential weight. Second, we have the vector :math:`\boldsymbol{\eta} = (\eta_1, \eta_2, ..., \eta_l) \in \mathbb{R}^l` called the *natural parameters* or *canonical parameters*. These define how the base measure will be modified. The natural parameters enter into the new measure by taking the dot product of these parameters against some function :math:`T(\cdot)` of :math:`\mathbf{x}= (x_1, x_2, ..., x_n) \in \mathbb{R}^n` and exponentiated. The vector :math:`T(\mathbf{x})= (T_1(\mathbf{x}), T_2(\mathbf{x}), ..., T_l(\mathbf{x}))` is called the *sufficient statistics* for :math:`\boldsymbol{\eta}`. This name is used since the information represented by :math:`T(\mathbf{x})` is sufficient to calculate the probability density and no other information from the sample :math:`\mathbf{x}`\ ’s are required. Third, we have :math:`A(\boldsymbol{\eta})`, which is referred to as the *cumulant function*, which ensures that the above distribution :eq:`eq_exp_pdf` integrates to one, i.e., .. math:: A(\boldsymbol{\eta}) = \log \left[\int h(\mathbf{x}) \cdot \exp \left(\boldsymbol{\eta}^{\top} \cdot T(\mathbf{x}) \right) d\mathbf{x} \right]. To be concrete, let’s consider the Gaussian. Assuming that :math:`\mathbf{x}` is an univariate variable, we saw that it had a density of .. math:: \begin{aligned} p(x \mid \mu, \sigma) &= \frac{1}{\sqrt{2 \pi \sigma^2}} \cdot \exp \left\{ \frac{-(x-\mu)^2}{2 \sigma^2} \right\} \\ &= \frac{1}{\sqrt{2 \pi}} \cdot \exp \left\{ \frac{\mu}{\sigma^2}x -\frac{1}{2 \sigma^2} x^2 - \left( \frac{1}{2 \sigma^2} \mu^2 +\log(\sigma) \right) \right\}. \end{aligned} This matches the definition of the exponential family with: - *underlying measure*: :math:`h(x) = \frac{1}{\sqrt{2 \pi}}`, - *natural parameters*: :math:`\boldsymbol{\eta} = \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} = \begin{bmatrix} \frac{\mu}{\sigma^2} \\ \frac{1}{2 \sigma^2} \end{bmatrix}`, - *sufficient statistics*: :math:`T(x) = \begin{bmatrix}x\\-x^2\end{bmatrix}`, and - *cumulant function*: :math:`A({\boldsymbol\eta}) = \frac{1}{2 \sigma^2} \mu^2 + \log(\sigma) = \frac{\eta_1^2}{4 \eta_2} - \frac{1}{2}\log(2 \eta_2)`. It is worth noting that the exact choice of each of above terms is somewhat arbitrary. Indeed, the important feature is that the distribution can be expressed in this form, not the exact form itself. As we allude to in :numref:`subsec_softmax_and_derivatives`, a widely used technique is to assume that the final output :math:`\mathbf{y}` follows an exponential family distribution. The exponential family is a common and powerful family of distributions encountered frequently in machine learning. Summary ------- - Bernoulli random variables can be used to model events with a yes/no outcome. - Discrete uniform distributions model selects from a finite set of possibilities. - Continuous uniform distributions select from an interval. - Binomial distributions model a series of Bernoulli random variables, and count the number of successes. - Poisson random variables model the arrival of rare events. - Gaussian random variables model the result of adding a large number of independent random variables together. - All the above distributions belong to exponential family. Exercises --------- 1. What is the standard deviation of a random variable that is the difference :math:`X-Y` of two independent binomial random variables :math:`X, Y \sim \textrm{Binomial}(16, 1/2)`. 2. If we take a Poisson random variable :math:`X \sim \textrm{Poisson}(\lambda)` and consider :math:`(X - \lambda)/\sqrt{\lambda}` as :math:`\lambda \rightarrow \infty`, we can show that this becomes approximately Gaussian. Why does this make sense? 3. What is the probability mass function for a sum of two discrete uniform random variables on :math:`n` elements? .. raw:: html
pytorchmxnettensorflow
.. raw:: html
`Discussions `__ .. raw:: html
.. raw:: html
`Discussions `__ .. raw:: html
.. raw:: html
`Discussions `__ .. raw:: html
.. raw:: html