import pandas as pd
import numpy as np
from scipy import stats
import seaborn as sns
import matplotlib.pyplot as plt
from decimal import Decimal
import warnings
warnings.filterwarnings('ignore')
df_salarios = pd.read_csv('dados/dados_tratados.csv').drop('Unnamed: 0', axis=1)
df_b3 = pd.read_csv('dados/b3_stocks_1994_2020.csv')
df_b3['datetime'] = pd.to_datetime(df_b3['datetime'])
Vamos a um exemplo para ficar fácil a compreensão. Vamos criar uma tabela de contingência de tamanho da companhia
por tipo de trabalho
.
dcf = pd.crosstab(df_salarios['tamanho_companhia'], df_salarios['tipo_trabalho'])
dcf_total = dcf.copy()
dcf_total['Total'] = dcf.sum(axis=1, numeric_only=True)
dcf2 = pd.DataFrame({dcf_total.columns[0]: dcf_total['Hibrido'].sum(),
dcf_total.columns[1]: dcf_total['Home office'].sum(),
dcf_total.columns[2]: dcf_total['Presencial'].sum(),
dcf_total.columns[3]: dcf_total['Total'].sum()}, index=['Total'])
dcf_total = dcf_total.append(dcf2)
dcf_total
Hibrido | Home office | Presencial | Total | |
---|---|---|---|---|
Grande | 110 | 220 | 124 | 454 |
Medio | 47 | 1332 | 1774 | 3153 |
Pequeno | 32 | 91 | 25 | 148 |
Total | 189 | 1643 | 1923 | 3755 |
Digamos que um profissional está vendo opções para um novo emprego e esse profissional está fazendo isso por um critério de pontos. Esses pontos seguem uma lógica:
Também sabemos o percentual de cada empresa e tipo de trabalho baseado na pesquisa.
Logo nós podemos ter as seguintes combinações:
Combinação | Probabilidade | Pontos |
---|---|---|
Grande - Home office | 0,0528 | 6 |
Grande - Híbrido | 0,006 | 5 |
Grande - Presencial | 0,0612 | 4 |
Media - Home office | 0,3696 | 5 |
Media - Híbrido | 0,042 | 4 |
Media - Presencial | 0,4284 | 3 |
Pequena - Home office | 0,0176 | 4 |
Pequena - Híbrido | 0,002 | 3 |
Pequena - Presencial | 0,0204 | 2 |
Com isso, podemos presumir que:
Cada um desses eventos tem uma probabilidade associada
com esses valores nós somos capazes de escrever a função $(x, p(x))$, que é um modelo teórico para a distribuição da variável X, que o profissional poderá usar para julgar a viabilidade de ir trabalhar em uma empresa.
x | $p(x)$ |
---|---|
6 | 0,0528 |
5 | 0,3756 |
4 | 0,1208 |
3 | 0,4304 |
2 | 0,0204 |
Definição:
Uma variável aleatória discreta ($X$) é uma função que atribui valores numéricos enumeráveis aos resultados de um experimento. Toda variável aleatória discreta tem uma probabilidade atribuída. Essa probabilidade chamamos de função massa de probabilidade por:
$$p(x_i) = P(X = x_i) = p_i$$Onde:
Voltando ao nosso exemplo pra simplificar esses termos. Temos o evento $A_1$ que é a combinação de Empresa Grande - Home office
. Esse evento atribuímos um valor numérico $x_1$ que é igual a 6. A partir disso calculamos a probabilidade desse evento ocorrer. Logo:
Isso nos mostra que quando nossa variável aleatória discreta for 6, temos essa probabilidade.
Pegando nosso exemplo anterior, qual será a pontuação média das empresas que o profissional espera conseguir?
Dá tabela de distribuição que criamos, temos que:
x | $p(x)$ |
---|---|
6 | 0,0528 |
5 | 0,3756 |
4 | 0,1208 |
3 | 0,4304 |
2 | 0,0204 |
Logo, a pontuação esperada para as empresas é:
$$\text{pontuação média} = (6 \cdot 0,0528) + (5 \cdot 0,3756) + (4 \cdot 0,1208) + (3 \cdot 0,4304) + (2 \cdot 0,0204) = 4,01$$Isso significa que, dado que as suposições feitas para determinar a distribuição da variável aleatória sejam verdadeiras, o profissional espera que as empresas tenham 4,01 pontos.
Formalizando, temos:
A esperança matemática ou valor médio de X é dado por:
$$E(X) = \sum_{i=1}^{n}x_i \cdot P(X = x_i) = \sum_{i=1}^{n}x_i \cdot p_i$$Com o valor da esperança matemática, somos capazes de achar o valor da variância da variável aleatória:
$$\text{Var}(X) = \sum_{i=1}^{n}[x_i - E(X)]² \cdot p_i$$Calculando para nosso caso:
$$\text{Var}(X) = ([6 - 4,01]² \cdot 0,0528) + ([5 - 4,01]² \cdot 0,3756) + ([4 - 4,01]² \cdot 0,1208) + ([3 - 4,01]² \cdot 0,4304) + ([2 - 4,01]² \cdot 0,0204) $$$$\text{Var}(X) = 0,21 + 0,37 + 0,000012 + 0,44 + 0,08 = 1,1$$Como temos a variância, podemos achar o desvio padrão.
$$\text{DP}(X) = \sqrt{\text{Var}(X)} = \sqrt{\sum_{i=1}^{n}[x_i - E(X)]² \cdot p_i} $$No nosso caso o desvio padrão é:
$$\text{DP}(X) = \sqrt{1,1} = 1,048$$Vamos achar esses valores com Python.
x = [2, 3, 4, 5, 6]
p_x = [0.0204, 0.4304, 0.1208, 0.3756, 0.0528]
df_esperanca = pd.DataFrame({'x': x, 'px': p_x})
df_esperanca
x | px | |
---|---|---|
0 | 2 | 0.0204 |
1 | 3 | 0.4304 |
2 | 4 | 0.1208 |
3 | 5 | 0.3756 |
4 | 6 | 0.0528 |
def esperanca_matematica(df, x, px):
return sum(df[x] * df[px])
esperanca_matematica(df_esperanca, 'x', 'px')
4.01
def varianca_variavel_aleatoria(df, x, px):
valor_medio = esperanca_matematica(df, x, px)
return sum(((df[x] - valor_medio)**2) * df[px])
varianca_variavel_aleatoria(df_esperanca, 'x', 'px')
1.0987
def desvio_padrao_variavel_aleatoria(df, x, px):
variancia = varianca_variavel_aleatoria(df_esperanca, x, px)
return np.sqrt(variancia)
desvio_padrao_variavel_aleatoria(df_esperanca, 'x', 'px')
1.0481889142707053
Voltando no nosso exemplo temos:
x | $p(x)$ |
---|---|
6 | 0,0528 |
5 | 0,3756 |
4 | 0,1208 |
3 | 0,4304 |
2 | 0,0204 |
Logo, a função de distribuição acumulada de X será dada por:
$$F(x) = \begin{cases} 0, & \text{se x} < 2 \\ 0,0204, & \text{se 2} \leq x < 3 \\ 0,4508, & \text{se 3} \leq x < 4 \\ 0,5716, & \text{se 4} \leq x < 5 \\ 0,9472, & \text{se 5} \leq x < 6 \\ 1, & \text{se x} \geq 6\\ \end{cases}$$Formalizando:
$$F(x) = P(X \leq x)$$Com python temos:
df_acumulado = df_esperanca.copy()
df_acumulado['fda'] = df_acumulado['px'].cumsum()
df_acumulado
x | px | fda | |
---|---|---|---|
0 | 2 | 0.0204 | 0.0204 |
1 | 3 | 0.4304 | 0.4508 |
2 | 4 | 0.1208 | 0.5716 |
3 | 5 | 0.3756 | 0.9472 |
4 | 6 | 0.0528 | 1.0000 |
sns.barplot(data=df_acumulado, x="x", y="fda")
<AxesSubplot:xlabel='x', ylabel='fda'>
Uma variável aleatória X é considerada uniforme se todos os valores tiveram os mesmos valores de probabilidade:
$$P(X = x_i) = p(x_i) = p = \frac{1}{k}$$para todo $i = 1, 2, 3, ..., k$
Exemplo: Seja a variável aleatória X o número de pontos marcados na face de um dado quando o mesmo é lançado. Qual a probabilidade de cada lado aparecer?
Considerando o dado não viciado, temos que a probabilidade é:
$$P(X = x_1) = P(X = x_2) = P(X = x_3) = P(X = x_4) = P(X = x_5) = P(X = x_6) = \frac{1}{6}$$Sua esperança é dada por:
$$E(X) = \sum_{i=1}^{n}x_i \cdot P(X = x_i) = \sum_{i=1}^{n}x_i \cdot p_i$$Sabendo que $p_i$ é igual para todos os valores compreendidos, então
$$E(X) =\frac{1}{k} \cdot \sum_{i=1}^{n}x_i = \frac{\sum_{i=1}^{n}x_i}{k} $$a variância é:
$$\text{Var}(X) = \frac{\sum_{i=1}^{n}[x_i - \frac{\sum_{i=1}^{n}x_i}{k}]²}{k}$$e a função de distribuição acumulada é dada por:
$$F(X) = \sum_{x_i \leq x}\frac{1}{k} = \frac{n(x)}{k}$$onde $n(x)$ é o número de $x_1 \leq x$.
def distribuicao_uniforme(k):
return 1/k
print(f'Cada um dos {6} resultados tem a probabilidade de {distribuicao_uniforme(6)} de ocorrer')
Cada um dos 6 resultados tem a probabilidade de 0.16666666666666666 de ocorrer
# vendo como o aumento de valores muda a probabilidade
lista = []
lista2 = []
for i in range(1, 51):
lista.append(distribuicao_uniforme(i))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.xlabel('Valores da variável aleatória')
plt.ylabel('Probabilidade')
plt.title('Distribuição uniforme')
plt.show()
Nessa distribuição, a variável aleatória X assume apenas dois valores,chamados de sucesso
e fracasso
.
Vamos ver novamente nossa tabela de contingência.
dcf
tipo_trabalho | Hibrido | Home office | Presencial |
---|---|---|---|
tamanho_companhia | |||
Grande | 110 | 220 | 124 |
Medio | 47 | 1332 | 1774 |
Pequeno | 32 | 91 | 25 |
Nesse caso, vamos imaginar que escolhemos um funcionário ao acaso entre todos os funcionários listados e vamos verificar se essa funcionário trabalha no regime presencial. Nossa opções seriam:
Logo para esse experimento acima, podemos definir uma variável aleatória X, que assume apenas dois valores:
Chamaremos de $p$ a probabilidade de sucesso, então temos:
$$p(0) = P(X = 0) = 1 - p$$$$p(1) = P(X = 1) = p$$Nesse caso, temos 1923 funcionários que trabalham presencialmente, para um total de 3755
então:
$$p(1) = P(X = 1) = \frac{1923}{3755} = 0,51$$$$p(0) = P(X = 1) = 1 - 0,51 = 0,49$$Temos 51% de probabilidade de ao acaso escolher um trabalhador que trabalhe no regime presencial, e 49% de não conseguir.
a esperança matemática é dada por:
$$E(X) = p$$a variância:
$$\text{Var}(X) = p-p² = p\cdot(1 - p) $$e a função de distribuição acumulada:
$$F(x) = \begin{cases} 0, & \text{se x} < 0 \\ 1 - p, & \text{se 0} \leq x < 1 \\ 1, & \text{se x} \geq 1\\ \end{cases}$$Quando uma variável aleatória tiver a distribuição de Bernoulli, usaremos a seguinte notação:
$$X \sim Ber(p)$$No Python, podemos escrever como:
def distribuicao_bernoulli(p):
sucesso = p
fracasso = 1 - p
return sucesso, fracasso
distribuicao_bernoulli(0.51)
(0.51, 0.49)
Essa forma acima é a forma padrão. Porém essa forma não é útil para lidarmos com dataframes do pandas. Vamos ver como seria essa função para um dataframe pandas.
def distribuicao_bernoulli_problema(df, variavel, condicao_sucesso):
return len(df[df[variavel] == condicao_sucesso]) / len(df)
Feito dessa forma, só precisamos passar nosso dataframe, qual variável que nós queremos e a condição de sucesso que queremos analisar.
distribuicao_bernoulli_problema(df_salarios, 'tipo_trabalho', 'Presencial')
0.5121171770972037
probabilidade = len(df_salarios[df_salarios['tipo_trabalho'] == 'Presencial'])/len(df_salarios)
stats.bernoulli.pmf(1, probabilidade)
0.5121171770972037
Vamos analisar outro caso
pleno = distribuicao_bernoulli_problema(df_salarios, 'nivel_experiencia', 'Pleno')
Usando o valor da função criada e passando na função geral, teremos:
distribuicao_bernoulli(pleno)
(0.21438082556591212, 0.7856191744340879)
Logo, temos que para a variável nível de experiência
que a probabilidade de sucesso de retirar um pleno dali é 21%, enquanto o fracasso é de 79%.
# vendo como o aumento da probabilidade de sucesso muda a distribuição
lista_sucesso = []
lista_fracasso = []
lista2 = []
valores = 10
for i in list(np.linspace(0, 1, valores)):
lista_sucesso.append(np.round(distribuicao_bernoulli(i)[0], 2))
lista_fracasso.append(distribuicao_bernoulli(i)[1])
lista2.append(i)
df_bernoulli = pd.DataFrame({'Sucesso': lista_sucesso, 'Fracasso': lista_fracasso})
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
df_bernoulli.plot(kind='bar')
plt.xlabel('Probabilidade de sucesso')
plt.ylabel('Probabilidade de cada evento (Sucesso, Fracasso)')
plt.title('Distribuição de Bernoulli')
plt.show()
<Figure size 1400x500 with 0 Axes>
Vamos imaginar que repetimos o experimento que fizemos acima, na distribuição de Bernoulli, n vezes, sendo que essas repetições feitas são independentes uma das outras.
Vamos dizer que em vezes de escolher ao acaso apenas um funcionário que trabalhe no regime presencial, queremos 5 funcionários. Vamos listar as 5 tentativas:
Logo, a probabilidade dessa amostra será:
$$(1 - p)\cdot p \cdot p \cdot (1-p) \cdot p = p³ \cdot (1-p)²$$Vamos considerar agora situação de uma moeda, qual a probabilidade de em 3 lançamentos, dar duas caras?
Podemos ter os seguintes resultados
Considerando a moeda honesta, temos a probabilidade de $\frac{1}{2}$ para dar cara. Sabendo que a ordem não importa, então temos:
$$P(SSF) = \frac{1}{2} \cdot \frac{1}{2} \cdot \frac{1}{2} = \frac{1}{8}$$$$P(SSF) = P(SFS) = P(FSS)$$$$P(A) = P(SSF) + P(SFS) + P(FSS)$$$$P(A) = \frac{3}{8}$$Chamando novamente a probabilidade de sucesso de $p$, e probabilidade de fracasso de $1 - p = q$, então
$$P(SSF) = p \cdot p \cdot q = p² \cdot q$$Substituindo para os outros valores, achamos que:
$$P(A) = 3p²q$$Generalizando, temos:
$$P(A) = 3p^kq^{n-k}$$Onde:
Nesse caso acima, formamos 3 possíveis sequências, mas e se jogássemos a moeda 30 vezes e buscássemos a probabilidade de dar 20 caras, como faríamos isso. Uma forma saber quantas sequências obteríamos é através da fórmula:
$${n \choose k} = \frac{n!}{k!\cdot(n-k)!}$$Logo, a fórmula final é:
$$P(X = k) = {n \choose k}p^kq^{n-k}$$Onde $k = 0, 1, ...., n$
a esperança matemática é:
$$E(X) = n\cdot p$$variância
$$\text{Var}(X) = n\cdot p\cdot q$$Definimos o experimento binomial ao experimento que:
Quando uma variável aleatória tiver a distribuição de binomial, usaremos a seguinte notação:
$$X \sim b(n, p)$$Com python temos:
def fatorial(x):
valor = 1
for i in range(1, x+1):
valor *= i
return valor
# número de sucessos = k
# tamanho da amostra = n
# probabilidade de sucesso = p
def distribuicao_binomial(numero_sucessos, tamanho_amostra, probabilidade_sucesso):
possiveis_sequencias = (fatorial(tamanho_amostra)/(fatorial(numero_sucessos)
* fatorial(tamanho_amostra-numero_sucessos)))
nao_sucessos = 1 - probabilidade_sucesso
return (possiveis_sequencias * (probabilidade_sucesso**numero_sucessos)
* (nao_sucessos **(tamanho_amostra-numero_sucessos)))
distribuicao_binomial(2, 3, 0.5)
0.375
# validando com scipy
stats.binom.pmf(2, 3, 0.5)
0.3750000000000001
def distribuicao_binomial_problema(df, variavel, condicao_sucesso, numero_sucessos):
tamanho_amostra = len(df)
probabilidade_sucesso = len(df[df[variavel] == condicao_sucesso]) / tamanho_amostra
possiveis_sequencias = Decimal((fatorial(tamanho_amostra)//(fatorial(numero_sucessos)
* fatorial(tamanho_amostra-numero_sucessos))))
nao_sucessos = 1 - probabilidade_sucesso
return float((possiveis_sequencias * Decimal((probabilidade_sucesso**numero_sucessos)
* (nao_sucessos **(tamanho_amostra - numero_sucessos)))))
(fatorial(3755) / fatorial(3730)) / fatorial(25)
1.3798435560850842e+64
distribuicao_binomial_problema(df_salarios, 'tipo_trabalho', 'Presencial', 1923)
0.0
Nesse caso, temos uma distribuição grande, fazendo com que nossa distribuição dê a probabilidade 0. Vamos pegar 50 valores aleatórios do dataframe para testar.
df_amostra = df_salarios.sample(n=50, random_state=42)
distribuicao_binomial_problema(df_amostra, 'tipo_trabalho', 'Presencial', 25)
0.058710477669917716
Agora temos que a probabilidade de pegar aleatoriamente 25 funcionários que trabalham no modo presencial é de 5,8%.
lista = []
lista2 = []
for i in range(0, 51):
lista.append(distribuicao_binomial_problema(df_amostra, 'tipo_trabalho', 'Presencial', i))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.xlabel('Número de sucessos')
plt.ylabel('Probabilidade')
plt.title('Distribuição Binomial')
plt.show()
Temos no gráfico acima que o número de sucessos que nos dá a probabilidade mais alta é 21 casos, logo é mais provável retirarmos 21 funcionários que trabalham no modo presencial uma amostra aleatória de 50.
lista = []
lista2 = []
for i in range(0, 3756):
lista.append(distribuicao_binomial_problema(df_salarios, 'tipo_trabalho', 'Presencial', i))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.xlabel('Número de sucessos')
plt.ylabel('Probabilidade')
plt.title('Distribuição Binomial')
plt.show()
Já no caso da amostra com todos os dados, temos que em todos os casos de número de sucesso, a probabilidade é 0.
Essa distribuição é adequada quando consideramos extrações casuais feitas sem reposição de uma população dividida segundo dois atributos.
Sua fórmula é:
$$P(X=x) = {r \choose k}{N - r \choose n - k}/{N \choose n}$$$$= \frac{\frac{r!}{k!\cdot(r-k)!}\cdot\frac{(N-r)!}{(n-k)!\cdot[(N-r)- (n-k)]!}}{\frac{N!}{n!\cdot(N-n)!}}$$Onde:
Vamos exemplificar, considerando que temos uma população de 100 pessoas, onde 30 são homens, vamos escolher 10 ao acaso. Qual a probabilidade de 5 dessas pessoas serem homens?
$$P(X=x) = {30 \choose 5}{100 - 30 \choose 10 - 5}/{100 \choose 10}$$$$= \frac{\frac{30!}{5!\cdot 25!}\cdot\frac{(70)!}{(5)!\cdot65!}}{\frac{100!}{10!\cdot(90)!}}$$$$= \frac{142506\cdot 12103014}{17310309460000} = 0,099$$Logo, a probabilidade de 5 dessas pessoas tiradas ao acaso serem homens é de 9,9%. E a probabilidade de pelo menos uma dessas 5 pessoas ser mulher é:
$$1 - p = 0,9$$a esperança matemática é:
$$E(X) = np $$a variância é:
$$\text{Var}(X) = np(1 - p)\frac{N - n}{N - 1}$$Quando uma variável aleatória tiver a distribuição de hipergeométrica, usaremos a seguinte notação:
$$X \sim hip(N, r, n)$$no Python:
def fatorial(x):
valor = 1
for i in range(1, x+1):
valor *= i
return valor
def distribuicao_hipergeometrica(populacao_atributo_desejado, qtd_sucessos,
populacao_total, numero_extraido_populacao):
passo1 = (fatorial(populacao_atributo_desejado) /
(fatorial(qtd_sucessos) *
fatorial((populacao_atributo_desejado - qtd_sucessos))))
passo2 = (fatorial((populacao_total-populacao_atributo_desejado)) /
(fatorial((numero_extraido_populacao - qtd_sucessos)) *
fatorial(((populacao_total-populacao_atributo_desejado) -
(numero_extraido_populacao - qtd_sucessos)))))
passo3 = (fatorial(populacao_total) /
(fatorial(numero_extraido_populacao) *
fatorial((populacao_total -
numero_extraido_populacao))))
return ((passo1 * passo2) / passo3)
distribuicao_hipergeometrica(30, 5, 100, 10)
0.09963727785596206
# validando com scipy
stats.hypergeom.pmf(5, 100, 30, 10)
0.09963727785596206
lista = []
lista2 = []
for i in range(1, 21):
lista.append(distribuicao_hipergeometrica(30, i, 100, 10))
lista2.append(i)
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.show()
def distribuicao_hipergeometrica_problema(df, variavel, condicao_sucesso,
qtd_sucessos, numero_extraido_populacao):
populacao_total = len(df)
populacao_atributo_desejado = len(df[df[variavel] == condicao_sucesso])
passo1 = Decimal(fatorial(populacao_atributo_desejado) //
(fatorial(qtd_sucessos) *
fatorial((populacao_atributo_desejado - qtd_sucessos))))
passo2 = Decimal(fatorial((populacao_total-populacao_atributo_desejado)) //
(fatorial((numero_extraido_populacao - qtd_sucessos)) *
fatorial(((populacao_total-populacao_atributo_desejado) -
(numero_extraido_populacao - qtd_sucessos)))))
passo3 = Decimal(fatorial(populacao_total) //
(fatorial(numero_extraido_populacao) *
fatorial((populacao_total -
numero_extraido_populacao))))
return float((passo1 * passo2) / passo3)
distribuicao_hipergeometrica_problema(df_salarios, 'tipo_trabalho', 'Presencial', 25, 50)
0.11136100027569679
Logo, considerando uma amostra total de 3755, retirando 50 valores aleatórios, temos a probabilidade de 11% de retirar 25 pessoas que trabalham no padrão presencial
.
lista = []
lista2 = []
for i in range(1, 1924):
lista.append(distribuicao_hipergeometrica_problema(df_salarios, 'tipo_trabalho',
'Presencial', i, 3000))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.xlabel('Número de sucessos')
plt.ylabel('Probabilidade')
plt.title('Distribuição Hipergeométrica')
plt.show()
A distribuição de Poisson é normalmente utilizada quando queremos contar eventos de certo tipo que ocorrem em um intervalo de tempo. Os eventos podem ser:
Sua fórmula é:
$$P(N = k) = \frac{e^{-\lambda} \lambda^{k}}{k!}$$onde:
a esperança matemática é:
$$E(X) = \lambda$$variância
$$\text{Var}(X) = \lambda$$A distribuição de Poisson é aplicável quando o número de possíveis ocorrências discretas é muito maior do que o número médio de ocorrências em um determinado intervalo de tempo ou espaço. O número de possíveis ocorrências, muitas vezes não se sabe exatamente. Os resultados devem ocorrer de forma aleatória, ou seja, totalmente por acaso e da probabilidade de ocorrência não deve ser afetado pelos resultados ocorridos anteriormente, de modo que as ocorrências são independentes. Em muitos casos, embora possamos contar as ocorrências, como as quantidade de grãos de coloração diferente em um pacote de arroz, não podemos contar as não ocorrências correspondentes, a quantidade de grãos de coloração não diferente.
Quando uma variável aleatória tiver uma distribuição de Poisson, usaremos a seguinte notação:
$$X \sim Pois(\lambda)$$Vamos ver um exemplo.
Qual a probabilidade de termos ações com valores de abertura acima 1 milhão de reais em toda a base de ações?
def distribuicao_poisson(probabilidade, tamanho_populacao, numeros_sucessos):
_lambda = probabilidade * tamanho_populacao
return (np.exp(-_lambda) * _lambda**numeros_sucessos) / fatorial(numeros_sucessos)
len(df_b3)
1883203
acoes_acima = len(df_b3[df_b3['open'] > 1000000])
probabilidade = acoes_acima / len(df_b3)
distribuicao_poisson(probabilidade, len(df_b3), 1)
0.2706705664732254
# validando com scipy
stats.poisson.pmf(1, 2)
0.2706705664732254
Logo, vemos que temos uma probabilidade de 27% de termos uma ação acima de 1 milhão de reais em todas as ações que temos.
lista = []
lista2 = []
valores = 10
for i in range(0, 100):
lista.append(distribuicao_poisson(0.000001, len(df_b3), i))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
plt.bar(lista2, lista)
plt.plot(lista2, lista)
plt.xlabel('Número de sucessos')
plt.ylabel('Probabilidade')
plt.title('Distribuição de Poisson')
plt.show()
lista_lambda1 = []
lista_lambda4 = []
lista_lambda10 = []
lista2 = []
valores = 10
for i in range(0, 100):
lista_lambda1.append(distribuicao_poisson(5.31e-7, len(df_b3), i))
lista_lambda4.append(distribuicao_poisson(4 * 5.31e-7, len(df_b3), i))
lista_lambda10.append(distribuicao_poisson(10 * 5.31e-7, len(df_b3), i))
lista2.append(i)
with sns.axes_style("whitegrid"):
plt.figure(figsize=(14, 5))
#plt.bar(lista2, lista)
plt.plot(lista2, lista_lambda1, label='$\lambda = 1$')
plt.plot(lista2, lista_lambda4, label='$\lambda = 4$')
plt.plot(lista2, lista_lambda10, label='$\lambda = 10$')
plt.ylabel('Probabilidade')
plt.title('Distribuição de Poisson')
plt.legend()
plt.show()