18.8. Distribuições
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in Colab
Open the notebook in SageMaker Studio Lab

Agora que aprendemos como trabalhar com probabilidade tanto na configuração discreta quanto na contínua, vamos conhecer algumas das distribuições comuns encontradas. Dependendo da área de machine learning, podemos precisar estar familiarizados com muito mais delas ou, para algumas áreas de deep learning, possivelmente nenhuma. Esta é, no entanto, uma boa lista básica para se familiarizar. Vamos primeiro importar algumas bibliotecas comuns.

%matplotlib inline
from math import erf, factorial
import numpy as np
from IPython import display
from d2l import mxnet as d2l
%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
%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

18.8.1. Bernoulli

Esta é a variável aleatória mais simples normalmente encontrada. Esta variável aleatória codifica um lançamento de moeda que dá \(1\) com probabilidade \(p\) e \(0\) com probabilidade \(1-p\). Se tivermos uma variável aleatória \(X\) com esta distribuição, vamos escrever

(18.8.1)\[X \sim \mathrm{Bernoulli}(p).\]

A função de distribuição cumulativa é

(18.8.2)\[\begin{split}F(x) = \begin{cases} 0 & x < 0, \\ 1-p & 0 \le x < 1, \\ 1 & x >= 1 . \end{cases}\end{split}\]

A função de massa de probabilidade está representada abaixo.

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()
../_images/output_distributions_c7d568_15_0.svg
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()
../_images/output_distributions_c7d568_18_0.svg
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()
../_images/output_distributions_c7d568_21_0.svg

Agora, vamos representar graficamente a função de distribuição cumulativa (18.8.2).

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.')
../_images/output_distributions_c7d568_27_0.svg
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.')
../_images/output_distributions_c7d568_30_0.svg
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.')
../_images/output_distributions_c7d568_33_0.svg

Se \(X \sim \mathrm{Bernoulli}(p)\), então:

  • \(\mu_X = p\),

  • \(\sigma_X^2 = p(1-p)\).

Podemos amostrar uma matriz de forma arbitrária de uma variável aleatória de Bernoulli como segue.

1*(np.random.rand(10, 10) < p)
array([[0, 0, 1, 1, 0, 1, 0, 1, 0, 1],
       [0, 0, 0, 1, 1, 0, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 0, 1, 0],
       [0, 0, 1, 0, 0, 0, 0, 1, 0, 0],
       [0, 1, 0, 0, 1, 0, 1, 1, 1, 1],
       [1, 0, 1, 0, 0, 1, 1, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 1, 0, 1],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0, 0, 0, 0, 0]])
1*(torch.rand(10, 10) < p)
tensor([[0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
        [0, 0, 1, 1, 0, 0, 0, 0, 0, 1],
        [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 1, 0, 1, 1, 0, 0, 1, 1],
        [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
        [0, 0, 0, 0, 0, 1, 1, 0, 1, 0],
        [0, 0, 0, 0, 1, 0, 0, 1, 0, 1],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
        [0, 0, 1, 0, 0, 1, 0, 1, 0, 0]])
tf.cast(tf.random.uniform((10, 10)) < p, dtype=tf.float32)
<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
array([[0., 1., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 1., 1., 0., 0., 1., 0., 0., 0., 0.],
       [1., 0., 0., 0., 1., 1., 1., 0., 0., 1.],
       [0., 0., 0., 0., 0., 0., 1., 1., 0., 1.],
       [0., 1., 1., 0., 1., 1., 0., 0., 1., 1.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 1., 0., 1., 1., 0., 0., 1., 1., 0.],
       [0., 0., 1., 0., 0., 0., 0., 0., 1., 1.],
       [0., 0., 0., 1., 0., 0., 0., 1., 1., 0.],
       [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>

18.8.2. Uniforme e Discreta

A próxima variável aleatória comumente encontrada é uma uniforme discreta. Para nossa discussão aqui, assumiremos que é suportada nos inteiros \(\{1, 2, \ldots, n\}\), entretanto qualquer outro conjunto de valores pode ser escolhido livremente. O significado da palavra uniforme neste contexto é que todos os valores possíveis são igualmente prováveis. A probabilidade para cada valor \(i \in \{1, 2, 3, \ldots, n\}\) é \(p_i = \frac{1}{n}\). Vamos denotar uma variável aleatória \(X\) com esta distribuição como

(18.8.3)\[X \sim U(n).\]

A função de distribuição cumulativa é

(18.8.4)\[\begin{split}F(x) = \begin{cases} 0 & x < 1, \\ \frac{k}{n} & k \le x < k+1 \text{ with } 1 \le k < n, \\ 1 & x >= n . \end{cases}\end{split}\]

Deixe-nos primeiro representar graficamente a função de massa de probabilidade.

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()
../_images/output_distributions_c7d568_51_0.svg
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()
../_images/output_distributions_c7d568_54_0.svg
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()
../_images/output_distributions_c7d568_57_0.svg

Agora, vamos representar graficamente a função de distribuição cumulativa: eqref:eq_discrete_uniform_cdf.

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.')
../_images/output_distributions_c7d568_63_0.svg
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.')
../_images/output_distributions_c7d568_66_0.svg
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.')
../_images/output_distributions_c7d568_69_0.svg

If \(X \sim U(n)\), then:

  • \(\mu_X = \frac{1+n}{2}\),

  • \(\sigma_X^2 = \frac{n^2-1}{12}\).

Podemos amostrar uma matriz de forma arbitrária a partir de uma variável aleatória uniforme discreta como segue.

np.random.randint(1, n, size=(10, 10))
array([[1, 2, 3, 1, 2, 1, 4, 2, 1, 3],
       [3, 2, 4, 3, 1, 2, 3, 3, 1, 1],
       [3, 4, 2, 4, 3, 1, 2, 1, 1, 1],
       [4, 2, 2, 1, 3, 4, 1, 1, 3, 4],
       [2, 3, 2, 1, 1, 1, 1, 4, 3, 3],
       [2, 4, 2, 2, 3, 4, 4, 4, 1, 2],
       [3, 2, 2, 4, 3, 4, 3, 1, 2, 3],
       [1, 3, 4, 3, 1, 4, 2, 1, 2, 2],
       [4, 4, 4, 4, 2, 3, 2, 2, 4, 1],
       [2, 4, 3, 4, 4, 3, 4, 2, 1, 2]])
torch.randint(1, n, size=(10, 10))
tensor([[2, 4, 2, 4, 1, 3, 2, 2, 2, 4],
        [2, 4, 3, 3, 1, 4, 2, 4, 2, 3],
        [1, 2, 1, 2, 2, 3, 2, 1, 1, 3],
        [3, 4, 2, 4, 1, 1, 2, 1, 2, 2],
        [1, 3, 3, 3, 2, 3, 4, 4, 1, 1],
        [4, 2, 2, 4, 1, 3, 1, 3, 2, 4],
        [3, 3, 3, 3, 4, 3, 4, 2, 1, 2],
        [3, 3, 4, 2, 3, 1, 4, 2, 3, 1],
        [3, 4, 3, 1, 4, 1, 2, 2, 1, 3],
        [4, 4, 1, 3, 4, 4, 2, 2, 3, 1]])
tf.random.uniform((10, 10), 1, n, dtype=tf.int32)
<tf.Tensor: shape=(10, 10), dtype=int32, numpy=
array([[2, 1, 4, 4, 3, 2, 2, 4, 4, 3],
       [2, 3, 4, 1, 2, 1, 4, 3, 3, 1],
       [1, 4, 2, 1, 1, 4, 2, 1, 1, 1],
       [2, 4, 4, 4, 3, 1, 3, 2, 1, 4],
       [2, 3, 4, 4, 3, 4, 1, 1, 1, 1],
       [2, 1, 3, 1, 2, 4, 1, 4, 4, 3],
       [3, 2, 1, 3, 2, 2, 4, 4, 4, 2],
       [1, 2, 2, 4, 1, 2, 3, 2, 2, 1],
       [4, 1, 2, 3, 1, 3, 4, 1, 3, 1],
       [4, 2, 2, 1, 2, 3, 1, 4, 2, 2]], dtype=int32)>

18.8.3. Uniforme e Contínua

A seguir, vamos discutir a distribuição uniforme contínua. A ideia por trás dessa variável aleatória é que, se aumentarmos \(n\) na distribuição uniforme discreta e, em seguida, escaloná-la para caber no intervalo \([a, b]\), abordaremos uma variável aleatória contínua que apenas escolhe um valor arbitrário em \([a, b]\) todos com probabilidade igual. Vamos denotar esta distribuição como

(18.8.5)\[X \sim U(a, b).\]

A função de densidade de probabilidade é

(18.8.6)\[\begin{split}p(x) = \begin{cases} \frac{1}{b-a} & x \in [a, b], \\ 0 & x \not\in [a, b].\end{cases}\end{split}\]

A função de distribuição cumulativa é

(18.8.7)\[\begin{split}F(x) = \begin{cases} 0 & x < a, \\ \frac{x-a}{b-a} & x \in [a, b], \\ 1 & x >= b . \end{cases}\end{split}\]

Vamos primeiro representar graficamente a função de densidade de probabilidade (18.8.6).

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.')
../_images/output_distributions_c7d568_87_0.svg
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.')
../_images/output_distributions_c7d568_90_0.svg
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.')
../_images/output_distributions_c7d568_93_0.svg

Agora, vamos representar graficamente a função de distribuição cumulativa (18.8.7).

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.')
../_images/output_distributions_c7d568_99_0.svg
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.')
../_images/output_distributions_c7d568_102_0.svg
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.')
../_images/output_distributions_c7d568_105_0.svg

Se \(X \sim U(a, b)\), então:

  • \(\mu_X = \frac{a+b}{2}\),

  • \(\sigma_X^2 = \frac{(b-a)^2}{12}\).

Podemos amostrar uma matriz de forma arbitrária a partir de uma variável aleatória uniforme da seguinte maneira. Observe que, por padrão, é uma amostra de \(U(0,1)\), portanto, se quisermos um intervalo diferente, precisamos escaloná-lo.

(b - a) * np.random.rand(10, 10) + a
array([[2.74743298, 2.03159855, 1.07516107, 1.0899085 , 1.56670805,
        2.83306649, 2.85052916, 1.20927866, 1.78954319, 1.42051624],
       [1.42525046, 2.40676598, 1.97061896, 2.58075441, 1.79179163,
        1.2028032 , 2.57083447, 2.16239145, 2.22592097, 2.2660454 ],
       [2.51061663, 2.82806143, 1.32962985, 1.94371877, 2.81431313,
        2.35960726, 2.91475722, 1.36934338, 1.85225797, 1.06361245],
       [2.89271126, 1.65814835, 1.59879384, 2.53255822, 1.15259466,
        1.17028711, 2.5488143 , 2.55240722, 1.61276803, 1.44948278],
       [2.97974614, 2.91643107, 1.68463885, 2.70473872, 2.19648016,
        1.23668542, 2.51995671, 1.48999533, 2.38393232, 1.99265306],
       [2.41501795, 2.04038989, 2.27832101, 1.6753532 , 1.42217372,
        1.91593201, 2.46707199, 2.55517501, 2.03477175, 2.98953302],
       [2.24644313, 1.95294047, 2.4238319 , 2.88006702, 2.46055798,
        1.48457728, 1.59907046, 2.95518618, 2.97693772, 1.66927585],
       [1.1555122 , 1.63482392, 2.00827154, 1.09354961, 1.1059348 ,
        2.10055009, 1.27081608, 2.37430206, 2.74896879, 1.69641912],
       [1.88719054, 1.23264616, 1.55329472, 2.18297288, 1.00754217,
        1.07738796, 1.74940998, 2.70668132, 1.65448103, 2.94373046],
       [1.08165866, 1.97111515, 2.90011096, 1.41029456, 1.54814817,
        2.56687118, 1.32947441, 2.85149868, 2.99477963, 1.60930713]])
(b - a) * torch.rand(10, 10) + a
tensor([[2.8223, 1.5381, 2.7166, 1.7558, 1.2417, 1.2230, 2.2913, 1.5042, 1.6630,
         2.5570],
        [1.5648, 1.4812, 1.9697, 1.5672, 1.9874, 1.5999, 1.4540, 1.8198, 2.4150,
         1.5929],
        [1.1754, 2.5958, 1.7233, 1.3277, 2.0125, 2.1797, 1.5919, 1.0497, 2.1812,
         1.3366],
        [2.4354, 1.6165, 1.1859, 2.9547, 2.0595, 1.8269, 1.1119, 2.3576, 1.9823,
         2.4681],
        [2.7830, 2.8629, 2.5027, 1.6039, 1.5405, 1.1954, 2.5066, 2.0107, 2.6782,
         1.3883],
        [1.2284, 2.3149, 2.1947, 2.4759, 1.0598, 1.1362, 2.7960, 2.9847, 2.3273,
         1.5196],
        [2.0935, 1.1542, 1.8042, 1.0448, 1.0768, 1.8240, 1.2579, 2.1343, 1.5140,
         1.9848],
        [1.5720, 2.2829, 1.2114, 2.2404, 1.8355, 1.2281, 1.1693, 2.3944, 2.2222,
         2.2738],
        [1.9178, 1.3517, 1.0908, 1.3381, 1.0433, 1.1117, 1.6149, 1.4846, 1.2166,
         2.9854],
        [2.3129, 1.2611, 2.3859, 2.4383, 1.8703, 1.3239, 1.5865, 2.9044, 2.6024,
         1.2154]])
(b - a) * tf.random.uniform((10, 10)) + a
<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
array([[2.5743196, 1.3981502, 1.9009221, 1.1490052, 1.706038 , 1.7902389,
        1.515626 , 1.8294001, 1.5888326, 1.4622917],
       [2.8573482, 1.9677377, 2.2720904, 2.7520683, 2.3761632, 2.6878052,
        2.2635167, 2.827392 , 1.8548663, 1.7824538],
       [2.4501195, 1.5826049, 2.1264813, 2.5482373, 2.0862455, 1.6647623,
        2.00781  , 1.2231951, 2.1638196, 2.969057 ],
       [1.8919764, 2.009572 , 2.306309 , 1.8404484, 2.6002595, 2.2673228,
        1.9613779, 1.0868602, 1.6551166, 1.2098784],
       [1.75547  , 2.8230114, 1.8819444, 2.0888054, 1.784781 , 2.8398924,
        1.7647202, 2.5125446, 1.7340975, 1.4983001],
       [1.1644859, 2.8613698, 2.7207723, 1.8036644, 1.1272769, 1.6745679,
        2.6924884, 1.5736811, 2.1638448, 1.6045713],
       [1.5872965, 2.3354874, 1.9195158, 1.482234 , 2.625816 , 1.6888325,
        2.211956 , 1.0187361, 1.7967486, 2.673982 ],
       [2.4621937, 2.0029144, 2.5823393, 1.9013302, 2.0870512, 1.9356115,
        1.5350621, 1.7278454, 2.1218483, 1.0979729],
       [1.7716286, 2.78604  , 1.0262277, 2.530601 , 2.3675945, 1.4779267,
        2.427811 , 1.3714404, 2.120826 , 2.9223158],
       [1.1754923, 2.539765 , 2.4559894, 1.0290706, 1.1161277, 1.4010811,
        1.0752444, 2.5588882, 2.758675 , 1.7770195]], dtype=float32)>

18.8.4. Binomial

Deixe-nos tornar as coisas um pouco mais complexas e examinar a variável aleatória binomial. Essa variável aleatória se origina da execução de uma sequência de \(n\) experimentos independentes, cada um dos quais tem probabilidade \(p\) de sucesso, e perguntando quantos sucessos esperamos ver.

Vamos expressar isso matematicamente. Cada experimento é uma variável aleatória independente \(X_i\), onde usaremos \(1\) para codificar o sucesso e \(0\) para codificar a falha. Como cada um é um lançamento de moeda independente que é bem-sucedido com a probabilidade \(p\), podemos dizer que \(X_i \sim \mathrm{Bernoulli}(p)\). Então, a variável aleatória binomial é

(18.8.8)\[X = \sum_{i=1}^n X_i.\]

Neste caso, vamos escrever

(18.8.9)\[X \sim \mathrm{Binomial}(n, p).\]

Para obter a função de distribuição cumulativa, precisamos observar que obter exatamente \(k\) sucessos podem ocorrer em \(\binom{n}{k} = \frac{n!}{k!(n-k)!}\) maneiras, cada uma das quais tem uma probabilidade de \(p^k(1-p)^{n-k}\) de ocorrer. Assim, a função de distribuição cumulativa é

(18.8.10)\[\begin{split}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 \text{ with } 0 \le k < n, \\ 1 & x >= n . \end{cases}\end{split}\]

Deixe-nos primeiro representar graficamente a função de massa de probabilidade.

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()
../_images/output_distributions_c7d568_123_0.svg
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()
../_images/output_distributions_c7d568_126_0.svg
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()
../_images/output_distributions_c7d568_129_0.svg

Now, let us plot the cumulative distribution function (18.8.10).

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.')
../_images/output_distributions_c7d568_135_0.svg
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.')
../_images/output_distributions_c7d568_138_0.svg
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.')
../_images/output_distributions_c7d568_141_0.svg

Se \(X \sim \mathrm{Binomial}(n, p)\), então:

  • \(\mu_X = np\),

  • \(\sigma_X^2 = np(1-p)\).

Isso decorre da linearidade do valor esperado sobre a soma das \(n\) variáveis aleatórias de Bernoulli e do fato de que a variância da soma das variáveis aleatórias independentes é a soma das variâncias. Isso pode ser amostrado da seguinte maneira.

np.random.binomial(n, p, size=(10, 10))
array([[1, 1, 3, 1, 3, 4, 0, 2, 1, 0],
       [1, 1, 2, 1, 1, 1, 2, 2, 1, 2],
       [3, 4, 2, 2, 4, 2, 3, 2, 2, 3],
       [4, 1, 1, 3, 1, 2, 3, 3, 2, 3],
       [3, 3, 2, 3, 0, 1, 2, 3, 2, 3],
       [3, 2, 1, 2, 3, 2, 1, 0, 1, 0],
       [2, 0, 2, 4, 2, 4, 3, 2, 1, 3],
       [2, 3, 2, 1, 3, 2, 2, 4, 0, 3],
       [4, 1, 3, 3, 0, 1, 2, 1, 2, 2],
       [0, 1, 3, 0, 1, 0, 5, 2, 4, 4]])
m = torch.distributions.binomial.Binomial(n, p)
m.sample(sample_shape=(10, 10))
tensor([[3., 3., 3., 2., 1., 4., 3., 1., 2., 2.],
        [1., 3., 1., 2., 1., 1., 3., 5., 2., 1.],
        [1., 2., 1., 0., 3., 4., 2., 1., 3., 1.],
        [2., 3., 0., 0., 3., 3., 3., 1., 3., 3.],
        [2., 3., 3., 1., 4., 1., 2., 2., 3., 2.],
        [1., 3., 2., 4., 1., 1., 1., 2., 3., 3.],
        [2., 4., 2., 1., 2., 4., 4., 1., 1., 3.],
        [2., 0., 3., 3., 0., 2., 2., 0., 3., 4.],
        [2., 1., 2., 3., 1., 1., 0., 3., 0., 2.],
        [3., 1., 2., 1., 1., 0., 0., 0., 1., 2.]])
m = tfp.distributions.Binomial(n, p)
m.sample(sample_shape=(10, 10))
<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
array([[5., 3., 7., 5., 8., 5., 5., 5., 7., 6.],
       [6., 4., 5., 5., 6., 6., 7., 5., 4., 9.],
       [4., 7., 5., 5., 6., 7., 6., 4., 8., 4.],
       [6., 6., 5., 6., 3., 4., 6., 6., 3., 7.],
       [5., 5., 4., 8., 6., 7., 4., 5., 5., 8.],
       [6., 6., 5., 5., 5., 6., 6., 5., 6., 3.],
       [5., 6., 5., 4., 4., 7., 3., 6., 4., 3.],
       [8., 6., 5., 5., 8., 5., 7., 4., 6., 4.],
       [6., 5., 3., 8., 5., 7., 3., 6., 7., 7.],
       [0., 4., 6., 8., 6., 4., 7., 6., 5., 8.]], dtype=float32)>

18.8.5. Poisson

Vamos agora realizar um experimento mental. Estamos parados em um ponto de ônibus e queremos saber quantos ônibus chegarão no próximo minuto. Vamos começar considerando \(X^{(1)} \sim \mathrm{Bernoulli}(p)\) que é simplesmente a probabilidade de que um ônibus chegue na janela de um minuto. Para paradas de ônibus longe de um centro urbano, essa pode ser uma boa aproximação. Podemos nunca ver mais de um ônibus por minuto.

Porém, se estivermos em uma área movimentada, é possível ou mesmo provável que cheguem dois ônibus. Podemos modelar isso dividindo nossa variável aleatória em duas partes nos primeiros 30 segundos ou nos segundos 30 segundos. Neste caso, podemos escrever

(18.8.11)\[X^{(2)} \sim X^{(2)}_1 + X^{(2)}_2,\]

onde \(X^{(2)}\) é a soma total, e \(X^{(2)}_i \sim \mathrm{Bernoulli}(p/2)\). A distribuição total é então \(X^{(2)} \sim \mathrm{Binomial}(2, p/2)\).

Why stop here? Let us continue to split that minute into \(n\) parts. By the same reasoning as above, we see that

(18.8.12)\[X^{(n)} \sim \mathrm{Binomial}(n, p/n).\]

Considere essas variáveis aleatórias. Pela seção anterior, sabemos que (18.8.12) tem média \(\mu_{X^{(n)}} = n(p/n) = p\), e variância \(\sigma_{X^{(n)}}^2 = n(p/n)(1-(p/n)) = p(1-p/n)\). Se tomarmos \(n \rightarrow \infty\), podemos ver que esses números se estabilizam em \(\mu_{X^{(\infty)}} = p\), e variância \(\sigma_{X^{(\infty)}}^2 = p\). Isso indica que pode haver alguma variável aleatória que podemos definir neste limite de subdivisão infinito.

Isso não deve ser uma surpresa, já que no mundo real podemos apenas contar o número de chegadas de ônibus, no entanto, é bom ver que nosso modelo matemático está bem definido. Essa discussão pode ser formalizada como a lei dos eventos raros.

Seguindo esse raciocínio com cuidado, podemos chegar ao seguinte modelo. Diremos que \(X \sim \mathrm{Poisson}(\lambda)\) se for uma variável aleatória que assume os valores \(\{0,1,2, \ldots\}\) com probabilidade

(18.8.13)\[p_k = \frac{\lambda^ke^{-\lambda}}{k!}.\]

O valor \(\lambda > 0\) é conhecido como taxa (ou o parâmetro forma) e denota o número médio de chegadas que esperamos em uma unidade de tempo.

Podemos somar essa função de massa de probabilidade para obter a função de distribuição cumulativa.

(18.8.14)\[\begin{split}F(x) = \begin{cases} 0 & x < 0, \\ e^{-\lambda}\sum_{m = 0}^k \frac{\lambda^m}{m!} & k \le x < k+1 \text{ with } 0 \le k. \end{cases}\end{split}\]

Vamos primeiro representar graficamente a função de massa de probabilidade (18.8.13).

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()
../_images/output_distributions_c7d568_159_0.svg
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()
../_images/output_distributions_c7d568_162_0.svg
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()
../_images/output_distributions_c7d568_165_0.svg

Agora, vamos representar graficamente a função de distribuição cumulativa (18.8.14).

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.')
../_images/output_distributions_c7d568_171_0.svg
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.')
../_images/output_distributions_c7d568_174_0.svg
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.')
../_images/output_distributions_c7d568_177_0.svg

Como vimos acima, as médias e variações são particularmente concisas. Se \(X \sim \mathrm{Poisson}(\lambda)\), então:

  • \(\mu_X = \lambda\),

  • \(\sigma_X^2 = \lambda\).

Isso pode ser amostrado da seguinte maneira.

np.random.poisson(lam, size=(10, 10))
array([[3, 6, 4, 5, 4, 6, 5, 1, 3, 3],
       [2, 0, 9, 6, 9, 1, 5, 5, 9, 1],
       [6, 4, 3, 6, 7, 2, 6, 6, 3, 4],
       [5, 3, 5, 2, 4, 3, 7, 5, 4, 4],
       [5, 8, 9, 4, 7, 3, 2, 8, 6, 3],
       [7, 3, 5, 3, 2, 7, 9, 6, 4, 7],
       [7, 4, 4, 6, 3, 9, 8, 5, 7, 2],
       [3, 5, 2, 4, 6, 3, 7, 6, 5, 5],
       [5, 2, 4, 8, 3, 3, 6, 4, 6, 6],
       [8, 4, 3, 3, 4, 6, 5, 7, 5, 5]])
m = torch.distributions.poisson.Poisson(lam)
m.sample((10, 10))
tensor([[ 4.,  7.,  5.,  6.,  4.,  7.,  4.,  6.,  3.,  3.],
        [ 5.,  6.,  7.,  9.,  6.,  5.,  3.,  7.,  3.,  6.],
        [10.,  5.,  2.,  2.,  6.,  4.,  5.,  6.,  3.,  4.],
        [ 3.,  8.,  7.,  8.,  3.,  1.,  7.,  3.,  5.,  6.],
        [ 6.,  4.,  6.,  9.,  8.,  7.,  4.,  7.,  3.,  7.],
        [ 5.,  9.,  3.,  3.,  3.,  3.,  2.,  5.,  4.,  8.],
        [ 4.,  2.,  5.,  2.,  4.,  8.,  2.,  9.,  9.,  3.],
        [ 2.,  2.,  5.,  6.,  1.,  5.,  4.,  6.,  6.,  2.],
        [ 8.,  5.,  6.,  4.,  5.,  7.,  9.,  9.,  3.,  6.],
        [ 3.,  2.,  4.,  7.,  3.,  6.,  5.,  2.,  4.,  4.]])
m = tfp.distributions.Poisson(lam)
m.sample((10, 10))
<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
array([[ 8.,  3.,  2.,  3.,  7.,  1.,  8.,  3.,  3.,  2.],
       [ 4.,  5.,  4.,  5.,  5.,  5.,  5.,  9.,  6.,  5.],
       [ 5.,  4.,  5.,  4.,  3.,  1.,  5.,  3.,  8.,  6.],
       [ 6.,  4.,  6.,  3.,  8.,  5.,  3.,  5.,  5.,  3.],
       [ 4.,  4.,  4.,  4.,  6.,  5.,  5.,  2.,  4.,  6.],
       [ 6.,  4.,  5.,  4.,  4.,  3.,  5.,  6.,  5.,  2.],
       [ 4.,  6.,  7.,  8.,  2.,  5.,  4.,  7.,  4.,  6.],
       [ 3., 10.,  3.,  6.,  7.,  7.,  7.,  8.,  5.,  6.],
       [ 3.,  3.,  3.,  3.,  8.,  6.,  5.,  4.,  4.,  4.],
       [ 8.,  5.,  5.,  3.,  7.,  5.,  6.,  2.,  6.,  3.]], dtype=float32)>

18.8.6. Gaussiana

Agora, vamos tentar um experimento diferente, mas relacionado. Digamos que estamos novamente realizando \(n\) medidas independentes de \(\mathrm{Bernoulli}(p)\) \(X_i\). A distribuição da soma delas é \(X^{(n)} \sim \mathrm{Binomial}(n, p)\). Em vez de considerar um limite à medida que \(n\) aumenta e \(p\) diminui, vamos corrigir \(p\) e enviar \(n \rightarrow \infty\). Neste caso \(\mu_{X^{(n)}} = np \rightarrow \infty\) e \(\sigma_{X^{(n)}}^2 = np(1-p) \rightarrow \infty\), portanto, não há razão para pensar que esse limite deva ser bem definido.

No entanto, nem toda esperança está perdida! Vamos apenas fazer com que a média e a variância sejam bem comportadas, definindo

(18.8.15)\[Y^{(n)} = \frac{X^{(n)} - \mu_{X^{(n)}}}{\sigma_{X^{(n)}}}.\]

Pode-se ver que isso tem média zero e variância um e, portanto, é plausível acreditar que convergirá para alguma distribuição limitante. Se traçarmos a aparência dessas distribuições, ficaremos ainda mais convencidos de que funcionará.

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()
../_images/output_distributions_c7d568_195_0.svg
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()
../_images/output_distributions_c7d568_198_0.svg
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()
../_images/output_distributions_c7d568_201_0.svg

Uma coisa a observar: em comparação com o caso de Poisson, agora estamos dividindo pelo desvio padrão, o que significa que estamos comprimindo os resultados possíveis em áreas cada vez menores. Isso é uma indicação de que nosso limite não será mais discreto, mas sim contínuo.

Uma derivação do que ocorre está além do escopo deste documento, mas o teorema do limite central afirma que, como \(n \rightarrow \infty\), isso resultará na Distribuição Gaussiana (ou as vezes na distribuição normal). Mais explicitamente, para qualquer \(a, b\):

(18.8.16)\[\lim_{n \rightarrow \infty} P(Y^{(n)} \in [a, b]) = P(\mathcal{N}(0,1) \in [a, b]),\]

onde dizemos que uma variável aleatória é normalmente distribuída com dada média \(\mu\) e variância \(\sigma^2\), escrita \(X \sim \mathcal{N}(\mu, \sigma^2)\) se \(X\) tem densidade

(18.8.17)\[p_X(x) = \frac{1}{\sqrt{2\pi\sigma^2}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}.\]

Vamos primeiro representar graficamente a função de densidade de probabilidade (18.8.17).

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.')
../_images/output_distributions_c7d568_207_0.svg
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.')
../_images/output_distributions_c7d568_210_0.svg
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.')
../_images/output_distributions_c7d568_213_0.svg

Agora, vamos representar graficamente a função de distribuição cumulativa. Está além do escopo deste apêndice, mas a f.d.c. Gaussiana não tem uma fórmula de forma fechada em termos de funções mais elementares. Usaremos erf, que fornece uma maneira de calcular essa integral numericamente.

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.')
../_images/output_distributions_c7d568_219_0.svg
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.')
../_images/output_distributions_c7d568_222_0.svg
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.')
../_images/output_distributions_c7d568_225_0.svg

Os leitores mais atentos reconhecerão alguns desses termos. Na verdade, encontramos essa integral em Section 18.5. Na verdade, precisamos exatamente desse cálculo para ver que esse \(p_X (x)\) tem área total um e, portanto, é uma densidade válida.

Nossa escolha de trabalhar com cara ou coroa tornou os cálculos mais curtos, mas nada nessa escolha foi fundamental. De fato, se tomarmos qualquer coleção de variáveis aleatórias independentes distribuídas de forma idêntica \(X_i\), e formar

(18.8.18)\[X^{(N)} = \sum_{i=1}^N X_i.\]

Then

(18.8.19)\[\frac{X^{(N)} - \mu_{X^{(N)}}}{\sigma_{X^{(N)}}}\]

será aproximadamente gaussiana. Existem requisitos adicionais necessários para fazê-la funcionar, mais comumente \(E[X^4] < \infty\), mas a filosofia é clara.

O teorema do limite central é a razão pela qual o Gaussiano é fundamental para probabilidade, estatística e aprendizado de máquina. Sempre que podemos dizer que algo que medimos é a soma de muitas pequenas contribuições independentes, podemos supor que o que está sendo medido será próximo de gaussiano.

Existem muitas outras propriedades fascinantes das gaussianas, e gostaríamos de discutir mais uma aqui. A Gaussiana é conhecida como distribuição de entropia máxima. Entraremos em entropia mais profundamente em Section 18.11, no entanto, tudo o que precisamos saber neste ponto é que é uma medida de aleatoriedade. Em um sentido matemático rigoroso, podemos pensar no gaussiano como a escolha mais aleatória de variável aleatória com média e variância fixas. Portanto, se sabemos que nossa variável aleatória tem alguma média e variância, a Gaussiana é, de certo modo, a escolha de distribuição mais conservadora que podemos fazer.

Para fechar a seção, vamos lembrar que se \(X \sim \mathcal{N}(\mu, \sigma^2)\), então:

  • \(\mu_X = \mu\),

  • \(\sigma_X^2 = \sigma^2\).

Podemos obter uma amostra da distribuição gaussiana (ou normal padrão), conforme mostrado abaixo.

np.random.normal(mu, sigma, size=(10, 10))
array([[ 1.49917742, -1.89738727, -0.15765172, -1.30406481,  1.39513244,
         0.73954538,  1.15326125,  1.27176545, -1.5794067 , -0.99068548],
       [-1.15778637,  1.6457573 ,  0.30449236,  0.74880239, -1.09216768,
        -0.572821  , -0.51135549,  1.19231727,  0.45957271, -0.02058818],
       [-0.05529317,  0.29419677,  0.18805374,  0.76098036, -0.97031427,
         1.96972514,  1.88326016,  0.6229381 ,  0.54420812, -0.7531442 ],
       [ 2.27807991, -0.21409296,  0.45279401, -0.89506324,  0.28100847,
        -1.86260982,  0.07614099, -0.24923532,  0.17389077, -0.7427528 ],
       [-0.36021216, -1.15600105, -0.25003882, -0.83905388,  0.01927618,
        -1.56239161,  1.14385223, -0.24816723,  0.50232904,  0.18643067],
       [-1.31329087,  0.05678681,  0.74464929,  0.61052243, -1.06151488,
        -0.40652285,  0.72652966,  1.12828664, -0.77463378, -0.90476107],
       [ 0.20437941, -1.15966042,  0.14822335,  1.34530682, -0.43604435,
        -0.48720988, -0.22021717, -0.03575601,  0.03048036, -1.27704417],
       [-1.23587311,  1.01658176, -0.30615902,  0.79378662,  0.62172223,
         2.20654089, -0.18224328, -1.90468774, -0.38497634, -0.40938212],
       [-1.69134761,  1.54025185, -0.33894673, -0.55753099, -0.19299495,
        -0.34038202, -0.26246888,  0.67041897, -1.5196233 ,  0.11619327],
       [ 0.23278424,  1.82530067,  1.8425147 ,  1.38355034,  2.09754797,
         0.68892611, -0.16139531, -1.61466365, -0.35005664,  0.92306538]])
torch.normal(mu, sigma, size=(10, 10))
tensor([[ 0.6520,  0.3000, -0.4574, -0.2548,  0.0422, -1.8848, -0.0027,  0.1869,
         -0.8954,  0.4869],
        [-0.2392, -1.8471, -1.2784,  0.1939, -0.3280,  2.1257, -0.5251, -0.2571,
          1.5258,  0.1374],
        [-0.1976,  1.2392, -1.3503, -1.1267,  1.2744,  0.2877, -0.8623,  0.6505,
         -0.0413, -0.6328],
        [ 0.2136, -0.6770,  0.5709,  0.2465, -0.4408,  1.0694,  0.9333, -0.8263,
         -0.3953, -1.5467],
        [-0.0639,  1.3519,  1.1904,  0.4413, -0.2036, -0.8335, -0.6494,  1.0609,
          0.3457, -0.0494],
        [-0.1203, -0.0650,  1.6500, -0.0922, -0.7590, -0.8886, -0.6484,  0.1333,
          0.9615,  0.8912],
        [ 0.9083, -0.0155,  0.3283,  1.1933, -0.5716, -0.0458, -0.0481, -1.4992,
          0.4722, -0.3956],
        [-0.6736, -1.6859,  0.1728, -1.0743,  0.8750,  0.1384, -0.1763,  0.7425,
          0.7856,  2.4783],
        [-1.5720,  0.0452, -0.0454,  0.1253, -0.2715,  0.4259, -1.0297, -0.9537,
          1.1536,  1.6208],
        [-0.7449,  1.9093, -0.1521,  1.6758,  0.7218,  0.7647, -2.6015,  0.0139,
          0.5314, -0.0911]])
tf.random.normal((10, 10), mu, sigma)
<tf.Tensor: shape=(10, 10), dtype=float32, numpy=
array([[-1.4912432 ,  0.4451671 ,  0.6260689 ,  0.5234036 , -0.3705675 ,
        -0.8627905 , -0.2095269 , -0.14264254, -0.8618236 , -0.15879707],
       [-2.9813936 , -0.4033666 ,  1.8460276 ,  0.24281931,  0.88338095,
        -1.0324891 , -2.4471316 , -0.00790913,  0.54268175, -0.21591146],
       [ 0.6091021 ,  1.0317754 ,  0.61147314, -1.3328887 ,  1.6148773 ,
         0.14458533,  0.14773923,  0.04071072, -0.10958313, -0.02937491],
       [ 1.4392412 ,  0.07901777, -0.52301794,  0.5837574 , -2.1088915 ,
         2.5911148 , -0.6457512 , -1.3024681 , -0.5892503 , -1.2592412 ],
       [-0.9908043 , -0.03393532,  0.4113675 , -0.5235521 ,  0.15274064,
         0.52918416,  0.05189318,  0.7893573 ,  1.0766877 , -1.0104825 ],
       [-0.7068546 ,  1.1505599 , -1.3734901 , -1.264961  , -1.8530722 ,
        -2.2136655 , -0.584304  ,  0.8976451 ,  1.0226982 ,  0.27116343],
       [ 0.8119495 ,  0.64451736,  1.1425577 , -0.5787743 ,  1.172663  ,
        -1.635346  , -0.69309866,  1.2681428 , -1.0573347 , -0.58386236],
       [-0.5360857 , -0.63382757, -0.8472088 ,  0.7535314 ,  0.74566555,
        -0.84775317,  0.03532044, -1.2786845 ,  0.29026207, -1.374856  ],
       [ 0.12005524, -1.0951283 , -1.1497281 , -1.9988611 , -0.5215675 ,
        -1.7956804 ,  1.1923795 , -1.2176396 , -0.0125352 , -0.41542777],
       [ 0.03475034,  0.9260897 , -2.4342093 , -0.23181166,  0.96121734,
         1.700627  ,  1.2121551 , -2.021329  , -0.18049796, -0.3070631 ]],
      dtype=float32)>

18.8.7. Família Exponencial

Uma propriedade compartilhada para todas as distribuições listadas acima é que todas pertencem à conhecida como família exponencial. A família exponencial é um conjunto de distribuições cuja densidade pode ser expressa no seguinte Formato:

(18.8.20)\[p(\mathbf{x} | \boldsymbol{\eta}) = h(\mathbf{x}) \cdot \mathrm{exp} \left( \boldsymbol{\eta}^{\top} \cdot T(\mathbf{x}) - A(\boldsymbol{\eta}) \right)\]

Como essa definição pode ser um pouco sutil, vamos examiná-la de perto.

Primeiro, \(h(\mathbf{x})\) é conhecido como a medida subjacente ou a medida de base. Isso pode ser visto como uma escolha original da medida que estamos modificando com nosso peso exponencial.

Em segundo lugar, temos o vetor \(\boldsymbol{\eta} = (\eta_1, \eta_2, ..., \eta_l) \in\mathbb{R}^l\) chamado de parâmetros naturais ou parâmetros canônicos. Eles definem como a medida base será modificada. Os parâmetros naturais entram na nova medida tomando o produto escalar desses parâmetros em relação a alguma função \(T(\cdot)\) de :raw-latex:`\mathbf{x}`= (x_1, x_2, …, x_n) :raw-latex:`in`:raw-latex:mathbb{R}`^n$ e exponenciado. O vetor :math:`T(mathbf{x})= (T_1(mathbf{x}), T_2(mathbf{x}), …, T_l(mathbf{x})) é chamado de estatísticas suficientes para \(\boldsymbol{\eta}\). Este nome é usado uma vez que a informação representada por \(T(\mathbf{x})\) é suficiente para calcular a densidade de probabilidade e nenhuma outra informação da amostra \(\mathbf{x}\) é requerida.

Terceiro, temos \(A(\boldsymbol{\eta})\), que é referido como a função cumulativa, que garante que a distribuição acima (18.8.20) integra-se a um, ou seja,

(18.8.21)\[A(\boldsymbol{\eta}) = \log \left[\int h(\mathbf{x}) \cdot \mathrm{exp} \left(\boldsymbol{\eta}^{\top} \cdot T(\mathbf{x}) \right) d\mathbf{x} \right].\]

Para sermos concretos, consideremos o gaussiano. Supondo que \(\mathbf{x}\) seja uma variável univariada, vimos que ela tinha uma densidade de

(18.8.22)\[\begin{split}\begin{aligned} p(x | \mu, \sigma) &= \frac{1}{\sqrt{2 \pi \sigma^2}} \cdot \mathrm{exp} \left\{ \frac{-(x-\mu)^2}{2 \sigma^2} \right\} \\ &= \frac{1}{\sqrt{2 \pi}} \cdot \mathrm{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}\end{split}\]

Isso corresponde à definição da família exponencial com:

  • medida subjacente: \(h(x) = \frac{1}{\sqrt{2 \pi}}\),

  • parâmetros naturais: \(\boldsymbol{\eta} = \begin{bmatrix} \eta_1 \\ \eta_2 \end{bmatrix} = \begin{bmatrix} \frac{\mu}{\sigma^2} \\ \frac{1}{2 \sigma^2} \end{bmatrix}\),

  • estatísticas suficientes: \(T(x) = \begin{bmatrix}x\\-x^2\end{bmatrix}\), and

  • função cumulativa: \(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)\).

É importante notar que a escolha exata de cada um dos termos acima é um pouco arbitrária. Na verdade, a característica importante é que a distribuição pode ser expressa nesta forma, não na forma exata em si.

Como aludimos em Section 3.4.6.2, uma técnica amplamente utilizada é assumir que a saída final \(\mathbf{y}\) segue uma distribuição da família exponencial. A família exponencial é uma comum e poderosa família de distribuições encontradas com frequência no machine learning.

18.8.8. Resumo

  • Variáveis aleatórias de Bernoulli podem ser usadas para modelar eventos com um resultado sim/não.

  • O modelo de distribuições uniformes discretas seleciona a partir de um conjunto finito de possibilidades.

  • Distribuições uniformes contínuas selecionam a partir de um intervalo.

  • As distribuições binomiais modelam uma série de variáveis aleatórias de Bernoulli e contam o número de sucessos.

  • Variáveis aleatórias de Poisson modelam a chegada de eventos raros.

  • Variáveis aleatórias gaussianas modelam o resultado da adição de um grande número de variáveis aleatórias independentes.

  • Todas as distribuições acima pertencem à família exponencial.

18.8.9. Exercícios

  1. Qual é o desvio padrão de uma variável aleatória que é a diferença \(X-Y\) de duas variáveis aleatórias binomiais independentes \(X, Y \sim \mathrm{Binomial}(16, 1/2)\).

  2. Se tomarmos uma variável aleatória de Poisson\(X \sim \mathrm{Poisson}(\lambda)\) e considerar \((X - \lambda)/\sqrt{\lambda}\) como \(\lambda \rightarrow \infty\), podemos mostrar que isso se torna aproximadamente gaussiano. Por que isso faz sentido?

  3. Qual é a função de massa de probabilidade para uma soma de duas variáveis aleatórias uniformes discretas em \(n\) elementos?