import numpy as np
import collections as c
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import math
from IPython.display import display
from ipywidgets import interact_manual
import ipywidgets as widgets
#Calcula a probabilidade de cair x caras ou y coroas
def calcula_probabilidade(moeda,qtd_lancamentos,qtd_cara,qtd_coroa,p_cara=0.5):
    
    qtd_lancamentos = qtd_lancamentos
    qtd_cara = qtd_cara 
    qtd_coroa = qtd_coroa 
    p_coroa = 1 - p_cara
        
    prob = p_cara**qtd_cara * p_coroa**(qtd_lancamentos-qtd_cara) * math.factorial(qtd_lancamentos)/(math.factorial(qtd_cara)*math.factorial(qtd_lancamentos-qtd_cara)) + \
           p_coroa**qtd_coroa * p_cara**(qtd_lancamentos-qtd_coroa) * math.factorial(qtd_lancamentos)/(math.factorial(qtd_coroa)*math.factorial(qtd_lancamentos-qtd_coroa))

    print("Para uma moeda %s, em %d lançamentos, a probabilidade de cair %d Caras ou %d Coroas é %.3f" %(moeda,qtd_lancamentos,qtd_cara,qtd_coroa,prob))

#Gera N lançamentos aleatórios de moeda
def gera_lancamentos(moeda,qtd_lancamentos,p_cara=0.5):
    eventos = ['K','C']
    p_coroa = 1 - p_cara

    probabilidades = [p_cara,p_coroa]
    lancamentos = np.random.choice(eventos,p=probabilidades,size=qtd_lancamentos)
    contagem = c.Counter(lancamentos)  
    
    return contagem

#Mostra os números obtidos com gera_lancamentos
def mostra_probabilidades(contagem):
    print('Quantidade de Caras: ',contagem['K'])
    print('P(K): ', contagem['K']/sum(contagem.values()))
    print('Quantidade de Coroas: ',contagem['C'])
    print('P(C): ', contagem['C']/sum(contagem.values()))
    
#Plota grafico de lançamentos
def grafico_lancamentos(moeda='justa',qtd_lancamentos=2000,p_cara=50):
    p_cara=p_cara/100
    probabilidades = pd.DataFrame(data={},columns=['qtd_lancamentos','prob_cara'])
    for i in range(1,qtd_lancamentos,10):
        contagem = gera_lancamentos(moeda,i,p_cara)
        prob_cara = contagem['K']/sum(contagem.values())
        probabilidades.loc[i,'qtd_lancamentos'] = i
        probabilidades.loc[i,'prob_cara'] = prob_cara

    fig = plt.figure(figsize=(30,5))
    ax = fig.add_subplot(1,1,1)
    l1 = ax.plot(probabilidades['qtd_lancamentos'],probabilidades['prob_cara'],label = 'Probabilidade calculada')
    l3 = ax.axhline(y=p_cara,linewidth=2, label = 'Probabilidade esperada', linestyle='--',color='r')
    ax.set_ylim(ymin=0,ymax=1)
    handles, labels = ax.get_legend_handles_labels()
    ax.legend(handles, labels, loc=2,prop={'size': 18})
    ax.set_title('P(K) de acordo com a quantidade de lançamentos', size=24)
    ax.set_ylabel('Probabilidade',size=20)
    ax.set_xlabel('Quantidade de Lançamentos',size=20)
    plt.xticks(fontsize=16)
    plt.yticks(fontsize=16)
"""
OBS: Para conseguir executar as células de código e mudar os parâmetros dos exemplos, clique em "Copiar e editar". Para executar uma célula, basta clicar sobre ela e, em seguida, no botão "Run" à esquerda (com formato de triângulo).
"""
"""
# Introdução à Ciência de dados
"""
"""
#### Porque usar dados?
O uso de dados nas organizações sempre existiu, mesmo que de forma escassa e pouco estruturada, mas foram os recentes avanços na tecnologia que possibilitaram o início da utilização de grandes volumes de dados.
Até pouco tempo atrás, algoritmos que poderiam ser utilizados na identificação de padrões e correlações ou na construção de modelos de previsão demoravam dias para processarem grandes volumes de informação. Atualmente algumas análises podem acontecer em tempo real, permitindo que a liderança tome decisões cada vez mais rápidas e assertivas.
Dessa forma, o uso de análise de dados é algo que as organizações não podem ignorar. 

Além disso, há alguns anos, o uso de *Big Data & Analytics* parecia uma tarefa impraticável em função da restrição de informações e de tecnologias disponíveis para implementar o uso de dados em uma empresa. Mas hoje, o uso de sistemas e estratégias para coleta, armazenagem e análise de dados está cada vez mais presente no dia a dia das grandes organizações, trazendo inúmeros benefícios para as diversas linhas de negócio, e principalmente, auxiliando em rápidas tomadas de decisão, de forma que as empresas que não fazem proveito de seus dados estarão sempre um passo atrás dos seus competidores.

Uma análise mais avançada dos dados permite identificar oportunidades de melhoria em uma companhia, tais como:

- O armazenamento de dados do histórico de compras permite uma comunicação mais efetiva com o cliente, proporcionando um melhor serviço ao consumidor


- O uso de dados obtidos em redes sociais, e-commerce ou pesquisas auxiliam na percepção de como determinado produto está sendo utilizado e recebido pelo mercado consumidor, servindo como feedback para futuros lançamentos


- A eficiência operacional de uma empresa pode ser totalmente transformada. A análise de dados pode ajudar na melhoria dos processos de manufatura, distribuição, gestão de estoque, alocação de pessoas e em diversas outras áreas


A Ciência de Dados é uma área multidisciplinar, que envolve conhecimentos de Matemática, Estatística, Ciência da Computação e Área de Negócio para extrair valor dos dados. O diagrama abaixo mostra como a intersecção de campos diferentes do conhecimento formam o que chamamos de Ciência de dados.

![img](https://www.datocms-assets.com/14946/1596797558-da-vs-ds-diagram.png)
"""
"""
Vamos começar pelo círculo da matemática, com probabilidade!
"""
"""
# Probabilidade
"""
"""
### Por Que Começar com Probabilidade?

A probabilidade está em todo lugar!

Probabilidade é a ciência da incerteza. Portanto, sempre que houver alguma dúvida sobre um evento, os conceitos de probabilidade são envolvidos para estimar a probabilidade de um evento. Se queremos prever um resultado de uma variável que pode assumir um dos muitos valores disponíveis, precisamos envolver a matemática da probabilidade. 

Portanto, podemos usar a teoria da probabilidade em diversas situações, seja em nossas vidas pessoais ou profissionais. A incerteza sempre estará lá, mas ela pode ser medida, pode ser gerenciada..

Identificação de transações fraudulentas, classificação de câncer em benigno e maligno, separação de emails de forma automática em grupos específicos... são exemplos de problemas que envolvem probabilidade aplicados no dia-a-dia de Ciência de Dados.
"""
"""
### O Que é Espaço de Probabilidade?
Um espaço de probabilidade é usado para modelar experimentos. Existem três componentes em um espaço de probabilidade: espaço de amostra, eventos e medida de probabilidade.

#### 1. Espaço de Amostra

É um conjunto de todos os resultados possíveis, ou seja, uma coleção única de elementos envolvendo todos as possibilidades de resultados. Por exemplo, o espaço de amostra ao jogar um dado é: $S = \{1, 2, 3, 4, 5, 6\}$, pois o dado com 6 faces oferece 6 resultados possíveis sempre que o dado é jogado.

O espaço de amostra de um movimento do preço das ações pode ser $S = \{Aumenta, Igual, Diminui\}$. Como Aumenta é um elemento de S, podemos escrever como Aumenta ∈ S (Aumenta pertence a S).

#### 2. Eventos

Um evento é um conjunto de resultados (um subconjunto do espaço amostral) ao qual é associado um valor de probabilidade. Assim, podemos dizer que, para um espaço amostral com um número finito de elementos, qualquer subconjunto seu é um evento. Confuso? Vejamos um exemplo:

Um baralho de 52 cartas tem um espaço amostral de 52 elementos, um associado a cada uma das 52 cartas. Um evento é qualquer subconjunto do espaço amostral, incluindo qualquer elemento sozinho, o conjunto vazio (definido como tendo probabilidade 0) e o conjunto inteiro de 52 cartas (com probabilidade 1). Outros eventos são subconjuntos contêm múltiplos elementos. Algumas possibilidades:

 - “O 5 de Copas” (1 elemento),
 - “Um Rei” (4 elementos),
 - “Uma carta de Espadas” (13 elementos),
 - “Uma carta” (52 elementos).

#### 3. Medida de Probabilidade

Sendo assim, podemos definir a probabilidade de um evento x como:

$P(x) = \frac{n(E)}{n(S)}$
"""
"""
# Probabilidade  na prática: Lançamento de moeda

A fim de apresentar algumas regras de probabilidade, vejamos um exemplo aplicado a lançamento de moedas.

![img](https://docplayer.com.br/docs-images/69/60074537/images/1-1.jpg)

Considere uma moeda justa padrão com dois lados: Cara (K) e coroa (C). Se eu jogar a moeda no ar, talvez veja cara ou coroa quando ela cair na minha mão. Para esse tipo de moeda, a probabilidade de obter cara, P(K), é 0,5 e a probabilidade de obter coroa, P(C), também é 0,5. Dessa forma, podemos dizer que a soma das probabilidades individuais é igual a 1, ou seja, $P(K) + P(C) = 1$. O mesmo princípio se aplica no caso de um dado justo de 6 lados, por exemplo; a probabilidade de que o dado caia em um dos lados é a mesma, $\frac{1}{6}$, e, dessa forma, a soma das probabilidades é 1 ($P(1)+P(2)+P(3)+P(4)+P(5)+P(6)=1$). Isso mostra o porquê da **probabilidade de um evento** ser sempre um valor **entre 0 e 1**.

Retomando nosso jogo de moedas, podemos ver que cara e coroa são os dois resultados possíveis, o que permite definir 2 regras da probabilidade:

**1. Princípio da Multiplicação:** Se jogarmos uma moeda duas vezes, a probabilidade de ver cara nas duas vezes, ou seja, Cara **E** Cara, é $P(K).P(K) = \frac{1}{2}\frac{1}{2} = \frac{1}{4}$;

**2. Princípio da Adição:** Se jogarmos uma moeda duas vezes, a probabilidade de ver Cara **OU** Coroa é 1 pois, $P(K) + P(C) = (0,5 + 0,5) = 1$. 

Esses dois eventos são independentes um do outro, porque jogar uma moeda uma vez não afeta o resultado de nosso próximo teste.

### Exercício 1: Moeda Justa

Vamos supor que queremos saber a probabilidade de tirar 2 coroas **OU** 2 caras em 3 lançamentos de moeda, isto é, queremos que **2 lançamentos sejam Cara e 1 Coroa ou que 2 sejam Coroa e 1 seja Cara**. Temos:

| 1º | 2º | 3º |
|----|----|----|
| K  | K  | K  |
| K  | C  | K  |
| K  | K  | C  |
| C  | K  | K  |
| C  | K  | C  |
| C  | C  | K  |
| K  | C  | C  |
| C  | C  | C  |

"""
"""
Com exceção das primeira e última linhas, todas as outras se adequam ao que queremos. Assim, temos 6 possibilidades em 8 possíveis: 

$Prob = \frac{n(E)}{n(S)} = \frac{6}{8}$.

De outra forma, podemos calcular a probabilidade utilizando algumas regrinhas de Análise Combinatória (uma outra especificidade de probabilidades). Resumidamente, funciona assim para o problema acima: $P(1º).P(2º).P(3º).\frac{n!}{K!C!}$. Temos a multiplicação das probabilidades individuais de cada lançamento, multiplicado pela quantidade de lançamentos (n) fatorial, dividido pela quantidade de caras (K) e coroas (C) fatorial. Um pouco confuso, né? Mas é bem simples, observe o desenvolvimetno abaixo:

$P(K).P(K).P(C).\frac{3!}{2!1!} + P(K).P(C).P(C).\frac{3!}{2!1!} = \frac{1}{2}.\frac{1}{2}.\frac{1}{2}.3 + \frac{1}{2}.\frac{1}{2}.\frac{1}{2}.3 = \frac{1}{8}.3 + \frac{1}{8}.3 = \frac{6}{8}$

Se caso o problema fosse com 4 lançamentos ao invés de 3, e quiséssemos obter 3 Caras ou 2 Coroas, teríamos o seguinte:

$P(K).P(K).P(K).P(C).\frac{4!}{3!1!} + P(K).P(K).P(C).P(C).\frac{4!}{2!2!} = \frac{1}{2}.\frac{1}{2}.\frac{1}{2}.\frac{1}{2}.4 + \frac{1}{2}.\frac{1}{2}.\frac{1}{2}.\frac{1}{2}.6 = \frac{1}{16}.4 + \frac{1}{16}.6 = \frac{5}{8}$

As células a seguir mostram um pequeno script que calcula de forma automática a proabilidade para este tipo de problema a partir de alguns parâmetros de entrada. Altere os parâmteros e veja como o resultado se comporta.

"""
## Calcula a probabilidade de cair K caras ou C coroas em n lançamentos de moeda
#OBS1: Para este problema, a quantidade de coroas e coroas devem ser menor ou igual do que o total de lançamentos
calcula_probabilidade(moeda='justa',qtd_lancamentos=3,qtd_cara=2,qtd_coroa=2)
"""
### Exercício 1: Moeda "Viciada"

Vimos como funciona a probabilidade para uma moeda justa, tanto pela forma exaustiva (passando por todas as possibilidades) quanto pela forma matemática; contudo, testar todas as possibilidades é impraticável para a maioria dos problemas, devido à enorme quantidade de opções (caso aumentassemos os lançamentos para 5, por exemplo, já teríamos 120 opções diferentes). Vale dizer também que, para moedas viciadas, o primeiro método não funcionaria, visto que as probabilidades individuais seriam diferentes.

Vejamos um exemplo:

    Uma moeda foi preparada para que Cara tenha probabilidade de 25% (P(K) = 0,25) e, consequentemente, Coroa de 75% (P(C) = 0,75). Para o mesmo problema anterior, onde, em 3 lançamentos, queremos determinar a probabilidade de cair 2 caras ou 2 coroas, teremos o seguinte resultado:
"""
calcula_probabilidade(moeda='viciada',qtd_lancamentos=3,qtd_cara=2,qtd_coroa=2,p_cara=0.25)
"""
Perceba que as probabilidades nos dois casos (justo e viciado) são diferentes, como era esperado. Abaixo mais alguns exemplos comparando os dois tipos de moeda.
"""
calcula_probabilidade(moeda='justa',qtd_lancamentos=4,qtd_cara=3,qtd_coroa=2)
calcula_probabilidade(moeda='viciada',qtd_lancamentos=4,qtd_cara=3,qtd_coroa=2,p_cara=0.15)
print()
calcula_probabilidade(moeda='justa',qtd_lancamentos=5,qtd_cara=2,qtd_coroa=3)
calcula_probabilidade(moeda='viciada',qtd_lancamentos=5,qtd_cara=2,qtd_coroa=3,p_cara=0.15)
"""
Experimente alterar a probabilidade de Cara (p_cara) de uma moeda viciada para 0,5 e veja o que acontece.
"""
calcula_probabilidade(moeda='justa',qtd_lancamentos=4,qtd_cara=3,qtd_coroa=2)
calcula_probabilidade(moeda='viciada',qtd_lancamentos=4,qtd_cara=3,qtd_coroa=2,p_cara=0.35)
"""
### Exercício 2: Moeda Justa

Agora, vamos supor um caso hipotético no qual você lança 20 moedas, obtendo 8 Caras e 12 Coroas. Isso significa que a moeda utilizada é viciada? 

Observe o teste abaixo:
"""
contagem = gera_lancamentos(moeda='justa',qtd_lancamentos=20)
mostra_probabilidades(contagem)
"""
Note que a as probabilidades são diferentes daquelas mostradas inicialmente de 50% e que, a cada execução da célula o número se altera. Mude a quantidade de lançamentos e observe o resultado.

Mas por que isso acontece?

Vamos rodar novamente o código, porém agora aumentando (muito) a quantidade de lançamentos:
"""
contagem = gera_lancamentos(moeda='justa',qtd_lancamentos=2000)
mostra_probabilidades(contagem)
"""
Faz mais sentido agora, né? À medida que aumentamos a quantidade de lançamentos, mais próximo da probabilidade individual ideal chegamos, isto é, se laçarmos infinitas moedas, 50% delas serão Caras e 50% Coroas. 

### Exercício 2: Moeda "Viciada"

E para uma moeda viciada, na qual a probabilidade de Cara é 25%, o que será que acontece?
"""
contagem = gera_lancamentos(moeda='viciada',qtd_lancamentos=20000,p_cara=0.25)
mostra_probabilidades(contagem)
"""
Assim como visto para uma moeda justa, a probabilidade esperada foi alcançada.
"""
"""
### Convergência da probabilidade esperada
"""
"""
Beleza, agora que já vimos que o aumento da quantidade de lançamentos leva à probabilidade esperada, fica o questionamento: quantas vezes eu preciso lançar a moeda para se aproximar desse valor? Será que 100 já é o suficientes? 10 mil, talvez? Abaixo, temos um exemplo com mil lançamentos para uma moeda justa. 
"""
"""
![image.png](attachment:a19dcc4c-02d0-4473-bde2-7d88e3c0ea91.png)
"""
"""
**O poder agora é seu!** Clique em "Copiar e editar" (na porção superior direita da tela) e, em seguida, em *Run All*. Deslize até o final do notebook para conseguir interagir com os sliders abaixo (é bem legal).
"""
# Deslize as opções abaixo e clique em "Run interact para ver como o gráfico se comporta"
_ = interact_manual(grafico_lancamentos, 
                    qtd_lancamentos =     widgets.IntSlider(min = 10, max = 20000, step = 50, value = 1000),
                    p_cara =     widgets.IntSlider(min = 0, max = 100, step = 5, value = 50))
"""
Bom, depois de uma pequena quantidade já é possível notar que os valores parecem ficar mais estáveis, oscilando em torno da probabilidade esperada, né? 
"""
"""
# Questionário

Agora que você já é craque em probabilidades, bora responder algumas questões sobre o tema.

Clique [aqui](https://forms.office.com/r/Jt9LdCjVHM) para responder as questões que preparamos para treinar o que você aprendeu. Ao final, temos um [formulário de feedback](https://forms.office.com/r/8JVU2N576u) que gostaríamos que respondesse também.
"""
"""
### Muito obrigado por participar! :)

A seguir, algumas opções de cursos gratuitos para você começar a estudar:

PS: alguns deles são em inglês, mas todos tem legendas para portugês

**Python:**

[Udemy - Introdução a python](https://www.udemy.com/course/intro_python/)

[Udacity - Introdução à programação em python](https://www.udacity.com/course/introduction-to-python--ud1110) 

[Coursera - Iniciando com python](https://www.coursera.org/learn/ciencia-computacao-python-conceitos)

[Python.org - relação de cursos para diversos níveis em python](https://python.org.br/introducao/)

**Matemática:**

[Relação de áreas e cursos sobre matemática para Ciência de Dados](https://www.agatetepe.com.br/matematica-para-ciencia-de-dados/)

**Ciência de dados:**

[Udacity - Introdução à Ciência de Dados](https://www.udacity.com/course/intro-to-data-science--ud359)

[Coursera - Python para análise de dados](https://www.coursera.org/learn/python-data-analysis)
"""