Você está na página 1de 223

Pense Bayes

Estatísticas bayesianas simples

Versão 1.0.9
Pense Bayes
Estatísticas bayesianas simples

Versão 1.0.9

Allen B. Downey

Green Tea Press


Needham
Copyright © 2012 Allen B. Downey.

Imprensa de
Chá Verde 9
Washburn Ave
Needham MA 02492
A permissão é concedida para copiar, distribuir e/ou modificar este
documento os termos da Atribuição Creative Commons-NonCommercial
3.0 Licença não portada, que pode ser aplicadaem licenças
http://creativecommons.org//por nc/3.0/. http://creativecommons.org/
Prefácio

1.1 Minha teoria, que é minha.


A premissa deste livro, e dos outros livros da série Think X, é que se você
souber programar, você pode usar essa habilidade para aprender outros
tópicos.

A maioria dos livros sobre estatísticas bayesianas usam notação


matemática e apresentam ideias em termos de conceitos matemáticos
como cálculo. Este livro usa código Python em vez de matemática, e
aproximações discretas em vez de matemática contínua. Como resultado,
o que seria uma parte integrante de um livro de matemática se torna uma
soma, e a maioria das operações em distribuições de probabilidade são
loops simples.

Eu acho que esta apresentação é mais fácil de entender, pelo menos para
pessoas com habilidades em programação. Também é mais geral, pois
quando tomamos decisões de modelagem, podemos escolher o modelo
mais adequado sem nos preocuparmos muito se o modelo se presta à
análise convencional.

Além disso, fornece um caminho de desenvolvimento suave, desde


exemplos simples até problemas do mundo real. O capítulo 3 é um bom
exemplo. Começa com um simples exemplo envolvendo dados, um dos
grampos da probabilidade básica. A partir daí, segue em pequenos passos
para o problema da locomotiva, que peguei emprestado dos Cinquenta
Problemas Desafiadores em Probabilidade com Soluções da Mosteller, e de lá
para o problema do tanque alemão, uma famosa aplicação bem sucedida
dos métodos bayesianos durante a Segunda Guerra Mundial.

1.2 Modelagem e aproximação


A maioria dos capítulos deste livro são motivados por um problema do
mundo real, então eles envolvem algum grau de modelagem. Antes de
aplicar os métodos bayesianos (ou qualquer outra análise), temos que
tomar decisões sobre quais partes do
vi Chapter 0. Preface

sistema do mundo real para incluir no modelo e quais detalhes podemos


abstrair. away.
Por exemplo, no Capítulo 7, o problema motivador é prever o vencedor
de um jogo de hóquei. Eu modelo gol-pontuação como um processo
poisson, o que implica que um gol é igualmente provável em qualquer
momento do jogo. Isso não é exatamente verdade, mas é provavelmente
um modelo bom o suficiente para a maioria dos propósitos.
No Capítulo 12, o problema motivador é interpretar os escores do SAT (o
SAT é um teste padronizado usado para admissões universitárias nos
Estados Unidos). Eu começo com um modelo simples que assume que
todas as perguntas SAT são igualmente difíceis, mas na verdade os
designers do SAT deliberadamente incluem algumas perguntas que são
relativamente fáceis e algumas que são relativamente difícil. Afinal,
apresento um segundo modelo que explica esse aspecto do design, e
mostro que ele não tem um grande efeito sobre os resultados, afinal.
Penso que é importante incluir a modelagem como parte explícita da
resolução de problemas porque nos lembra de pensar em erros de
modelagem (ou seja, erros devido a simplificações e pressupostos do
modelo).
Muitos dos métodos deste livro são baseados em distribuições discretas, o
que faz com que algumas pessoas se preocupem com erros numéricos.
Mas para os problemas do mundo real, erros numéricos são quase sempre
menores do que erros de modelagem.
Além disso, a abordagem discreta muitas vezes permite melhores decisões
de modelagem, e eu prefiro ter uma solução aproximada para um bom
modelo a uma solução exata para um modelo ruim.
Por outro lado, métodos contínuos às vezes produzem vantagens de
desempenho — por exemplo, substituindo uma computação linear ou
quadrática por uma solução de tempo constante.
Por isso, recomendo um processo geral com estas etapas:

1. Enquanto você está explorando um problema, comece com modelos


simples e implemente-os em código que seja claro, legível e
comprovadamente correto. Concentre sua atenção em boas decisões
de modelagem, não em otimização.
2. Uma vez que você tenha um modelo simples funcionando,
identifique as maiores fontes de erro. Você pode precisar aumentar o
número de valores em uma aproximação discreta, ou aumentar o
número de iterações em uma simulação de Monte Carlo, ou adicionar
detalhes ao modelo.
3. Se o desempenho da sua solução for bom o suficiente para a sua
aplicação, você pode não ter que fazer qualquer otimização. Mas se
você fizer isso, são duas abordagens a considerar. Você pode rever
seu código e olhar
0.3. Working with the code vii

para otimizações; por exemplo, se você armazenar resultados


previamente computados, você pode ser capaz de evitar a
computação redundante. Ou você pode procurar métodos analíticos
que produzam atalhos computacionais.

Um benefício desse processo é que as Etapas 1 e 2 tendem a ser rápidas,


para que você possa explorar vários modelos alternativos antes de investir
pesado em qualquer um deles.
Outro benefício é que se você chegar ao Passo 3, você estará começando
com uma implementação de referencia que provavelmente será correta,
que você pode usar para testes de regressão (ou seja, verificar se o código
otimizado produz os mesmos resultados, pelo menos aproximadamente).

1.3 Trabalhando com o código


As amostras de código e som utilizadas neste livro estão disponíveis em
https://github.com/AllenDowney/ThinkBayes. Git é um system de controle
de versão que permite que você acompanhe os arquivos que compõem um
projeto. Uma coleção de arquivos sob o controle de Git é chamada de
"repositório". GitHub é um serviço de hospedagem que fornece
armazenamento para repositórios git e uma interface web conveniente.
A homepage h do GitHub para o meu repositório fornece várias maneiras
de trabalhar com o código:

• Você pode criar uma cópia do meu repositório no GitHub


pressionando o botão Fork. Se você ainda não tiver uma conta no
GitHub, você precisará criar uma. Depois de bifurcar, você terá seu
próprio repositório no GitHub que você pode usar para manter o
controle do código que você escreve enquanto trabalha neste livro.
Em seguida, você pode clonar o repo, o que significa que você copiar
os arquivos para o seu computador.

• Ou pode clonar meu repositório. Você não precisa de uma conta do


GitHub para fazer isso, mas não poderá escrever suas alterações de
volta ao GitHub.

• Se você não quiser usar o Git, você pode baixar os arquivos em um


arquivo Zip usando o botão no canto inferior direito da página do GitHub.

O código da primeira edição do livro funciona com Python 2. Se você


estiver usando o Python 3, você pode querer usar o código atualizado em
https://github.com/AllenDowney/ThinkBayes2 em vez disso.

Eu desenvolvi este livro usando Anaconda da Continuum Analytics, que é


uma distribuição python gratuita que inclui todos os pacotes que você vai
precisar
Vii Capítulo 0.
i Prefácio
executar o código (e muito mais). Achei a Anaconda fácil de instalar. Por
padrão, ele faz uma instalação em nível de usuário, não no nível do
sistema, para que você não precise de privilégios administrativos. Você
pode baixar Anaconda de http://continuum.io/downloads.
Se você não quiser usar o Anaconda, você precisará dos seguintes pacotes:
• NumPy para computação numérica básica, http://www.numpy.org/;;
• SciPy para computação científica, http://www.scipy.org/;;
• matplotlib para visualização, http://matplotlib.org/.
Embora estes sejam pacotes comumente usados, eles não são incluindo
todas as instalações Python, e podem ser difíceis de instalar em alguns
ambientes. Se você tiver problemas para instalá-los, recomendo o uso da
Anaconda ou de uma das outras distribuições Python que incluem esses
pacotes.
Muitos dos exemplos deste livro utilizam classes e funções definidas em
thinkbayes.py. Alguns deles também usam thinkplot.py, que fornece
invólucros para algumas das funções em pyplot, que é parte de matplotlib.

1.4 Estilo de código


Programadores Python experientes notarão que o código deste livro não
está em conformidade com pep 8, que é o guia de estilo mais comum para
Python (http://www.python. org/dev/peps/pep-0008/).
Especificamente, pep 8 chamas nomes de funções minúsculas com
sublinhados ser- palavras de interpolar, like_this. Neste livro e os nomes
do código, função e método que acompanham começam com uma letra
maiúscula e usam o estojo de camelo, LikeThis.
I Quebrei essa regra porque desenvolvi parte do código enquanto era
cientista visitante no Google, então segui o guia de estilo do Google, que
se desvia do PEP 8 em alguns lugares. Uma vez que me acostumei com o
estilo do Google, descobri que gostei. E neste ponto, seria muito trabalho
para mudar.
Também sobre o tema do estilo, escrevo "Teorema de Bayes" com um s
após o apostrophe, que é preferido em alguns guias de estilo e preterido
em outros. Não tenho uma preferência forte. Eu tive que escolher um, e
este é o que eu escolhi.
E, finalmente, uma nota tipográfica: ao longo do livro, uso PMF e CDF
para o conceito matemático de uma função de massa de probabilidade ou
função de distribuição cumulative, e PMF e Cdf para se referir aos objetos
Python que uso para representá-los.
0.5. Prerequisites ix

1.5 Pré-requisitos
Existem vários módulos excelentes para fazer estatísticas bayesianas em
Python, incluindo pymc e OpenBUGS. Eu escolhi não os usar para este
livro isto porque você precisa de uma boa quantidade de conhecimento de
fundo para começar com esses módulos, e eu quero manter os pré-
requisitos mínimos. Se você conhece Python e um pouco sobre
probabilidade, você está pronto para começar este livro.

O capítulo 1 é sobre probabilidade e teorema de Bayes; não tem código.


Chapter 2 introduz PMF, um dicionário Python pouco disfarçado que eu
uso para representar uma função de massa de probabilidade (PMF). Em
seguida, o Capítulo 3 introduz o Suite, uma espécie de PMF que fornece
uma estrutura para fazer atualizações bayesianas.

Em alguns dos capítulos posteriores, uso distribuições analíticas,


incluindo a distribuição Gaussian (norma l), as distribuições exponenciais
e poisson, e a distribuição beta. No capítulo 15 eu quebro a distribuição
menos comum de Dirichlet, mas eu explico à medida que vou avançando.
Se você não está familiarizado com essas distributions, você pode ler sobre
eles na Wikipedia. Você também pode ler o companheiro para este livro,
Think Stats, ou um livro de estatísticas introdutória (embora eu receio que
a maioria deles adote uma abordagem matemática que não é
particularmente útil para fins práticos).

Lista de contribuintes
Se você tiver uma sugestão ou correção, envie um e-mail para
downey@allendowney.com. Se eu fizer uma mudança com base no seu
feedback, eu vou adicioná-lo à lista de contribuintes (a menos que você
peça para ser omitido).

Se você incluir pelo menos parte da frase em que o erro aparece, isso torna
mais fácil para mim pesquisar. Números de páginas e seções também são
bons, mas não tão fáceis de trabalhar. Thanks!

• Primeiro, tenho que reconhecer o excelente livro de David MacKay,


Information The-ory, Inference, and Learning Algorithms, que foi onde eu vim
pela primeira vez para os métodos bayesianos. Com sua permissão, uso
vários problemas de seu livro como exemplos.

• Este livro também se beneficiou das minhas interações com Sanjoy


Mahajan, especially no outono de 2012, quando eu auditei sua aula sobre
Inferência Bayesiana no Olin College.

• Escrevi partes deste livro durante as noites de projeto com o Boston Python
User Group, então gostaria de agradecê-los por sua empresa e pizza.
x Capítulo 0.
Prefácio
• Olivier Yiptong enviou várias sugestões úteis.

• Yuriy Pasichnyk encontrou vários erros.

• Kristopher Overholt enviou uma longa lista de correções e sugestões.

• Max Hailperin suggested um esclarecimento no Capítulo 1.

• Markus Dobler apontou que tirar biscoitos de uma tigela com substituição
é um cenário irrealista.

• Na primavera de 2013, os alunos da minha classe, Computational Bayesian


Statistics, fizeram correções e sugestões úteis: Kai Austin, Claire Barnes,
Kari Bender, Rachel Boy, Kat Mendoza, Arjun Iyer, Ben Kroop, Nathan
Lintz, Kyle McConnaughay, Alec Radford, Brendan Ritter e Evan Simpson.

• Greg Marra e Matt Aasted me ajudaram a esclarecer a discussão do


problema "O Preço é Certo".

• Marcus Ogren apontou que a declaração original da locomotiva prob-lem


era ambígua.

• Jasmine Kwityn e Dan Fauxsmith da O'Reilly Media revisaram o livro e


encontraram muitas oportunidades de melhoria.

• Linda Pescatore encontrou um erro de digitação e fez algumas sugestões úteis.

• Tomasz Mia sko enviou muitas correções e sugestões excelentes.

Outras pessoas que detectaram erros de digitação e pequenos erros incluem Tom
Pollard, Paul A. Giannaros, Jonathan Edwards, George Purkins, Robert Marcus,
Ram Limbu, James Lawry, Ben Kahle, Jeffrey Law e Alvaro Sanchez.
Conteúdo

Prefác V
io
0.1 A minha teoria, que é a minha. . . . . . . . . . . . . . . . . . . . . . . . . . V
.................................................
0.2 Modelagem e aproximação. . . . . . . . . . . . . . . . . . . . . . . . . . . . . V
..............................................
0.3 Trabalhando com o V
código. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
........................
0.4 Estilo de V
código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
.......................................... i
0.5 Pré- I
requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x
...............................................

1 Teorema de Bayes 1
1.1 Probabilidade condicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
...................................................
1.2 Probabilidade conjunta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
......................................................
1.3 O problema dos biscoitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
..................................................
1.4 Teorema de Bayes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
............................................................
1.5 A interpretação 5
diacrônica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...............
1.6 O problema do M&M. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
.......................................................
1.7 O problema de Monty 8
Hall. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
....
1.8 Discussão 1
............................................................... 0
................................

2 Estatísticas Computacionais 1
1
2.1 Distribuições 1
............................................................... 1
...............................
2.2 O problema dos biscoitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
.................................................. 2
xii Conteúd
o
2.3 A estrutura bayesiana ......................................................................13

2.4 O problema de Monty Hall............................................................15

2.5 Encapsulando a estrutura...............................................................16

2.6 O problema de M&M ......................................................................17

2.7 Discussão............................................................................................18

2.8 Exercícios............................................................................................19

3 Estimativa 21

3.1 O problema dos dados ....................................................................21

3.2 O problema da locomotiva .............................................................22

3.3 E aquele anterior? ............................................................................25

3.4 Uma alternativa anterior.................................................................25

3.5 Intervalos críveis...............................................................................27

3.6 Funções de distribuição cumulativa..............................................28

3.7 O problema do tanque alemão......................................................29

3.8 Discussão............................................................................................30

3.9 Exercícios............................................................................................30

4 Mais Estimativa 33

4.1 O problema do Euro ........................................................................33

4.2 Resumindo o ...................................................................35 posterior

4.3 Inundando os antecedentes............................................................36

4.4 Otimização.........................................................................................37

4.5 A distribuição beta ...........................................................................38

4.6 Discussão............................................................................................40

4.7 Exercícios............................................................................................41
Conteúd xiii
o
5 Probabilidades e Adição 43
5.1 Probabilidades...................................................................................43
5.2 A forma de probabilidades do teorema de Bayes .......................44
5.3 Sangue de Oliver...............................................................................45
5.4 Complementos...................................................................................46
5.5 Maxima...............................................................................................49
5.6 Misturas..............................................................................................51
5.7 Discussão............................................................................................54

6 Análise de Decisão 55
6.1 O problema preço é certo ..................................................................55
6.2 Os.....................................................................................56 anteriores
6.3 A densidade de probabilidades funciona.....................................57
6.4 Representando PDFs........................................................................57
6.5 Modelando os concorrentes............................................................60
6.6 Probabilidade.....................................................................................62
6.7 Atualização........................................................................................63
6.8 Lance ideal.........................................................................................64
6.9 Discussão............................................................................................67

7 Previsão 69
7.1 O problema de Boston Bruins.......................................................69
7.2 Processos de Poisson........................................................................71
7.3 Os posteriores....................................................................................71
7.4 A distribuição das metas.................................................................72
7.5 A probabilidade de ganhar.............................................................74
7.6 Morte súbita.......................................................................................75
7.7 Discussão............................................................................................76
7.8 Exercícios............................................................................................78
xiv Conteúd
8 Viés observador o 81
8.1 O problema da Linha Vermelha...................................................81
8.2 O modelo............................................................................................82
8.3 Tempos de espera..............................................................................84
8.4 Prever tempos de espera................................................................86
8.5 Estimando a taxa de chegada .........................................................89
8.6 Incorporando incerteza....................................................................91
8.7 Análise de decisão.............................................................................92
8.8 Discussão............................................................................................95
8.9 Exercícios............................................................................................95

9 Duas Dimensões 97
9.1 Paintball..............................................................................................97
9.2 A suíte.................................................................................................98
9.3 Trigonometria....................................................................................99
9.4 Probabilidade...................................................................................101
9.5 Distribuições conjuntas..................................................................102
9.6 Distribuições condicionais.............................................................103
9.7 Intervalos críveis.............................................................................104
9.8 Discussão..........................................................................................106
9.9 Exercícios..........................................................................................107

10 Computação bayesiana aproximada 109


10.1 A Hipótese de Variabilidade .......................................................109
10.2 Desvio médio e padrão.................................................................110
10.3 Atualização......................................................................................112
10.4 A distribuição posterior do CV....................................................113
Conteúd xv
o 10.5 Subfluxo............................................................................................114

10.6 Probabilidade de.......................................................................log 115

10.7 Um pouco de otimização..............................................................116

10.8 ABC...................................................................................................118

10.9 Estimativa robusta..........................................................................119

10.10 Quem é mais variável? .................................................................122

10.11 Discussão..........................................................................................123

10.12 Exercícios..........................................................................................124

11 Teste de hipóteses 125

11.1 De volta ao problema do ................. .


Euro. .. 12
5
11.2 Fazer uma comparação ................. .
justa .. 12
6
11.3 O triângulo anterior. ................. .
..... .. 12
8
11.4 ................. .
.. 12
Discussão . . . . . . . . . . . . . . . . . . . 9
..................
11.5 Exercícios . . . . . . . . . . . . . . ................. .
.......................... .. 12
9

1 Provas 131
2
12.1 Interpretando pontuações do SAT . . . . . . . . . . . . . . . . . . . . . . .
.................................................... ..... 13
1
12.2 A escala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.................................................... 13
2
xvi Conteúd
o
12.3 O anterior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
...................................................... 13
2
12.4 Posterior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
................................................... 13
4
12.5 Um modelo melhor. .
............................................................. 13
.............................. 6
12.6 Calibração .
............................................................. 13
................................... 8
12.7 Distribuição posterior da eficácia . . . . . . . . . . . . . . . . . . . . . . . .
........................................... 13
9
12.8 Distribuição preditiva .
............................................................. 14
................. 1
12.9 Discussão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.................. 14
2
Conteúd xvii
o
13 Simulação 145
13.1 O problema do tumor renal...........................................................145
13.2 Um modelo simples ......................................................................146
13.3 Um modelo mais geral...................................................................148
13.4 Implementação................................................................................150
13.5 Caching a distribuição conjunta ...................................................151
13.6 Distribuições condicionais...............................................................152
13.7 Correlação Serial..............................................................................154
13.8 Discussão..........................................................................................157

14 Um Modelo Hierárquico 159


14.1 O problema geiger contador .........................................................159
14.2 Comece simples...............................................................................160
14.3 Torná-lo hierárquico......................................................................161
14.4 Um pouco de otimização..............................................................163
14.5 Extraindo os posteriores................................................................163
14.6 Discussão..........................................................................................164
14.7 Exercícios..........................................................................................165

15 Lidando com Dimensões 167


15.1 Bactéria do umbigo .......................................................................167
15.2 Leões, tigres e ursos.......................................................................168
15.3 A versão hierárquica ......................................................................170
15.4 Amostragem aleatória....................................................................172
15.5 Otimização.......................................................................................174
15.6 Desmoronando a hierarquia.........................................................175
15.7 Mais um problema.........................................................................177
15.8 Ainda não terminamos ...............................................................179.
15.9 Os dados do umbigo ......................................................................181
15.10 Distribuições preditivas...................................................................184
15.11 Posterior articular............................................................................187
15.12 Cobertura..........................................................................................188
15.13 Discussão..........................................................................................190
xviii Contents
Teorema do Capítulo 1

Bayes

1.1 Probabilidade condicional


A ideia fundamental por trás de todas as estatísticas bayesianas é o
teorema de Bayes, que é surpreendentemente fácil de derivar, desde que
você entenda a probabilidade condicional. Então começaremos com
probabilidade condicional, então o teorema de Bayes, e sobre as estatísticas
bayesianas.
Uma probabilidade é um número entre 0 e 1 (incluindo ambos) que
representa um grau de crença em um fato ou previsão. O valor 1
representa a certeza de que um fato é verdadeiro, ou que uma previsão se
tornará realidade. O valor 0 representa a certeza de que o fato é falso.
Valores intermediários representam graus de certeza. O valor 0,5, muitas
vezes escrito dez como 50%, significa que um resultado previsto é tão
provável de acontecer como não. Por exemplo, a probabilidade de que
uma moeda aterrissa de frente é muito próxima de 50%.
Uma probabilidade condicional é uma probabilidade baseada em algum
fundo de formação. Por exemplo, eu quero saber a probabilidade de que
eu vou ter um ataque cardíaco no próximo ano. De acordo com o CDC,
"Todos os anos cerca de 785.000 americanos têm um primeiro ataque
coronário. (http://www.cdc.gov/heartdisease/facts.htm)"
Os EUA. população é de cerca de 311 milhões, então a probabilidade de
que um americano escolhido aleatoriamente terá um ataque cardíaco no
próximo ano é de aproximadamente 0,3%.
Mas eu não sou um americano escolhido aleatoriamente. Epidemiologistas
identificaram muitos fatores que afetam o risco de ataques cardíacos;
dependendo desses fatores, meu risco pode ser maior ou menor do que a
média.
2 Capítulo 1. Teorema de
Bayes
Sou homem, 45 anos, e tenho colesterol alto. Esses fatores aumentam
minhas chances. No entanto, tenho pressão baixa e não fumo, e esses
fatores diminuem minhas chances.

Conectando tudo na calculadora online em http://cvdrisk.nhlbi.


nih.gov/calculator.asp, acho que meu risco de ataque cardíaco no próximo
ano é de cerca de 0,2%, menos do que o average nacional. Esse valor é
uma probabilidade condicional, porque se baseia em uma série de fatores
que compõem minha "condição".

A notação usual para probabilidade condicional|é p(A|B), qual é a


probabilidade de A, dado que B seja verdadeiro. Este Exemplo A
Representa a previsão de que eu vou ter um ataque cardíaco no próximo
Ano E B é o conjunto de condições que eu Listados.

1.2 Probabilidade conjunta


Probabilidade conjunta é uma maneira extravagante de dizer a
probabilidade de que duas coisas sejam verdadeiras. Eu escrevo p(A e B)
isso significa que a probabilidade de que A e B sejam ambos verdadeiros.

Se você aprendeu sobre probabilidade no contexto de tosses de moedas e


dados, você pode ter aprendido a seguinte fórmula:

p(A e B) = p(AA) p(B) AVISO: nem sempre é verdade

Por exemplo, se eu jogar duas moedas, e A significa que a primeira moeda


cai de frente para cima, e B significa que a segunda moeda cai de frente
para cima, então p(A) = p(B) = 0,5, e com certeza, p(A e B) = p(A) p(B) =
0,25.

Mas essa fórmula só funciona porque neste caso A e B são independentes;


ou seja, saber o resultado do primeiro evento não muda a proba-bility do
segundo. Ou, mais formalmente, p(B| A) = p(BB).

Aqui está um exemplo diferente onde os eventos não são independentes.


Suponha que A signifique que chove hoje and B significa que chove
amanhã. Se eu sei que choveu hoje, é mais provável que chova amanhã,
então p(B | A) > p(B).

Em geral, a probabilidade de uma conjunção é

p(A e B)= p(A) p(B| A)


1.3. The cookie problem 3

para qualquer A e B. Então, se a chance de chuva em qualquer dia é de 0,5,


a chance de chuva em dois dias consecutivos não é 0,25, mas
provavelmente um pouco maior.

1.3 O problema dos biscoitos


Chegaremos ao teorema de Bayes em breve, mas quero motivá-lo com um
exemplo chamado problema dos biscoitos. 1 Suponha que haja duas
tigelas de biscoitos. A tigela 1 contém 30 biscoitos de baunilha e 10
biscoitos de chocolate. A tigela 2 contém 20 de cada.
Agora suponha que você escolha uma das tigelas aleatoriamente e, sem
olhar, selecione um cookie aleatoriamente. O biscoito é baunilha. Qual é a
probabilidade de que veio da Tigela 1?
Esta é uma probabilidade condicional; queremos p |(Tigela 1 baunilha),
mas não é óbvio como computá-lo. Se eu perguntasse uma pergunta
diferente — a probabilidade de um biscoito de baunilha dado Bowl 1 —
seria fácil:

p(baunilha| Tigela 1) = 3/4

| p(A B) É Não o mesmo que p(B A)Mas há uma maneira de ir


Infelizmente,
de um para o outro: o teorema de Bayes.

1.4 Teorema de Bayes


Neste momento temos tudo o que precisamos para derivar o teorema de
Bayes. Vamos começar com a observação de que a conjunção é comutativa;

p(A e B)= p(B e A)

para quaisquer eventos A e B.


Em seguida, escrevemos a probabilidade de uma conjunção:

p(A e B)= p(A) p(B| A)

Uma vez que não dissemos nada sobre o que A e B significam, eles são
intermutáveis. Intermutá-los rende

p(B and A) = p(B) p(A|B)


1
Com base em um exemplo de http://en.wikipedia.org/wiki/Bayes'_theorem que não
está mais lá.
4 Capítulo 1. Teorema de
Bayes
Isso é tudo que precisamos. Juntando essas peças, nós temos

p( B) p ( A | B ) = p ( A ) p ( B | A )

O que significa que há duas maneiras de calcular a conjunção. Se você


Tem p(A), você multiplica pela probabilidade condicional
| p(B A). Ou você
pode fazê-lo ao contrário; se você sabe p(B), você multiplica por|p(Um B).
De qualquer forma, você deve ter o mesmo Coisa.

Finalmente podemos dividir por p: (B):)(

p(A) p(B|A)
p(A|B) = p(B)

E esse é o teorema de Bayes! Pode não parecer muito, mas acaba por ser
surpreendentemente poderoso.

Por exemplo, podemos usá-lo para resolver o problema dos cookies.


Escreverei B1 para a hipótese de que o biscoito veio da Tigela 1 e V para o
biscoito de baunilha.
Pcarregando no teorema de Bayes que temos

p(B1) p(V|B1)
| V) =
p(B p(V)
1
O termo à esquerda é o que queremos: a probabilidade da Tigela 1, dado
que escolhemos um biscoito de baunilha. Os termos à direita são:

• p(B1): Esta é a probabilidade de que escolhemos a Tigela 1,


incondicionada pelo tipo de biscoito que temos. Uma vez que o
problema diz que escolhemos uma tigela aleatoriamente, podemos
assumir p(B1) = 1/2.

• p(V |B1): Esta é a probabilidade de obter um biscoito de baunilha da


Bowl 1, que é 3/4.

• p(V): Esta é a probabilidade de sacar um biscoito de baunilha de qualquer


tigela. Como tínhamos a mesma chance de escolher qualquer tigela e
as tigelas contêm o mesmo número de biscoitos, tivemos a mesma
chance de escolher qualquer cookie. Entre as duas tigelas há 50 vanilla
e 30 biscoitos de chocolate, então p(V) = 5/8.

Juntando tudo, nós temos

(1/2) (3/4)
p(B
1 V) =
5/8
|
1.5. The diachronic interpretation 5

que reduz para 3/5. Então o biscoito de baunilha é uma evidência a favor
da tese que escolhemos a Tigela 1, porque biscoitos de baunilha são mais
propensos a vir da Tigela 1.

Este exemplo demonstra um uso do teorema de Bayes: ele fornece um


| a partir de p(B A) Para p(Um B). Essa estratégia é
estrat-egy para obter
útil em casos como o problema dos cookies, onde é mais fácil calcular os
termos do lado direito teorema de Bayes do que o termo sobre o Deixou.

1.5 A interpretação diacrônica


Há outra maneira de pensar no teorema de Bayes: ele nos dá uma maneira
de atualizar a probabilidade de uma hipótese, H, à luz de algum corpo de
dados, D.

Essa forma de pensar sobre o teorema de Bayes é chamada de inter-


pretação diacrônica. "Diachronic" significa que algo está acontecendo ao
longo do tempo; neste caso, a probabilidade de as hipóteses mudar, ao
longo do tempo, à medida que vemos novos dados.

Reescrever o teorema de Bayes com rendimentos De H e D: yields:

p(H ) p (D | H )
p(H|D) = p(D)
Nesta interpretação, cada termo tem um nome:

• p(H ) é a probabilidade da hipótese antes de vermos os dados,


chamado de probabilidade prévia, ou apenas anterior.

• p(H |D) É Que Nós Quero Para Calcular O Probabilidade De O


hipótese depois de ver os dados, chamado de posterior.

• p(D |H) é a probabilidade dos dados a hipótese, chamada O


probabilidade.

• p(D) é a probabilidade dos dados qualquer hipótese, chamada de


normalizando constante.

Às vezes, podemos calcular o anterior com base em informações de fundo.


Por exemplo, o problema do cookie especifica que escolhemos uma tigela
aleatoriamente com igual probabilidade.
6 Capítulo 1. Teorema de
Bayes
Em outros casos, o anterior é subjetivo; ou seja, pessoas razoáveis podem
desconcordar, seja porque usam informações de fundo diferentes ou
porque interpretam as mesmas informações de forma diferente.

A probabilidade é geralmente a parte mais fácil de calcular. No problema


dos biscoitos, se soubermos de que tigela o biscoito veio, encontramos a
probabilidade de um biscoito de baunilha contando.

A constante normalizadora pode ser complicada. É suposto ser a


probabilidade de ver os dados qualquer hipótese,mas no caso mais geral é
difícil descobrir o que isso significa.

Na maioria das vezes, simplificamos as coisas especificando um conjunto de hipóteses que são

Mutuamente exclusivo: No máximo uma hipótese no conjunto pode ser verdade, e

Coletivamente exaustivo: Não há outras possibilidades; pelo menos uma


das hipóteses tem que ser verdadeira.

Eu uso a palavra suíte para um conjunto de hipóteses que tem essas propriedades.

No problema dos cookies, há apenas duas hipóteses — o cookie veio do


Bowl 1 ou bowl 2 — e eles são mutuamente exclusivos e coletivamente
exaustivos.

Nesse caso, podemos calcular p(D) usando a lei da probabilidade total,


que diz que se há duas maneiras exclusivas de que algo possa acontecer,
você pode somar as probabilidades como esta:

p ( D ) = p (B 1 ) p ( D | B 1 ) + p (B 2 ) p ( D | B 2 )

Conectando os valores do problema do cookie, temos p(D) =

(1/2) (3/4) +(1/2) (1/2) = 5/8 ) + (

que é o que calculamos anteriormente, combinando mentalmente as duas tigelas.

1.6 O problema de M&M


M&M's são pequenos chocolates revestidos de doces que vêm em uma
variedade de cores. Mars, Inc., que faz M&M's, muda a mistura de cores
de tempos em tempos.
1.6. The M&M problem 7

Em 1995, eles introduziram M&M's azuis. Antes disso, o mix de cores em


um saco de M&M's simples era 30% marrom, 20% amarelo, 20% vermelho,
10% verde, 10%
Laranja, 10% bronzeado. Depois foi 24% Azul, 20% Verde, 16% Laranja,
14% Amarelo, 13% Vermelho, 13% Marrom.

Suponha que um amigo meu tenha dois sacos de M&M's, e ele me diga
que um é de 1994 e outro de 1996. Ele não me diz qual é qual, mas ele me
dá um M&M de cada saco. Um é amarelo e o outro é verde. Qual é a
probabilidade de que o amarelo veio do saco de 1994?

Este problema é semelhante ao problema do cookie, com a torção que eu


desenho uma amostra de cada tigela/saco. Este problema também me dá a
chance de demonstrar o método de tabela, que é útil para resolver
problemas como este no papel. No próximo capítulo vamos resolvê-los
computacionalmente.

O primeiro passo é enumerar as hipóteses. O saco do M&M amarelo veio


de eu vou chamar saco 1; Vou ligar para o outro Saco 2. Então as hipóteses
são:

• A: O saco 1 é de 1994, o que implica que bag 2 é de 1996.

• B: Saco 1 é de 1996 e Saco 2 de 1994.

Agora construímos uma tabela com uma linha para cada hipótese e uma
coluna para cada termo no teorema de Bayes:

Pa Probabili Posterio
nte dade p(H) p(D| r p(H|
rio p(D| H) H) D)
r(
H))
U 1/ (20) (20) 200 20/27
m 2 (14) (10) 70 7/27
B 1/
2
A primeira coluna tem os antecedentes. Com base na afirmação do
problema, é razoável escolher p(A) = p(B) = 1/2.

A segunda coluna tem as probabilidades, que seguem a partir das


informações sobre o problema. Por exemplo, se A for verdade, o M&M
amarelo veio da bolsa de 1994 com probabilidade de 20%, e o verde veio
da bolsa de 1996 com probabilidade de 20%. Se B for verdade, o yelbaixo
M&M veio do saco de 1996 com probabilidade de 14%, e o verde veio do
saco de 1994 com probabilidade de 10%. Como as seleções são
independentes, temos a probabilidade conjunta multiplicando-se.

A terceira coluna é apenas o produto das duas anteriores. A soma desta


coluna, 270, é a constante normalizadora. Para obter a última coluna, que
8 Capítulo 1. Teorema de
Bayes
contém os posteriores, dividimos a terceira coluna pelo con-stant
normalizador. stant.
É isso, é isso. Simples, certo?
Bem você pode ser incomodado por um detalhe. Eu escrevo
| p(D H ) em
termos de porcentos, não probabilidades, o que significa que está fora por
um fator de 10.000. Mas isso se cancela quando nos dividimos pela
constante normalizadora, então não afeta o Resultado.
Quando o conjunto de hipóteses é mutuamente exclusivo econtativa, você
pode multiplicar as probabilidades por qualquer fator, se for conveniente,
desde que aplique o mesmo fator em toda a coluna.

1.7 O problema de Monty Hall


O problema de Monty Hall pode ser a pergunta mais controversa na sua-
tory de probabilidade. O cenário é simples, mas a resposta correta é tão
coun-terintuitive que muitas pessoas simplesmente não podem aceitá-lo, e
muitas pessoas inteligentes têm se envergonhado não apenas por errar,
mas argumentando o lado errado, agressivamente, em public.
Monty Hall foi o apresentador original do game show Let's Make a Deal.. O
problema de Monty Hall é baseado em um dos jogos regulares do show.
Se você está no show, aqui está o que acontece:

• Monty mostra três portas fechadas e diz que há um prêmio atrás de


cada porta: um prêmio é um carro, os outros dois são prêmios menos
valiosos, como manteiga de amendoim e unhas falsas. Os prêmios são
organizados aleatoriamente.
• O objetivo do jogo é adivinhar qual porta tem o carro. Se você acertar,
você pode ficar com o carro.
• Você escolhe uma porta, que chamaremos de Porta A. Vamos chamar
as outras portas B e C.
• Antes de abrir a porta que você escolheu, Monty aumenta o suspense
abrindo a porta B ou C, o que não tiver o carro. (Se o car está
realmente atrás da porta A, Monty pode abrir com segurança B ou C,
então ele escolhe um aleatoriamente.)
• Em seguida, Monty oferece-lhe a opção de ficar com a sua escolha
original ou mudar para a porta não aberta restante.
1.7. The Monty Hall problem 9

A questão é, você deve "pau" ou "troca" ou não faz diferença?


A maioria das pessoas tem a forte intuição de que não faz diferença. Há
duas portas sobrando, eles raciocinam, então a chance de o carro ficar
atrás da porta A é de 50%.
Mas isso está errado. Na verdade, a chance de ganhar se você ficar com a
Porta A é de apenas 1/3; se você mudar, suas chances são de 2/3.
Aplicando o teorema de Bayes, podemos quebrar esse problema em
pedaços simples, e talvez nos convencer de que a resposta correta é, de
fato, correta.

Para começar, devemos fazer uma declaração cuidadosa dos dados. Neste caso D
consiste em duas partes: Monty escolhe a porta B e não há carro lá.
Em seguida, definimos três hipóteses: A, B,e C representam a hipótese de
que o carro está atrás da porta A, porta B ou porta C. Novamente, vamos
aplicar o método da tabela: method:
Pa Probabili Posterio
nte dade p(H) p(D| r p(H|
rio p(D| H) H) D)
r(
H))
U 1/ 1 1/6 1
m 3 / /
2 3
B 1/ 0 0 0
3
C 1/ 1 1/3 2
3 /
3
Preencher os antecedentes é fácil porque nos dizem que os prêmios são
organizados aleatoriamente, o que sugere que o carro é igualmente
provável de estar atrás de qualquer porta.
Descobrir as probabilidades requer algum pensamento, mas com cuidado
razoável podemos estar confiantes de que temos razão:

• Se o carro está realmente atrás de A, Monty poderia abrir com segurança portas B ou
C. Então a probabilidade de que ele escolha B é 1/2. E como o carro
está um atrás deA, a probabilidade de que o carro não esteja atrás de
B é de 1.

• Se o carro está realmente atrás de B, Monty tem que abrir a porta C,


então a prob-habilidade que ele abre a porta B é 0.

• Finalmente, se o carro está atrás da porta C, Monty abre B com


probabilidade 1 e não encontra nenhum carro lá com probabilidade
1.
Agora a parte difícil acabou; o resto é apenas aritmética. A soma da
terceira coluna é 1/2. Dividindo através de|rendimentos p (A D) = 1/3 e
p(C D) = 2/3. Então é melhor você trocar.
10 Capítulo 1. Teorema de
Bayes
Há muitas variações do problema de Monty Hall. Um dos pontos fortes da
abordagem bayesiana é que ela generaliza para lidar com essas variações.

Por exemplo, suponha que Monty sempre escolhe B se puder, e só escolhe


C se for preciso (porque o carro está atrás de B). Nesse caso, a tabela
revisada é:
P Probabili Posterio
ant dade p(H) p(D| r p(H|
eri p(D| H) H) D)
or(
H))
U 1/ 1 1/3 1
m 3 /
2
B 1/ 0 0 0
3
C 1/ 1 1/3 1
3 /
2
A única mudança é p(D| A). Se o carro estiver atrás de A,Monty pode
optar por abrir B ouC. Mas nessa variação ele sempre escolhe B, então
p(D| A) = 1.

Como resultado, as probabilidades são as mesmas para Um E C, e os


posteriores São|O mesmo: p(Um D) = p(C D) = 1/2. Neste caso, o fato de
que Monty escolheu B não revela nenhuma informação sobre a localização
do Carro por isso não importa se o concorrente varas ou Interruptores.
Por outro lado, se ele tivesse aberto C,saberíamos p(B| D) = 1.

Eu incluí o problema de Monty Hall neste capítulo porque eu acho que é


divertido, e porque o teorema de Bayes torna a complexidade do
problema um pouco mais gerenciável. Mas não é um uso típico do
teorema de Bayes, então se você achou confuso, não se preocupe!

1.8 Discussão
Para Muitos Problemas Envolvendo Condicional Probabilidade Bayes
Teorema pró- vides uma divisão-e-conquistar | Estratégia. Se p(Um B) é
difícil de calcular, ou difícil de calcular Medida Experimentalmente
Verificar Se ele Pode Ser Fácil Para Calcular os outros termos no teorema
de Bayes, p(B|A)P(A) E p(B).

Se o problema de Monty Hall é a sua idéia de diversão, eu coletei um


num-ber de problemas semelhantes em um artigo chamado "All your
Bayes são pertencem a nós", que você pode ler em
http://allendowney.blogspot.com/2011/10/ todos-seus-bayes-são-pertencem-
a-nós.html.
Capítulo 2 Estatísticas

Computacionais

2.1 Distribuições
Nas estatísticas, uma distribuição é um conjunto de valores e suas proba-
bilidades correspondentes.
Por exemplo, se você rolar um dado de seis lados, o conjunto de valores
possíveis são os números 1 a 6, e a probabilidade associada a cada valor é
de 1/6.
Como outro exemplo, você pode estar interessado em quantas vezes cada
palavra aparece no uso comum do inglês. Você poderia construir uma
distribuição que em- cludes cada palavra e quantas vezes ela aparece.
Para representar uma distribuição em Python, você pode usar um
dicionário que mapeia de cada valor para sua probabilidade. Eu escrevi
uma classe chamada PMF que usa um dicionário Pythonexatamente dessa
maneira, e fornece uma série de métodos úteis. Chamei a classe PMF em
referência a uma funçãode massa de probabilidade, que é uma forma de
representar matematicamente uma distribuição.
PMF é definido em um módulo Python que escrevi para acompanhar este
book, thinkbayes.py. Você pode baixá-lo a partir de http://thinkbayes.com/
thinkbayes.py. Para obter mais informações, consulte a Seção 0.3.

Para usar o PMF você pode importá-lo assim:


de thinkbayes importação PMF
O código a seguir constrói um PMF para representar a distribuição dos
resultados de um dado de seis lados:
PMF = PMF()
para x em [1,2,3,4,5,6]: pmf.
Set(x, 1/6.0)
12 Capítulo 2. Estatísticas
Computacionais
PMF cria um PMF vazio sem valores. O método Definir define a proba-
bility associada a cada valor como 1/6.

Aqui está outro exemplo que conta o número de vezes que cada palavra
aparece em uma seqüência:
PMF = PMF()
por palavra em word_list: PMF. Incr
(palavra, 1)
O Incr aumenta a "probabilidade" associada a cada palavra por 1. Se uma
palavra ainda não está no PMF, ela é adicionada.

Coloquei "probabilidade" entre aspas porque, neste exemplo, as


probabilidades não são normalizadas; ou seja, eles não somam 1. Então
eles não são verdadeiras proba-bilidades.

Mas neste exemplo as contagens de palavras são proporcionais às


probabilidades. Então, depois de contarmos todas as palavras, podemos
calcular probabilidades dividindo-se pelo número total de palavras. PMF
fornece um método, Normalize, que faz exactly que:
Pmf. Normalizar()
Uma vez que você tenha um objeto PMF, você pode pedir a probabilidade
associada a qualquer valor:
imprimir pmf. Prob( o )' '

E isso imprimiria a freqüência da palavra "o" como uma fração das


palavras da lista.

PMF usa um dictionar Python ypara armazenar os valores e suas


probabilidades, de modo que os valores no PMF podem ser qualquer tipo
hashable. As probabilidades podem ser de qualquer tipo numérico, mas
geralmente são números de pontos flutuantes (tipo flutuador).).

2.2 O problema dos biscoitos


No contexto do teorema de Bayes, é natural usar um PMF para mapear de
cada hipótese para sua probabilidade. No problema dos biscoitos, as
hipóteses são B1 e B2. Em Python, represento-os com strings:
PMF = PMF..
Conjunto( Bowl 1 , 0.5)
' '

Pmf. Conjunto( Bowl 2 , 0.5)


' '
2.3. The Bayesian framework 13

Esta distribuição, que contém os antecedentes para cada hipótese, é


chamada (aguarde) a distribuição prévia.

Para atualizar a distribuição com base em novos dados (o cookie de


baunilha), nós mul-tiply tiply cada um anterior pela probabilidade
correspondente. A probabilidade de desenhar um biscoito de baunilha da
Tigela 1 é 3/4. A probabilidade de Bowl 2 é 1/2.
Pmf. Mult( Bowl 1 , 0.75)
' '

Pmf. Mult( Bowl 2 , 0.5)


' '

Mult faz o que você esperaria. Obtém a probabilidade para a dada hy-
pothesis e multiplica-se pela probabilidade dada.

Após esta atualização, a distribuição não é mais normalizada, mas como


essas hipóteses são mutuamente exclusivas e collectivamente exaustivas,
podemos renormalizar::
Pmf. Normalizar()
O resultado é uma distribuição que contém a probabilidade posterior para
cada hipótese, que é chamada (espere agora) a distribuição posterior.

Finalmente, podemos obter a probabilidade posterior para a Bowl 1:


imprimir pmf. Prob( Bowl 1 )
' '

E a resposta é 0,6. Você cum download este exemplo de http://


thinkbayes.com/cookie.py. Para obter mais informações, consulte a Seção
0.3.

2.3 A estrutura bayesiana


Antes de irmos para outros problemas, quero reescrever o código da seção
pré-vious para torná-lo mais geral. Primeiro definirei uma classe para
encapsular o código relacionado a este problema:
classe Cookie (PMF):

Def __init__(self, hypos):


Pmf.__init__(self)
para hipo em hipos: self. Set(hypo,
1)
Auto. Normalizar()
Um objeto Cookie é um PMF que mapeia de hipóteses para suas
probabilidades. O método __init__ dá a cada hipótese a mesma
probabilidade prévia. Como na seção anterior, há duas hipóteses:
14 Capítulo 2. Estatísticas
Computacionais
hipos = [ Bowl 1 , Bowl 2 ] pmf =
' ' ' '

Cookie(hypos)
O Cookie fornece um método de atualização que toma os dados como
parâmetro e atualiza as probabilidades:
def Update (self, data):
para hipo em si mesmo. Valores():
como = eu. Probabilidade (dados, hipo) auto.
Mult (hipo, como)
Auto. Normalizar()
A atualização percorre cada hipótese no conjunto e o multipencontra sua
proba-bility bility pela probabilidade dos dados sob a hipótese, que é
calculada pela Probabilidade:
misturas = {
'Bowl 1 :dict (baunilha =0,75, chocolate =0,25),
'

'Bowl 2 :dict (baunilha =0,5, chocolate = 0,5),


'

def Probabilidade (self, data, hypo):


mix = self.mixes[hypo]
como =
mix[dados]
retorno como
Likelihood usa mixes, que é um dicionário que mapeia desde o nome de
uma tigela até a mistura de biscoitos na tigela.
Veja como é a atualização:
Pmf. Atualização( baunilha vanilla ) )

E então podemos imprimir a probabilidade posterior de cada hipótese:


para hipo, prob em PMF. Itens():
imprimir hypo, prob
O resultado é
Tigela 10.6
Tigela 2 0.4
que é o mesmo que temos antes. Este código é mais complicado do que o
que vimos na seção anterior. Uma vantagem é que ele se torna geral para
o caso em que tiramos mais de um biscoito da mesma tigela (com
substituição):
conjunto de dados = [ baunilha , chocolate ,
' ' ' '

baunilha ] para dados no conjunto de dados:


' '

Pmf. Atualização (dados)


2.4. The Monty Hall problem 15

A outra vantagem é que ele fornece uma estrutura para resolver muitos
problemas sim-ilar. Na próxima seção, resolveremos o problema de
Monty Hall com putcionalmente e depois veremos quais partes da
estrutura são as mesmas.
O código nesta seção está disponível from http://thinkbayes.com/cookie2.
py. Para obter mais informações, consulte a Seção 0.3.

2.4 O problema de Monty Hall


Para resolver o problema de MontyH, definirei uma nova classe:
classe Monty (PMF):

Def __init__(self, hypos):


Pmf.__init__(self)
para hipo em hipos: self. Set(hypo,
1)
Auto. Normalizar()
Até agora Monty e Cookie são exatamente iguais. E o código que cria o
PMF também é o mesmo, exceto pelos nomes das hipóteses:
hypos = ABC
' '

pmf = Monty (hipos)


Chamada Atualização é praticamente a mesma coisa:
dados = B pmf.
' '

Atualização (dados)
E a implementação do Update é exatamente a mesma:
def Update (self, data):
para hipo em si mesmo. Valores():
como = eu. Probabilidade (dados, hipo) auto. Mult
(hipo, como)
Auto. Normalizar()
A única parte que requer algum trabalho é
Likelihood: def Likelihood (self, data, hypo):
se hipo == dados:
retorno 0
elif hypo == A :' '

retorno 0,5
Mais:
retornar 1
16 Capítulo 2. Estatísticas
Computacionais
Finalmente, imprimir os resultados é o mesmo:
para hipo, prob em PMF. Itens():
print hypo,prob
E a resposta é
Um 0.333333333333
B 0.0
C 0.666666666667
Neste exemplo, escrever Probabilidade é um pouco complicado, mas o
quadro-trabalho da atualização bayesiana é simples. O código nesta seção
é útil a partir de http://thinkbayes.com/monty.py. Para obter mais
informações, consulte a Seção 0.3.

2.5 Encapsulando o quadro


Agora que vemos quais elementos da estrutura são os mesmos, podemos
encapsulá-los em um objeto — uma Suíte é um PMF que fornece
__init____init__, Atualizaçãoe Print:
Suíte de classe (PMF):
""Representa um conjunto de hipóteses e suas probabilidades."

Def __init__(self, hypo=tuple()): """Initializes the


distribution."""

def Update (self, data):


""Atualiza cada hipótese com base nos dados."

def Print(self):
""Imprime as hipóteses e suas probabilidades."
A implementação do Suite está em thinkbayes.py. Para usar o Suite,você
deve escrever uma classe que herda dela e fornece Probabilidade. Por
exemplo, aqui está a solução para o problema de Monty Hall reescrito
para usar suite:
do thinkbayes importação Suite class

Monty(Suite):

def Probabilidade (self, data, hypo):


se hipo == dados:
retorno 0
2.6. The M&M problem 17

elif hypo == A : ' '

retorno 0,5
Mais:
retornar 1
E aqui está o código que usa esta classe:
suíte = Suíte
Monty( ABC
' ').

Atualizar( B suíte.
' '

Impressão()
Você pode baixar este exemplo de http://thinkbayes.com/monty2.py. Para
obter mais informações, consulte a Seção 0.3.

2.6 O problema de M&M


Podemos usar a estrutura do Suite para resolver o problema de M&M. Escrevendo o
A função de probabilidade é complicada, mas todo o resto é simples.

Primeiro eu preciso codificar as misturas de cores de antes e depois de


1995:
mix94 = dict (brown=30,
amarelo=2
0,
vermelho=
20,
verde=10,
laranja=10,
bronzeado
=10)

mix96 = dict (azul=24,


verde=20,
laranja=16,
amarelo=1
4,
vermelho=
13,
marrom=1
3)
Então eu tenho que codificar as hipóteses:
hypoA = dict (bag1=mix94, bag2=mix96)
hypoB = dict (bag1=mix96, bag2=mix94)
hypoA representa a hipótese de que o Saco 1 é de 1994 e o Saco 2 de 1996.
hypoB é o contrário.
Em seguida, mapei a partir do nome da hipótese para a representação:
hipóteses = dita (A=hipoA, B=hypoB)
18 Capítulo 2. Estatísticas
Computacionais
E finalmente eu posso escrever Likelihood. Neste caso, a hipótese, hipo, é
uma corda, ou A ou B. Os dados são uma tuple que especifica um saco e
uma cor.
def Probabilidade (self, dados, hypo):
saco, cor = dados
mix = auto.hipóteses[saco] como =
mistura[cor]
retornar como
Aqui está o código que cria a suíte e a atualiza:
suíte = M_and_M( AB )' '

Suite. Atualização (( ' bag1 , amarelo ))


' ' '

Suite. Atualização (( ' bag2 , verde'))


' ' '

Suite. Impressão()
E aqui está o resultado:
Um 0.740740740741
B 0,259259259259
A probabilidade posterior de A é de aproximadamente 20/27, que é o que
temos antes.
O código nesta seção está disponível a partir de
http://thinkbayes.com/m_and_ m.py. Para obter mais informações,
consulte a Seção 0.3.

2.7 Discussão
Este capítulo apresenta a classe Suite, que encapsula a estrutura bayesiana
atualizada.
Suite é um tipo abstrato,o que significa que ele define a interface que um Suite
deveria ter, mas não fornece uma implementação completa. A interface
Suite inclui Atualização e Probabilidade,mas a classe Suite só fornece uma
implementação de Atualização,não Probabilidade.
Um tipo concreto é uma classe que estende uma classe parental abstrata e
fornece uma implementação dos métodos ausentes. Por exemplo, Monty
extends Suite, por issoherda atualização e fornece Probabilidade.
Se você estiver familiarizado com padrões de design, você pode
reconhecer isso como um exemplo do padrão do método de modelo. Você
pode ler sobre este padrão em
http://en.wikipedia.org/wiki/Template_method_pattern.
2.8. Exercises 19

A maioria dos exemplos nos capítulos seguintes seguem o mesmo padrão;


para cada problema definimos uma nova classe que estende o Suite,herda
atualizaçãoefornece Probabilidade. Em alguns casos, anulamos
atualização,geralmente para melhorar o desempenho.

2.8 Exercícios
Exercício 2.1. Na Seção 2.3 eu disse que a solução para o problema dos cookies é
o caso em que desenhamos vários cookies com substituição.

Mas no cenário mais provável onde comemos os cookies que desenhamos, a


probabilidade de cada sorteio depende dos sorteios anteriores.

Modifique a solução neste capítulo para lidar com a seleção sem substituição.
Dica: adicione variáveis de instância ao Cookie para representar o estado
hipotético das tigelas e modifique a Probabilidade de acordo. Você pode querer
definir um objeto Bowl.
20 Capítulo 2. Estatísticas
Computacionais
Estimativa do

Capítulo 3

3.1 O problema dos dados


Suponha que eu tenha uma caixa de dados que contém um dado de 4
lados, um dado de 6 lados, um dado de 8 lados, um dado de 12 lados, e
um dado de 20 lados. Se você já jogou Dungeons & Dragons,sabe do que
estou falando.
Suponha que eu selecione um dado da caixa aleatoriamente, roleit, e
obtenha um 6. Qual é a probabilidade de eu ter enrolado cada morte?
Deixe-me sugerir uma estratégia de três passos para abordar um problema como este.
1. Escolha uma representação para as hipóteses.
2. Escolha uma representação para os dados.
3. Escreva a função de probabilidade.

Em exemplos anteriores eu usei strings para representar hipóteses e


dados, mas para o problema da morte eu vou usar números.
Especificamente, uso os inteiros 4, 6, 8, 12 e 20 para representar hipóteses:
suíte = Dados ([4, 6, 8, 12, 20])
E inteiros de 1 a 20 para os dados. Essas representações facilitam a
gravação da função de probabilidade:
classe Dice (Suíte):
def Probabilidade (self, data, hypo):
se hypo < dados:
retornar
0 mais:
retorno 1.0/hypo
22 Capítulo 3. Estimativa

É assim que a Probabilidade funciona. Se hypo<dados,isso significa que o


rolo é maior do que o número de lados no dado. Isso não pode acontecer,
então a probabilidade é 0.
Caso contrário, a questão é: "Dado que existem lados hipo, qual é a chance
de rolar dados?" A resposta é 1/hypo,independentemente dos dados.
Aqui está a declaração que faz a atualização (se eu rolar um 6):
Suite. Atualização(6)
E aqui está a distribuição posterior:
4 0.0
6 0.392156862745
8 0.294117647059
12 0.196078431373
20 0.117647058824
Depois de rolar um 6, a probabilidade de fosão o dado de 4 lados é 0. A
alternativa mais provável é o dado de 6 lados, mas ainda há quase 12% de
chance de morrer de 20 lados.
E se rolarmos mais algumas vezes e pegarmos 6, 8, 7, 7, 5 e 4?
para rolar em [6, 8, 7, 7, 5, 4]: suíte.
Atualização(roll)
Com esses dados, o dado de 6 lados é eliminado, e o dado de 8 lados
parece bastante provável. Aqui estão os resultados:
4 0.0
6 0.0
8 0.943248453672
12 0.0552061280613
20 0.0015454182665
Agora, a probabilidade é de 94% de que estamos rolando o dado de 8
lados, e menos de 1% para o dado de 20 lados.
O problema dos dados é baseado em um exemplo que vi na aula de
Sanjoy Mahajan sobre inferência bayesiana. Você pode baixar o código
nesta seção a partir de http:
thinkbayes.com/dice.py. Para obter mais informações, consulte a Seção 0.3.

3.2 O problema da locomotiva


Encontrei o problema da locomotiva em Frederick Mosteller,Cinquenta
Problemas Desafiadores em Probabilidade com Soluções (Dover, 1987):
3.2. The locomotive problem 23

0.006

0.005

Probabilidade
0.004

0.003

0.002

0.001

0.000
0 200 400 600 800 1000
Número de trens

Figura 3.1: Distribuição posterior para o problema da locomotiva, com


base em um uniforme anterior.

"Uma ferrovia emite suas locomotivas na ordem 1..N. Um dia


você vê uma locomotiva com o número 60. Estimar quantos
loco-motivos a ferrovia tem.

Com base nessa observação, sabemos que a ferrovia tem 60 ou mais


locomotives. Mas quantos mais? Para aplicar o raciocínio bayesiano,
podemos dividir este problema em duas etapas:

1. O que sabíamos sobre N antes de vermos os dados?


2. Para qualquer valor de N, qual é a probabilidade de ver os dados
(uma locomotiva com o número 60)?

A resposta para a primeira pergunta é a anterior. A resposta para a


segunda é a probabilidade.
Não temos muita base para escolher um anterior, mas podemos começar
com algo simples e depois considerar alternativas. Vamos supor que N é
igualmente provável que seja qualquer valor de 1 a 1000.
hipos = xrange(1, 1001)
Agora tudo o que precisamos é de uma função de probabilidade. Em uma
frota hipotética de N lo-comotives, qual é a probabilidadede vermos o
número60? Se assumirmos que há apenas uma empresa de operação de
trens (ou apenas uma que nos importa) e que é igualmente provável que
vejamos qualquer uma de suas locomotivas, então a chance de ver
qualquer locomotiva em particular é de 1/N.
Aqui está afunção de lihood como:
24 Capítulo 3. Estimativa

classe Trem (Suíte):


def Probabilidade (self, data, hypo):
se hypo < dados:
retornar
0 mais:
retorno 1.0/hypo
Isso pode parecer familiar; as funções de probabilidade para o prob-lem
locomotiva e o problema dos dados são idênticos.

Aqui está a atualização:


suíte = Suíte de trem (hipos).
Atualização(60)
Há muitas hipóteses para imprimir, então eu plotei os resultados na
Figura 3.1. Não surpreende que todos os valores de N abaixo de 60
tenham sido eliminados.

O valor mais provável, se você tivesse que adivinhar, é 60. Isso pode não
parecer um palpite muito bom; afinal, quais são as chances de você ver o
train com o número mais alto? No entanto, se você quer maxi-mize a
chance de obter a resposta exatamente certo, você deve adivinhar 60.

Mas talvez esse não seja o objetivo certo. Uma alternativa é calcular a
média da distribuição posterior:
def Mean(suíte): total
=0
para hypo, prob na suíte. Itens(): total
+= hipo * prob
retorno total

imprimir Mean(suíte)
Ou você pode usar o método muito semelhante fornecido
pela PMF: suíte de impressão. Média()
A média do posterior é 333, então isso pode ser um bom palpite se você
quiser minimizar o erro. Se você jogou este jogo de adivinhação
repetidamente, usando a média da parte posterior como sua estimativa
minimizaria o erro médio quadrado no longo prazo (ver
http://en.wikipedia.org/ wiki/Minimum_mean_square_error).

Você pode baixar este exemplo de http://thinkbayes.com/train.py. Para


obter mais informações, consulte a Seção 0.3.
3.3. What about that prior? 25

3.3 E aquele anterior?


Para fazer qualquer progresso no problema da locomotiva tivemos que
fazer assumpições, e alguns deles foram bastante arbitrários. Em
particular, escolhemos um uniforme anterior de 1 a 1000, sem muita
justificativa para escolher 1000, ou para escolher um uniforme
distribution.
Não é loucura acreditar que uma companhia ferroviária possa operar 1000
loco-motivos, mas uma pessoa razoável pode adivinhar mais ou menos.
Então, podemos nos perguntar se a distribuição posterior é sensível a
essas suposições. Com tão poucos dados — only uma observação —
provavelmente é.
Lembre-se que com um uniforme anterior de 1 a 1000, a média do posterior é
333. Com um limite superior de 500, temos uma média posterior de 207, e
com um limite superior de 2000, a média posterior é de 552.
Então isso é ruim. Sãoduas maneiras de proceder:

• Obter mais dados.


• Obtenha mais informações sobre os antecedentes.

Com mais dados, distribuições posteriores baseadas em diferentes


antecedentes tendem a convergir. Por exemplo, suponha que além do
trem 60 também vemos os trens 30 e 90. Podemos atualizara distribuição
assim:
para dados em [60, 30, 90]: suíte. Atualização
(dados)
Com esses dados, os meios dos posteriores são
Supe Posteri
rior or
Limit Média
e
500 152
1000 164
2000 171
Então as diferenças são menores.

3.4 Uma alternativa anterior


Se mais dados não estiverem disponíveis, outra opção é melhorar os
antecedentes coletando mais informações de fundo. Provavelmente não é
razoável sumificar que uma empresa de operação de trens com 1000
locomotivas seja tão provável quanto uma empresa com apenas 1.
26 Capítulo 3. Estimativa

0.018

Uniforme
0.016
lei do poder
0.014

Probabilidade
0.012

0.010

0.008

0.006

0.004

0.002

0.000
0 200 400 600 800 1000
Número de trens

Figura 3.2: Distribuição posterior com base em uma lei de poder anterior,
em comparação com um uniforme anterior.

Com algum esforço, poderíamos encontrar uma lista de empresas que


operam locomotivas na área de observação. Ou podemos entrevistar um
especialista em transporte ferroviário para coletar informações sobre o
tamanho típico das empresas.

Mas mesmo sem entrar nos detalhes da economia ferroviária, podemos


fazer alguns palpites educados. Na maioria dos campos, há muitos
pequenos compa-nies, menos empresas de médio porte, e apenas um ou
dois com-panies muito grandes. De fato, a distribuição dos tamanhos das
empresas tende a seguir uma lei de poder, como relata Robert Axtell em
Science (ver http://www.sciencemag.org/ conteúdo/293/5536/1818.full.pdf).
Esta lei sugere que, se houver 1000 empresas com menos de 10 loco-
motivos, pode haver 100 empresas com 100 locomotivas, 10 empresas com
1000, e possivelmente uma empresa com10.000 locomotivas.

Matematicamente, uma lei de poder significa que o número de empresas


com um determinado tamanho é inversamente proporcional ao tamanho,
ou
. Σα
1
PMF(x)
X

onde PMF(xx) é a função de massa de probabilidade de x e α é um


parâmetro que muitas vezes está perto de 1.
Podemos construir uma lei de poder antes disso:
classe Trem (Dados):
3.5. Credible intervals 27

Def
__init__(self, hypos, alfa=1.0):
PMF.__init__(self)
para hipo em hipos:
Auto. Conjunto (hypo, hypo**(-alfa)) self.
Normalizar()
E aqui está o código que constrói o anterior:
hipos = intervalo (1, 1001)
suíte = Trem (hipos)
Mais uma vez, o limite superior é arbitrário, mas com uma lei de poder
anterior, o poste-rior é menos sensível a essa escolha.

A Figura 3.2 mostra o novo posterior com base na lei de poder, em


comparação com o posterior com base no uniforme anterior. Usando as
informações de fundo representadas na lei de poder anterior, podemos
todos, mas eliminar valores de N maior essegundo fim de 700.

Se começarmos com isso anteriormente e observarmos os trens 30, 60 e 90,


os meios dos posteriores são

Supe Posteri
rior or
Limit Média
e
500 131
1000 133
2000 134

Agora as diferenças são muito menores. Na verdade, com um aumento


arbitrariamente grande por limite, a média converge em 134.

Assim, a lei do poder anterior é mais realista, porque se baseia na


formação geral sobre o tamanho das empresas, e se comporta melhor na
prática.

Você pode baixar os exemplos nesta seção de http://thinkbayes.


com/train3.py. Para obter mais informações, consulte a Seção 0.3.

3.5 Intervalos críveis


Uma vez que você calculou uma distribuição posterior, muitas vezes é útil
para soma-marize th eresultados com uma estimativa de ponto único ou
umintervalo. Para os pontos é comum usar a média, mediana ou o valor
com a máxima probabilidade.
28 Capítulo 3. Estimativa

Para intervalos, geralmente relatamos dois valores computados de modo


que há 90% de chance de que o valor desconhecido caia entre eles (ou
qualquer outro probabil-ity). Esses valores definem um intervalo crível..
Uma maneira simples de calcular um intervalo crível é somar as
probabilidades na distribuição posterior e registrar os valores que
correspondem a prob-habilidades 5% e 95%. Em outras palavras, os
percentis 5 e 95.
thinkbayes fornece uma função que calcula percentis:
def Percentile (pmf, percentual): p =
percentage / 100.0
total = 0
para val, prob em PMF. Itens():
total += prob
se total >= p:
return val
E aqui está o código que o usa:
intervalo = Percentil (suíte, 5), percentil (suíte, 95) intervalo de
impressão
Para o exemplo anterior — o problema da locomotiva com uma lei de
energia anterior e três trens — o intervalo de 90% de credibilidade é (91,
243)) (. A largura desta faixa sugere, corretamente, que ainda estamos
bastante incertos sobre quantas locomotivas existem.

3.6 Funções de distribuição cumulativa


Na seção anterior, calculamos percentis iterando através dos valores e
probabilidades em um PMF. Se precisarmos calcular mais do que alguns
percentis, é mais eficiente usar uma função de distribuição cumulativa, ou
Cdf.
Cdfs e PMFs são equivalentno sentido de que eles contêm o mesmo infor-
mation sobre a distribuição, e você pode sempre converter de um para o
outro. A vantagem do Cdf é que você pode calcular percentis de forma
mais eficiente.
thinkbayes fornece uma classe Cdf que represents uma função de
distribuição cumulativa. PMF fornece um método que torna o Cdf
correspondente:
cdf = suíte. MakeCdf()
E o CDF fornece uma função chamada Percentil
3.7. The German tank problem 29

intervalo = cdf. Percentil(5), cdf. Percentil(95)


A conversão de um PMF para um Cdf leva tempo proporcional ao
número de valores, len(pmf). O Cdf armazena os valores e probabilidades
em listas classificadas, então procurar uma lity probabi para obter o valor
correspondente leva "tempo de registro": ou seja, tempo proporcional ao
logaritmo do número de valores. Procurar um valor para obter a
probabilidade correspondente também é logarítmico, de modo que os
Cdfs são eficientes para muitos cálculos.
Os exemplos nesta seção estão em http://thinkbayes.com/train3.py. Para
obter mais informações,consulte a Seção 0.3.

3.7 O problema dos tanques alemães


Durante a Segunda Guerra Mundial, a Divisão de Guerra Econômica do
Em-Bassy americano em Londres usou análise estatística para estimar a
produção alemã de tanques e outros equipamentos. 1
Os Aliados Ocidentais capturaram livros de registro, inventários e
registros de reparos que incluíam números de série de chassis e motores
para tanques individuais.
A análise desses registros indicou que os números de série foram alocados
por manufacturer e tipo tanque em blocos de 100 números, que os
números em cada bloco foram usados sequencialmente, e que nem todos
os números em cada bloco foram utilizados. Assim, o problema de estimar
a produção alemã de tanques poderia ser re-induzido, dentro de cada
bloco de 100 números, para uma forma de locomotiva prob-lem.
Com base nessa visão, analistas americanos e britânicos produziram
estimativas substancialmente inferiores às estimativas de outras formas de
inteligência. E depois da guerra, os registros indicaram que eram
substancialmente mais precisos.
Eles realizaram análises semelhantes compneus, caminhões, foguetes e
outros equipamentos, gerando inteligência econômica precisa e acionável.
O problema dos tanques alemães é historicamente interessante; it é
também um bom exemplo de aplicação no mundo real da estimativa
estatística. Até agora, muitos dos exames deste livro foram problemas de
brinquedo, mas não vai demorar muito até começarmos a resolver
problemas reais. Penso que é uma vantagem da análise bayesiana,
especialmente com a abordagem computacional que estamos tomando,
que fornece um caminho tão curto para aintrodução básica da fronteira
dapesquisa.
1
Ruggles e Brodie, "Uma Abordagem Empírica da Inteligência Econômica na Segunda
Guerra Mundial", Journal of the American Statistical Association ,Vol. 42, No. 237 (março de
1947).
30 Capítulo 3. Estimativa

3.8 Discussão
Entre os bayesianos, há duas abordagens para escolher distribuições
anteriores. Alguns recomendam escolher o anterior que melhor representa
o fundo de fundo sobre o problema; nesse caso, diz-se que o anterior é
informativo. O problema com o uso de um antecedente informativo é que
as pessoas podem usar informações de fundo dif-ferent (ou interpretá-la
de forma diferente). Então, os antecedentes informativos muitas vezes
parecem subjetivos.

A alternativa é o chamado prior não informativo,que pretende ser omais


irrestrito possível, a fim de permitir que os dados falem por si mesmos.
Em alguns casos, você pode identificar um único antes que tenha alguma
propriedade desejável, como representar informações prévias mínimas
sobre a quantidade estimada.

Antecedentes não informativos são atraentes porque parecem mais


objetivos. Mas eu sou geralmente a favor do uso de antecedentes
informativos. Porque? Em primeiro lugar, a análise bayesiana é sempre
baseada em decisões de modelagem. Escolher o anterior é uma dessas
decisões, mas não éapenas uma, e pode até não ser a mais subjetiva.
Portanto, mesmo que um antes não informativo seja mais objetivo, toda a
análise ainda é subjetiva.

Além disso, para a maioria dos problemas práticos, é provável que você
esteja em um dos dois regimes: ou você tem um monte de dados ou não
muito. Se você tem muitos dados, a escolha do anterior não importa
muito; os antecedentes informativos e não informativos produzem quase
os mesmos resultados. Veremos um exemplo como este no próximo
capítulo.

Mas se, como no problema da locomotiva, você não tem muitos dados,
usar informações de fundo rele-vant (como a distribuição da lei de
energia) faz uma grande diferença.

E se, como no problema do tanque alemão, você tem que tomar decisões
de vida ou morte com base em seus resultados, você provavelmente deve
usar toda a infor-mation à sua disposição, em vez de manter a ilusão de
objetividade fingindo saber menos do que você faz.

3.9 Exercícios
Exercício 3.1. Para escrever uma função de probabilidade para o problema da
locomotiva, tivemos que responder a esta pergunta: "Se a ferrovia tem
locomotivas N, qual é a probabilidade de vermos o número 60?"
3.9. Exercises 31

A resposta depende do processo de amostragem que usamos quando observamos o


loco-motivo. In Neste capítulo, resolvi a ambiguidade especificando que há apenas
uma empresa de operação de trens (ou apenas uma que nos importa).

Mas suponha que existam muitas empresas com diferentes números de trens. E
suponha que você é igualmente provável de ver qualquer trem operado por
qualquer empresa. Nesse caso, a função de probabilidade é diferente porque é mais
provável que você veja um trem operado por uma grande empresa.

Um exercício, implementar a função de probabilidade para esta variação do


problema da locomotiva, e comparar os resultados. s
32 Capítulo 3. Estimativa
Capítulo 4

Mais Estimativas

4.1 O problema do euro


Em Teoria da Informação, Inferência e Algoritmos de Aprendizagem, David
MacKay apresenta este problema:

Uma declaração estatística apareceu no "The Guardian" na


sexta-feira 4 de janeiro de 2002:
Quando girada na borda 250 vezes, uma moeda belga
de um euro subiu cabeças 140 vezes e coroa 110.
"Parece muito suspeito para mim", disse Barry Blight,
professor de estatística da London School of
Economics. "Se a moeda fosse imparcial, a chance de
obter um resultado tão extremo como isso seria
inferior a 7%."
Masesses dados dão provas de que a moeda é tendenciosa e
não justa?

Para responder a essa pergunta, vamos prosseguir em dois passos. A


primeira é esti-mate a probabilidade de que a moeda aterrisse de frente
para cima. A segunda é avaliar se os dados apoiam a hipótese de que a
moeda é tendenciosa.

Você pode baixar o código neste section de http://thinkbayes.com/


euro.py. Para obter mais informações, consulte a Seção 0.3.

Qualquer moeda tem alguma probabilidade, x, de aterrissar cabeças para


cima quando girada na borda. Parece razoável acreditar que o valor de x
depende de algumas características físicas da moeda, principalmente a
distribuição de peso.
34 Capítulo 4. Mais
Estimativas

0.14
Uniforme
0.12

0.10

Probabilidade
0.08

0.06

0.04

0.02

0.00
0 20 40 60 80 100
X

Figura 4.1: Distribuição posterior para o problema do Euro em um uniforme anterior.

Se uma moeda é perfeitamente equilibrada, esperamos que x seja perto de


50%, mas para uma moeda lop-sided, x pode ser substancialmente
diferente. Podemos usar o teorema de Bayes e os dados observados para
estimar x.
Vamos definir 101 hipóteses, onde Hx é a hipótese de que a probabilidade
de cabeças é x%, para valores de 0 a 100. Vou começar com um uniforme
anterior onde a probabilidade de Hx é a mesma para todos x x. Voltaremos
mais tarde para considerar outros antecedentes.

A função de probabilidade é relativamente fácil: Se Hx for verdadeiro, a


probabilidade de cabeças é x/100 e a probabilidade de caudas é de 1 −
x/100.
classe Euro(Suite):

def Probabilidade (self, data, hypo): x


= hypo
se os dados == H : ' '

retorno x/100.0
Mais:
retorno 1 - x/100.0
Aqui está o código que faz a suíte e atualiza-a:
suíte = Euro (xrange(0, 101))
dataset = H * 140 + T * 110
' ' ' '

para dados no conjunto de dados:


suite. Atualização (dados)
O resultado está na Figura 4.1.
4.2. Summarizing the posterior 35

4.2 Resumindo o posterior


Novamente, há várias maneiras de resumir a distribuição posterior. Uma
opção é encontrar o valor mais provável na distribuição posterior.
thinkbayes fornece uma função que faz isso:
def MaximumLikelihood (pmf):
""Devolve o valor com maior probabilidade.""" prob, val =
max((prob, val) para val, prob in pmf. Itens()) retorno val
Neste caso o resultado é 56, que também é o percentual observado de
cabeças, 140/250 = 56%. Então isso sugere (corretamente) que o percentual
observed é o estimador de probabilidade máxima para a população.

Podemos também resumir o posterior calculando a média e eu-dian:


imprimir Mean , suíte. Média()
' '

imprimir Median , thinkbayes. Percentil (suíte, 50)


' ',

A média é 55,95; a mediana é 56. Finalmente, podemos calcular um


intervalo crível:
imprimir CI , thinkbayes. CredibleInterval (suíte, 90)
' '

O resultado é :51, 61.. (

Agora, voltando à pergunta original, gostaríamos de saber se a moeda é


justa. Obse rve obseque o intervalo de credibilidade posterior não inclui
50%, o que sugere que a moeda não é justa.

Mas essa não é exatamente a pergunta que começamos. MacKay


perguntou: "Esses these dados dão provas de que a moeda é tendenciosa e
não justa?" Para responder a essa pergunta, teremos que ser mais precisos
sobre o que significa dizer que os dados constituem evidência para uma
hipótese. E esse é o tema do próximo capítulo.

Mas antes de continuarmos, quero abordar uma possível fonte de


confusão. Uma vez que queremos saber se a moeda é justa, pode ser
tentador pedir a probabilidade de que x é de 50%:
suíte de impressão. Prob(50)
O resultado é 0,021, mas esse valor é quase sem sentido. A decisão de
avaliar 101 hipóteses foi arbitrária; poderíamos ter dividido o alcance em
mais ou menos pedaços, e se tivéssemos, a probabilidade de qualquer hy-
pothesis seria maior ou menor.
36 Capítulo 4. Mais
Estimativas

0.025

Uniforme
Triângulo
0.020

Probabilidade
0.015

0.010

0.005

0.000
0 20 40 60 80 100
X

Figura 4.2: Antecedentes uniformes e triangulares para o problema do Euro.

4.3 Inundando os antecedentes


Começamos com um uniforme antes, mas isso pode não ser uma boa
escolha. Posso acreditar que se uma moeda for desequilibrada, x pode
desviar substancialmente de 50%, mas parece improvável que a moeda
euro belga esteja tão desequilibrada que x é de 10% ou 90%.

Pode ser mais razoável escolher um anterior que dê maior probabilidade a


valores de x perto de 50% e menor probabilidade a valores extremos.

Como exemplo, construí um antes triangular, mostrado na Figura 4.2.


Aqui está o código que constrói o anterior:
def TrianglePrior(): suite =
Euro()
para x em alcance (0, 51): suíte.
Conjunto(x, x)
para x em alcance (51, 101): suíte.
Conjunto (x, 100-x)
Suite. Normalizar()
A Figura 4.2 mostra o resultado (e o uniforme anterior à comparação).
Updat- ing este anterior com o mesmo conjunto de dados produz a
distribuição posterior mostrada na Figura 4.3. Mesmo com antecedentes
substancialmente diferentes, as distribuições posteriores são muito
semelhantes. similar. As medianas e os intervalos críveis são idênticos; os
meios diferem em menos de 0,5%.

Este é um exemplo de inundação dos antecedentes : com dados


suficientes,pessoas que começam com antecedentes diferentes tendem a
convergir no mesmo posterior.
4.4. Optimization 37

0.14
Uniforme
0.12 Triângulo

0.10

Probabilidade
0.08

0.06

0.04

0.02

0.00
0 20 40 60 80 100
X

Figura 4.3: Distribuições posteriores para o problema do euro.

4.4 Otimização
O código que mostrei até agora é fácil de ler, mas não é muito eficiente.
Em geral, eu gosto de desenvolver código que é comprovadamente
correto, em seguida, verificar se é rápido o suficiente para os meus
propósitos. Se assim for, não há necessidade de otimizar. Para este
exemplo, se nos preocupamos com o tempo de execução, há várias
maneiras de acelerar.

A primeira oportunidade é reduzir o número de vezes que normalizamos


a suíte. No código original, chamamos Atualizar uma vez para cada
rodada.
conjunto de dados = H * cabeças + T * caudas
' ' ' '

para dados no conjunto


de dados: suite.
Atualização (dados)
E aqui está como a atualização se parece:
def Update (self, data):
para hipo em si mesmo. Valores():
como = eu. Probabilidade (dados, hipo) auto. Mult
(hipo, como)
retorno auto. Normalizar()
Cada atualização itera através das hipóteses, em seguida, chama de
Normalize, que itera através das hipóteses novamente. Podemos
economizar algum tempo fazendo todas as atualizações antes de
normalizar.

O Suite fornece um método chamado UpdateSet que faz exatamente isso. Aqui está:
38 Capítulo 4. Mais
Estimativas
def UpdateSet (self, dataset): para
dados no conjunto de dados:
para hipo em si mesmo. Valores():
como = eu. Probabilidade (dados, hipo)
auto. Mult (hipo, como)
retorno auto. Normalizar()
E é assim que podemos invocá-lo:
conjunto de dados = H * cabeças + T * suíte de caudas. Conjunto
' ' ' '

de atualização (conjunto de dados)


Essa otimização acelera as coisas, mas o tempo de execução ainda é
proporcional à quantidade de dados. Podemos acelerar ainda mais as
coisas reescrevendo a Probabilidade para processar todo o conjunto de
dados, em vez de um giro de cada vez.

Naversão de origem al, os dados são uma string que codifica cabeças ou coroas:
def Probabilidade (self, data, hypo): x
= hypo / 100.0
se os dados ==
' H : retorno x
'

Mais:
retornar 1-x
Como alternativa, poderíamos codificar o conjunto de dados como uma
tuplo de dois inteiros: o número de cara e coroa. Nesse caso, a
probabilidade é assim:
def Probabilidade (self, data, hypo): x
= hypo / 100.0
cara, coroa = dados
como = x**cabeças * (1-x)**caudas
retornar como
E então podemos chamar Atualização assim:
cara, coroa = 140, 110 suíte.
Atualização((cabeças, coroas))
Uma vez que substituímos a multiplicação repetida por exponenciação,
esta versão leva o mesmo tempo para qualquer número de rodadas.

4.5 A distribuição beta


Há mais uma otimização que resolve esse problema ainda mais rápido.
4.5. The beta distribution 39

Até agora usamos um objeto PMF para representar um conjunto discreto


de valores para x. Agora vamos usar uma distribuição contínua,
especificamente a distribuição beta (ver
http://en.wikipedia.org/wiki/Beta_distribution).

A distribuição beta é definida no intervalo de 0 a 1 (incluindo ambos), por


isso é uma escolha natural para descrever proporções e
probabilidades.lities. Mas espere, fica melhor.

Acontece que se você fizer uma atualização bayesiana com uma função de
probabilidade binomial, que é o que fizemos na seção anterior, a
distribuição beta é um prior conjugado. Isso significa que se a distribuição
prévia para x isuma distribuição beta, o posterior também é uma
distribuição beta. Mas espere, fica ainda melhor.
A forma da distribuição beta depende de dois parâmetros, escritoα e β, ou
alfa e beta. Se o anterior for uma distribuição beta com parâmetros alfa e
beta, e vemos dadoscom cabeças h e caudas t, o posterior é uma
distribuição beta com parâmetros alfa+h e beta+t . Em outras palavras,
podemos fazer uma atualização com duas adições.

Então isso éótimo, mas só funciona se pudermos encontrar uma


distribuição beta que é uma boa escolha para um anterior. Felizmente, para
muitos antecedentes realistas há uma distribuição beta que é pelo menos
uma boa aproximação, e para um uniforme antes há uma combinação
perfeita. A distribuição beta com alfa=1 e beta=1 é uniforme de 0 a 1.

Vamos ver como podemos tirar vantagem de tudo isso. thinkbayes.py


fornece uma classe que representa uma distribuição beta:
classe Beta(objeto):

Def __init__(self, alpha=1, beta=1): self.alpha =


alpha
self.beta = beta
Por padrão, __init__ faz uma distribuição uniforme. uniform Atualização executa um
Atualização bayesiana:
def Update(self, data):
cara, coroa = dados
self.alfa += cabeças
self.beta += caudas
dados é um par de inteiros representando o número de cabeças e

caudas. Por isso, temos mais uma maneira de resolver o problema do

Euro:
40 Capítulo 4. Mais
Estimativas
beta = thinkbayes. Beta()
beta. Atualização((140, 110))
beta de impressão. Média()
Beta fornece Mean, que calcula uma função simples de alfa e beta: def
Mean(self):
flutuador de retorno (self.alfa) / (self.alfa + self.beta)
Para o problema do Euro, a média posterior é de 56%, que é o mesmo
resultado que opassamos usando pmfs.

O Beta também fornece OEvalPdf, que avalia a densidade de probabilidade


func-tion(PDF) da distribuição beta:
def EvalPdf(self,x):
retorno x**(self.alfa-1) * (1-x)**(self.beta-1)
Finalmente, o Beta fornece o MakePMF, que usa o EvalPdf para gerar uma
aproximação discreta da distribuição beta.

4.6 Discussão
Neste capítulo resolvemos o mesmo problema com dois antecedentes
diferentes e descobrimos que com um grande conjunto de dados, os
antecedentes ficam atolados. Se duas pessoas começam com crenças
anteriores diferentes, elas geralmente descobrem, à medida que vêem
mais dados, que suas distribuições posteriores convergem. Em algum
momento, a diferença entre suas distribuições é pequena o suficiente para
que não tenha efeito prático.

Quando isso acontece, alivia um pouco da preocupação com a


objetividade que discuti no capítulo anterior. E para muitos problemas do
mundo real, mesmo crenças anteriores podem eventualmente ser
conciliadas por dados.

Mas nem sempre é assim. Primeiro, lembre-se que toda análise bayesiana
é baseada em decisões de modelagem. Se você e eu não escolhermos o
mesmo modelo, podemos interpretar dados differently. Assim, mesmo
com os mesmos dados, calcularíamos diferentes probabilidades, e nossas
crenças posteriores podem não convergir.

Além disso, observe que em uma atualização bayesiana, multiplicamos


cada probabilidade anterior por uma | probabilidade, então se p (H) é 0,
p(H D) é também 0, independentemente de D. No problema do Euro, se
você está convencido de que X é menos de 50%, e você atribui
probabilidade 0 a todos os outros hypotes, nenhuma quantidade de dados
vai convencê-lo do contrário.
4.7. Exercises 41

Esta observação é a base da regrade Cromwell, que é a recommen-dation


que você deve evitar dar uma probabilidade prévia de 0 a qualquer
hipoth-esis que é remotamente possível (ver http://en.wikipedia.org/wiki/
cromwell's_rule).

A regra de Cromwell tem o nome de Oliver Cromwell, que escreveu: "Eu


te suplico, nas entranhas de Cristo, acho possível que você esteja
enganado." Para os bayesianos, isso acaba por ser um bom advice (mesmo
que seja um pouco exagerado).

4.7 Exercícios
Exercício 4.1. Suponha que, em vez de observar moedas, você meça o resultado
usando um instrumento que nem sempre está correto. Especificamente, suponha
que há uma probabilidade de que uma cara real seja relatada como coroa, ou
caudas reais re-portadas como cabeças.
Escreva uma classe que estima o viés de uma moeda dada uma série de resultados
e o valor de y.
Como a disseminação da distribuição posterior depende de y?
Exercício 4.2. Este exercício é inspirado em uma pergunta postada por um
"redditor" chamado dominosci nas estatísticas do Reddit "subreddit" em http: //
reddit. com/ r/ statistics .

Reddit é um fórum online com muitos grupos de interesse chamados subreddits.


Usuários, chamados redditors, postam links para a tenda de con onlinee outras
páginas da Web. Outros redditors votam nos links, dando um "upvote" para links
de alta qualidade e um "downvote" para links que são ruins ou irrelevantes.
Um problema, identificado pela dominosci, é que alguns redditors são mais
confiáveis do que outros, e o Reddit não leva isso em conta.
O desafio é elaborar um sistema para que, quando um redditor lança um voto, a
qualidade estimada do link seja atualizada de acordo com a confiabilidade do
redditor, e a confiabilidade estimada do redditor sejaatualizada de acordo com
aqualidade do link.

Uma abordagem é modelar a qualidade do link como a probabilidade de obter um


upvote, e modelar a confiabilidade do redditor como a probabilidade de dar
corretamente um upvote a um em de altaqualidade.
Escreva definições de classe para redditors e links e uma função de atualização que
atualiza ambos os objetos sempre que um redditor lança uma votação.
42 Capítulo 4. Mais
Estimativas
Capítulo 5

Probabilidades e Adesões

5.1 Probabilidades
Uma maneira de representar uma probabilidade é com um número entre 0
e 1, mas essa não é a única maneira. Se você já apostou em um jogo de
futebol ou em uma corrida de cavalos, provavelmente já encontrou outra
representação de probabilidade, chamada odds.
Você pode ter ouvido expressões como "as chances são de três para um",
mas você pode não saber o que isso significa. As probabilidades a favor
de um evento são a razão da probabilidade que ocorrerá à probabilidade
de que não ocorrerá.
Então, se eu acho que meu time tem 75% de chance de ganhar, eu diria
que as chances a seu favor são de três para um, porque a chance de ganhar
é três vezes a chance de perder.

Você pode escrever probabilidades em forma decimal, mas é mais comum


escrevê-las como uma proporção de inteiros. Então "três para um" está
escrito 3 : 1.
Quando as probabilidades são baixas, é mais comum relatar as
probabilidades contra o que as probabilidades a favor. Por exemplo, se eu
acho que meu cavalo tem 10% de chance de ganhar, eu diria que as
chances contra são 9 : 1.

Probabilidades e probabilidades são representações diferentes da mesma


informação. Dada a probabilidade, você pode calcular as probabilidades
como esta:
def Odds(p):
retorno p / (1-p)
Dadas as probabilidades a favor, na forma decimal, você pode converter-
se em probabilidade como esta:
44 Capítulo 5. Probabilidades e
Adesões
def Probabilidade(o):
retorno o / (o+1)
Se você representar probabilidades com um numerador e denominador,
você pode converter para probabilidade como esta:
def Probabilidade2 (sim, não):
retorno sim / (sim + não)
to Quando trabalho com probabilidades na minha cabeça, acho útil
imaginar pessoas na pista. Se 20% deles acham que meu cavalo vai
ganhar, então 80% deles não, então as chances a favor são 20: 80 ou 1 : 4.

Se as chances são 5: 1 contra o meu cavalo, então cinco em seis pessoas


pensam que ela vai perder, então a probabilidade de ganhar é de 1/6.

5.2 A forma de probabilidades do teorema de Bayes


No capítulo 1 escrevi o teorema de Bayes na forma de probabilidade::

p(H ) p (D | H )
p(H|D) = p(D)

Se tivermos duas hipóteses, A e B,podemos escrever a razão de


probabilidades posteriores como esta:

p( A | D ) p(A ) p( D | A )
p ( B | D ) = p( B) p ( D | B )

Observe que a constante normalizadora, p(D), saidesta equação.

Se Um E B são mutuamente exclusivos e coletivamente exaustivos, o que


p(B) = 1 p(A), para que possamos reescrever a razão dos
significa −
antecedentes, e a razão dos posteriores, como probabilidades.
Escrevendo o(AA) para as probabilidades a favor de A,nós otemos:
p(D|A)
o(Um|D) = o(A)
p (D| B)
Em palavras, isso diz que as probabilidades posteriores são as
probabilidades anteriores vezes a proporção de lihood semelhante. Esta é
a forma de probabilidade do teorema de Bayes.

Este formulário é mais conveniente para calcular uma atualização


bayesiana no papel ou na sua cabeça. Por exemplo, vamos voltar
aoproblema cookie:
5.3. Oliver’s blood 45

Suponha que haja duas tigelas de biscoitos. A tigela 1 contém


30 biscoitos de baunilha e 10 biscoitos de chocolate. A tigela 2
contém 20 de cada.
Agora suponha que você escolha uma das tigelas
aleatoriamente e, com- olhando para fora, selecione um biscoito
aleatoriamente. O biscoito é baunilha. É aprobabilidade deque
veio da Tigela 1?

A probabilidade anterior é de 50%, então as chances anteriores são 1: 1, ou


apenas 1. A relação likeli-hood é 3 / 1 , ou 3/2. Assim, as chances
posteriores são
4 2 3 : 2, que corresponde
a probabilidade de 3/5.

5.3 Sangue de Oliver


Aqui está outro problema da Teoria da Informação, Inferência e Algoritmos de
Aprendizagem do MacKay::

Duas pessoas deixaram vestígios de seu próprio sangue na cena


de um crime. Um suspeito, Oliver, é testado e descobriu-se que
tem sangue tipo 'O'. blood. Os grupos sanguíneos dos dois
traços são do tipo 'O' (tipo comum na população local, com
frequência de 60%) e do tipo 'AB' (tipo raro, com frequência
1%). Esses dados [os vestígios encontrados na cena] dão provas
a favor da proposta de que Oliver era uma das pessoas [que
deixou sangue na cena]?

Para responder a essa pergunta, precisamos pensar sobre o que significa


que os dados premem evidências a favor (ou contra) de uma hipótese.
Intuitivamente, podemos dizer que os dados favorecem uma hipótese se a
hipótese é mais provável à luz dos dados do que era antes.
No problema do cookie, as chances anteriores são de 1 : 1, ou
probabilidade de 50%. As probabilidades posteriores são 3 : 2, ou
probabilidade de 60%. Então podemos dizer que o biscoito de baunilha é
evidência a favor da Tigela 1.
A forma de probabilidade do teorema de Bayes fornece uma maneira de
tornar essa intuição mais precisa. Novamente
p(D|A)
o(Um|D) = o(A)
p (D| B)
Ou dividindo por o: (A):)(

o(A | D ) p (D| A)
o ( A) = p(D | B )
46 Capítulo 5. Probabilidades e
Adesões
O termo à esquerda é a razão das probabilidades posteriores e anteriores.
O termo à direita é a razão de probabilidade, também chamado de fator
Bayes. .
Se o valor do fator Bayes for maior que 1, isso significa que os dados eram
mais prováveis abaixo de A do que abaixo de B. E como a razão de
chances também é maior que 1, isso significa que as chances são maiores, à
luz dos dados, do que eram antes.
Se o Bayes factor é menor que 1, isso significa que os dados eram menos prováveis sob
A do que abaixo de B,então as chances a favor de A vão para baixo.
Finalmente, se o fator Bayes é exatamente 1, os dados são igualmente
prováveis qualquer hipótese, de modo que as chances não mudam.
Agora podemos voltar ao problema de sangue do Oliver. Se Oliver é uma
das pessoas que deixaram sangue na cena do crime, então ele contabiliza a
amostra de 'O', então a probabilidade dos dados é apenas a probabilidade
de que um membro aleatório da população tenhasangue ty pe'AB', que é
de 1%.
Se Oliver não deixou sangue na cena do crime, então temos duas amostras
para explicar. for. Se escolhermos duas pessoas aleatórias da população,
qual é a chance de encontrar uma com tipo 'O' e outra com tipo 'AB'? Bem,
há duas maneiras de acontecer: a primeira pessoa que escolhemos pode ter
tipo 'O' e o segundo 'AB', ou o contrário. Assim, a probabilidade total é de
2(0,6)(0,01)= 1,2%.
A partedos dados é um pouco maior se Oliver não for uma das pessoas
que deixaram sangue na cena do crime, então os dados de sangue são
evidências contra a culpa de Oliver.
Este exemplo é um pouco inventado, mas é um exemplo do resultado
contra-intuitivo de que dados consistentes com uma hipótese não são
necessariamente a favor da hipótese.
Se esse resultado é tão contraintuitivo que te incomoda, essa forma de
pensar pode ajudar: os dados consistem em um evento comum, tipo 'O'
sangue, e um evento raro, digite sangue 'AB'. Se Oliver explica o evento
comum, isso deixa o raro evento ainda inexplicado. Se Oliver não
contabilizar o sangue 'O', então temos duas chances de encontrar alguém
na população com sangue 'AB'. E esse factor de dois faz a diferença.

5.4 Complementos
A operação fundamental das estatísticas bayesianas é a Atualização,que
toma uma distribuição prévia e um conjunto de dados, e produz uma
distribuição posterior.
5.4. Addends 47

Mas resolver problemas reais geralmente envolve uma série de outras


operações, incluindo dimensionamento, adição e outras operações
aritméticas, máx e min, e misturas.

Este capítulo apresenta adição e max; Apresentarei outras operações como


precisamos delas.

Oprimeiro exemplo é baseado em Dungeons & Dragons, um jogo deRPG


onde os resultados das decisões dos jogadores são geralmente
determinados por dados de rolagem. Na verdade, antes do jogo começar,
os jogadores geram cada atributo de seus personagens — força,
inteligência,sabedoria, destreza, constituição e carisma — rolando três
dados de seis lados e somando-os.

Então você pode estar curioso para saber a distribuição desta soma. Há
duas maneiras de calcular:

Simulação: Dado um PMF que representa a distribuição de um único


dado, você pode desenhar amostras aleatórias, adicioná-las e
acumular a destributação de somas simuladas.

Enumeração: Dado dois PMFs, você pode enumerar todos os pares


possíveis de val-ues e calcular aributação dist das somas.

thinkbayes fornece funções para ambos. Aqui está um exemplo do


primeiro ap-proach. Primeiro, vou definir uma classe para representar um
único dado como um PMF:
classe Die (thinkbayes. PMF):

Def __init__(self, sides):


thinkbayes.Pmf.__init__(self) for x
in xrange(1, sides+1):
Auto. Definir (x, 1) auto.
Normalizar()
Agora eu posso criar um dado de 6 lados:
d6 = Morrer(6)
E use thinkbayes. SampleSum para gerar uma amostra de 1000 rolos.
dados = [d6] * 3
três = thinkbayes. SampleSum (dados, 1000)
SampleSum leva lista de distribuições (objetos PMF ou Cdf) e o tamanho
sam-ple, n. Ele gera n somas aleatórias e retorna sua distribuição como um
objeto PMF.
48 Capítulo 5. Probabilidades e
Adesões
def SampleSum (dists,n):
pmf = MakePmfFromList(RandomSum(dists) para i in xrange(n))
return PMF
SampleSum usa RandomSum,também em thinkbayes.py::
def RandomSum(dists):
total = soma(dist.Random() para dist in dists) retorno
total
RandomSum invoca Random em cada distribuição e soma os resultados.

A desvantagem da simulação é que o resultado é apenas


aproximadamente correto. À medida que n fica maior, ele fica mais
preciso, mas é claro que o tempo de execução aumenta também.
A outra abordagem é enumerar todos os pares de valores e calcular a
soma e a probabilidade de cada par. Isso é implementado em PMF.__add__:
# classe PMF

Def __add__(self, other):


PMF = PMF()
para v1, p1 em si mesmo. Itens():
para v2, p2 em outro. Itens(): pmf. Incr
(v1+v2, p1*p2)
retorno pmf
auto é um PMF, é claro; outro pode ser um PMF ou qualquer outra coisa
que pro-vides Items. O resultado é um novo PMF. O tempo de execução
__add__ depende do número de itens em si mesmo e em outros;; it é
proporcional ao len(self)
* len (outro).
E é assim que é usado:
three_exact = d6 + d6 + d6
Quando você aplica o operador + a um PMF, python invoca __add__. Neste
exemplo, __add__ é invocado duas vezes.
A Figura 5.1 mostra um resultado aproximado gerado pela simulação e o
resultado exato computadopelaenumeração.
Pmf.__add__ baseia-se no pressuposto de que as seleções aleatórias de cada
PMF são independentes. No exemplo de rolar vários dados, este como-
sumption é muito bom. Em outros casos, teríamos que estender este
método para usar probabilidades condicional.
O código desta seção está disponível em http://thinkbayes.com/
dungeons.py. Para obter mais informações, consulte a Seção 0.3.
5.5. Maxima 49

0.14 Amostra
Exata
0.12

Probabilidade
0.10

0.08

0.06

0.04

0.02

0.00
2 4 68 8 10 12 14 16 18
Soma de três d6

Figura 5.1: Distribuições aproximadas e exatas para a soma de três dados


de seis lados.

5.5 Maxima
Quando você gera um personagem de Dungeons & Dragons, você está
particularmente interessado nos melhores atributos do personagem, então
você pode gostar de saber a distribuição do atributo máximo.
Existem três maneiras de calcular a distribuição de um máximo:

Simulação: Dada uma PMF que representa adistributiação para uma


única lecção se, você pode gerar amostras aleatórias, encontrar o
máximo e acumular a distribuição de maxima simulada.
Enumeração: Dado dois PMFs, você pode enumerar todos os pares
possíveis de val-ues e calcular a distribuição do máximo.
Exponenciação: Se convertermos um PMF em um Cdf, há um algoritmo
simples e eficiente para encontrar o Cdf do máximo.

O código para simular maxima é quase idêntico ao código para simular


somas:
def RandomMax(dists):
total = max(dist. Total de retorno aleatório() para dist
in dists)

def SampleMax(dists,n):
pmf = MakePmfFromList(RandomMax(dists) para i in xrange(n))
return PMF
50 Capítulo 5. Probabilidades e
Adesões

0.20

Probabilidade
0.15

0.10

0.05

0.00
2 4 68 8 10 12 14 16 18
Soma de três d6

Figura 5.2: Distribuição do máximo de seis rolos de três dados.

Tudo o que fiz foi substituir "soma" por "max". E o código para
enumeração é quase idêntico, também:
def PmfMax(pmf1, pmf2): res
= thinkbayes. PMF()
para v1, p1 em pmf1. Itens():
para v2, p2 em pmf2. Itens(): res. Incr (max(v1,
v2), p1*p2)
retornar res
Na verdade, você poderia generalizar esta função tomando o adequado
opera-tor como um parâmetro.

O único problema com este algoritmo é que se cada PMF tem valores m, o
tempo de execução é proporcional a m2. E se quisermos o máximo de
seleções k, leva tempo proporcional ao km2.

Se convertermos os PMFs em Cdfs, podemos fazer o mesmo cálculo muito


mais rápido! A chave é lembrar a definição da distribuição cumulativa:
tion:
CDF(xx) = p(X ≤ x)
onde X é uma variável aleatória que significa "um valor escolhido
aleatoriamente a partir desta distribuição". Assim, por exemplo, CDF(55) é
a probabilidade de que um valor dessa distribuição seja menor ou igual a
5.

Se eu tirar X de CDF1 e Y do CDF2, e calcular omáximo Z = max(X, Y),qual


é a chance deque Z seja menor ou igual a 5? Bem, nesse caso, tanto X
quanto Y devem ser menores ou iguais a 5.
Se as seleções de X e Y forem independentes,

CDF3(5) = CDF1(5)CDF2(5)

onde cdf3 é a distribuição de Z. Escolhi o valor 5 porque acho que torna as


fórmulas fáceis de ler, mas podemos generalizar por qualquer valor de z::

CDF3(z)= CDF1(z)CDF2((zz)

No caso especial em que desenhamos valores k da mesma distribuição,

CDFk(z)= CDF(1(zz)k

Então, para encontrar a distribuiçãosobre o máximo de valores k, podemos


enumerar as probabilidades no dado Cdf e elevá-los à potência kth. O CDF
fornece um método que faz exatamente isso:
# classe Cdf

def Max(self.k):
cdf = self. Cópia()
cdf.ps = [p**k para p em cdf.ps]
retorno cdf
Max pega o número de seleções, k, e retorna umnovo Cdf que repre- envia
a distribuição do máximo de seleções k. O tempo de execução deste
método é proporcional a m, o número deitens no Cdf.
PMF.Max faz a mesma coisa para pmfs. Tem que fazer um pouco mais de
trabalho para converter o PMF em um Cdf, então o tempo de execução é
proporcional ao m log m,mas isso ainda é melhor do que o quadrático.
Finalmente, aqui está um exemplo que calcula a distribuição do melhor
tributo de umpersonagem:
best_attr_cdf = three_exact. Max(6)
best_attr_pmf = best_attr_cdf. MakePMF()
Onde three_exact é definida na seção anterior. Se imprimirmos os re-sults,
vemos que a chance de gerar um personagem com pelo menos um tributo
de 18 é de3%. A Figura 5.2 mostra a distribuição.

5.6 Misturas
Vamos fazer mais um exemplo de Dungeons & Dragons. Suponha que eu
tenha uma caixa de dados com o seguinte inventário:
0.18

Mistura
0.16

0.14

Probabilidade
0.12

0.10

0.08

0.06

0.04

0.02

0.00
0 5 10 15 20 25
Resultado

Figura 5.3: Resultado da distribuição para dado aleatório de uma caixa.

5 4-sided Da
do
s
4 6 lados Da
do
s
3 8 lados Da
do
s
2 12 lados Da
do
s
1 20 lados M
orr
er
Eu escolho um dado da caixa e rolo-lo. Qual é a distribuição do out-come?
Se você sabe que morrer é, a resposta é fácil. Um dado com n lados rende
uma distribuição uniforme de 1 a n,incluindo ambos.

Mas se não sabemos que morrer é, a distribuição resultante é uma mistura


de distribuições uniformes com diferentes limites. Em geral, esse tipo de
mistura não se encaixa em nenhum modelo matemático simples,mas é
simples calcular a distribuição na forma de um PMF.
Como sempre, uma opção é simular o cenário, gerar um sam-ple aleatório
e calcular o PMF da amostra. Essa abordagem é simples e gera
umasolução aproximada rapidamente. Mas se queremos uma sodação
exata, precisamos de uma abordagem diferente.
Vamos começar com uma versão simples do problema onde há apenas
dois dados, um com 6 lados e outro com 8. Podemos fazer um PMF para
representar cada um dado:
d6 = Die(6)
d8 = Die(8)
Então criamos um PMF para representar a mistura:
mix = thinkbayes. PMF()
para morrer em [d6, d8]:
para o resultado, prob em morrer. Itens():
misture. Incr (resultado, prob)
Mistura. Normalizar()
O primeiro loop enumera os dados; o segundo enumera os resultados e
suas probabilidades. Dentro do loop, o PMF.Incr soma as contribuições das
duas distribuições.

Este código pressupõe que os dois dados são igualmente prováveis. Em


geral, precisamos saber a probabilidade de cada morte para que possamos
ponderar os resultados de acordo.

Primeiro criamos um PMF que mapeia de cada dado para a probabilidade de ser
selecionado:
pmf_dice = thinkbayes. pmf_dice. Conjunto
(Die(4), 5)
pmf_dice. Conjunto (Die(6), 4)
pmf_dice. Conjunto (Die(8), 3)
pmf_dice. Conjunto (Die(12), 2)
pmf_dice. Set(Die(20), 1) pmf_dice.
Normalizar()
Em seguida, precisamos de uma versão mais geral do algoritmo de mistura:
mix = thinkbayes. PMF()
para morrer, peso em pmf_dice. Itens():
para resultado, prob in die. Itens():
Mistura. Incr (resultado, peso*prob)
Agora cada dado tem um peso associado a ele (o que faz dele um dado
ponderado, suponho). Quando adicionamos cada resultado à mistura, sua
probabilidade é multiplicada por peso.

A Figura 5.3 mostra o resultado. Como esperado, os valores 1 ºáspero 4


são os mais prováveis porque qualquer dado pode produzi-los. Valores
acima de 12 são improváveis de ser- porque há apenas um dado na caixa
que pode produzi-los (e ele faz isso menos da metade do tempo).

thinkbayes fornece uma função chamada MakeMixture que encapsula este


algoritmo, para que pudéssemos ter escrito:
mix = thinkbayes. MakeMixture(pmf_dice)
Vamos usar MakeMixture novamente nos capítulos 7 e 8.
5.7 Discussão
Além da forma de probabilidades do teorema de Bayes, este capítulo não
é especificamente bayesiano. Mas a análise bayesiana é toda sobre
distribuições, por isso é importante entender bem o conceito de uma
distribuição. A partirde uma point computacional de visão, uma
distribuição é qualquer estrutura de dados que representa um conjunto de
valores (possíveis resultados de um processo aleatório) e suas
probabilidades.

Vimos duas representações de distribuições: PMFs e Cdfs. Essas


representações são equivalentes no sentido de que contêm a mesma infor-
mation, para que você possa converter de uma para a outra. A principal
diferença entre eles é o desempenho: algumas operações são mais rápidas
e fáceis com um PMF; outras são mais rápidas com um Cdf.

O outro objetivo deste capítulo é introduzir operações que atuam em


distri-butions, como PMF.__add__, Cdf.Max, e thinkbayes. MakeMistura.
Usaremos essas operações mais tarde, mas as apresento agora para
incentivá-lo a pensar em uma distribuição como uma unidade
fundamental de computação,, não apenas um con-tainer para valores e
probabilidades.
Capítulo 6

Análise de

Decisão

6.1 O problema preço é certo


Em 1 de novembro de 2007, concorrentes chamados Letia e Nathaniel
apareceram em The Price is Right, um game showamericano. show. Eles
competiram em um jogo chamado The Showcase, onde o objetivo é
adivinhar o preço de uma vitrine de prêmios. O competidor que chegar
mais perto do preço real da vitrine, sem passar por cima, ganha os
prêmios.
Nathaniel nósnt primeiro. Sua vitrine incluía uma lava-louças, um armário
de vinho, um computador portátil e um carro. Ele ofereceu $26.000.
A vitrine de Letia incluiu uma máquina de pinball, um jogo de fliperama,
uma mesa de sinuca e um cruzeiro pelas Bahamas. Ela ofereceu 21.500
dólares.
O preço real da vitrine de Nathaniel foi de $25.347. Seu lance era muito
alto, então ele perdeu.
O preço real da vitrine de Letia foi de $21.578. Ela só estava fora por US $
78, então ela ganhou sua exibição e, como seu lance foi fora por menos de
US $ 250, ela também ganhou a vitrine de Nathaniel.
Para um pensador bayesiano, este cenário sugere várias perguntas:

1. Antes de ver os prêmios, que crenças anteriores o participante deve


ter sobre o preço da vitrine?
2. Depois de ver os prêmios, como o concorrente deve atualizar esses
ser-liefs?
3. Com base na distribuição posterior, o que o concorrente deve oferecer?
56 Capítulo 6. Análise de
Decisões

0.05

vitrine 1
vitrine 2
0.04

0.03

Pdf
0.02

0.01

0.00
0 10000 20000 30000 40000 50000 60000 70000 80000
preço ($)

Figura 6.1: Distribuição de preços para vitrines no Preço é Certo,2011-12.

A terceira pergunta demonstra um uso comum da análise bayesiana:


análise de decisão. Dada uma distribuição posterior, podemos escolher o
lance que maximiza o retorno esperado do competidor.

Este problema é inspirado em um exemplo no livrode Cameron Davidson-


Pilon, Bayesian Methods for Hackers. O código que escrevi para este capítulo
é útil a partir de http://thinkbayes.com/price.py;ele lê arquivos de dados que
você pode baixar de http://thinkbayes.com/showcases.2011.csv e http:
thinkbayes.com/showcases.2012.csv. Para mais informações see Sec-tion
tion 0.3.

6.2 O anterior
Para escolher uma distribuição prévia dos preços, podemos aproveitar os
dados dos episódios anteriores. Felizmente, os fãs do show mantêm
registros detalhados. records. Quando me correspondi com o Sr.
Davidson-Pilon sobre seu livro, ele me enviou dados coletados por Steve
Gee em http://tpirsummaries.8m.com. Inclui o preço de cada vitrine das
temporadas de 2011 e 2012 e os lances oferecidos pelos concorrentes.

A Figura 6.1 mostra a distribuição dos preços dessas vitrines. O valor


mais comum para ambas as vitrines é de cerca de US $ 28.000, mas a
primeira vitrine tem um segundo modo perto de US $ 50.000, e a segunda
vitrine ocasionalmente vale mais de US $ 70.000.

Essas distribuições são baseadas em dados reais, mas foram suavizadas


6.3. Probability density functions 57

pela estimativa de densidade do kernel gaussiano (KDE). Antes de


continuarmos, quero fazer um desvio para falar sobre funções de
densidade de probabilidade e KDE.

6.3 Funções de densidade de probabilidade


Até agora temos trabalhado com funções de massa de probabilidade, ou
PMFs. Um PMF é um mapa de cada valor possível para sua
probabilidade. Na minha implemen-tation, um objeto PMF fornece um
método chamado Prob que pega um valor e retorna uma probabilidade,
também conhecida como massa de probabilidade..

Uma função de densidade de probabilidade , ou PDF, é a versão contínua


de um PMF, onde os valores possíveis compõem um intervalo contínuo
em vez de um conjunto discreto.

Na notação matemática, os PDFs são geralmente escritos como funções;


para exame-ple, aqui está o PDF de uma distribuição gaussiana com
média 0 e padrão
desvio 1:
1
F (x) = ➤ Exp(−− 2 x

/2) 2π
Para um determinado valor de xx, esta função calcula uma densidade de
probabilidade. Um den-sity é semelhante a uma massa de probabilidade
no sentido de que uma maior densidade indi- cates que um valor é mais
provável.

Mas uma densidade não é uma probabilidade. Uma densidade pode ser 0
ou qualquer valor de positive; não é limitada, como uma probabilidade,
entre 0 e 1.

Se você integrar uma densidade em um intervalo contínuo, o resultado é


uma probabilidade. Mas para as aplicações neste livro raramente temos
que fazer isso.

Em vez disso, usamos principalmente densidades de probabilidade como


parte de uma probabilidade func-tion. Veremos um exemplo em breve.

6.4 Representando PDFs


Para representar PDFs em Python, thinkbayes.py fornece uma classe
chamada Pdf. Pdf é um tipo abstrato,o que significa que ele define a
interface que um Pdf deveria ter, mas não fornece uma implementação
completa. A interface Pdf inclui dois métodos, Density e MakePmf:
classe Pdf (objeto):
58 Capítulo 6. Análise de
Decisões
def Density (self,x):
aumentar o Métodode NãoImplementadoException()

def MakePmf(self, xs):


PMF = PMF()
para x em xs:
Pmf. Definir(x, self. Densidade (x)) pmf.
Normalizar()
retorno pmf
A densidade leva um valor, x, e retorna adensidade correspondente. MakePmf
faz uma aproximação discreta ao PDF.
Pdf fornece uma implementação do MakePMF, mas não densidade, que tem
que ser fornecido por umaclasse infantil.
Um tipo concreto é uma classe infantil que estende um tipo abstrato e
fornece uma implementação dos etods m perdidos. Por exemplo, gaussianPdf
estende pdf e fornece densidade:
classe GaussianPdf(Pdf):

Def __init__(self, mu, sigma): self.mu


= mu
self.sigma = sigma

def Density (self,x):


retornar scipy.stats.norm.pdf(x, self.mu, self.sigma)
__init__ pega mu e sigma, que são a média e desvio padrão dadistribuição,
e armazena-os como atributos.
A densidade usa uma função de scipy.stats para avaliar o PDF gaussiano. A
função é chamada de norm.pdf porque a distribuição gaussiana também é
chamada de distribuição "normal".
O PDF gaussiano é definido por uma função matemática simples, por isso
é fácil de avaliar. E é útil porqueas quantidades masculinas no mundo real
têm distribuições que são aproximadamente gaussianas.
Mas com dados reais, não há garantia de que a distribuição seja gaussiana
ou qualquer outra função matemática simples. Nesse caso, podemos usar
uma amostra para estimar o PDF de toda a população.
Por exemplo, nos dados do Price Is Right, temos 313 preços para o
primeiro show-case. Podemos pensar nesses valores como uma amostra da
population de todos os preços possíveis deexibição.
6.4. Representing PDFs 59

Esta amostra inclui os seguintes valores (em ordem):

28800, 28868, 28941, 28957, 28958

Na amostra, não aparecem valores entre 28801 e 28867, mas não há razão
para pensar queesses valores são impossíveis. Com base em nossas
informações de fundo, esperamos que todos os valores nesta faixa sejam
igualmente prováveis. Em outras palavras, esperamos que o PDF seja
bastante suave.
A estimativa de densidade do kernel (KDE) é um algoritmo que pega uma
amostra efind um PDF adequadamente suave que se encaixa nos dados.
Você pode ler detalhes em
http://en.wikipedia.org/wiki/Kernel_density_estimation.

scipy fornece uma implementação do KDE e thinkbayes fornece uma classe


chamada EstimatedPdf que o usa:
classe EstimatedPdf(Pdf):

Def __init__(self, sample):


self.kde = scipy.stats.gaussian_kde(amostra)

def Density (self,x):


retorno self.kde.assess(x)
__init__ pega uma amostra e calcula uma estimativa de densidade do
kernel. O resultado é um objeto gaussian_kde que fornece um método de
avaliação.

Density pega um valor, chama gaussian_kde.avaliar, e retorna a densidade


resultante.
Finalmente, aqui está um esboço do código que usei para gerar a Figura 6.1:
preços = ReadData()
pdf = thinkbayes. EstimadoPdf(preços)

baixo, alto = 0, 75000


n = 101
xs = numpy.linspace (baixo, alto, n)
pmf = pdf. MakePmf(xs)
pdf é um objeto Pdf, estimado pelo KDE. PMF é um objeto PMF que se
aproxima do Pdf avaliando a densidade em uma seqüência de valores
igualmente espaçados.
linspace significa "espaço linear". Ele pega um intervalo, baixo e alto,e o
número de pontos, n, e retorna umanova matriz numpy com n n elementos
igualmente espaçados entre baixo e alto,incluindo ambos.
E agora de volta ao Preço é Certo..
60 Capítulo 6. Análise de
Decisões

1.0

jogador 1
player 2
0.8

0.6

Cdf

0.4

0.2

0.0
30000 20000 10000 0 10000 20000 30000 40000 50000
diff ($)

Figura 6.2: Distribuição cumulativa (CDF) da diferença entre o lance do


concorrente e o preço real.

6.5 Modelando os concorrentes


Os PDFs da Figura 6.1 estimam a distribuição dos possíveis preços. Se
você fosse um contestant no show, você poderia usar esta distribuição para
quan-tify sua crença anterior sobre o preço de cada vitrine (antes de ver os
prêmios).

Para atualizar esses antecedentes, temos que responder a essas perguntas:

1. Quais dados devemos considerar e como quantificá-lo?

2. Podemos calcular uma função de probabilidade; ou seja, para cada


valor hipotético de preço,, podemos calcular a probabilidade
condicional dos dados?

Para responder a essas perguntas, vou modelar o concorrente como um


instrumento de adivinhação de preço com características de erro
conhecidas. Em outras palavras, quando o participante vê os prêmios, ele
ou ela adivinha o preço de cada prêmio — idealmente sem levar
emconsideração o fato de que o prêmio faz parte de uma vitrine — e
aumenta os preços. Vamos chamar isso de palpitetotal.

Neste modelo, a pergunta que temos que responder é: "Se o preço real é
preço,qual é a probabilidade de que a estimativa do concorrenteseja
adivinhar?"?”

Ou se definirmos
erro = preço - adivinhe
6.5. Modeling the contestants 61

então poderíamos perguntar: "Qual é a probabilidade de que a estimativa


do concorrente esteja errada por erro?"?”

Para responder a essa pergunta, podemos usar os dados históricos


novamente. A Figura 6.2 mostra a distribuição cumulativa de diff,
adiferença entre o lance do con-testante e o preço real da vitrine.

A definição de diff é
diff = preço - lance

Quando diff é negativo, o lance é muito alto. À parte, podemos usar essa
distribuição para calcular a probabilidade de que os concorrentes superem
o lance: o primeiro concorrente supera 25% das vezes; o segundo
concorrente supera 29% das vezes.

Também podemos ver que os lancessão tendenciosos; ou seja, eles são


mais propensos a serem muito baixos do que muito altos. E isso faz
sentido, dadas as regras do jogo.

Finalmente, podemos usar esta distribuição para estimar a confiabilidade


dos palpites dos contes- tants. Este passo é um pouco complicado porquee
nós realmente não sabemos os palpites do concorrente; só sabemos o que
eles oferecem.

Então teremos que fazer algumas suposições. Especificamente, assumo


que a distribuição do erro é gaussiana com média 0 e a mesma variância
que diff.

A classe Player implementa este modelo:


classe Player (objeto):

Def __init__(self, prices, bids, diffs): self.pdf_price =


thinkbayes.EstimatedPdf(prices) self.cdf_diff =
thinkbayes.MakeCdfFromList(diffs)

mu = 0
sigma = numpy.std(diffs)
auto.pdf_error = thinkbayes. GaussianPdf(mu, sigma)
preços é uma seqüência de preços de vitrine, lances é uma seqüência de lances, e
diffs é uma seqüência de difusos, onde novamente diff = preço - lance.

pdf_price é o PDF suavizado dos preços, estimado pelo KDE. cdf_diff é a


distribuição cumulativa de diff, que vimosna Figura 6.2. E pdf_error é o PDF
que caracteriza a distribuição de erros; onde erro = preço - adivinhe.
62 Capítulo 6. Análise de
Decisões
Novamente, usamos a variância do diff para estimara variância do erro.
Esta estimativa não é perfeita porque os lances dos concorrentes às vezes
são estratégicos; por exemplo, se o Jogador 2 acha que o Jogador 1 tem
overbid, o Jogador 2 pode fazer um lance muito baixo. Nesse caso, diff não
reflete erro. Se este happens muito, a variância observada em diff pode
superestimar a variância no erro. No entanto, acho que é uma decisão
razoável de modelagem.

Como alternativa, alguém que se prepara para aparecer no programa


poderia estimar sua própria distribuição de erros assistindo programas
anteriores e registrando seus palpites e os preços reais.

6.6 Probabilidade
Agora estamos prontos para escrever a função de probabilidade. Como
sempre, defino uma nova classe que amplia os thinkbayes. Suíte:
Class Price (thinkbayes. Suíte):

Def __init__(self, pmf, player):


thinkbayes.Suite.__init__(self, pmf) self.player =
player
PMF representa a distribuição anterior e o jogador é um objeto Jogador
como de-sumido na seção anterior. Aqui está a probabilidade::
def Probabilidade (self, dados, hypo):
preço = hipo
palpite = dados

erro = preço - adivinhe


como = self.player.ErrorDensity (erro)

retornar como
hypo é o preço hipotético da vitrine. dados é o melhor palpite do
concorrente pelo preço. erro é a diferença, e como é a probabilidade dos
dados, dada a hipótese.

A densidade de erros é definida no Player::


# Jogador de classe:

def ErrorDensity (auto, erro):


retorno self.pdf_error. Densidade (erro)
6.7. Update 63

0.08

Antes
0.07
posterior

0.06

0.05

Pmf
0.04

0.03

0.02

0.01

0.00
0 10000 20000 30000 40000 50000 60000 70000 80000
preço ($)

Figura 6.3: Distribuições anteriores e posteriores para o Jogador 1, com


base em um melhor palpite de $20.000.

ErrorDensity funciona avaliando pdf_error no valor dado de erro. O


resultado é uma densidade de probabilidade, então não é realmente uma
probabilidade. Mas re-membro thna Likelihood não precisa calcular uma
probabilidade; ele só tem que calcular algo proporcional a uma
probabilidade. Enquanto a constante da proporcionalidade for a mesma
para todas as probabilidades, ela é cancelada quando normalizamos a
distribuição posterior.on.

E, portanto, uma densidade de probabilidade é uma probabilidade perfeitamente boa.

6.7 Atualização
O jogador fornece um método que leva o palpite do participante e calcula a
distribuição posterior:
# Jogador de classe

def MakeBeliefs(self, guess): pmf


= self. PMFPrice()
self.prior = Price(pmf, self) self.posterior =
self.prior.Copy()
self.posterior.Update(guess)
PmfPrice gera uma aproximação discreta ao PDF de preço, que usamos
para construir o anterior.

PmfPreço usa MakePmf, que avalia pdf_price em uma seqüência de valores:


64 Capítulo 6. Análise de
Decisões
# Jogador de classe

n = 101
price_xs = numpy.linspace (0, 75000, n)

def PmfPrice(self):
retorno self.pdf_price. MakePmf(self.price_xs)
Para construir o posterior, fazemos uma cópia do anterior e, emseguida,
invocamos Update, que invoca A Probabilidade para cada hipótese,
multiplica o pri-ors by asprobabilidades, e renormaliza.

the Então vamos voltar ao cenário original. Suponha que você é o Jogador
1 e quando você vê sua vitrine, seu melhor palpite é que o preço total dos
prêmios é de $20.000.

A Figura 6.3 mostra prioucrenças posteriores sobre o preço real. O


posterior é deslocado para a esquerda porque seu palpite está na
extremidade baixa do intervalo anterior.

Em um nível, este resultado faz sentido. O valor mais provável no anterior é


$27.750, seu melhor palpite é $20.000, e a média do posterior é algum-
onde no meio: $25.096.

Em outro nível, você pode achar este resultado bizarro, porque sugere que
se você acha que o preço é $20,000, então você deve acreditar que o preço é
$24.000.

Para resolver esse aparente paradoxo, lembre-se de que você está


combinando duas fontes de informação, dados históricos sobre vitrines
passadas e palpites sobre os prêmios que você vê.

Estamos tratando os dados históricos como os anteriores e atualizando-os


com base em seus palpites, but poderíamos usar equivalentemente seu
palpite como um anterior e atualizá-los com base em dados based on
historical históricos. guesses, bu

Se você pensar dessa forma, talvez seja menos surpreendente que o valor
mais provável na parte posterior não seja o seu palpite original.

6.8 Licitação ideal


Agora que temos uma distribuição posterior, podemos usá-la para
calcular o lance ideal, que defino como o lance que maximiza o retorno
esperado (ver http://en.wikipedia.org/wiki/Expected_return).
6.8. Optimal bidding 65

Vou apresentar os métodos nesta seção de cima para baixo, o que significa
que vou mostrar como eles são usados antes de mostrar como eles
funcionam. Se você vir um método desconhecido, não se preocupe; a
definição será em breve.
Para calcular os lances ideais, escrevi uma classe chamada
GainCalculator: class GainCalculator(object):

Def
__init__(self, player, opponent):
self.player = player self.opponent =
opponent
jogador e adversário são objetos do jogador.

GainCalculator fornece ExpectedGains, que calcula uma seqüência de lances e


o ganho esperado para cada lance:
def ExpectedGains (self, low=0, high=75000, n=101): bids =
numpy.linspace (baixo, alto, n)

ganhos = [eu. ExpectedGain(lance) para licitação] lances

de retorno, ganhos
baixo e alto especificam a gama de possíveis lances; n é o número de lances
para tentar.

ExpectedGains chama ExpectedGain, quecalcula o ganho esperado para um


determinado lance:
def ExpectedGain (self, bid): suite =
self.player.posterior total = 0
por preço, prob em classificado (suíte. Itens()):
ganho = auto. Ganho (lance, preço)
total += prob * retorno
de retorno total
O ExpectedGain loops through os valores na parte posterior e calcula o
ganho para cada lance, dado os preços reais da vitrine. Ele pondera cada
ganho com a probabilidade correspondente e retorna o total.
ExpectedGain invoca Gain, que leva uma oferta e um preço real e volta
oganho esperado:
def Gain (self, bid, price): se
lance > preço:
retorno 0
66 Capítulo 6. Análise de
Decisões
20000
Jogador 1
Jogador 2

ganho esperado ($)


15000

10000

5000

0
0 10000 20000 30000 40000 50000 60000 70000 80000
lance ($)

Figura 6.4: Ganho esperado versus lance em um cenário onde o melhor


palpite do Jogador 1 é $20.000 e o melhor palpite do Jogador 2 é $40.000.

diff = preço - lance


prob = self. ProbWin(diff)

se diff <= 250:


retorno 2 * preço * prob else:
preço de retorno * prob
Se você não quer, você não ganha nada. Caso contrário, calculamos a
diferença ser- interpolar seu lance e o preço, que determina a sua
probabilidade de ganhar- ning.

Se diff for menos de $250, você ganha ambas as vitrines. Para simplificar,
presumo que ambas as vitrines tenham o mesmo preço. Como esse
resultado é raro, não faz muita diferença.
Finalmente, temos que calcular a probabilidade de ganhar com base
em diff: def ProbWin(self, diff):
prob = (self.opponent.ProbOverbid() +
self.opponent.ProbWorseThan(diff))
retornar prob
Se seu oponente exagerar, você ganha. Caso contrário, você tem que
esperar que seu oponente esteja fora por mais do que dife. O jogador
fornece métodos para calcular ambas as probabilidades:
# Jogador de classe:
6.9. Discussion 67

def ProbOverbid(self):
retorno self.cdf_diff. Prob(-1)

def ProbWorseThan(self, diff):


retorno 1 - self.cdf_diff. Prob(diff)
Este código pode ser confuso porque a computação é agora doponto de
vista do oponente, que está calculando: "Qual é a probabilidade de eu ter
superado?" e "Qual é a probabilidade de meu lance estar fora por mais do
que dife?"?”
Ambas as respostas são baseadas no CDF da diff. Se a diferença do
oponente for menor ou igual a -1, você ganha. Se a diferença do oponente
for pior que a sua, você ganha. Caso contrário, você perde.
Finalmente, aqui está o código que calcula lances ideais:
# Jogador de classe:

def OptimalBid (self, guess, opponent): self. MakeBeliefs


(palpite)
calc = GainCalculator (self, opponent)
bids, gains = calc. Ganhos esperados()
ganho, lance = lance de retorno máximo
(zip(ganhos, lances))
Dado um palpite e um oponente, O OptimalBid calcula o distri-bution
posterior, instancia um GainCalculator,calcula os ganhos esperados para
uma série de lances e retorna o lance ideal e o ganho esperado. Ufa!
A Figura 6.4 mostra os resultados para ambos os jogadores, baseado em
um cenário onde o melhor palpite do Jogador 1 é $20.000 e o melhor
palpite do Jogador 2 é $40.000.
Para o Jogador 1, o lance ideal é de $21,000, gerando um retorno esperado de quase
16.700 dólares. Este é um caso (que acaba por ser incomum) onde o lance
ideal é realmente maior do que omelhor palpite do concorrente.
Para o Jogador 2, o lance ideal é de $31.500, gerando um retorno esperado de quase
19.400 dólares. Este é o caso mais típico em que o lance ideal é menor do
que o melhor palpite.

6.9 Discussão
Uma das características da estimativa bayesiana é que o resultado vem na
forma de uma distribuição posterior. Estimativa clássica geralmente gera
um
68 Capítulo 6. Análise de
Decisões
estimativa de ponto único ou um intervalo de confiança, o que é suficiente
se a estimativa fora última etapa do processo, mas se você quiser usar uma
estimativa como entrada para uma análise subseqüente, estimativas de
pontos e intervalos muitas vezes não ajudam muito.

Neste exemplo, usamos a distribuição posterior para calcular um lance


ideal. O retorno de uma determinada oferta é assimétrico e descontínuo
(se você pagar demais, você perde), então seria difícil resolver esse
problema analiticamente. Mas é relativamente simples de fazer
computacionalmente.

Os recém-chegados ao pensamento bayesiano são frequentemente


tentados a resumir o pos-terior distribution calculando a média ou a
probabilidade máxima es-timate. Estes resumos podem ser úteis, mas se
isso é tudo que você precisa, então você provavelmente não precisa de
métodos bayesianos em primeiro lugar.

Os métodos bayesianos são mais úteis quando você pode levar o distri-
bution posterior para o próximo passo da análise para realizar algum tipo
de análise de decisão, como fizemos neste capítulo, ou algum tipo de
previsão, como vemos no próximo capítulo.
Previsão do

Capítulo 7

7.1 O problema de Boston Bruins


Nas Finais da National Hockey League (NHL) de 2010-11, meu amado
Boston Bruins jogou uma série melhor de sete contra o desprezado
Vancouver Canucks. Boston perdeu os dois primeiros jogos 0-1 e 2-3,
depois venceu os dois jogos seguintes 8-1 e 4-0. At Neste point na série,
qual é a capacidade prob-que Boston vai ganhar o próximo jogo, e qual é a
sua probabilidade de ganhar o campeonato?

Como sempre, para responder a uma pergunta como essa, precisamos


fazer algumas críticas. Em primeiro lugar, é razoável acreditar que
marcargols no hóquei é pelo menos aproximadamente um processo de
Poisson, o que significa que é igualmente provável que um gol seja
marcado a qualquer momento durante um jogo. Em segundo lugar,
podemos supor que contra um determinado adversário, cada equipe tem
alguma média de gols por jogo, denotada λ.

Dadas essas suposições, minha estratégia para responder a esta pergunta é

1. Use estatísticas de jogos anteriores para escolher uma distribuição prévia para
λ.
2. Use a pontuação dos quatro primeiros jogos para estimar λ para cada equipe.

3. Use as distribuições posteriores de λ para calcular a distribuição de


gols para cada equipe, a distribuição do diferencial de gols e a proba-
bilidade que cada equipe ganha no próximo jogo.

4. Compute a probabilidade de que cada equipe ganhe a série.


70 Capítulo 7. Previsão

Para escolher uma distribuição prévia, recebi algumas estatísticas de


http://www.nhl. com, especificamente a média de gols por jogo para cada
equipe na temporada 2010-11. A distribuição é aproximadamente
gaussiana com média de 2,8 e desvio padrão 0,3.

A distribuição gaussiana é contínua, mas vamosaproximá-la de um


discreto PMF. thinkbayes fornece MakeGaussianPMF para fazer exatamente
isso:

def MakeGaussianPMF(mu, sigma, num_sigmas, n=101):


PMF = PMF()
baixo = mu - num_sigmas*sigma
alto = mu + num_sigmas*sigma

para x em numpy.linspace (baixo, alto, n):


p = scipy.stats.norm.pdf(x, mu, sigma) pmf.
Conjunto(x, p)
Pmf. Normalizar()
retorno pmf

mu e sigma são o desvio médio e padrão do distri-bution gaussiano.


num_sigmas é o número de desvios-padrão acima de umnd abaixo da
média que a PMF vai seestender, e n é o número de valores na PMF.

Novamente usamos numpy.linspace para fazer uma matriz de valores


igualmente espaçados entre baixo e alto,incluindo ambos.

norm.pdf avalia a função de densidade de probabilidade gaussiana (PDF).

Voltando ao problema do hóquei, aqui está a definição para uma suíte de


hy-potheses sobre o valor de λ.

classe Hóquei (thinkbayes. Suíte):

Def __init__(self):
pmf = thinkbayes. MakeGaussianPMF (2.7, 0.3, 4)
thinkbayes. Suite.__init__(self, pmf)

Assim, a distribuição anterior é gaussiana com média de 2,7, desvio padrão


0,3, e abrange 4 sigmas acima e abaixo da média.

Como sempre, temos que decide como representar cada hipótese; in neste
caso, represento a hipótese de que λ = x com o valor de ponto flutuante x.
7.2. Poisson processes 71

7.2 Processos de Poisson


Nas estatísticas matemáticas, um processo é um modelo estocástico de um
sys-tem físico ("estocástico" significa que o modelo tem algum tipo de
aleatoriedade nele). Por exemplo, um processo bernoulli é um modelo de
uma seqüência de eventos, chamado trials, em que cada ensaio tem dois
resultados possíveis, como sucedee fail-ure. Assim, um processo Bernoulli
é um modelo natural para uma série de lançamentos de moedas, ou uma
série de tiros no gol.
Um processo de Poisson é a versão contínua de um processo bernoulli,
onde um evento pode ocorrer a qualquer momento com igual
probabilidade. Os processos de Poisson podem ser usados para modelar
clientes que chegam em uma loja, ônibus chegando em um ponto de
ônibus ou gols marcados em um jogo de hóquei.
Em muitos sistemas reais, a probabilidade de um evento muda com o
tempo. Cus-tomers são mais propensos a ir a uma loja em determinadas
horas do dia, ônibus devem chegar em intervalos fixos, e os objetivos são
mais ou menos prováveis em momentos diferentes durante um jogo.
But todos os modelos são baseados em simplificações, e neste caso
modelar um jogo de hóquei com um processo poisson é uma escolha
razoável. Heuer, Müller e Rubner (2010) analisam a pontuação em uma
liga alemã de futebol e chegam à mesma conclusão; veja
http://www.cimat.mx/Eventos/vpec10/img/ poisson.pdf.

A vantagem de usar esse modelo é que podemos calcular a distribuição de


goals por jogo de forma eficiente, bem como a distribuição de tempo entre
metas. Especificamente, se a média de gols em um jogo for lam,, a
distribuição de gols por jogo é dada pelo PMF poisson:
def EvalPoissonPMF(k, lam):
retornar (lam)**k * math.exp(-lam) / math.factorial(k)
E a distribuição do tempo entre as metas é dada pelo PDF exponencial:

def EvalExponentialPdf(x, lam): return


lam * math.exp(-lam * x)
Eu uso a variável lam porque lambda é uma palavra-chave reservada em
Python. Ambas as funções estão em thinkbayes.py.

7.3 Os posteriores
Agora podemos calcular a probabilidade de que uma equipe com um
valor hipotético de lam marque k gols em um jogo:
72 Capítulo 7. Previsão

0.018

Bruins
0.016
Canucks
0.014

Probabilidade
0.012

0.010

0.008

0.006

0.004

0.002

0.000
1.5 2.0 2.5 3.0 3.5 4.0
Gols por jogo

Figura 7.1: Distribuição posterior do número de gols por jogo.

# classe Hóquei

def Probabilidade (self, data, hypo):


lam = hypo
k = dados
como = thinkbayes. Retorno de
EvalPoissonPMF(k, lam) como
Cada hipótese é um possível valor de λ;; dados são o número observado de
metas, k.
Com a função de probabilidade no lugar, podemos fazer uma suíte para
cada equipe e atualizá-los com as pontuações dos quatro primeiros jogos.
suite1 = Hóquei( bruins suite1. ' '

UpdateSet([0, 2, 8, 4])

suite2 = Hóquei( canucks suíte2. ' '

Conjunto de atualizaçãos ([1, 3,


1, 0])
A Figura 7.1 mostra as distribuições posteriores resultantes para lam. Com
base nos quatro primeiros jogos, os valores mais prováveis para lam são
2.6 para os Canucks e
2.9 para os Bruins.

7.4 A distribuição de metas


Para calcular a probabilidade de cada equipe ganhar o próximo jogo,
precisamos calcular a distribuição de gols para cada equipe.
7.4. The distribution of goals 73

0.25
Bruins
Canucks
0.20

Probabilidade
0.15

0.10

0.05

0.00
0 2 4 6 8 10
Objetivos

Figura 7.2: Distribuição de gols em um único jogo.

Se soubéssemos exatamente o valor de lam, poderíamos usar a distribuição


de Poisson novamente. thinkbayes fornece um método que calcula uma
aproximação truncada de uma distribuição poisson:
def MakePoissonPMF(lam, alta):
PMF = PMF()
para k em xrange (0, alto+1):
p = EvalPoissonPMF(k, lam) PMF.
Conjunto(k, p)
Pmf. Normalizar()
retorno pmf
A faixa de valores na PMF computada é de 0 a alta. Então, se o valor de
lam fosse exatamente 3.4, calcularíamos:
lam = 3,4
goal_dist = thinkbayes. MakePoissonPMF(lam, 10)
Eu escolhi o limite superior, 10, porque a probabilidade de marcar mais de
10 gols em um jogo é bastante baixa.

Isso é bastante simples até agora; o problema é que não sabemos o valor de
eu sou exatamente. Em vez disso, temosuma distribuição de possíveis valores para lam.

Para cada valor de lam,a distribuição das metas é de Poisson. Assim, a


distribuição global das metas é uma mistura dessas distribuições poisson,
ponderadas de acordo com as probabilidades na distribuição de lam.

Dada a distribuição posterior de lam,aqui está o código que faz a


destributação dos objetivos:
74 Capítulo 7. Previsão

0.0030

Bruins
Canucks
0.0025

Probabilidade
0.0020

0.0015

0.0010

0.0005

0.0000
0.0 0.5 1.0 1.5 2.0
Jogos até o gol

Figura 7.3: Distribuição do tempo entre as metas.

def MakeGoalPmf(suite):
metapmf = thinkbayes.
PMF()

para lam, prob na suíte. Itens():


pmf = thinkbayes. MakePoissonPMF(lam, 10)
metapmf. Set(pmf, prob)

mix = thinkbayes. MakeMixture (metapmf)


return mix
Para cada valor de lam fazemos um PMF poisson e adicionamos ao meta-
PMF. Eu chamo de meta-PMF porque é uma PMF que contém PMF como
seus valores.
Em seguida, usamos MakeMixture para calcular a mistura (vimos
MakeMixture na Seção 5.6).

A Figura 7.2 mostra a distribuição resultante de metas para os Bruins e


Canucks. Os Bruins são menos propensos a marcar 3 gols ou menos no
próximo jogo, e mais propensos a marcar 4 ou mais.

7.5 A probabilidade de ganhar


Para obter a probabilidade de ganhar, primeiro calculamosa distribuição
do diferencial de metas:
goal_dist1 = MakeGoalPMF(suite1)
goal_dist2 = MakeGoalPMF(suite2)
diff = goal_dist1 - goal_dist2
7.6. Sudden death 75

O operador de subtração invoca o Pmf.__sub__, que enumera pares de


valores e calcula a diferença. Subtrair duas distribuições é quase o mesmo
que adicionar, o que vimos na Seção 5.4.

Se o diferencial de gol for positivo, os Bruins vencem; se negativo, os


Canucks ganham; se 0, é um empate:
p_win = diff. ProbGreater(0)
p_loss = diff. ProbLess(0) p_tie
= diff. Prob(0)
Com as distribuições da seção anterior, p_win é de 46%, p_loss é de 37%, e
p_tie é de 17%.

Em caso de empate no final do "jogo de regulamento", as equipes jogam


períodos de prorrogação até que um time marque. Uma vez que o jogo
termina imediatamente quando o primeiro gol é marcado, este formato de
prorrogação é conhecido como "morte súbita".

7.6 Morte súbita


Para calcular a probabilidade de ganhar em uma prorrogação de morte
súbita, a estatística im-portant não é gols por jogo, mas tempo até o
primeiro gol. A suposição de que marcar gols é um processo de Poisson
implica que o tempo seja- tween gols é exponencialmentedtributed.
Dado lam,podemos calcular o tempo entre metas como esta:
lam = 3,4
time_dist = thinkbayes. MakeExponentialPMF(lam, high=2, n=101)
alta é o limite superior da distribuição. Nesse caso escolhi 2, pois a
probabilidade de ficar mais de dois jogos sem marcar é pequena. n é o
número de valores no PMF.

Se soubermos exatamente o lam, é só isso. Mas nós não; em vez disso, temos
uma distribuição posterior de valores possíveis. Assim como fizemos com
a destributação das metas, fazemos um meta-PMF e computamos uma
mistura de PMF.

def MakeGoalTimePmf(suite):
metapmf = thinkbayes.
PMF()

para lam, prob na suíte. Itens():


pmf = thinkbayes. MakeExponentialPMF (lam, high=2, n=2001) metapmf.
Set(pmf, prob)
76 Capítulo 7. Previsão

mix = thinkbayes. MakeMixture (metapmf)


return mix
A Figura 7.3 mostra as distribuições resultantes. Por valores de tempo
inferiores a um período (um terço de um jogo), os Bruins são mais
propensos a marcar. O tempo até a pontuação dos Canucks é mais
provável que seja maior.
Eu estaco o número de valores, n,, bastante alto, a fim de minimizar o
número de empates, já que não é possível para ambas as equipes marcar
simultaneamente.
Agora calculamos a probabilidade de que os Bruins marquem primeiro:
time_dist1 = MakeGoalTimePMF(suite1) time_dist2
= MakeGoalTimePMF(suite2)
p_overtime = thinkbayes. PMFProbLess(time_dist1, time_dist2)
Para os Bruins, a probabilidade de ganhar na prorrogação é de 52%.
Finalmente, a probabilidade total de ganhar é a chance de ganhar no final
do jogo regulamentar mais a probabilidade de ganhar na prorrogação.
p_tie = diff. Prob(0)
p_overtime = thinkbayes. PMFProbLess (time_dist1, time_dist2)

p_win = diff. ProbMaior(0) + p_tie * p_overtime


Para os Bruins, a chance geral de ganhar o próximo jogo é de 55%.
Para ganhar a série, os Bruins podem vencer os dois próximos jogos ou
dividir os dois próximos e ganhar o terceiro. Novamente, podemos
calcular a probabilidade total:
# ganhe os próximos
dois p_series =
p_win**2

# dividir os dois seguintes, ganhar o terceiro


p_series += 2 * p_win * (1-p_w)* p_win
A chance dos Bruins ganharem a série é de 57%. E em 2011, eles fizeram.

7.7 Discussão
Como sempre, a análise neste capítulo baseia-se nas decisões de
modelagem, e a modelagem é quase sempre um processo iterativo. Em
geral, você quer começar com algo simples que produz uma resposta
aproximada, identificar prováveis fontes de erro e procurar oportunidades
de melhoria.
Neste exemplo, eu consideraria estas opções:
7.7. Discussion 77

• Escolhi um antes com base na média de gols por jogo para cada time.
Mas essa estatística é média entre todos os oponentes. Contra um
oponente particu-lar, podemos esperar mais variabilidade. Por
exemplo, se o time com o melhor ataque joga coma pior defesa, os gols
esperados por jogo podem ser vários desvios padrão acima da
média.

• Para os dados eu usei apenas os quatro primeiros jogos da série do


campeonato. Se os mesmos times jogassem entre si durante a
temporada regular, eu poderia usar os resultados desses jogos também.
Uma complicação é que a composição das equipes muda durante a
temporada devido a trocas e lesões. Então talvez seja melhor dar
mais peso aos jogos recentes.

• Para aproveitar todas as informações disponíveis, poderíamosusar os


resultados de todos os jogos da temporada regular para estimar a taxa de
pontuação de cada equipe, possivelmente ajustada estimando um
fator adicional para cada par- wise match-up. Essa abordagem seria
mais complicada, mas ainda é viável.

Para a primeira opção, poderíamos usar os resultados da temporada


regular para esti-mate a variabilidade em todos os match-ups em pares.
Graças a Dirk Hoag no http://forechecker.blogspot.com/, consegui o n
umber de gols marcados duranteo jogo regulamentar (não prorrogação)
para cada jogo na temporada regular. season.

Equipes em conferências diferentes só jogam uma ou duas vezes na


temporada regular, então eu me concentrei em duplas que jogaram entre
si 4-6 vezes. Para cada pair, calculei a média de gols por jogo, que é uma
estimativa de λ,então plotei a distribuição dessas estimativas.

A média dessas estimativas é de 2,8, novamente, mas o desvio padrão é


0,85, substancialmente maior do que o que temos computando uma
estimativa para cada equipe.

Se executarmos a análise novamente com a maior variância anterior, a


probabilidade de que os Bruins ganhem a série é de 80%,
substancialmente maior do que o resultado com a baixa variância anterior,
57%.

Então acontece que os resultados são sensíveis ao anterior, o que faz


sentido considerando os poucos dados com os quais temos que trabalhar.
Com base na diferença entre o modelo de baixa variância e o modelo de
alta variável, parece que vale a pena se esforçar para acertar o anterior.
78 Capítulo 7. Previsão

O código e os dados deste capítulo estão disponíveis a partir de


http://thinkbayes. com/hockey.py e http://thinkbayes.com/hockey_data.csv.
Para obter mais informações, consulte a Seção 0.3.

7.8 Exercícios
Exercício 7.1. Se os ônibus chegarem a um ponto de ônibus a cada 20 minutos, e
você chegar ao ponto de ônibus em um horário aleatório, seu tempo de espera até
que o ônibus chegue é distribuído uniformemente de 0 a 20 minutos.

Mas, na realidade, há variabilidade no tempo entre os ônibus. Suponha que você


está esperando por um ônibus, e você sabe a distribuição histórica de tempo entre
ônibus. Calcule sua distribuição dos tempos de espera.

Dica: Suponha que o tempo entre os ônibus seja de 5 ou 10 minutos com igual
probabilidade. Qual é a probabilidade de você chegar durante um dos intervalos de
10 minutos?

Eu resolvo uma versão deste problema no próximo capítulo.


Exercício 7.2. Suponha que os passageiros que chegam ao ponto de ônibus sejam
bem modelados por um processo de Poisson com parâmetro λ. Se você chegar na
parada e encontrar 3 pessoas esperando, qual é a sua distribuição posterior para o
tempo desde que o último ônibus chegou.

Eu resolvo uma versão deste problema no próximo capítulo.


Exercício 7.3. Suponha que você seja um ecologista amostrando a população de
insetos em um novo ambiente. Você implanta 100 armadilhas em uma área de
teste e volta no dia seguinte para verificá-las. Você descobre que 37 armadilhas
foram acionadas, prendendo um inseto dentro. Uma vez que uma armadilha é
acionada, ela não pode prender outro inseto até que tenha sido reset.

Se você reiniciar as armadilhas e voltar em dois dias, quantas armadilhas você


espera encontrar desencadeadas? Calcule uma distribuição preditiva pós-erior
para o número de armadilhas.

Exercício 7.4. Suponha que você seja o gerente de um prédio de apartamentos


com 100 lâmpadas em áreas comuns. É sua responsabilidade substituir lâmpadas
quando elas quebram.

Em 1º de janeiro, todas as 100 lâmpadasestão funcionando. Quando você


inspecioná-los em 1 º de fevereiro, você encontra 3 lâmpadas fora. Se você voltar
em 1 º de abril, quantas lâmpadas você espera encontrar quebradas?

No exercício anterior, você poderia razoavelmente assumir que um evento é


igualmente provável a qualquer momento. Para lâmpadas, a probabilidade de
falha depende da idade do
7.8. Exercises 79

Bulbo. Especificamente, lâmpadas antigas têm uma taxa de falha crescente devido
à evaporação do filamento.

Este problema é mais aberto do que alguns; você terá que fazer modelagem de-
cisions. Você pode querer ler sobre a distribuição weibull (http: // en. wikipedia.
org/ wiki/ distribuição Weibull_ ). Ou você pode querer olhar em volta para
informações sobre curvas de sobrevivência de lâmpadas.
80 Capítulo 7. Previsão
Capítulo 8

Viés

observador

8.1 O problema da Linha Vermelha

Em Massachusetts, a Linha Vermelha é um metrô que liga Cambridge e


Boston. Quando eu estava trabalhando em Cambridge eu peguei a Linha
Vermelha de Kendall Square para South Station e peguei o trem para
Needham. Na hora do rush, os trens da Linha Vermelha funcionam a cada
7 a 8 minutos, em média.

Quando cheguei à estação, pude estimar a hora até o próximo trem com
base no número de passageiros na plataforma. Se houvesse apenas
algumas pessoas, eu inferi que perdi um trem e esperava esperar cerca de
7 minutos. Se houvesse mais passageiros, esperava que o trem chegasse
mais cedo. Mas se houvesse um grande número de passageiros, eu
suspeitava que os trens não estavam funcionando no horário, então eu
voltaria para o nível da rua e pegaria um táxi.

Enquanto esperava por trens, pensei em como a estimativa bayesiana


poderia ajudar a prever meu tempo de espera e decidir quando eu deveria
desistir e pegar um táxi. Este capítulo apresenta a análise que eu inventei.

Este capítulo é baseado em um projeto de Brendan Ritter e Kai Austin, que


tiveram uma aula comigo no Olin College. O código neste capítulo está
disponível em http://thinkbayes.com/redline.py. O código que usei para
coletar dados está em http://thinkbayes.com/redline_data.py. Para obter
mais informações, consulte a Seção 0.3.
82 Capítulo 8. Viés
observador

0.025
z zb

0.020

0.015

Cdf

0.010

0.005

0.000
0 5 10 15 20
Tempo (min)

Figura 8.1: PMF de lacunas entre trens, com base em dados coletados,
suavizado pelo KDE. z é a distribuição real; zb é a distribuição tendenciosa
vista pelos passageiros.

8.2 O modelo
Antes de chegarmos à análise, temos que tomar algumas decisões de
modelagem. Primeiro,trarei as chegadas de passageiros como um processo
de Poisson, o que significa que assumo que os passageiros são igualmente
propensos a chegar a qualquer momento, e que eles chegam a uma taxa
desconhecida, λ, medido empassageiros por minuto. Uma vez que
observo os passageiros durante um curto período de tempo, e ao mesmo
tempo todos os dias, assumo que λ é constante.

Por outro lado, o processo de chegada dos trens não é Poisson. Os trens
para Boston devem sair do final da linha (estação Alewife) a cada 7-8
minutos durante os horários de pico, mas quando chegam à Praça
Kendall, o tempo entre os trens varia entre 3 e 12 minutos.

Para coletar dados sobre o tempo entre os trens, escrevi um roteiro que
derrubadados em tempo real de
http://www.mbta.com/rider_tools/developers/, se- lects trens com destino
ao sul chegando na praça Kendall, e registra seus tempos de ar-rival em
um bancode dados. Eu corri o script das 16:00 às 18:00 todos os dias da
semana durante 5 dias, e registrei cerca de 15 chegadas por dia. Em
seguida, calculei o tempo entre chegadas consecutivas; a distribuição
dessas lacunas é mostrada na Figura 8.1, rotulada z.

Se você ficou na plataforma das16h às 18h e registrou a hora dos trens,


esta é a distribuição que você veria. Mas se você chegar em algum
momento aleatório (sem levar em conta o horário do trem) você veria um
distribuição diferente. O tempo médio entre os trens, como visto por um
passageiro ran-dom, é substancialmente maior do que a média real.

Porque? Porque um passageiro é mais como chegar durante um grande


intervalo do que um pequeno. Considere um exemplo simples: suponha
que o tempo entre os trens seja de 5 minutos ou 10 minutos com igual
probabilidade. Nesse caso, o tempo médio entre os trens é de 7,5 minutos.

Mas é mais provável que um passageiro chegue durante uma diferença de


10 minutos do que uma lacuna de 5 minutos; na verdade, duas vezes mais
provável. Se inspetermossemos os passageiros que chegavam,
descobriríamos que 2/3 deles chegaram durante um intervalo de 10
minutos, e apenas 1/3 durante um intervalo de 5 minutos. Assim, o tempo
deraiva entre os trens, como visto por um passageiro que chega, é de 8:33
minutos.

Esse tipo de viés observador aparece em muitos contextos. Os alunos


acham que as aulas são maiores do que são porque a maioria deles está
nas classes grandes. Os passageiros das companhias aéreas acham que os
aviões estão mais cheios do que são porque a maioria deles está em voos
completos.

Em cada caso, os valores da distribuição real são superamostrados em


proporção ao seu valor. No exemplo da Linha Vermelha, uma lacuna duas
vezes maior é duas vezes mais provável de ser observada.

Assim, dada a distribuição real de lacunas, podemos calcular a


distribuição de lacunas como visto pelos passageiros. BiasPMF faz essa
computação:

def BiasPMF(pmf):
new_pmf = PMF.
Cópia()

para x, p em PMF. Itens():


new_pmf. Mult (x, x)

new_pmf. Normalizar ()
retorno new_pmf

PMF é a distribuição real; new_pmf é a distribuição tendenciosa. Dentro do


loop, multiplicamos a probabilidade de cada valor, x,pela probabilidade
de ser observado, que é proporcional a x. Então normalizamos o resultado.

A Figura 8.1 mostra a distribuição real das lacunas, rotuladas z, e a


distribuição de lacunas observadas pelos passageiros, rotuladas zb para "z
tendenciosas".
1.0

Z
zb y
0.8

0.6

Cdf

0.4

0.2

0.0
0 5 10 15 20
Tempo (min)

Figura 8.2: CDF de z, zb, e o tempo de espera visto pelos passageiros, y.

8.3 Tempos de espera


O tempo de espera, que eu chamo de y,é o tempo entre a chegada de um
passageiro e a próxima chegada de umtrem. O tempo decorrido, que eu
chamo de x,é o tempo entre a chegada do trem anterior e a chegada de um
passageiro. I Escolhi essas definições para que zb = x + y.

Dada a distribuição de zb,podemos calcular a distribuição de y. Começarei


com um caso simples e depois generalizarei. Suponha, como no ex-amplo
anterior, que zb é ou 5 minutos com probabilidade 1/3, ou 10 minutos
com probabilidade 2/3.

Se chegarmos em um tempo aleatório durante um intervalo de 5 minutos,


y é uniforme de 0 a 5 minutos. Se chegarmos durante um intervalo de 10
minutos, y é uniforme de 0 a 10. Assim, a distribuição global é uma
mistura de distribuições uniformes ponderadas de acordo com a
probabilidade de cada lacuna.

A função a seguir toma a distribuição de zb e computa tele distri-bution de


y:
def PmfOfWaitTime(pmf_zb):
metapmf = thinkbayes. PMF()
para lacuna, prob em pmf_zb. Itens():
uniforme = MakeUniformPMF(0,
gap) metapmf. Conjunto (uniforme,
prob)

pmf_y = thinkbayes. MakeMix (metapmf)


retorno pmf_y
PMFOfWaitTime faz um meta-PMF que mapeia de cada distribuição
uniforme para sua probabilidade. Em seguida, ele usa MakeMixture, que
vimos em Sec-tion 5.6, para calcular a mistura.
PMFOfWaitTime também usa MakeUniformPMF, definido aqui:
def MakeUniformPMF (baixo,
alto): pmf = thinkbayes.
PMF()
para x em MakeRange (baixo=baixo, alto=alto):
pmf. Conjunto(x, 1)
Pmf. Normalizar()
retorno pmf
baixo e alto são a faixa da distribuição uniforme, (ambas as extremidades
em- cluded). Finalmente, makeuniformPMF usa MakeRange,defined aqui:
def MakeRange (baixo, alto, skip=10): faixa
de retorno (baixo, alto+skip, skip)
MakeRange define um conjunto de valores possíveis para o tempo de
espera (expresso em sec-onds). Por padrão, ele divide o intervalo em
intervalos de 10 segundos.

Para encapsular o processo deco-mputing dessas distribuições, criei uma


classe chamada WaitTimeCalculator:
classe WaitTimeCalculator (objeto):

Def __init__(self, pmf_z):


auto.pmf_z = pmf_z
auto.pmf_zb = BiasPMF(pmf)

auto.pmf_y = eu. PMFOfWaitTime(self.pmf_zb)


self.pmf_x = self.pmf_y
O parâmetro, pmf_z,é a distribuição imparcial de z. pmf_zb é a distribuição
tendenciosa do tempo de intervalo, como visto pelos passageiros.

pmf_y é a distribuição do tempo de espera. pmf_x é a distribution do


tempo decorrido, que é o mesmo que a distribuição do tempo de espera.
Para ver por que, remem-ber que para um valor particular de zp, a
distribuição de y é uniforme de 0 a zp. Também
x = zp - y

Assim, a distribuição de x também é uniforme de 0 a zp.

Afigura e 8.2 mostra a distribuição de z, zb, e y com base nos dados que
coletei no site da Linha Vermelha.
1.0

x anterior
0.8 posterior x pred y

0.6

Cdf

0.4

0.2

0.0
0 5 10 15 20
Tempo (min)

Figura 8.3: Prior e posterior de x e y previsto y.

Para apresentar essas distribuições, estou mudando de PMFs para Cdfs. A


maioria das pessoas está mais familiarizada com os PMFs, mas eu acho
que os Cdfs são mais fáceis de interpretar, uma vez que você se acostuma
com eles. E se você quiser traçar várias distribuições nos mesmos eixos,
Cdfs são o caminho a percorrer.
A média de z é de 7,8 minutos. A média de zb é 8,8 minutos, cerca de 13%
maior. A média de y é 4.4, metade da média de zb.
À parte, o cronograma da Linha Vermelha informa que os trens
funcionam a cada 9 minutos durante os horários depico. Isso é próximo da
média de zb,mas superior à média de z. Troquei e-mail com um
representante do MBTA, que confirmou que o tempo relatado entre os
trens é deliberadamente conservador para dar conta da variabilidade.

8.4 Prever wait vezes


Vamos voltar à pergunta motivadora: suponha que quando eu chegar na
plataforma eu vejo 10 pessoas esperando. Quanto tempo devo esperar até
o próximo trem chegar?
Como sempre, vamos começar com a versão mais fácil do problema e
trabalhar nosso caminho para cima. Suponha que nos seja dada a
distribuição real de z, e sabemos que a taxa de chegada dos passageiros, λ,
é de2 passageiros por minuto.
Nesse caso, podemos:
1. Use a distribuição de z para calcular a distribuição prévia de zp,o
tempo entre os trens visto por um passageiro.
8.4. Predicting wait times 87

2. Então podemos usar o número de passageiros para estimar a


distribuição de x, o tempodecorrido desde o último trem.

3. Finally, usamos a relação y = zp - x para obter a distribuição de y.

O primeiro passo é criar um WaitTimeCalculator que encapsula os distri-


butions de zp, xe y, antes de levar em conta o número depassen-gers.
wtc = WaitTimeCalculator(pmf_z)
pmf_z é a distribuição dada dos tempos de
intervalo.
O próximo passo é fazer um DecorridoTimeEstimator (definido abaixo), que
encapsula a distribuição posterior de x e a distribuição preditiva de y.
ete = DecorridoTimeEstimator (wtc,
lam=2,0/60,
num_passengers=15)
Os parâmetros são o WaitTimeCalculator,a taxa de chegada dos
passageiros, lam (expresso inpassageiros por segundo), e o número
observado de passen-gers, digamos 15.
Aqui está a definição de
DelapseedTimeEstimator: class
DelapsedTimeEstimator(objeto):

Def __init__(self, wtc, lam, num_passengers):


auto.prior_x = Decorridos (wtc.pmf_x)

self.post_x = self.prior_x.Copy()
self.post_x.Update((lam, num_passengers))

self.pmf_y = PredictWaitTime (wtc.pmf_zb, self.post_x)


prior_x e posterior_x são as distribuições prévias e posteriores do tempo
decorrido. pmf_y é a distribuição preditiva do tempo de espera.
DecorridoTimeEstimator usa Delapseed e PredictWaitTime,definido abaixo.

Decorrido é uma Suíte que representa a distribuição hipotética de x.


Adistribuição prior de x vem diretamente do WaitTimeCalculator. Em
seguida, usamos os dados, que consistem na taxa de chegada, lam, e o
número de passageiros na plataforma, para calcular a distribuição
posterior.
Aqui está a definição de Decorrido::
88 Capítulo 8. Viés
observador
classe Decorrido (thinkbayes. Suíte):

def Probabilidade (self, data, hypo): x


= hypo
lam, k = dados
como = thinkbayes. EvalPoissonPMF(k, lam * x)
retorno como
Como sempre, a Probabilidade pega uma hipótese e dados, e calcula a
responsabilidade semelhante dos dados sob a hipótese. In Neste caso, hipo
é o tempo decorrido desde o último trem e os dados são uma tupla de lam
e o número de passageiros.

A probabilidade dos dados é a probabilidade de obter k chegadas em x


tempo, dada a taxa de chegada lam. Calculamos que usando o PMF da
destributação de Poisson.

Finalmente, aqui está a definição de PredictWaitTime:


def PredictWaitTime(pmf_zb, pmf_x):
pmf_y = pmf_zb - pmf_x
RemoveNegatives(pmf_y)
return pmf_y
pmf_zb é a distribuição de lacunas entre os trens; pmf_x é a distribuição do
tempo decorrido, com base no número observado de passageiros. Desde y
= zb
-x, podemos calcular
pmf_y = pmf_zb - pmf_x
O operador de subtração invoca o PMF.__sub__, que enumera todos os
pares de zb e x,calcula as diferenças e adiciona os resultados a pmf_y.

A PMF resultante inclui alguns valores negativos, que sabemos que são
im- possíveis. Por exemplo, se você chegar durante um intervalo de 5
minutos, você não pode esperar mais de 5 minutos. RemoveNegatives
remove o valor impossível da distribuição e renormalizas.
def RemoveNegatives(pmf):
para val em pmf. Valores():
se val < 0:
Pmf. Remova (val) pmf.
Normalizar()
A Figura 8.3 mostra os resultados. A distribuição prévia de x é a mesma
da distribuição de y na Figura 8.2. A distribuição posterior de x mostra
que, depois de ver 15 passageiros na plataforma, acreditamos que o tempo
desde
1.0

Antes
posterior
0.8

0.6

Cdf
0.4

0.2

0.0
0 1 2 3 4 5
Taxa de chegada (passageiros / min)

Figura 8.4: Distribuições anteriores e posteriores de lam com base em cinco


dias de dados de passageiros.

o último trem é provavelmente 5-10 minutos. A distribuição preditiva de y


in-dicates que esperamos o próximo trem em menos de 5 minutos, com
cerca de 80% de confiança.

8.5 Estimando a taxa de chegada


A análise até agora foi baseada no pressuposto de que conhecemos (1) a
distribuição das lacunas e (2) a taxa de chegada dos passageiros. Agora
estamos prontos para relaxar a segunda suposição.

Suponha que você acabou de se mudar para Boston, então você não sabe
muito sobre a taxa de chegada de passeenger na Linha Vermelha. Depois
de alguns dias de deslocamento, você poderia fazer um palpite, pelo
menos qualitativamente. Com um pouco mais de esforço, você poderia
estimar λ quantitativamente.

Todos os dias, quando você chega à plataforma, você deve observar a hora
e o número de passageiros esperando (se a plataforma for muito grande,
você pode escolher uma área de amostra). Em seguida, você deve registrar
o seu tempo de espera e o número de recém-chegados enquanto você está
esperando.

Depois de cinco dias, você pode ter dados como este:

k1 Y k
-- -- 2
- -
-
17 4.6 9
22 1. 0
0
23 1. 4
4
18 5. 12
4
4 5. 11
8

onde k1 é o número de passageiros esperando quando você chega, y é o


seu tempo de espera em minutos, e k2 é o número de passageiros que
chegam enquanto você está esperando.
Ao longo de uma semana, você esperou 18 minutos e viu 36 passen-gers
chegar, então você estimaria que a taxa de chegada é de 2 passageiros por
minuto. Para fins práticos essa estimativa é boa o suficiente, mas por uma
questão de completude vou calcular uma distribuição posterior para λ e
mostrar como usar essa distribuição no resto da análise.
ArrivalRate é uma Suíte que representa hipóteses sobre λ. Como sempre, a
Probabilidade pega uma hipótese e dados, e calcula a probabilidade dos
dados ae hipótese.
Neste caso, a hipótese é um valor de λ. Os dados são um par, y, k,onde y
é um tempo de espera e k é o número de passageiros que chegaram.
classe ArrivalRate (thinkbayes. Suíte):

def Probabilidade (self, data, hypo):


lam = hypo
y, k = dados
como = thinkbayes. EvalPoissonPMF(k, lam * y)
retorno como
Essa probabilidade pode parecer familiar; é quase idêntica ao
Decorrido.Probabilidade na Seção 8.4. A diferençaé que em
Decorrido.Probabilidade a hipótese é x, otempo decorrido; em
ArrivalRate.Likelihood a hipótese é lam, a taxade chegada. Mas em ambos os
casos a probabilidade é a probabilidade de ver k chegadas em algum
período de tempo, dado lam.
ArrivalRateEstimator encapsula o processo de estimativa λ. O pa-
rameter, passenger_data, é uma lista de k1, y, k2 tuplas, como na tabela
acima.

classe ArrivalRateEstimator (objeto):

Def __init__(self, passenger_data):


baixo, alto = 0, 5
n = 51
8.6. Incorporando incerteza 91

1.0
Mistura

0.8

0.6

Cdf
0.4

0.2

0.0
0 2 4 6 8 10
Tempo de espera (min)

Figura 8.5: Distribuições preditivas de y para possíveis valores de lam.

hipos = numpy.linspace (baixo, alto, n) / 60

self.prior_lam = ArrivalRate(hypos) self.post_lam

= self.prior_lam. Cópia()
para k1, y, k2 em passenger_data: self.post_lam.
Atualização((y, k2))
__init__ constrói hipos, que é uma seqüência de valores hipotéticos para
lam, então constróia distribuição prévia, prior_lam. O loop for atualiza o
anterior com dados, produzindo o bution distri posterior, post_lam.

A Figura 8.4 apresenta as distribuições anteriores e posteriores. Como


esperado, a média e a mediana do posterior estão próximas da taxa
observada, 2 passageiros por minuto. Mas a propagação da distribuição
posterior captura nossa uncer-tainty sobre λ baseado em uma pequena
amostra.

8.6 Incorporando a incerteza


Sempre que houver incerteza sobre um dos insumos para uma análise,
podemos levá-lo em conta por um processo como este:

1. Implementar a análise com base em um valor determinístico do


parâmetro incerto (neste caso λ).

2. Calcule a distribuição do parâmetro incerto.


3. Execute a análise para cada valor do parâmetro e gere um conjunto
de distribuições preditivas.

4. Calcular uma mistura das distribuições preditivas, utilizando os


pesos da distribuição do parâmetro.
Já fizemos as etapas (1) e (2). Eu escrevi uma aula chamada
WaitMixEstimator para lidar com as etapas (3) e (4).
classe WaitMixtureEstimator (objeto):

Def __init__(self, wtc, are, num_passengers=15):


self.metapmf = thinkbayes. PMF()

para lam, prob em classificado (são.post_lam. Itens()):


ete = Estimador de Tempo Decorrido(wtc, lam, num_passengers)
self.metapmf.Set(ete.pmf_y, prob)

auto.mistura = thinkbayes. MakeMixture (self.metapmf)


wtc é o WaitTimeCalculator que contém a distribuição de zb. são é o
ArrivalTimeEstimator que contém a distribuição de lam.

A primeira linha faz um meta-PMF que mapeia de cada possível


distribuição de y para sua probabilidade. Para cada valor de lam,usamos O
DelapseedTimeEstimator para calcular a distribuição correspondente de y e
armazená-lo no Meta-PMF. Em seguida, usamos MakeMixture para
calcular a mistura.
A Figura 8.5 mostra os resultados. As linhas sombreadas no fundo são as
distribuições de y para cada valor de lam,com espessura de linha que
representaprobabilidade. A linha escura é a mistura dessas distribuições.
Neste caso, poderíamos obter um resultado muito semelhante using uma
estimativa de ponto único de lam. Portanto, não era necessário, para fins
práticos, incluir a uncer-tainty da estimativa.
Em geral, é importante incluir a variabilidade se a resposta do sistema não
for linear; ou seja, se pequenas alterações no input podem causar grandes
mudanças na saída. Neste caso, a variabilidade posterior no lam é pequena
e a resposta do sistema é aproximadamente linear para pequenas
perturbações.

8.7 Análise de decisões


Neste ponto podemos usar o número de passageiros na plataforma para
pré-ditaria a distribuição dos tempos de espera. Agora vamos para a
segunda parte do
8.7. Análise de 93
decisão

0.12

0.10

P(y > 15 min)


0.08

0.06

0.04

0.02

0.00
0 5 10 15 20 25 30 35
Passageiros num

Figura 8.6: Probabilidade de que o tempo de espera exceda 15 minutos em


função do número de passageiros na plataforma.

pergunta: quando devo parar de esperar pelo trem e ir pegar um táxi?


Lembre-se que no cenário original, estou tentando chegar à Estação Sul
para pegar o trem. Suponha que eu saia do escritório com tempo
suficiente para esperar 15 minutos e ainda fazer minha conexão na Estação
Sul.
Nesse caso, gostaria de saber a probabilidade de que y exceda 15 minutos
em função de num_passengers. É fácil usar a análise da Seção 8.4 e executá-
la por uma variedade de num_passengers.
Mas há um problema. A análise é sensível à frequência de delays longos, e
como longos atrasos são raros, é difícil estimar sua frequência.
Só tenho dados de uma semana, e o maior atraso que observei foi de 15
minutos. Então não posso estimar a frequência de atrasos mais longos com
precisão.
No entanto, posso usar observações anteriores para fazer pelo menos uma
estimativa grosseira. Quando eu comutei pela Linha Vermelha para um
ouvido y, eu vi três longos atrasos causados por um problema de
sinalização, uma queda de energia, e "atividade policial" em outra parada.
Então eu estimo que há cerca de 3 grandes atrasos por ano.
Mas lembre-se que minhas observações são tendenciosas. É mais provável
que observe longos atrasos porque afetam um grande número de
passageiros. Portanto, devemos tratar minhas observações como uma
amostra de zb em vez de z. É assim que podemos fazer isso.
Durante meu ano de deslocamento, levei a Linha Vermelha para casa
cerca de 220 vezes. Então eu tomo os tempos delacuna supressivas,
gap_times,gerar uma amostra de 220 lacunas, e calcular seu PMF:
n = 220
cdf_z = thinkbayes. MakeCdfFromList(gap_times)
sample_z = cdf_z.Sample(n)
pmf_z = thinkbayes. MakePmfFromList(sample_z)
Em seguida, eu viés pmf_z obter a distribuição de zb,desenhar uma
amostra, e, em seguida, adicionar em atrasos de 30, 40 e 50 minutos
(expresso em segundos):
cdf_zp = BiasPMF(pmf_z). MakeCdf()
sample_zb = cdf_zp. Amostra(n) + [1800, 2400, 3000]
Cdf.Sample é mais eficiente que PMF.Sample,por isso é geralmente mais
rápido para enganar um PMF para um Cdf antes da amostragem.

Em seguida, uso a amostra de zb para estimar um Pdf usando KDE e, em


seguida, converter o Pdf para um PMF:
pdf_zb = thinkbayes. EstimatedPdf(sample_zb)
xs = MakeRange (baixo=60)
pmf_zb = pdf_zb. MakePmf(xs)
Finalmente eu desviei a distribuição de zb para obter a distribuição de z,
que eu uso para criar o WaitTimeCalculator:
pmf_z = UnbiasPmf(pmf_zb)
wtc = WaitTimeCalculator(pmf_z)
Este processo é complicado, mas todas as etapas são operações que já
vimos antes. Agora estamos prontos para calcular a probabilidade de uma
longa espera.
def ProbLongWait(num_passengers, minutos):
ete = ElapsedTimeEstimator (wtc, lam, num_passengers) cdf_y
= ete.pmf_y.MakeCdf()
prob = 1 - cdf_y.Prob (minutos * 60)
Dado o número de passengers na plataforma, o ProbLongWait faz um
DelapseedTimeEstimator,extrai a distribuição do tempo de espera e coloca a
probabilidade de que o tempo de espera exceda minutos minutes.

A Figura 8.6 mostra o resultado. Quando o número de passageiros é


menor que 20, inferimos que o sistema está operando normalmente, então
a probabilidade de um longo atraso é pequena. Se houver 30 passageiros,
estimamos que já se passaram 15 minutos desde o último trem; isso é mais
longo do que um atraso normal, então infe infer que algo está errado e
esperar atrasos mais longos. that something is wrong and expect longer

Se estamos dispostos a aceitar 10% de chance de perder a conexão na


Estação Sul, devemos ficar e esperar enquanto houver menos de 30
passen-gers, e pegar um táxi se houver mais.
8.8. Discussion 95

e Ou, para levar essa análise adiante, poderíamos quantificar o custo de


perder a conexão e o custo de pegar um táxi, e então escolher o limite que
minimiza o custo esperado.

8.8 Discussão
A análise até agora foi baseada no pressuposto de que a taxa de chegada
dos passengersé a mesma todos os dias. day. Para um trem de passageiros
na hora do rush, isso pode não ser uma má suposição, mas há algumas
exceções óbvias. Por exemplo, se houver um evento especial por perto, um
grande número de pessoas pode chegar ao mesmo tempo. In Nesse caso, a
estimativa de lam seria muito baixa, então as estimativas de x e y seriam
muito altas.

Se eventos especiais são tão comuns quanto grandes atrasos, seria


importante incluí-los no modelo. Poderíamos fazer isso estendendo a
distribuição de lam para incluir valores ocasionais de grande porte.

Começamos com a suposição de que conhecemos a distribuição de z.


Como um alter-nativo, um passageiro poderia estimar z,mas não seria
fácil. Como um passen-ger, você só observir apenas o seu próprio
tempode espera, y. A menos que você pule o primeiro trem e espere pelo
segundo, você não observa a distância entre os trens, z.

No entanto, poderíamos fazer algumas inferências sobre zb. Se notarmos o


número de passageiros esperando quando chegarmos, podemos
estiacopdar o tempo decorrido desde o último trem, x. Então observamos
y. Se adicionarmos a dis-tributação posterior de x ao y observado, obtemos
uma distribuição que representa nossa crença posterior sobre o valor
observado de zb.

Podemos usar essa distribuição para aumentarnossascrenças sobre a


distribuição de zb. Finalmente, podemos calcular o inverso da BiasPMF
para passar da distribuição da zb para a distribuição de z.

Deixo essa análise como um exercício para o leitor. Uma sugestão: você
deve ler o Capítulo 15 primeiro. Você pode encontrar o esboço de uma
solução em http://thinkbayes.com/redline.py. Para obter mais informações,
consulte a Seção 0.3.

8.9 Exercícios
Exercício 8.1. Este exercício é de MacKay, Teoria da Informação, Inferência e
Algoritmos de Aprendizagem :
96 Capítulo 8. Viés
observador
Instável Partículas São Emitido De a Fonte E Decadência Em a
Distância X Um número real que tem uma distribuição de
probabilidade exponencial com [pa- rameter] λ. Eventos de
decaimento só podem ser observados se ocorrerem em um win-dow
estendendo-se a partir de x = 1 cm a x = 20 cm. N decaisão são
observadas em locais {1.5, 2, 3, 4, 5, 12} Cm. Qual é o distribuição
?
posterior de λ

Você pode baixar uma solução para este exercício a partir de http: //
thinkbayes. com/ decadência. py .
Capítulo 9

Duas dimensões

9.1 Paintball
Paintball é um esporte no qual equipes concorrentes tentam atirar umas
nas outras com armas que disparam balas cheias de tinta que quebram no
impacto, deixando uma marca colorida no alvo. Geralmente é jogado em
uma arena decorada com barreiras e outros objetos que podem ser usados
como cobertura.
Suponha que você está jogando paintball em uma arena interior 30 pés de
largura e 50 pés de comprimento. Você está perto de uma das paredes de
30 pés, e você suspeita que um de seus oponentes se cobriu nas
proximidades. Ao longo da parede, você vê vários patters de pintura,
todos da mesma cor, que você acha que seu oponente disparou
recentemente.
Os respingos estão a 15, 16, 18 e 21 pés, medidos a partir do canto inferior
esquerdo da sala. Com base nesses dados, onde você acha que seu
oponente está se escondendo?
A Figura 9.1 mostra um diagrama da arena. Usando o canto inferior
esquerdo da sala como origem, denoto a localização desconhecida do
atirador com coordenadas α e β,ou alfa e beta. A localização de um
respingo é rotulada
x. O umgle que o oponente atira é φ ou theta.

O problema do Paintball é uma versão modificada do problema do Farol,


um exemplo comum de análise bayesiana. Minha nota segue a
apresentação do problema em D.S. Sivia, Data Analysis: a Bayesian Tutorial,
Second Edition (Oxford, 2006).
Você pode baixar o código neste capítulo de http://thinkbayes.com/
paintball.py. Para obter mais informações, consulte a Sectiem 0.3.
98 Capítulo 9. Duas dimensões

shooter
β
θ

wall α x

Figura 9.1: Diagrama do layout para o problema do paintball.

9.2 A suíte
Para começar, precisamos de uma Suíte que represente um conjunto de
hipóteses sobre a localização do oponente. Cada hipótese é um par de
coordenadas: (alfa, beta).
Aqui está a definição da suíte Paintball:
classe Paintball (thinkbayes. Suíte, thinkbayes. Conjunto):

Def __init__(self, alphas, betas, locations):


self.locations = locations
pares = [(alfa, beta)
para alfa em alfas para
beta em betas]
thinkbayes. Suite.__init__(self, pares)
Paintball herda da Suite, que jávimos antes, e Joint, que explicarei em breve.

alfas é a lista de valores possíveis para alfa;; betas é a lista de valores para
beta. pares é uma lista de todos os pares (alfa, beta).

locais é uma lista de possíveis locais ao longo da parede; ele é armazenado para uso em
Probabilidade.

O quarto tem 30 pés de largura e 50 pés de comprimento, então aqui está o


código que cria a suíte:
alfas = alcance (0, 31)
9.3. Trigonometry 99

1.0

0.8

0.6

Prob
0.4

0.2

Alfa
Beta
0.0
0 10 20 30 40 50
Distância

Figura 9.2: CDFs posteriores para alfa e beta,dados os dados.

betas = intervalo (1, 51) locais


= intervalo (0, 31)

suíte = Paintball (alfas, betas, locais)

Esta distribuição prévia pressupõe que todos os locais da sala são


igualmente prováveis. Dado um mapa da sala, podemos escolher um
anterior mais detalhado, mas vamos começar simples.

9.3 Trigonometria
Agora precisamos de uma função de probabilidade, o que significa que
temos que descobrir a probabilidade de atingir qualquer ponto ao longo
da parede, dada a localização do oponente.

Como um modelo simples, imagine que o oponente é como uma torre


giratória, igualmente provável para atirar em umadireção ny. Nesse caso,
é mais provável que ele atinja a parede no local alfa, e menos provável que
atinja aparede longe do alfa.

Com um pouco de trigonometria, podemos calcular a probabilidade de


atingir qualquer ponto ao longo da parede. Imagine que o atirador dispara
um tiro no ângulo φ;; a pelota atingiria a parede no local x, onde

x − α = β tan φ
100 Capítulo 9. Duas dimensões

0.055

beta = 10
0.050 beta = 20
beta = 40
0.045

0.040

Prob 0.035

0.030

0.025

0.020

0.015

0.010
0 5 10 15 20 25 30
Distância

Figura 9.3: PMF de localização dada alfa=10, para vários valores de beta.

Resolvendo esta equação para φ yields


X−α
φ = Tan−1 . Σ
Β
Assim, dada a localização na parede, podemos encontrar φ.
Tomando a derivada da primeira equação em relação aos rendimentos φ
dx β
=
dθ cos2 θ
Este derivativo é o que eu vou chamar de "velocidade de strafing", que é a
velocidade do local de the destino ao longo da parede à medida que φ
aumenta. A probabilidade de acertar um determinado ponto na parede
está inversamente relacionada à velocidade de escoramento.

Se soubermos as coordenadas do atirador e um local ao longo da parede,


podemos calcular a velocidade de strafing:
def StrafingSpeed (alfa, beta, x): theta =
math.atan2(x - alfa, beta) speed =
beta / math.cos(theta)**2 velocidade de
retorno
alfa e beta são as coordenadas do atirador; x é a localização de um
respingos. O resultado é a derivada de x em relação a teta.

Agora podemos calcular um PMF que representa a probabilidade de


acertar qualquer lo-cation na parede. MakeLocationPMF pega alfa e apostaa,
ascoordenadas do atirador, e localizações, uma lista de possíveisvalores de
x.
9.4. Likelihood 101

def MakeLocationPMF(alfa, beta, localizações): pmf


= thinkbayes. PMF()
para x em locais:
prob = 1,0 / StrafingSpeed(alfa, beta, x) pmf.
Conjunto(x, prob)
Pmf. Normalizar()
retorno pmf

MakeLocationPMF calcula a probabilidade de atingir cada local, o que está


inversely relacionado à velocidade de strafing. O resultado é um PMF de
locais e suas probabilidades.

A Figura 9.3 mostra a PMF de localização com alfa = 10 e uma gama de


valores para beta. Para todos os valores de beta a localização mais
provável de respingos é x = 10; à medida que o beta aumenta, assim como
a propagação do PMF.

9.4 Probabilidade
Agora tudo o que precisamos é de uma função de probabilidade. Podemos
usar o MakeLocationPMF para calcular a probabilidade de qualquer valor
de x,dadas as coordenadas do oponente.
def Probabilidade (self, data, hypo): alfa,
beta = hypo
x = dados
pmf = MakeLocationPMF (alfa, beta, self.locations) como =
pmf. Prob(x)
retornar como

Novamente, alfa e beta são as coordenadas hipotéticas do atirador, e


x é a localização de um respingo observado.

PMF contém a probabilidade de cada local, dadas as coordenadas do


atirador. A partir deste PMF, selecionamos a probabilidade do local
observado.

E nósterminamos. Para atualizar o conjunto, podemos usar UpdateSet, queé


inher- ited from Suite.
Suite. Conjunto de atualizaçãos ([15, 16, 18, 21])

O resultado é uma distribuição que mapeia cada par (alfa, beta) para uma
probabilidade posterior. probability.
102 Capítulo 9. Duas dimensões

9.5 Distribuições conjuntas


Quando cada valor em uma distribuição é uma tupla de variáveis, é
chamada de distribuição conjunta porque representa as distribuições das
variáveis em conjunto, ou seja, "conjuntamente". Uma distribuição
conjunta contém as distribuições dos vari-ables, bem como informações
sobre as relações entre eles.

Dada uma distribuição conjunta, podemos calcular as distribuições de


cada variável de forma independente, que são chamadas de distribuições
marginais. .

thinkbayes. A Joint fornece um método que computa distribuições


marginais:
# classe Conjunta:

def Marginal(eu, i): pmf =


PMF()
para vs. prob em si mesmo.
Itens(): pmf. Incr(vs[i], prob)
retorno pmf
i é o índice da variável que queremos; neste exemplo i=0 indica a
distribuição de alfa, e i=1 indica a distribuição do beta.

Aqui está o código que extrai osíons distribut os marginais:


marginal_alpha = suíte. Marginal(0) marginal_beta
= suíte. Marginal(1)

A Figura 9.2 mostra os resultados (convertidos em CDFs). O valor médio


para alfa é 18, perto do centro da massa dos respingos observados. Para
beta, osvalores prováveis most estão perto da parede, mas além de 3
metros a distribuição é quase uniforme, o que indica que os dados não
distinguem fortemente entre esses possíveis locais.

Dado os marginais posteriores, podemos calcular intervalos críveis para


cada coordenada de forma independente:
imprimir alpha CI , marginal_alpha. CredibleInterval(50) print
' '

'beta CI , marginal_beta. Intervalo crível(50)


'

Os intervalos de 50% de credibilidade são (14, 21) para alfa e (5, 31) para
beta. Os dados fornecem evidências de que o atirador está no lado
próximo da sala. Mas não é uma evidência forte. Os intervalos de 90% de
credibilidade cobrem a maior parte da sala!
9.6. Conditional distributions 103

0.09

beta = 10
0.08 beta = 20
beta = 40
0.07

0.06

0.05

Prob
0.04

0.03

0.02

0.01

0.00
0 5 10 15 20 25 30
Distância

Figura 9.4: Distribuições posteriores para alfa condicionadas em vários


valores de beta.

9.6 Distribuições condicionais


As distribuições marginais contêm informações sobre as variáveis inde-
pendently, mas não captam a dependência entre variáveis, se houver.
Uma forma de visualizar a dependência é computando distribuições
condicionais.. thinkbayes. A Joint fornece um método que faz isso:
def Conditional(self, i, j, val): pmf =
PMF()
para vs. prob em si mesmo.
Itens(): se vs[j] != val:
continue pmf. Incr(vs[i],
prob)

Pmf. Normalizar()
retorno pmf
Mais uma vez, eu sou o índice da variável que queremos; j é o índice da
variável condi-tioning, e val é o valor condicional.
O resultado é a distribuição daiª variável a condição de que o
jth variável é val.
Por exemplo, o código a seguir calcula as distribuições condicionais de
alfa para uma gama de valores
de beta: betas = [10, 20, 40]
104 Capítulo 9. Duas dimensões

50

40

30 75

Beta
20

50

10

25

0
0 5 10 15 20 25 30
Alfa

Figura 9.5: Intervalos críveis para as coordenadas do oponente.

para beta em betas:


cond = suíte. Condicional(0, 1, beta)
A Figura 9.4 mostra os resultados, que poderíamos descrever como
"distribuições marginais condicionais posteriores". Ufa!

Se as variáveis fossem independentes, as distribuições condicionais seriam


todas iguais. Uma vez que eles são todos diferentes, podemos dizer que as
variáveis são depen-dent. Por exemplo, se soubermos (de alguma forma)
que beta = 10, a distribuição condicional do alfa é bastante estreita. Para
valores maiores de beta,a distri-bution de alfa é mais ampla.

9.7 Intervalos críveis


Outra forma de visualizar a distribuição posterior da articulação é calcular
os intervalos cred-ible. Quando olhamos para intervalos críveis na Seção
3.5, pulei um ponto sutil: para uma determinada distribuição, há muitos
intervalos com o mesmo nível de credibilidade. Para example, se você
quiser um inter-val 50% de credibilidade, você pode escolher qualquer
conjunto de valores cuja probabilidade soma até 50%.

Quando os valores são unidimensionais, é mais comum escolher o


intervalo credível cen-tral;porexemplo, o intervalo central de 50% de
credibilidade con-tains todos os valores entre os percentis 25 e 75.

Em múltiplas dimensões é menos óbvio qual deve ser o intervalo de


credibilidade certo. A melhor escolha pode depender do contexto, mas um
comum
9.7. Credible intervals 105

escolha é o intervalo de probabilidade máxima crível, que contém os


valores mais prováveis que somam até 50% (ou alguma outra
porcentagem).
thinkbayes. A Joint fornece um método que calcula intervalos de
probabilidade máxima de credibilidade.
# classe Conjunta:

def MaxLikeInterval (self, percentagem=90):


intervalo = []
total = 0

t = [(prob, val) para val, prob em si mesmo. Itens()] t.sort


(reverso=True)

para prob, val in t:


interval.append(val)
total += prob
se total >= porcentagem/100.0:
quebra

intervalo de retorno
O primeiro passo é fazer uma lista dos valores da suíte, classificados em
ordem decrescentepor probabilidade. Em seguida, atravessamos a lista,
adicionando cada valor ao intervalo, até que a probabilidade total exceda
a porcentagem. O resultado é uma lista de valores da suíte. Observe que
este conjunto de valores não é necessariamente contíguo.
Para visualizaros intervalos, escrevi uma função que "colore" cada valor
ac-cording para quantos intervalos ele aparece em:
def MakeCrediblePlot(suíte):
d = dict((par, 0) para par na suíte. Valores())

percentuais = [75, 50, 25] para


p em percentuais:
intervalo = suíte. MaxLikeInterval(p)
para par no intervalo:
d[par] += 1

d retorno
d é um dicionário que mapeia de cada valor na suíte para o número de
intervalos em que aparece. O loop calcula intervalos para várias
porcentagens e modifica d.
106 Capítulo 9. Duas dimensões

A Figura 9.5 mostra o resultado. O intervalo de 25% de credibilidade é a


região mais escura perto da parede inferior. Para percentuais mais
elevados, o intervalo de credibilidade é maior, é claro, e desviado para o
lado direito do room.

9.8 Discussão
Este capítulo mostra que a estrutura bayesiana dos capítulos anteriores
pode ser estendida para lidar com um espaço de parâmetrobidimensional.
A única diferença é que cada hipótese é representada por uma tupla de
parâmetros.

Também apresentei joint, que é uma classe dos pais que fornece
metanfetamina-ods que se aplicam a distribuições articulares: Marginal,
Condicionale MakeLikeInterval. Em termos orientados a objetos, Joint é uma
mixin (veja http:
en.wikipedia.org/wiki/Mixin).

Há um monte de vocabulário novo neste capítulo, então vamos rever:

Distribuição conjunta: Uma distribuição que representa todos os valores


possíveis em umespaço onal multidimensi e suasprobabilidades. O
exemplo neste capítulo é um espaço bidimensional composto pelas
coordenadas alfa e beta. A distribuição conjunta representa a
probabilidade de cadapar(alfa, beta).) pair.

Distribuição marginal: A distribuição doparâmetro one em distri-bution


articular, tratando os outros parâmetros como desconhecidos. Por
exemplo, fig-ure 9.2 mostra as distribuições de alfa e beta
independentemente.

Distribuição condicional: A distribuição de um parâmetro em


destributação conjunta, condicionada a um ou mais dos outros
parâmetros. Fig-ure 9.4 várias distribuições para alfa,, condicionadas
em diferentes valores de beta.

Dada a distribuição conjunta, você pode calcular destribuções marginais e


condicionais. Com distribuições condicionais suficientes, você poderia
recriar a distribuição conjunta, pelo menos aproximadamente. Mas dadas
as distribuições marginais, você não pode recriar a distribuição conjunta
porque você perdeu a inação sobre a dependência entre variáveis.

Se não houver valores possíveis para cada um dos dois parâmetros, a


maioria das operações na distribuição conjunta leva tempo proporcional a
n2. Se houver parâmetros d, o tempo de execução é proporcional a nd, o
que rapidamente se torna impraticável à medida que o número de
dimensões aumenta.
9.9. Exercises 107

Se você pode processar um milhão de hipóteses em um período razoável


de tempo, você poderia lidar com duas dimensões com 1000 valores para
cada parâmetro, ou três dimensões com 100 valores cada, ou seis
dimensões com 10 valores cada um.

Se você precisa de mais dimensões, ou mais valores por dimensão,


sãotimizações op que você pode tentar. Apresento um exemplo no
Capítulo 15.

Você pode baixar o código neste capítulo de http://thinkbayes.com/


paintball.py. Para obter mais informações, consulte a Seção 0.3.

9.9 Exercícios
Exercício 9.1. Em nosso modelo simples, o oponente é igualmente provável para
atirar em qualquer direção. Como exercício, vamos considerar melhorias neste
modelo.

A análise deste capítulo sugere que um atirador é mais provável que atinja a
parede mais próxima. Mas, na realidade, se opônei está perto de uma parede, é
improvável que ele atire na parede porque é improvável que ele veja um alvo entre
ele e a parede.

Projete um modelo melhorado que leve em conta esse comportamento. Tente


encontrar um modelo que seja mais realista, mas não muito complicated.
108 Capítulo 9. Duas dimensões
Capítulo 10

Computação bayesiana
aproximada

10.1 A Hipótese de Variabilidade


Eu tenho um ponto fraco para a ciência da manivela. Recentemente visitei
a Torre Norumbega, que é um monumento duradouro às teorias malucas
de Eben Norton Horsford, inventor do fermento em pó de dupla ação e da
história falsa. Mas não é disso que se trata este capítulo.
Tseu capítulo é sobre a Hipótese de Variabilidade, que

"originou-se no início do século XIX com Johann Meckel, que


argumentou que os machos têm uma maior gama de
habilidades do que os machos, especialmente na inteligência.
Em outras palavras, ele acreditava que a maioria doseniuses e a
maioria das pessoas mentalmente são homens. most g Porque
ele considerava os machos como o "animal superior", Meckel
concluiu que a falta de variação das fêmeas era um sinal de
inferioridade."
De http://en.wikipedia.org/wiki/Variability_
hipótese..

Eu particularmente gosto dessa última parte, porque suspeito que se as


mulheres forem realmente mais variáveis, Meckel tomaria isso como um
sinal de ferioridade, também. De qualquer forma, você não ficará surpreso
ao ouvir que a evidência para a Hipótese de Variabilidade é fraca.
No entanto, surgiu na minha classe recentemente quando olhamos para os
dados do Sistema de Vigilância de Fatores de Risco Comportamental
(BRFSS) do CDC, especificamente
110 Capítulo 10. Computação bayesiana aproximada

as alturas autorreferidas de homens e mulheres americanos adultos. O


conjunto de dados inclui respostas de 154407 homens e 254722 mulheres.
Eis o que encontramos:

• A altura média para os homens é de 178 cm; a altura média para as


mulheres é de 163 cm. Então os homens são mais altos, em média.
Não é surpresa.
• Para os homens, o desvio padrão é de 7,7 cm; para as mulheres é de
7,3 cm. Assim, em termos absolutos, as alturas dos homens são mais
variáveis.
• Mas para comparar a variabilidade entre os grupos, é mais
significativo utilizar o coeficiente de variação (CV), que é o desvio
padrão dividido pela média. É uma medida adimensional de
variabilidade rela-tive para escalar. Para homens cv é 0,0433; para as
mulheres é 0,0444.

Isso é muito próximo, então podemos concluir que este conjunto de dados
fornece uma fraca idence contra a Hipótese de Variabilidade. Mas
podemos usar metanfetamina bayesiana para tornar essa conclusão
maisprecisa. E responder a essa pergunta me dá a chance de demonstrar
algumas técnicas para trabalhar com grandes conjuntos de dados.
Eu vou prosseguir em alguns passos:

1. Começaremos com a implementação mais simples, mas ela só


funciona para conjuntos de dados menores que 1000 valores.
2. Calculando probabilidades uma transformação de log, podemos
escalar até o tamanho total do conjunto de dados, mas a computação
fica lenta.
3. Finalmente, aceleramosas coisas com a Computação Bayesiana
Aproximada, também conhecida como ABC. ubstantially with
Approximate

Você pode baixar o código neste capítulo de http://thinkbayes.com/


variability.py. Para obter mais informações, consulte a Seção 0.3.

10.2 Desvio médio e padrão


No capítulo 9 estimamos dois parâmetros simultaneamente usando uma
destributação conjunta. Neste capítulo utilizamos o mesmo método para
estimar os param-eters de uma distribuição gaussiana: a média, mu, e
odesvio padrão, sigma.
Para este problema, eu defino uma Suíte chamada Height que representa
um mapa de cada mu, par sigma para its probabilidade:
10.2. Mean and standard deviation 111

classe Height (thinkbayes. Suíte, thinkbayes. Conjunto):

Def
__init__(eu, mus, sigmas): pares =
[(mu, sigma)
para mu em mus
para sigma em sigmas]

thinkbayes. Suite.__init__(self, pares)


mus é uma seqüência de valores possíveis para mu;; sigmas é uma
seqüência de valores para sigma. A distribuição prévia é uniforme sobre
todos os pares mu, sigma. pairs.
A função de probabilidade é fácil. Dado os valores hipotéticos de mu e
sigma,calculamos a probabilidade de um determinado valor, x. Isso é o que
o EvalGaussianPdf faz, então tudo o que temos que fazer é usá-lo::
# classe Altura

def Probabilidade (self, data, hypo): x


= dados
mu, sigma = hypo
como = thinkbayes. Retorno de EvalGaussianPdf(x, mu,
sigma) como
Se você estudou estatísticas de uma perspectiva matemática, você sabe
que quando você avalia um PDF, você tem uma densidade de capacidade
proba.bility In Para obter uma probabilidade, você tem que integrar
densidades de probabilidade em algum intervalo.
Mas para nossos propósitos, não precisamos de uma probabilidade; só
precisamos de algo proporcional à probabilidade que queremos. Uma
densidade de probabilidade faz esse trabalho muito bem.
A parte mais difícil deste problema acaba por ser a escolha de faixas
apropriadas para mus e sigmas. Se o alcance é muito pequeno, omitimos
algumas possibilidades com probabilidade não desprezível e obtemos a
resposta errada. Se o alcance é muito grande, temos a resposta certa, mas
desperdiça o poder computacional.
Portanto, esta é uma oportunidade de usar a estimativa clássica para
tornar a tecnologia bayesiana mais eficiente. Especificamente, podemos
usar estimadores clássicos para encontrar um local provável para mu e
sigma, e usar os erros detandard desses esti-mates para escolher um
spread provável. , and use the s
Se os parâmetros verdadeiros da distribuição forem μ e σ,e tirarmos uma
amostra de n valores, um estimador de μ é a média amostral, m.
E um estimador de σ é a variância padrão da amostra, s.
112 Capítulo 10. Computação bayesiana aproximada

The standard error
√ of the estimated µ is s/ n and the standard error of
the estimated σ is s/ 2(n − 1).
Aqui está o código para calcular tudo isso:
def FindPriorRanges(xs, num_points, num_stderrs=3.0):

# computação m e s
n = len(xs)
m=
numpy.mean(xs) s =
numpy.std(xs)

# faixas de computação para m e s


stderr_m = s / math.sqrt(n)
mus = MakeRange(m, stderr_m, num_stderrs)

stderr_s = s / math.sqrt(2 * (n-1))


sigmas = MakeRange(s, stderr_s, num_stderrs)

retorno mus, sigmas


xs é o conjunto de dados. num_points é o número desejado de valores na
faixa. num_stderrs é a largura do range em cada lado daestimativa, em
num-ber de erros padrão.
O valor de retorno é um par de seqüências, mus e
sigmas. Aqui está MakeRange::
def MakeRange (estimativa, stderr, num_stderrs):
spread = stderr * num_stderrs
matriz = numpy.linspace (estimativa-spread,
estimate+spread,
num_points)
matriz de retorno
numpy.linspace faz uma matriz de elementos igualmente espaçados entre
estimativa-spread e estimativa+spread,incluindo ambos.

10.3 Atualização
Finalmente aqui está o código para fazer e atualizar a suíte:
mus, sigmas = FindPriorRanges (xs, num_points) suite
= Altura(mus, sigmas)
10.4. The posterior distribution of CV 113

Suite. Conjunto de atualização(xs)


suíte de impressão. Máxima Probabilidade()
Esse processo pode parecer falso, porque usamos os dados para escolher o
intervalo da distribuição anterior e, em seguida, usamos os dados
novamente para fazer a atualização. Em geral, usar os mesmos dados duas
vezes é, de fato, falso.

Mas neste caso está tudo bem. A sério. Usamos os dados para escolher o
intervalo para o anterior, mas apenas para evitar calcular um monte de
pressobabilities que teria sido muito pequeno de qualquer maneira. Com
num_stderrs=4,o intervalo é grande o suficiente para cobrir todos os valores
com probabilidade não desprezível. Depois disso, torná-lo maior não tem
efeito sobre os resultados.

Na verdade, o anterior é uniforme sobre todos os valores de mu e


sigma,mas para a eficiência com-putational ignoramos todos os valores
que não importam.

10.4 A distribuição posterior do CV


Uma vez que tenhamos a distribuição articular posterior de mu e
sigma,podemos com- pute adistribuição de CV para homens e mulheres, e
então a probabilidade de que um exceda o outro.
Para calcular a distribuição de CV, enumeramos pares de mu e sigma:
def CoefVariation(suite):
pmf = thinkbayes. PMF()
para (mu, sigma), p na suíte. Itens(): pmf. Incr
(sigma/mu, p)
retorno pmf
Então usamos thinkbayes. PMFProbMaior para calcular a probabilidade de
que os homens são mais variáveis.

A análise em si é simples, mas há mais duas questões que temos que lidar:

1. À medida que o tamanho do conjunto de dados aumenta, nos


deparamos com uma série de problemas computacionais devido às
limitações da aritmética de ponto flutuante.

2. O conjunto de dados contém uma série de valores extremos que são


quase erros cer-tainly. Precisaremos tornar o processo de estimativa
robusto na presença desses outliers.

As seções a seguir explicam esses problemas e suas soluções.


114 Capítulo 10. Computação bayesiana aproximada

10.5 Underflow
Se selecionarmos os primeiros 100 valores do conjunto de dados BRFSS e
executarmos a análise que acabei de descrever, ele roda sem erros e temos
distribuições posteriores que parecem razoáveis.
Se selecionarmos os primeiros 1000 valores e executarmos o programa
novamente, teremos um erro em PMF.Normalize::
ValueError: a probabilidade total é zero.
O problema é que estamos usando densidades de probabilidade para
calcular likeli-hoods, e densidades de distribuições contínuas tendem a ser
pequenas. E se você pegar 1000 pequenos valores e multiplicá-los
together, o resultado é muito pequeno. Neste caso, é tão pequeno que não
pode ser representado por um número de ponto flutuante, por isso é
arredondado para zero, que é chamado de subfluxo. E se todas as
probabilidades na distribuição são 0, não é mais uma distribuição.
Uma solução possível é renormalizar o PMF após cada atualização, ou
após cada lote de 100. Isso funcionaria, mas seria lento.
Uma alternativa melhor é calcular as probabilidades uma transformação
de tronco. Dessa forma, em vez de multiplicar pequenos valores, podemos
somar probabilidades de log. Pmf fornece métodos Log, LogUpdateSet e Exp
para facilitar esse processo.

Log calcula o registro das bilidades de probaem um PMF:


# classe PMF

def Log(self):
m = self. MaxLike()
para x, p em self.d.iteritems(): se p:
Auto. Definir(x,
math.log(p/m)) mais:
Auto. Remover(x)
Antes de aplicar o log transform Log usa MaxLike para encontrar m, a
maior probabilidadeno PMF. Ele divide todas as probabilidades por m,de
modo que a maior proba-bility fica normalizada para 1, o que produz um
log de 0. As outras probabilidades de registro são todas negativas. Se
houver algum valor na PMF com probabilidade 0, eles são removidos.
Enquanto o PMF estiver uma transformação de log, não podemos usar
UpdateUpdate, UpdateSetou Normalize. O resultado seria absurdo; se você
tentar, PMF levanta uma exceção. Em vez disso, temos que usar logupdate
e logupdateset.
10.6. Log-likelihood 115

Aqui está a implementação do LogUpdateSet:


# Suíte de classe

def LogUpdateSet (self, dataset): para


dados no conjunto de dados:
Auto. LogUpdate (dados)
LogUpdateSet faz loops através dos dados e chama
LogUpdate: # class Suite

def LogUpdate (self, data):


para hipo em si mesmo. Valores():
como = eu. LogLikelihood (dados, hypo) self.
Incr(hipo, como)
LogUpdate é como atualização, exceto que ele chama LogLikelihood em vez de
Likelihood, e Incr em vez de Mult.

O uso de probabilidades de log evita o problema com o fluxo de fluxo, mas


enquanto o PMF está a transformação do tronco, não há muito que
possamos fazer com ele. Temos que usar a Exp para inverter a
transformação:
# classe PMF

def Exp(self):
m = self. MaxLike()
para x, p em self.d.iteritems(): self.
Conjunto(x, math.exp(p-m))
Se as probabilidades de log forem grandes números negativos, as
probabilidades resultantes podem subfluir. Assim, a Exp encontra a
probabilidade máxima de log, m, e muda todasas probabilidades para
cima por m. A distribuição resultante tem um máximo de lito de 1. Este
processo inverte a transformação do tronco com perda mínima de
precisão.

10.6 Probabilidade de log


Agora tudo o que precisamos é
de LogLikelihood. # classe Altura

def LogLikelihood (self, data, hypo): x =


dados
116 Capítulo 10. Computação bayesiana aproximada

mu, sigma = hypo


loglike = scipy.stats.norm.logpdf(x, mu, sigma) loglike de
retorno
norm.logpdf calcula a probabilidade de log do PDF gaussiano. Veja
como é todo o processo de atualização:
Suite. Log()
Suite. Pacote
LogUpdateSet(xs). Suíte
Exp( Normalizar()
Para revisar, o Log coloca a suíte uma transformação de log. LogUpdateSet
chama LogUpdate, quechamas LogLikelihood. O LogUpdate usa
PMF.Incr,porque adicionar uma probabilidade de log é o mesmo que multiplicar
por uma probabilidade.
Após a atualização, as probabilidades de log são grandes números
negativos, então o Exp os desloca antes de inverter a transformação, que é
como avoid un-derflow.
Uma vez que a suíte é transformada de volta, as probabilidades são
"lineares" novamente, o que significa "não logarítmico", para que
possamos usar normalizar novamente.
Usando este algoritmo, podemos processar todo o conjunto de dados sem
subfluxo, mas ainda é lento. No meu computador pode levar uma hora.
Podemos fazer melhor.

10.7 Um pouco de otimização


Esta seção usa a matemática e a otimização computacional para acelerar as
coisas por um factor de 100. Mas a seção a seguir apresenta um algoritmo
que é ainda mais rápido. Então, se você quer ir direto para as coisas boas,
sinta-se livre para pular esta seção.
Suite.LogUpdateSet chama LogUpdate uma vez para cada ponto de dados.
Podemos acelerá-lo calculando a probabilidade de registro de todo o
conjunto de dados de uma só vez.
Vamos começar com o PDF gaussiano:
. Σ2
1 Σ 1 x−µ Σ

√ exp σ
σ 2π 2
e calcular o log (soltando o termo constante):
. Σ2
1
− log σ − X − µ
Σ
2
10.7. A little optimization 117

Dada uma seqüência de valores, xi, a probabilidade total delog é


. Σ2
− log σ −1 xi − µ
∑i σ
2
Puxando os termos que não dependem de i,nós temos
1
−n log σ − –(xxi − μ)2
2σ2 i

que podemos traduzir em Python:


# classe Altura

def LogUpdateSetFast(self, data): xs =


tuple(dados)
n = len(xs)

para hipo em si mesmo.


Valores(): mu, sigma =
hypo
total = Soma (xs, mu)
loglike = -n * math.log(sigma) - total / 2 / sigma**2 self. Incr (hipo, loglike)
Por si só, isso seria uma pequena melhoria, mas cria uma oportunidade
para uma maior. Observe quea somação só depende de mu, não
sigma,então só temos que computá-lo uma vez para cada valor de mu.

Para evitar recomputação, eu fatorar uma função que calcula a soma, e


memorizá-la para que ele armazena resultados previamente computados
em um dicionário (ver http://en.wikipedia.org/wiki/Memoization):
def Summation(xs, mu, cache={}):
tente:
cache de retorno[xs, mu]
exceto KeyError:
ds = [(x-mu)**2 para x em xs]
total = soma(ds)
cache[xs, mu] = total de
retorno total
cache armazena somas previamente computadas. A declaração de tentativa
retorna um re-sult do cache, se possível; caso contrário, ele calcula a soma,
em seguida, caches e retorna o resultado.
A única pegadinha é que não podemos usar uma lista as uma chave no cache, porque é
118 Capítulo 10. Computação bayesiana aproximada

não um tipo hashable. É por isso que o LogUpdateSetFast converte o


conjunto de dados em uma tuplo.
Essa otimização acelera a computação em cerca de 100, pro-cessing todo o
conjunto de dados (154 407 homens e 254 722 mulheres) em menos de um
minuto no meu computador não muito rápido.

10.8 Abc
Mas talvez você não tenha esse tipo de tempo. Nesse caso, aComputação
Bayesiana aproximada (ABC) pode ser o caminho a percorrer. A
motivação do ABC é que a probabilidade de qualquer conjunto de dados
em particular é:

1. Muito pequeno, especialmente para grandes conjuntos de dados, e é


por isso que tivemos que usar a transformação de log,
2. Caro para calcular, e é por isso que tivemos que fazer tanto
optimização, e
3. Não é bem o que queremos.

Nós realmente não nos importamos com a probabilidade de ver o conjunto


de dados exato que vimos. Especialmente para variáveis contínuas, nos
preocupamos com a probabilidade de ver qualquer conjunto de dados
como o que vimos.
Por exemplo, no problema do Euro, não nos importamos com a ordem dos
lançamentos de moedas, apenas o número total de cara e coroa. E no
problema da locomotiva, não nos importamos com quais trens
particulares foram vistos, apenas o número de trens e o máximo dos
números de série.
Da mesma forma, na amostra BRFSS, não queremos realmente saber a
probabilidade de ver um determinado conjunto de valores (especialmente
porque existem centenas de milhares deles). It É mais relevante perguntar:
"Se amostramos 100.000 pessoas de uma população com valores
hipotéticos de μ e σ,qual seria a chance de coletar uma amostra com a
média e variância observadas?"
Para amostras de uma distribuição gaussiana, podemos responder a esta
pergunta effi-ciently porque podemos encontrar a distribuição das
estatísticas amostrais analito-lyt-ly- ly. Em fato, nós já fizemos isso quando
calculamos o alcance do anterior.

Se você desenhar n valores de uma distribuição gaussiana com parâmetros μ e


σ, e calcular o sa➤mple média, m, a distribuição de m é gaussian com
parâmetros μ e σ/ n.
Da mesma forma O Distribuição
√ De O SamPle Padrão Desvio s, É
Gaussiano com parâmetros Σ E σ/ 2(N − 1).
Podemos usar essas distribuições amostrais para calcular a probabilidade
das estatísticas sam-ple, m e s,dado valores hipotéticos para μ e σ. Aqui
está uma nova versão do LogUpdateSet que faz isso:
def LogUpdateSetABC(self, data): xs
= dados
n = len(xs)

# compute sample statistics m


= numpy.mean(xs)
s = numpy.std(xs)

para hipo em ordenado (eu. Valores()):


mu, sigma = hypo

# probabilidade de registro computacional de m,


dado hipo stderr_m = sigma / math.sqrt(n)
loglike = EvalGaussianLogPdf(m, mu, stderr_m)

#compute probabilidade de registro de s, dado


hipstderr_s = sigma / math.sqrt(2 * (n-1))
loglike += EvalGaussianLogPdf(s, sigma, stderr_s)

Auto. Incr (hipo, loglike)


No meu computador esta função processa todo o conjunto de dados em
cerca de um segundo ond, e o resultado concorda com o resultado exato
com cerca de 5 dígitos de preci-sion.

10.9 Estimativa robusta


Estamos quase prontos para olhar para os resultados, mas temos mais um
problema para resolver. Há uma série de excepcionais neste conjunto de
dados que são quase certamente erros. Por exemplo, há três adultos com
altura relatada de 61 cm, o que os colocaria entre os adultos vivos mais
curtos do mundo. Na outra ponta, há quatro mulheres com altura relatada
de 229 cm, pouco menos que as mulheres mais altas do mundo.
Não é impossível que esses valores estejam corretos, mas é improvável, o
que torna difícil saber como lidar com eles. E nós temos que pegá-lo
Distribuição articular posterior
7.35

7.34
Stddev (cm)

7.33

0.006
7.32

7.31

0.003
7.30

7.29

7.28
178.46 178.48 178.50 178.52 178.54
Altura média (cm)

Figura 10.1: Parcela de contorno da distribuição articular posterior da


média e desvio padrão de altura para homens nos EUA.

Distribuição articular posterior


7.04

7.03
Stddev (cm)

7.02
0.006

7.01

7.00 0.003

6.99

163.46 163.47 163.48 163.49 163.50 163.51 163.52 163.53


Altura média (cm)

Figura 10.2: Parcela de contorno da distribuição articular posterior da


média e desvio padrão de altura para mulheres nos EUA.
certo, porque esses valores extremos têm um efeito desproporcional sobre
a variabilidade estimada.

Como o ABCbaseia-se em estatísticas sumárias, em vez de todo o conjunto


de dados, podemos torná-lo mais robusto escolhendo estatísticas sumárias
que são robustas na presença de outliers. Por exemplo, em vez de usar a
média amostral e o desvio padrão, poderíamos usar a faixa mediana e
interquartil (IQR), que é a diferença entre os percentis 25 e 75.

De forma mais geral, poderíamos calcular uma faixa interpercentil (IPR)


que abrange qualquer fração da distribuição, p::
def MedianIPR(xs,p):
cdf = thinkbayes. MakeCdfFromList(xs)
mediana = cdf. Percentil(50)

alfa = (1-p) / 2
ipr = cdf. Valor (1-alfa) - cdf. Mediana de retorno de
valor (alfa), ipr

xs é uma seqüência de valores. p é a faixa desejada; por exemplo, p=0,5


produz a faixa entre quartils.

MedianIPR funciona calculando o CDF de xs,depois extraindo a mediana e


a diferença entre dois percentis.

Podemos converter de ipr para uma estimativa de sigma usando o CDF


gaussiano para calcular a fração da bution districoberta por um
determinado número dedesvios padrão. Por exemplo, é uma regra de
ouro bem conhecida que 68% de uma distribuição gaussiana se enquadra
em um desvio padrão da média, o que deixa 16% em cada cauda. Se
calcularmos a faixa entre os percentis 16e 84, esperamos que o resultado
seja 2 * sigma. Assim, podemos can estimar sigma calculando o IPR de 68%
e dividindo por 2.

Em geral, poderíamos usar qualquer número de sigmas. MedianS executa a


versão mais geral desta computação:
def MedianS(xs, num_sigmas):
half_p = thinkbayes. StandardGaussianCdf(num_sigmas) - 0,5

mediana, ipr = MedianIPR(xs, half_p * 2) s =


ipr / 2 / num_sigmas

mediana de retorno, s
1.0

0.8

Probabilidade
0.6

0.4

0.2

Masculino
Fêmea
0.0
0,0405 0.0410 0.0415 0.0420 0.0425 0.0430 0.0435
Coeficiente de variação

Figura 10.3: Distribuições posteriores de CV para homens e mulheres, com


base em estimadores robustos.

Novamente, xs é a seqüência de valores; num_sigmas é o número de


desvios-padrão em que os resultados devem ser baseados. O resultado é
mediano, que esti-mates μ, e s,que estima σ.

Finalmente, no LogUpdateSetABC podemos substituir a média da amostra


e o desvio padrão por mediana e s. E isso faz isso.
Pode parecer estranho que estejamos usando percentis observados para
estimar μ e σ,mas é um exemplo da flexibilidade da abordagem bayesiana.
Na verdade, estamos perguntando: "Dado os valores hipotéticos para μ e
σ, e uma amostragem pro-cess que tem alguma chance de introduzir erros,
qual é a probabilidade de gerar um determinado conjunto de estatísticas
sample?"
Somos livres para escolher qualquer estatística amostral que gostamos, até
um ponto: μ e σ determinar a localização e a disseminação de uma
distribuição, por isso precisamos escolher estatísticas que capturem essas
características. Por exemplo, se escolhermos os percentis 49 e 51,
obteríamos muito pouca informação sobre a disseminação, então isso
deixaria a estimativa de σ relativamente sem restrições pelos dados. Todos
os valores de sigma teriam quase a mesma probabilidade de produzir os
valores observados, de modo que adistribuição poste rior de sigma seria
muito parecida com a anterior.

10.10 Quem é mais variável?


Finalmente estamos prontos para responder à pergunta que começamos: o
coeffi-cient de variação é maior para os homens do que para as mulheres?
10.11. Discussion 123

Utilizando ABC com base na mediana e IPR com num_sigmas=1, calculei as


distributions articularesposteriores para mu e sigma. As figuras 10.1 e 10.2
mostram os resultados como um enredo de contorno com mu no eixo x,
sigma no eixo y e probabilidade no eixo z.

Para cada distribuição conjunta, calculei a distribuição posterior do CV.


Fig-ure 10.3 mostra essas distribuições para homens e mulheres. A média
para os homens é de 0,0410; para as mulheres é de 0,0429. Como não há
sobreposição entre as destribuções, concluímos com quase certeza que as
mulheres são mais variáveis em altura do que os homens.

Então, esse é o fim da Hipótese de Variabilidade? Infelizmente, não.


Acontece que esse resultado depende da escolha da faixa interpercentil.
Com num_sigmas=1, we concluir que as mulheres são maisvariáveis, mas
com num_sigmas=2 concluímos com igual confiança que os homens são
mais variáveis.

A razão para a diferença é que há mais homens de baixa estatura, e sua


distância da média é maior.

Assim, nossaalusão à hipótese de variabilidade depende da interpretação


da "variabilidade". Com num_sigmas=1 focamos em pessoas próximas à
média. À medida que aumentamos num_sigmas,damos mais peso aos
extremos.

Para decidir qual ênfase é apropriada, precisaríamos de uma afirmação


mais precisa da hipótese. Como é, a Hipótese de Variabilidade pode ser
muito vaga para ser avaliada.

No entanto, isso me ajudou a demonstrar várias novas ideias e, espero que


você concorde, fazum exemplo n interessante.

10.11 Discussão
Há duas maneiras de pensar na ABC. Uma interpretação é que é, como o
nome sugere, uma aproximação que é mais rápida de calcular do que o
valor exato.

Mas lembre-se que a análise bayesiana é sempre baseada em modelagem


deci-sions, o que implica que não há uma solução "exata". Para qualquer
sistema físico interessante ore são muitos modelos possíveis, e cada
modelo produz resultados diferentes. Para interpretar os resultados,
temos que avaliar os modelos.
124 Capítulo 10. Computação bayesiana aproximada

Então outra interpretação da ABC é que ela representa um modelo


| compute p(D H), estamos
alternativo de probabilidade. Quando nós
perguntando Qual é a probabilidade dos dados uma determinada
hipótese?

Para grandes conjuntos de dados, a probabilidade dos dados é muito


pequena, o que é um indício de que podemos não estar fazendo a
pergunta certa. O que realmente queremos saber é a probabilidade de
qualquer resultado como os dados, onde a definição de "like" é mais uma
decisão de modelagem.

A ideia subjacente do ABC é que dois conjuntos de dados são iguais se


eles produzem as mesmas estatísticas sumárias. Mas, em alguns casos,
como o exemplo neste chapter, não é óbvio quais estatísticas sumárias
escolher.

Você pode baixar o código neste capítulo de http://thinkbayes.com/


variability.py. Para obter mais informações, consulte a Seção 0.3.

10.12 Exercícios
Exercício 10.1. Um "tamanho de efeito" é uma estatística destinada a medir
a diferença entre dois grupos (ver http: // en. wikipedia. org/ wiki/
tamanho Effect_ ).

Por exemplo, poderíamos usar dados da BRFSS para compor a diferença de altura
entre homens e mulheres. Por meio de valores amostrais das distribuições
posteriores de μ e σ,poderíamos gerar a distribuição posterior dessa diferença.

Mas pode ser melhor usar uma medida adimensionada do tamanho do efeito, em
vez de uma diferença medida em cm. Uma opção é usar a divisão através do desvio
padrão (semelhante ao que fizemos com o coeficiente de variação).
Se os parâmetros para Group 1 são (μ1, σ1), e osparâmetros para o Grupo 2 são
(μ2, σ2) , o tamanho do efeito adimensional é
µ1 − µ2
(σ1 + σ2) /2
Escreva uma função que leve distribuições articulares de mu e sigma para dois
grupos e retorne a distribuição posterior do tamanho do efeito.

Dica: se enumerar todos os pares das duas distribuições demorar muito, considere
a amostragem aleatória.
Teste de hipóteses

do capítulo 11

11.1 De volta ao problema do Euro


Na Seção 4.1 apresentei um problema da Teoria da Informação da MacKay,
In-ference e Algoritmos de Aprendizagem::
Uma declaração estatística apareceu no "The Guardian" na
sexta-feira 4 de janeiro de 2002:
Quando girada na borda 250 vezes, uma moeda belga
de um euro subiu cabeças 140 vezes e coroa 110.
"Parece muito suspeito para mim", disse Barry Blight,
professor de estatística da London School of
Economics. "Se a moeda fosse imparcial, a chance de
obter um resultado tão extremo como isso seria
inferior a 7%."
Mas esses dados dão provas de que a moeda é tendenciosa e
não justa?
Estimamos a probabilidade de a moeda cair de frente, mas não
respondemos à pergunta de MacKay: os dados dão provas de que a
moeda é tendenciosa?
No capítulo 4 propus que os dados são a favor de uma hipótese se os
dados são mais prováveis sob a hipótese do que sob a alternativa ou,
equivalentemente, se o fator Bayes for maior que 1.
No exemplo euro, temos duas hipóteses a considerar: uso F para a
hipótese de que a moeda é justa e B para a hipótese de que ela é
tendenciosa.
Se a moeda é justa, é fácil calcular a probabilidade dos dados, p (D |
F). Na
verdade, nós já escrevemos a função que faz isso.
126 Capítulo 11. Teste de hipóteses

def Probabilidade (self, data, hypo): x


= hypo / 100.0
cabeça, cauda = dados
como = x**cabeças * (1-x)**caudas
retornar como
Para usá-lo, podemos criar uma suíte Euro e invocar A
Probabilidade: suite = Euro()
probabilidade = suíte. Probabilidade (dados, 50)
p(D |F) é 5.5 10−76, o que não nos diz muito, exceto que a probabilidade de
ver qualquer conjunto de dados em particular é muito pequena. É preciso
duas probabilidades para fazer uma proporção, então também temos que
calcular p(D|B).

Não é óbvio como calcular a probabilidade de B,porque não é obvi-ous o


que significa "tendencioso".

Uma possibilidade é trapacear e olhar para os dados antes de definirmos o


hipoth-esis. Nesse caso, diria que "tendencioso" significa que a
probabilidade de cara é de 140/250.
actual_percent = 100,0 * 140 / 250
probabilidade = suíte. Probabilidade (dados, actual_percent)
Esta versão de B Eu chamo B_cheat; a probabilidade de b_cheat É· 34 10−76 E
a razão de probabilidade é de 6,1. Então, nós gostaríamos de dizer que os
dados são evidências a favor desta versão de B.

Mas usar os dados para formular a hipótese é obviamente falso. Por essa
definição, qualquer conjunto de dados seria evidência a favor de B,, a
menos que a porcentagem observada de cabeças seja exatamente de 50%.

11.2 Fazendo uma comparação justa


Para fazer uma comparação legítima, temos que definir B sem olhar para
os dados. Então vamos tentar uma definição diferente. Se você inspecionar
uma moeda euro belga, você pode notar queolado "cabeças" é mais
proeminente do que o lado "coroa". Você pode esperar que a forma tenha
algum efeito em x, mas não tenha certeza se isso torna as cabeças mais ou
menos prováveis. Então você pode dizer "Eu acho que a moeda é
tendenciosa de modo que x é ou 0,6 ou 0,4, mas eu não tenho certeza
qual."

Podemos pensar nesta versão, que chamarei de B_two como uma hipótese
composta de duas subhipóteses. Podemos calcular a probabilidade de cada
sub-hipótese e, em seguida, calcular a probabilidade média.
11.2. Making a fair comparison 127

como40 = suíte. Probabilidade (dados, 40)


como60 = suíte. Probabilidade (dados, 60)
probabilidade = 0,5 * like40 + 0,5 * como 60
A razão de probabilidade (ou fator Bayes) para b_two é de1,3, o que
significa que os dados fornecem evidências fracas em favor de b_two. is 1

Em geral, suponha que você suspeite que a moeda é tendenciosa, mas


você não tem nenhuma pista sobre o valor de x. Nesse caso, você pode
construir uma Suíte, que eu chamo de b_uniform,para representar sub-
hipótesesde 0 a 100.
b_uniform = Euro(xrange(0, 101))
b_uniform. Remova(50) b_uniform.
Normalizar()
Eu inicializo b_uniform com valores de 0 a 100. Removi a sub-hipótese de
que x é 50%, porque se x é 50% a moeda é justa, mas quase não tem efeito
sobre o resultado se você removê-lo ou não.

Para calcular a probabilidade de b_uniform calculamos a probabilidade de


cada subhipótese e acumulamos uma média ponderada.
def SuiteLikelihood (suíte, dados):
total = 0
para hypo, prob na suíte. Items():
como = suíte. Probabilidade (dados, hip)
total += prob * como
retorno total
A razão de probabilidade para b_uniform é de 0,47, o que significa que os
dados são evidências fracas contra b_uniform, emcomparação com F.

Se você pensar sobre o cálculo realizado pelo capuz SuiteLikeli,hood você


pode notar que ele é semelhante a uma atualização. Para atualizar sua
memória, aqui está a função Atualizar:
def Update (self, data):
para hipo em si mesmo. Valores():
como = eu. Probabilidade (dados, hipo) auto. Mult
(hipo, como)
retorno auto. Normalizar()
E aqui está Normalize::
def Normalize(self): total =
self. Total()

fator = 1,0 / total


128 Capítulo 11. Teste de hipóteses

para x em self.d: self.d[x] *=


fator

retorno total
O valor de retorno de Normalize é o total das probabilidades no Suite, que
é a média das probabilidades para as subhipóteses, ponderadas pelas
probabilidades anteriores. E o Update passa esse valor junto, então, em vez
de usar o SuiteLikelihood,poderíamos calcular a probabilidadede b_uniform
assim:
probabilidade = b_uniform. Atualização (dados)

11.3 O triângulo anterior


No Capítulo 4 também consideramos um antes em forma de triângulo
que dá maior probabilidade a valores de x perto de 50%. Se pensarmos
nisso antes como um conjunto de subhipóteses, podemos calcular sua
probabilidade assim:
b_triangle = Probabilidade de
TrianglePrior() = b_triangle.
Atualização(data)
A razão de probabilidade para b_triangle é de 0,84, em comparação com
F,então novamente podemos dizer que os dados são evidências fracas
contra B.
A tabela a seguir mostra os antecedentes que consideramos, a
probabilidade de cada um e a razão de probabilidade (ou fator Bayes)
relative a F.

Hipótese Probabili Baye


dade s
×
6 10
−7 Fator
F 5.5 –
B_cheat 34 6.1
B_two 7.4 1.3
B_unifor 2.6 0.47
m
B_triangle 4.6 0.84
Dependendo da definição que escolhermos, os dados podem fornecer
evidências a favor ou contra a hipótese de que a moeda é tendenciosa, mas
em ambos os casos é uma evidência relativamente fraca.
Em resumo, podemos usar testes de hipótesebayesiano para comparar o
likeli-hood de F e B,mas temos que fazer alguns trabalhos para especificar
precisamente o que B significa. Essa especificação depende de informações
de fundo sobre moedas e seu comportamento quando giradas, para que as
pessoas possam discordar razoavelmente sobre a definição certa.
11.4. Discussion 129

Minha apresentação deste exemplo segue a discussão de David MacKay, e


chega à mesma conclusão. Você pode baixar o código que usei neste
capítulo de http://thinkbayes.com/euro3.py. Para obter mais informações,
consulte a Seção 0.3.

11.4 Discussão
O fator Bayes para B_uniform é de 0,47, o que significa que os dados
fornecem evidências contra essa hipótese, em comparação com F. Na
seção anterior, eu caracterizei essa evidência como "fraca", mas não disse
por quê.
Parte da resposta é histórica. Harold Jeffreys, um dos primeiros
defensores das estatísticas bayesianas, sugeriu uma escala para interpretar
os fatores de Bayes:

Bayes Força
Fator
1–3 Mal vale a pena
mencionar
3 – 10 Substancial
10 – 30 Forte
30 – Muito forte
100
> 100 Decisivo
No exemplo, o fator Bayes é 0,47 a favor de B_uniform, por isso é 2,1 a
favor de F, o que Jeffreys consideraria "mal vale a pena mencionar".
Outros autores sugeriram variações na redação. Para evitar discutir sobre
adjetivos, poderíamos pensar em probabilidades em vez disso.
Se suas chances anteriores são 1:1, e você vê evidências com bayes fator 2,
vocêr chances posteriores são 2:1. Em termos de probabilidade, os dados
mudaram seu grau de crença de 50% para 66%. Para a maioria dos
problemas do mundo real, essa mudança seria pequena em relação a erros
de modelagem e outras fontes de incerteza.
Por outro lado, se você tivesse visto evidências com o fator Bayes 100, suas
chances posteriores seriam 100:1 ou mais de 99%. Se você concorda ou não
que tais evidências são "decisivas", é certamente forte.

11.5 Exercícios
Exercício 11.1. Algumas pessoas acreditam na existência de percepção extra-
sensorial (ESP); por exemplo, a capacidade de algumas pessoas de adivinhar o
valor de uma carta de jogo invisível com probabilidade melhor do que o acaso.
130 Capítulo 11. Teste de hipóteses

Qual é o seu grau prévio de crença neste tipo de ESP? Você acha que é tão
provável que exista como não? Ou você está mais cético sobre isso? Anote suas
chances anteriores.

Agora calcule a força das evidências que seria necessário para convencê-lo de que
o ESP tem pelo menos 50% de chances de existir. Que fator Bayes seria necessário
para ter 90% de certeza de que o ESP existe?
Exercício 11.2. Suponha que sua resposta à pergunta anterior seja 1000; ou seja,
evidências com o fator Bayes 1000 a favor da ESP seriam suficientes para
changnge sua mente.
Agora suponha que você leia um artigo em uma respeitável revista científica
revisada por pares que apresenta evidências com o fator Bayes 1000 a favor do
ESP. Isso mudaria sua opinião?

Se não, como você resolve a aparente contradição? Você pode achar útil ler sobre o
artigo de David Hume, "Of Miracles", em http: // en. wikipedia. org/ wiki/
Of_ Miracles .
Capítulo 12

Evidência

12.1 Interpretando pontuações do SAT


Suponha que você é o Reitor de Admissão em uma pequena faculdade de
engenharia em Massachusetts, e você está considerando dois candidatos,
Alice e Bob, cujas qualificações são semelhantes em muitos aspectos, com
exceção de que Al-ice obteve uma pontuação mais alta no portode
matemática do SAT, um teste padronizado destinado a medir a preparação
parao trabalho de nível universitário em matemática.

Se Alice conseguiu 780 e Bob conseguiu um 740 (de um possível 800), você
pode querer saber se essa diferença é uma evidência de que Alice está
melhor preparada que Bob, e qual é a força dessa evidência.

Agora, na realidade, ambas as pontuações são muito boas, e ambos os


candidatos provavelmente estão bem preparados para a matemática da
faculdade. Assim, o verdadeiro Reitor de Admissão sugeriria que
escolhessemos o candidato que melhor demonstra as outras habilidades e
atitudes que buscamos nos alunos. Mas como exemplo de teste de
hipóteses bayesianos, vamos manter uma pergunta mais estreita: "Quão
forte é a evidência de que Alice está melhor preparada do que Bob?"

Para responder a essa pergunta, precisamos tomar algumas decisões de


modelagem. Vou começar com uma simplificação que eu sei que é errado;
então voltaremos e provaremos o modelo. Eu finjo, temporariamente, que
todas as perguntas do SAT são igualmente difíceis. Na verdade, os
designers do SAT escolhem questionscom uma gama de dificuldade,
porque isso melhora a capacidade de medir diferenças estatísticas entre os
tomadores de teste.

Mas se escolhermos um modelo onde todas as questões são igualmente


difíceis, podemos definir uma característica, p_correct,para cada candidato,
which é o probabil-
132 Capítulo 12. Provas

idade de responder qualquer pergunta corretamente. Essa simplificação


facilita a computação da probabilidade de uma determinada pontuação.

12.2 A escala
Para entender as pontuações do SAT, temos que entender o processo de
pontuação e escala. Cada tomador de teste obtém uma pontuação bruta
com base no número de perguntas corretas e incorretas. A pontuação
bruta é convertida em uma pontuação escalonada na faixa 200-800.

Em 2009, havia 54 questões sobre o sat dematemática. A pontuação bruta


para cada tomador de teste é o número de perguntas respondidas
corretamente menos uma penalidade de 1/4 ponto para cada pergunta
respondida incorretamente.

O Conselho Universitário, que administra o SAT, publica o mapa desde


pontuações brutas até pontuações dimensionadas. Baixei esses dados e
enrolei-os em um objeto Interpolator que fornece uma pesquisa para a
frente (do score bruto à escala) e uma pesquisa reversa (de pontuação
escalocada a cru).

Você pode baixar o código para este exemplo de http://thinkbayes.com/


sat.py. Para obter mais informações, consulte a Seção 0.3.

12.3 O anterior
O Conselho Universitário também publica a distribuição de pontuações
dimensionadas para todos os participantes do teste. Se convertermos cada
escore escalonado em um escore bruto, e dividirmos pelo número de
perguntas, o resultado é uma estimativa de p_correct. Assim, podemos
utilizar a distribuição de escores brutos para modelar a distribuição prévia
de p_correct.

Aqui está o código que lê e processa os dados:


classe Exame (objeto):

Def __init__(self):
self.scale = ReadScale() scores =
ReadRanks()
score_pmf = thinkbayes. MakePmfFromDict(dict(scores))
self.raw = self. ReverseScale(score_pmf) self.max_score =
max(self.raw.Values())
self.prior = DivideValues (self.raw, self.max_score)
12.3. The prior 133

1.0

Antes

0.8

0.6

Cdf
0.4

0.2

0.0
0.0 0.2 0.4 0.6 0.8 1.0
p_correct

Figura 12.1: Distribuição prévia de p_correct para os participantes do teste SAT.

O exame encapsula as informações que temos sobre o exame. ReadScale e


ReadRanks lêem arquivos e returnem objetos que contêm os dados:
self.scale é o Interpolador que se converte de pontuações brutas para
pontuações dimensionadas e de volta; scores é uma lista de pares
(pontuação, frequência).

score_pmf é o PMF das pontuações escalonadas. self.raw é o PMF dos


escores brutos, e self.prior é o PMF de p_correct.

A Figura 12.1 mostra a distribuição prévia de p_correct. Esta distribuição é


aproximadamente gaussiana, mas é comprimida nos extremos. Pelo
design, o SAT tem o maior poder para discriminar entre os tomadores de
teste dentro de dois desvios padrão da média, e menos potência fora desse
intervalo.

Para cada tomador de teste, defino uma Suíte chamada Sat que representa
a distribuição de p_correct. Aqui está a definição:
classe Sáb (thinkbayes. Suíte):

Def __init__(self, exam, score):


thinkbayes.Suite.__init__(self)

auto.exame =
autoexame.score =
pontuação

# comece com a distribuição prévia


para p_correct, prob em exam.prior.Items(): self.
Conjunto(p_correct, prob)
134 Capítulo 12. Provas

1.0

posterior 780
posterior 740
0.8

0.6

Cdf
0.4

0.2

0.0
0.70 0.75 0.80 0.85 0.90 0.95 1.00
p_correct

Figura 12.2: Distribuições posteriores de p_correct para Alice e Bob.

# update baseado em uma pontuação de exame


self. Atualização (pontuação)
__init__ tem um objeto do Exame e uma pontuação escalonada. Ele faz
uma cópia da distribuição anterior e, em seguida, atualiza-se based na
pontuação do exame.
Como de costume, herdamos atualização do Suite e
fornecemos Probabilidade: def Probabilidade (self, dados,
hypo):
p_correct = hipo
pontuação = dados

k = autoexame.Reverso (escore)
n = auto.exame.max_score
como = thinkbayes. Retorno da EvalBinomialPMF(k, n,
p_correct) como
hypo é um valor hipotético de p_correct, e os dados são um escore escalonado.

Para manter as coisas simples, interpreto a pontuação bruta como o


número de respostas corretas, ignorando a penalidade por respostas
erradas. Com essa simplificação, a probabilidade é dada pela distribuição
binomial, que calcula a probabilidade de k respostas corretas a partir de n
perguntas.

12.4 Posterior
A Figura 12.2 mostra as distribuições posteriores de p_correct para Alice e
Bob com base em suas notas no exame. Podemos ver que eles se
sobrepõem, então é possível que p_correct seja realmente maior para Bob,
mas parece improvável.
12.4. Posterior 135

O que nos leva de volta à pergunta original: "Quão forte é a evidência de


que Alice está melhor preparada que Bob?" Podemos usar as distribuições
posteriores de p_correct para responder a esta pergunta.
Para formular a questão em termos de teste de hipóteses bayesianas,
defino duas hipóteses:

• A: p_correct é maior para Alice do que para Bob.

• B: p_correct é maior para Bob do que para Alice.

Para calcular a probabilidade de A,podemos enumerar todos os pares de


valores das distribuições posteriores e somar a probabilidade total dos
casos em que p_correct é maior para Alice do que para Bob. E nós já temos
uma função, thinkbayes. PMFProbMaior, que faz isso.

Assim, podemos definir um Suite que calcula as probabilidades posterior de A e


B:
classe TopLevel (thinkbayes. Suíte):

def Update(self, data):


a_sat, b_sat = dados

a_like = thinkbayes. PMFProbGreater(a_sat, b_sat)


b_like = thinkbayes. PMFProbLess(a_sat, b_sat) c_like =
thinkbayes. PMFProbEqual (a_sat, b_sat)

a_like += c_like / 2
b_like += c_like / 2

Auto. Mult( A , a_like)


' '

self. Mult( B , b_like)


B '

Auto. Normalizar()
Normalmente, quando definimos uma nova Suíte, herdamos a Atualização
e fornecemos Probabilidade. Neste caso eu anular atualização,porque é mais
fácil avaliar a probabilidade de ambas as hipóteses ao mesmo tempo.
Os dados passados para Atualização são objetos sat que representam as
distri-butions posteriores de p_correct.
a_like é a probabilidade total de que p_correct seja maior para Alice; b_like é
essa probabilidade de que seja maior para Bob.
136 Capítulo 12. Provas

c_like é a probabilidade de serem "iguais", mas essa igualdade é um


artefato da decisão de modelar p_correct com um conjunto de valores
discretos. Se usarmos mais valores, c_like é menor, e no extremo, se
p_correct continua, c_like é zero. Então eu trato c_like como uma espécie de
erro de round-off e dividi-lo uniformemente between a_like e b_like.
Aqui está o código que cria toplevel e o atualiza:
exame = Exame()
a_sat = Sáb(exame, 780)
b_sat = Sáb(exame, 740)

topo = TopLevel( AB )
' '

superior. Atualização((a_sat,
b_sat)) superior. Impressão()
A probabilidade de A é 0,79 e a probabilidade de B é 0,21. A razão de
probabilidade (ou fator Bayes) é de 3,8, o que significa que esses
resultados de teste são evidências de que Alice é melhor do que Bob em
responder perguntas de sat. Se acreditássemos, antes de ver os resultados
do teste, que A e B somosigualmente prováveis, então depois de ver as
pontuações devemos acreditar que a probabilidade de A é de 79%, o que
significa que ainda há 21% de chance de Bob estar realmente melhor
preparado.

12.5 Um modelo melhor


Lembre-se que a análise que fizemos até agorae baseia-se na simplificação
de que todas as questões do SAT são igualmente difíceis. Na realidade,
alguns são mais fáceis que outros, o que significa que a diferença entre
Alice e Bob pode ser ainda menor.

Mas qual é o tamanho do erro de modelagem? Se for pequeno, concluímos


que o primeiro modelo — baseado na simplificação de que todas as
questões são igualmente difíceis — é bom o suficiente. Se for grande,
precisamos de um modelo melhor.

Nas próximas seções, desenvolvo um modelo melhor e descubro (alerta de


spoiler!) que o erro de modelagem é pequeno. Então, se você está satisfeito
com o modelo simples, você pode pular para o próximocha pter. Se você
quiser ver como o modelo mais realista funciona, continue lendo...

• Suponha que cada testador tenha algum grau de eficácia, o que mea -
garante sua capacidade de responder a perguntas sat.

• Suponha que cada pergunta tenha algum nível de dificuldade..


12.5. A better model 137

• Por fim, suponha que a chance de um tomador de teste responder


corretamente a uma pergunta esteja relacionada à eficácia e
dificuldade de acordo com este func-tion:

def ProbCorrect (eficácia, dificuldade, a=1):


retorno 1 / (1 + math.exp(-a * (eficácia - dificuldade))

Esta função é uma versão simplificada ory da curva usada na resposta ao


item, que você pode ler sobre http://en.wikipedia.org/wiki/Item_
response_theory. eficácia e dificuldade são consideradas na mesma escala, e a
probabilidade de acertar uma pergunta depende apenas da diferença entre eles.

Quando a eficácia e a dificuldade são iguais, a probabilidade de acertar a


pergunta é de 50%. À medida que a eficácia aumenta, essa probabilidade se
aproxima de 100%. À medida que diminui (ou à medida que a dificuldade
aumenta), a probabilidade de ap- proaches 0%.

Dada a distribuição da eficácia entre os tomadores de teste e a distribuição


da dificuldade entre as questões, podemos calcular a distribuição esperada
dos escores brutos. Faremos isso em dois passos. First, para uma pessoa
com dada eficácia,vamos calcular a distribuição de escores brutos.
def PmfCorrect (eficácia, dificuldades): pmf0 =
thinkbayes. PMF([[0])

ps = [ProbCorrect(eficácia, diff) para difundir em dificuldades] pmfs


= [BinaryPMF(p) para p em ps]
dist = soma (pmfs, pmf0)
dist retorno
dificuldades é uma lista de dificuldades, uma para cada pergunta. ps é uma
lista de probabilidades, e pmfs é uma lista de objetos de PMF de dois
valores; aqui está o func-tion que os torna:
def BinaryPMF(p):
pmf = thinkbayes. PMF.
Conjunto(1, p)
Pmf. Set(0, 1-p)
retorno pmf
dist é a soma dessas PMFs. Lembre-se da Seção 5.4 que quando somamos
objetos da PMF, o resultado é a distribuição das somas. Para usar a soma
do Python para somar PMFs, temos que fornecer pmf0 que é a identidade
para PMFs, então pmf + pmf0 é sempre PMF.
138 Capítulo 12. Provas

Se soubermos a eficácia de uma pessoa, podemos calcular sua distribuição


de escores brutos. Para um grupo de pessoas com diferentes eficácias, a
distri-bution resultante de escores brutos é uma mistura. Aqui está o
código que calcula a mistura:
# Exame de classe:

def MakeRawScoreDist(self, efficacies): pmfs


= thinkbayes. PMF()
para eficácia, prob em eficácias. Itens():
scores = PMFCorrect (eficácia, self.difficulties) pmfs.
Set(pontuações, prob)

mix = thinkbayes. Mistura de retorno


MakeMixture (pmfs)
MakeRawScoreDist toma eficácias, que é um PMF que representa a
destributação da eficácia entre os tomadores de teste. Presumo que seja
Gaussian com média 0 e desvio padrão 1.5. Essa escolha é arbitrária.
arbitrary. A probabilidade de acertar uma pergunta depende da diferença
entre eficácia e dificuldade, para que possamos escolher as unidades de
eficácia e, em seguida, calibrar as unidades de dificuldade em
conformidade.
pmfs é um meta-PMF que contém um PMF para cada nível de eficácia, e
mapeia a fração de tomadores de teste nesse nível. MakeMixture pega o
meta-pmf e calcula a distribuição da mistura (ver Seção 5.6).

12.6 Calibração
Se nos fosse dada a distribuição da dificuldade, poderíamos usar o
MakeRawScoreDist para calcular a distribuição de pontuações brutas. Mas
para nós o problema é o contrário: recebemos a distribuição do escore
brutoequeremos inferir a distribuição da dificuldade.
Assumo que a distribuição da dificuldade é uniforme com parâmetros
central e largura.. MakeDifficulties faz uma lista de dificuldades com esses
parâmetros.
def MakeDifficulties (centro, largura, n): low,
alto = centro-largura, centro+largura
retorno numpy.linspace (baixo, alto, n)
Ao experimentar algumas combinações, descobri que centro=-0,05 e
largura=1,8 produzem uma distribuição de escores brutos semelhantes aos
dados reais, como mostrado na Figura 12.3.
12.7. Posterior distribution of efficacy 139

1.0

Dados
Modelo

0.8

0.6

Cdf
0.4

0.2

0.0
0

10 20 30 40 50 60
pontuação bruta

Figura 12.3: Distribuição real de escores brutos e um modelo para encaixá-lo.

Assim, assumindo que a distribuição da dificuldade é uniforme, seu


alcance é ap-proximamente -1,85 a 1,75, dado que aeficácia é gaussiana
com média 0 e desvio padrão 1,5.

A tabela dedevendo foll mostra a gama de ProbCorrect para os tomadores


de teste em níveis de eficácia dif-ferent:

Dificuldade
Eficáci - - 1.7
a 1.85 0.0 5
5
3.00 0.99 0.9 0.7
5 8
1.50 0.97 0.8 0.4
2 4
0.00 0.86 0.5 0.1
1 5
-1.50 0.59 0.1 0.0
9 4
-3.00 0.24 0.0 0.0
5 1
Alguém com eficácia 3 (dois desvios padrão acima da média) tem 99% de
chance de responder às perguntas mais fáceis do exame, e 78% de chance
de responder as mais difíceis. Na outra ponta da faixa, alguém com dois
desvios padrão abaixo da média tem24% de chance de responder às
perguntas mais fáceis.

12.7 Distribuição posterior da eficácia


Agora que o modelo está calibrado, podemos calcular a distribuição
posterior da eficácia para Alice e Bob. Aqui está uma versão da classe Sat
que usa o novo modelo:
140 Capítulo 12. Provas

1.0

posterior 780
posterior 740
0.8

0.6

Cdf
0.4

0.2

0.0
0 1 2 3 4
Eficácia

Figura 12.4: Distribuições posteriores de eficácia para Alice e Bob.

classe Sat2 (thinkbayes. Suíte):

Def __init__(self, exam, score):


auto.exame =
autoexame.score =
pontuação

# comece com o gaussiano anterior


eficácias = thinkbayes. MakeGaussianPMF(0, 1.5, 3) thinkbayes. Suite.__init__(self,
efficacies)

# update baseado em uma pontuação de exame


self. Atualização (pontuação)

A atualização invoca a Probabilidade, quecalcula a probabilidade de uma


determinada pontuação de teste para um nível hipotético de eficácia.

def Probabilidade (self, dados, hypo):


eficácia = hipo
pontuação = dados
bruto = auto.exame.Reverso(escore)

pmf = self.exam.PmfCorrect (eficácia)


como = pmf. Prob(bruto)
retornar como

PMF é a distribuição de escores brutos para um tomador de teste com a eficácia dada;
como é a probabilidade da pontuação observada.
12.8. Predictive distribution 141

A Figura 12.4 mostra as distribuições posteriores de eficácia para Alice e


Bob. Como esperado, a localização da distribuição de Alice é mais à
direita, mas novamente há alguma sobreposição.
Usando TopLevel novamente, comparamos A, a hipótese de que a eficácia
deAlice é maior, e B, a hipótese de que Bob é maior. A relação de
probabilidade é de 3,4, um pouco menor do que o que obtivemos do
modelo simples (3.8). Portanto, este modelo indica que os dados são
evidências a favor de A,mas um pouco maisfracos que a estimativa
anterior.
Se nossa crença anterior é que A e B são igualmente prováveis, então à luz
desta evidência daríamos a A uma probabilidade posterior de 77%,
deixando uma chance de 23% de que a eficácia de Bob é maior.

12.8 Distribuição preditiva


A análise que fizemos até agora gera estimativas para a eficácia de Alice e
Bob, mas como a eficácia não é diretamente observável, é difícil validar os
resultados.
Para dar ao modelo poder preditivo, podemos usá-lo para responder a uma
pergunta relacionada: "Se Alice e Bob fizerem o exame de matemática
novamente, qual é a chance de Alice fazer melhor de novo?"
Responderemos a esta pergunta em duas etapas:

• Usaremos a distribuição posterior da eficácia para gerar uma


distribuição preditiva de pontuação bruta para cada testador.

• Vamos comparar as duas distribuições preditivas para calcular a


proba-bility que Alice recebe uma pontuação mais alta novamente.

Já temos a maior parte do código que precisamos. Para calcular as


tributrações preditivas, podemos usar MakeRawScoreDist novamente:
exame = Exame()
a_sat = Sáb(exam, 780)
b_sat = Sáb(exame, 740)

a_pred = exame. MakeRawScoreDist(a_sat)


b_pred = exame. MakeRawScoreDist(b_sat)
Então podemos encontrar a probabilidade de Alice fazer melhor no
segundo teste, Bob faz melhor, ou eles empatam:
142 Capítulo 12. Provas

1.00

0.95

p_correct Bob
0.90

0.85

0.80
0.80 0.85 0.90 0.95 1.00
p_correct Alice

Figura 12.5: Distribuição posterior conjunta de p_correct para Alice e Bob.

a_like = thinkbayes. PMFProbGreater(a_pred, b_pred)


b_like = thinkbayes. PMFProbLess(a_pred, b_pred) c_like
= thinkbayes. PMFProbEqual (a_pred, b_pred)
A probabilidade de Alice se sair melhor no segundo exame é de 63%, o
que significa que Bob tem 37% de chance de fazer tão bem ou melhor.

Note que temos maiscondence sobre a eficácia de Alice do que sobre o


resultado do próximo teste. As chances posteriores são 3:1 que a eficácia
de Alice é maior, mas apenas 2:1 que Alice vai fazer melhor no próximo
exame.

12.9 Discussão
Começamos este capítulo com a pergunta: "Quão forte é a evidência de
que Alice está mais preparada que Bob?" Diante disso, parece que
queremos testar duas hipóteses: ou Alice está mais preparada ou Bob está.

Mas para calcular as probabilidades dessas hipóteses, temos que


resolverum problema esti mation. Para cada tomador de teste temos que
encontrar a distribuição posterior de p_correct ou eficácia.

Valores como este são chamados de parâmetros incômodos porque não


nos importamos com o que são, mas temos que estimá-los para responder
à pergunta que nos importa.

Uma forma de visualizar a análise que fizemos neste capítulo é traçar o


espaço desses parâmetros. thinkbayes. MakeJoint leva dois PMFs.com...
12.9. Discussion 143

coloca sua distribuição conjunta, e devolve um pmf conjunto de cada par


de valores possíveis e sua probabilidade.
def MakeJoint(pmf1, pmf2):
conjunto = Conjunto()
para v1, p1 em pmf1. Itens():
para v2, p2 em pmf2. Itens(): conjunto.
Conjunto ((v1, v2), p1 * p2)
conjunto de retorno
Esta função pressupõe que as duas distribuições são independentes.

A Figura 12.5 mostra a distribuição posterior conjunta de p_correct para


Alice e Bob. A linha diagonal indica a parte do espaço onde p_correct é a
mesma para Alice e Bob. À direita desta linha, Alice está mais preparada;
à esquerda, Bob está mais preparado.

Em TopLevel.Update, quando calculamos as probabilidades de A e


B,somamos a massa de probabilidade em cada lado desta linha. Para as
células que caem na linha, somamos a massa total e dividimos entre A e B.

O processo que usamos neste capítulo — estimando o incômodo


paramedidores para avaliar a probabilidade de hipóteses concorrentes —
é uma abordagem bayesiana comum para problemas como este.
144 Capítulo 12. Provas
Simulação do

Capítulo 13

Neste capítulo eu descrevo minha solução para um problema colocado


por um paciente com um tumor renal. Acho que o problema é importante
e relevante para pacientes com esses tumores e médicos que os tratam.
E eu acho que a solução é interessante porque, embora seja uma
abordagem bayesiana para o problema, o uso do teorema de Bayes está
implícito. I Apresento a solução e meu código; no final do capítulo
explicarei a parte bayesiana.
Se você quiser mais detalhes técnicos do que eu apresento aqui, você pode
ler o meu artigo sobre otrabalho delena http://arxiv.org/abs/1203.6890.

13.1 O Tumor problema do tumor renal


Sou um leitor frequente e ocasionalmente contribuinte para o fórum de
estatísticas online em http://reddit.com/r/statistics. Em novembro de 2011,
li a seguinte mensagem:

"Eu tenho câncer de rim estágio IV e estou tentandodeterminar


se o câncer se formou antes de eu me aposentar do exército
Dado
as datas de aposentadoria e detecção é possível determinar
quando havia 50% de chance de eu desenvolver a doença? É
possível determinar a probabilidade na data da aposentadoria?
Meu tumor foi de 15,5 cm x 15 cm na detecção. Grau II."

Eucontacentio o autor da mensagem e tenho mais informações; Aprendi


que os veteranos recebem diferentes benefícios se é "mais provável do que
não" que um tumor se formou enquanto estavam no serviço militar (entre
outras considerações).
146 Capítulo 13. Simulação

Distribution of RDT
1.0

0.8

0.6

Cdf
0.4

0.2

model
Dados
0.0
2 1 0 1 2 3 4 5 6 7
RDT (duplicações de volume por ano)

Figura 13.1: CDF de RDT em duplicações por ano.

Como os tumores renais crescem lentamente, e muitas vezes não causam


sintomas, às vezes são deixados sem tratamento. Como resultado, os
médicos podem observar ataxa de crescimento de tumores não tratados
comparando os exames do mesmo paciente em momentos diferentes.
Vários jornais relataram essas taxas de crescimento.

Eu coletei dados de um artigo de Zhang et al1. Entrei em contato com os


autores para ver se conseguia dados brutos, mas eles recusaram por
motivos de privacidade médica. No entanto, eu fui capaz de extrair os
dados que eu precisava imprimindo um de seus gráficos e medindo-os
com uma régua.

Eles relatam taxas de crescimento no tempo de duplicação do ReciproCal


(RDT), que está em unidades de duplicações por ano. Assim, um tumor
com RDT = 1 dobra em volume a cada ano; com RDT = 2 quadruplica ao
mesmo tempo, e com RDT =
−1, ele metade. A Figura 13.1 mostra a distribuiçãode RDT para 53 pacientes.
Os quadrados são os pontos de dados do papel; a linha é um modelo que
eu me encaixo nos dados. A cauda positiva se encaixa bem em uma
distribuição exponencial, então usei uma mistura de dois exponenciais.

13.2 Um modelo simples


Geralmente é uma boa ideia começar com um modelo simples antes de
tentar algo mais desafiador. Às vezes, o modelo simples é suficiente para o
1
Zhang et al, Distribuição das Taxas de Crescimento do Tumor Renal Determinada
sustais por meio de medições de tomografia volumétrica serial, janeiro de 2009 Radiologia,
250, 137-144.
13.2. A simple model 147

problema em mãos, e se não, você pode usá-lo para validar o modelo mais
complex.
Para o meu modelo simples, eu assumo que os tumores crescem com um
tempo de duplicação constante, e que eles são tridimensionais no sentido
de que se a medição linear máxima dobra, o volume é multiplicado por
oito.
Aprendi com meu correspondente que o tempo entre sua alta militar e seu
diagnóstico foi de 3291 dias (cerca de 9 anos). Então meu primeiro cálculo
foi: "Se esse tumor crescesse na taxa mediana, quão grande teria sido na
data da alta? "
O tempo médio de duplicação do volume relatado por Zhang et al é de
811 dias. Assumindo a geometria tridimensional, o tempo de duplicação
para uma medida linear é três vezes maior.
# tempo entre a alta e o diagnóstico, no intervalo de dias =
3291,0

# dobrar o tempo na medida ar linhaé dobrar o tempo em volume * 3 dt =


811.0 * 3

# número de duplicações desde as duplicações


de descarga = intervalo / dt

# quão grande era o tumor no momento da descarga (diâmetro em


cm) d1 = 15,5
d0 = d1 / 2,0 ** duplicações
Você pode baixar o código neste capítulo de http://thinkbayes.com/
kidney.py. Para obter mais informações, consulte a Seção 0.3.

O result, d0,tem cerca de 6 cm. Então, se este tumor se formou após a data
da descarga, ele deve ter crescido substancialmente mais rápido do que a
taxa mediana. Lá, concluí que é "mais provável do que não" que este
tumor tenha se formado antes da data da alta.
Além disso, calculei a taxa de crescimento que estaria implícita se esse
tumor tivesse se formado após a data da alta. Se assumirmos um tamanho
inicial de 0,1 cm, podemos calcular o número de duplicações para chegar a
um tamanho final de 15,5 cm:
# assumir uma medida linear inicial de 0,1 cm d0 =
0,1
d1 = 15,5
148 Capítulo 13. Simulação

# quantas duplicações seriam necessários para ir de d0 a d1


duplicações = log2(d1 / d0)

Que tempo linear de duplicação isso implica? dt =


intervalo / duplicações

# calcular o tempo de duplicação volumétrica e RDT


vdt = dt / 3
rdt = 365 / vdt
dt é tempo de duplicação linear, então vdt é tempo de duplicação
volumétrica, e rdt é tempo de duplicação recíproco.

O número de duplicações, em medida linear, é de 7,3, o que implica um RDT de


2.4. Nos dados de Zhang et al, apenas 20% dos tumores cresceram tão
rápido durante um período de observação. Então, novamente, concluí que
é "mais provável do que não" que o tumor formou prior até a datada alta.

Estes cálculos são suficientes para responder à pergunta como colocada, e


em nome do meu correspondente, escrevi uma carta explicando minhas
conclusões à Administração de Benefícios dos Veteranos.

Mais tarde eu disse a um amigo, que é oncologista, sobre meus resultados.


the Ele foi surdo- prendido pelas taxas de crescimento observadas por
Zhang et al, e pelo que eles implicam sobre as idades desses tumores. Ele
sugeriu que os resultados poderiam estar em teres para pesquisadores e
médicos.

Mas para torná-los úteis, eu queria um modelo mais geral da relação entre
idade e tamanho.

13.3 Um modelo mais geral


Dado o tamanho de um tumor no momento do diagnóstico, seria mais útil
saber a probabilidade de que o tumor se formou antes de qualquer data;
em outras palavras, a distribuição de idades.

Para encontrá-lo, faço simulações de crescimento tumoral para obter a


distribuição de tamanho condicionada à idade. Então podemos usar uma
abordagem bayesiana para obter a distri-bution da idade condicionada ao
tamanho.
A simulação começa com um pequeno tumor e executa estas etapas:

1. Escolha uma taxa growth a partir da distribuição de RDT.


13.3. A more general model 149

Simulações de crescimento de tumores


20

diâmetro (cm, escala de tronco)


10

0.5

0.2
0 5 10 15 20 25 30 35 40
idade do tumor (anos)

Figura 13.2: Simulações de crescimento do tumor, tamanho versus tempo.

2. Calcule o tamanho do tumor no final de um intervalo.

3. Registre o tamanho do tumor em cada intervalo.

4. Repita até que o tumor exceda o tamanho máximo relevante.

Para o tamanho inicial escolhi 0,3 cm, porque os carcinomas menores do


que os que são menos propensos a serem invasivos e menos propensos a
ter o suprimento de sangue necessário para o rápido crescimento (ver
http://en.wikipedia.org/wiki/Carcinoma_in_situ).

Escolhi um intervalo de 245 dias (cerca de 8 meses) porque esse é o tempo


médio entre as medições na fonte de dados.

Para o tamanho máximo escolhi 20 cm. Na fonte de dados, o intervalo de


tamanhos ob-servidos é de 1,0 a 12,0 cm, por isso estamos extrapolando
além da faixa observada em cada extremidade, mas não de longe, e não de
forma provável de ter um forte efeito sobre os resultados.

A simulação baseia-se em uma grande simplificação: a taxa de


crescimento é escolhida independentemente durante cada intervalo,
portanto não depende da idade, tamanho ou taxa de crescimento durante
os intervalos anteriores. growth rate during previous

Na Seção 13.7 eu reviso essas suposições e considero mod-els mais


detalhados. Mas primeiro vamos olhar para alguns examples.

A Figura 13.2 mostra o tamanho dos tumores simulados em função da


idade. A linha tracejada de 10 cm mostra a faixa etária dos tumores nesse
tamanho: o tumor que mais cresce chega lá em 8 anos; o mais lento leva
mais de 35.
150 Capítulo 13. Simulação

Estou apresentando resultados em termos de medições lineares, mas os


cálculos são em termos de volume. Para converter de um para o outro,
novamente, eu uso o volume de uma esfera com o diâmetro dado.

13.4 Implementação
Aqui está o kernel da simulação:
def MakeSequence(rdt_seq, v0=0,01, interval=0,67, vmax=Volume(20,0)): seq =
v0,
idade = 0

para rdt em rdt_seq:


intervalo de idade
+=
final, seq = ExtendSequence (idade, seq, rdt, intervalo) se
final > vmax:
Quebrar

retorno seq
rdt_seq é um iterator que produz valores aleatórios do CDF da taxa de
crescimento. v0 é o volume inicial em mL. intervalo é o passo de tempo em
anos. vmax é o volume final correspondente a uma medição linear de 20
cm.
O volume se converte da medição linear em cm para o volume em mL, com
base na simplificação de que o tumor é uma esfera:
def Volume (diâmetro, fator=4*math.pi/3): fator
de retorno * (diâmetro/2,0)**3
ExtendSequence calcula o volume do tumor no final do inter-val.
def ExtendSequence (idade, seq, rdt, intervalo): inicial =
seq[-1]
duplicações = rdt * intervalo final
= inicial * 2**duplicações new_seq
= seq + (final,) cache. Adicionar
(idade, new_seq, rdt)

retorno final, nova_seq


idade é a idade do tumor no final do intervalo. seq é uma tuple que contém
os volumes até agora. rdt é a taxa de crescimento durante o intervalo, em
duplicações por ano. intervalo é o tamanho do passo de tempo em anos.
13.5. Caching the joint distribution 151

diâmetro (cm, escala de tronco)


20

10

0.5

0.2
0 5 10 15 20 25 30 35 40
Idades

Figura 13.3: Distribuição conjunta da idade e tamanho do tumor.

Os valores de retorno são finais, o volume do tumor no final do inter-val, e


new_seq, uma novatuple contendo os volumes em seq mais o novo volume
final.

Cache.Add registra a idade e o tamanho de cada tumor no final de cada


intervalo, conforme explicado na próxima seção.

13.5 Caching a distribuição conjunta


É assim que o cache funciona.
cache de classe (objeto):

Def __init__(self):
auto.joint = thinkbayes. Articulação( )
articulada é uma PMF conjunta que registra a frequência de cada par de
tamanho de idade, por isso aproxima-se da distribuição conjunta de idade
e tamanho.
No final de cada intervalo simulado, extendSequence
chamadas Adicionar: # cache de classe

def Add (self, age, seq): final


= seq[-1]
cm = Diâmetro (final)
balde = rodada (CmToBucket(cm)) self.joint.Incr(idade,
balde))
152 Capítulo 13. Simulação

Distribution of age for several diameters


1.0

0.8

0.6

Cdf
0.4

2 Cm
0.2 5 cm
10 cm
15 cm

0.0
0 10 20 30 40 50
idade do tumor (anos)

Figura 13.4: Distribuições de idade, condicionadas em tamanho.

Novamente, a idade é a idade do tumor, e seq é a seqüência de volumes até


agora.

Antes de adicionar os novos dados à distribuição conjunta, usamos


diâmetro para converter de volume para diâmetro em centímetros:
def Diâmetro (volume, fator=3/math.pi/4, exp=1/3.0):
retorno 2 * (fator * volume) ** exp
E CmToBucket para converter de centímetros para um número de balde discreto:
def CmToBucket (x, factor=10): fator
de retorno * math.log(x)
Os baldes são igualmente espaçados em uma escala de log. O uso do
fator=10 rende um número razoável de baldes; por exemplo, mapas de 1
cm para o balde 0 e 10 cm mapas para o balde 23.

Após a execução das simulações, podemos traçar a distribuição articular


como um enredo pseu-docolor, onde cada célula representa o número de
tumores observados em um determinado par de tamanho-idade. pair. A
Figura 13.3 mostra a distribuição conjunta após 1000 simulações.

13.6 Condicionais distribuições


Ao tirar uma fatia vertical da distribuição articular, podemos obter a
distribuição de tamanhos para qualquer idade. Ao tomar uma fatia
horizontal, podemos obter a distribuição de idades condicionadas em
tamanho.
13.6. Conditional distributions 153

Intervalo crível para idade x diâmetro


45

40
95

idade do tumor (anos)


35

30

25
75º 50º 25º

20

15

10

0
0.5 1 2 5 10 20
diâmetro (cm, escala de tronco)

Figura 13.5: Percentis da idade do tumor em função do tamanho.

Aqui está o código que lê a distribuição conjunta e constrói a distribuição


condicional para um determinado tamanho.

# cache de classe

def ConditionalCdf(self, bucket):


pmf = auto.joint.Condicional(0, 1, balde) cdf =
pmf. MakeCdf()
retorno cdf

balde é onúmero inteiro bucket correspondente ao tamanho do tumor.


Conjunto.Condiciona o PMF da idade condicionado ao balde. O resultado é
o CDF de idade condicionado em balde.

A Figura 13.4 mostra vários desses CDFs, para uma variedade de


tamanhos. Para resumir essas distribuições, podemos calcular percentis
em função do tamanho.

percentis = [95, 75, 50, 25, 5]

para balde em cache. GetBuckets():


cdf = ConditionalCdf(balde)
ps = [cdf. Percentil(p) para p em percentis]

A Figura 13.5 mostra esses percentis para cada balde de tamanho. Os


pontos de dados são calculados a partir da distribuição conjunta estimada.
No modelo, tamanho e tempo são discretos, o que contribui com erros
numéricos, por isso também mostro um mínimo quadradopara cada
seqüência de percentis.
154 Capítulo 13. Simulação

13.7 Correlação serial


Os resultados até agora são baseados em uma série de decisões de
modelagem; vamos revisá-los e considerar quais são as fontes de erro mais
prováveis:

• Para converter de medida linear para volume, assumimos que os


tumores são aproximadamente esféricos. Esta suposição é
provavelmente boa para tumores de até alguns centímetros, mas não
para tumores muito grandes.
• A distribuição das taxas de crescimento nas simulações baseia-se em
um modelo con-tinuous que escolhemos para se adequar aos dados
relatados por Zhang et al, que é baseado em 53 pacientes. O ajuste é
apenas aproximado e, mais impor-tantly, uma amostra maior
produziria uma distribuição diferente.
• O modelo de crescimento não leva em conta o subtipo ou grau do
tumor; este íon assumtoé consistente com a conclusão de Zhang et al: "As
taxas de crescimento em tumores renais de diferentes tamanhos,
subtipos e graus representam uma ampla gama e se sobrepõem
substancialmente." Mas com uma amostra maior, uma diferença pode
se tornar aparente.
• A distribuição da taxa de crescimento não depende do tamanho do
tumor. Essa suposição não seria realista para tumores muito pequenos
e muito grandes, cujo crescimento é limitado pelo suprimento de sangue.
Mas os tumores observados por Zhang et al variaram de 1 a 12 cm, e
não encontraram nenhuma relação estatisticamente significante entre
tamanho e taxa de crescimento. Então, se há uma relação, é provável
que seja fraca, pelo menos nesta faixa de tamanho.
• Nas simulações, a taxa de crescimentoh durante cada intervalo é
independente das taxas de crescimento anteriores. Na realidade, é
plausível que tumores que cresceram rapidamente no passado são
mais propensos a crescer rapidamente. Em outras palavras,
provavelmente há uma correlação serial na taxa de crescimento.

Destes, o primeiro e o último parecem os mais problemáticos. Vou


investigar a correlação em série primeiro, depois voltar à geometria
esférica.
Para simular o crescimento correlacionado, escrevi uma geraçãoou2 que
produz uma série correlacionada de um dado Cdf. Veja como o algoritmo
funciona:

1. Generate correlated values from a Gaussian distribution. This is easy


to do because we can compute the distribution of the next value con-
ditioned on the previous value.
2
Se você não estiver familiarizado com geradores Python, consulte
http://wiki.python.org/moin/ Geradores.
13.7. Serial Correlation 155

2. Transforme cada valor em sua probabilidade cumulativa usando o


CDF gaussiano. CDF.

3. Transforme cada probabilidade cumulativa para o valor


correspondente, inserindo o dado Cdf.

Aqui está o que parece em código:


def CorrelatedGenerator (cdf, rho): x =
random.gauss(0, 1)
rendimento Transform(x)

sigma = math.sqrt(1 - rho**2);


enquanto True:
x = random.gauss (x * rho, sigma)
rendimento Transform(x)
cdf é o Cdf desejado; rho é a correlação desejada. Os valores de x são
gaussianos; Transformar converte-os para a distribuição desejada.

O primeiro valor de x é gaussiano com média 0 e desvio padrão 1. Para


valores subseqüentes, a média e o desvio padrão dependem do valor
previ-ous. Dado o xanterior, a média do próximo valor é x * rho, ea
variância é 1 - rho**2.

Transforme mapas de cadavalor aussiano G, x, para um valordo dado Cdf,


y.
def Transform(x):
p = thinkbayes. GaussianCdf(x)
y = cdf. Valor(p)
retorno y
GaussianCdf calcula o CDF da distribuição gaussiana padrão em
x,retornando uma probabilidadecumulativa. probability. Cdf.Value mapeia
de uma probabilidade cumulativa para o valor correspondente em cdf.

Dependendo da forma do cdf,as informações podem ser perdidas na


transformação, de modo que a correlação real pode ser menor do que rho.
Por exemplo, quando eu gen-erate 10000 valores da distribuição detaxas
de linha gcom rho =0,4, acorrelação real é de 0,37. Mas já que estamos
supondo a correlação certa de qualquer maneira, isso é perto o suficiente.

Lembre-se que MakeSequence toma um iterator como argumento. Essa


inter-face permite que ele trabalhe com diferentes orasgeradoras:
156 Capítulo 13. Simulação

Série Diâmetr Percentis da idade


Correlaçã o 5º Di 50 75 95
o (cm) a
25.
0.0 6. 10. 15. 19. 23. 30.
0.4 0 7 4 5 5 2
6. 9. 15. 20. 26. 36.
0 4 4 8 2 9
Tabela 13.1: Percentis da idade tumoral condicionados ao tamanho.

iterizador = Gerador Não Correlacionado


(cdf) seq1 = MakeSequence (iterator)

iterizador = Gerador Correlacionado (cdf,


rho) seq2 = MakeSequence(iterator)
Neste exemplo, seq1 e seq2 são extraídos da mesma distribuição, mas os
valores em seq1 não estão correlacionados e os valores em seq2 estão
correlacionados com um coeficiente de aproximadamente rho.

has Agora podemos ver o efeito da correlação serial nos resultados; a


tabela de acompanhamento mostra acentiles de idade para um tumor de
6cm, utilizando o gerador não correlacionado e um gerador correlacionado
com alvo ρ = 0,4.

A correlação torna os tumores que crescem mais rápido e os mais lentos,


de modo que a faixa etária é maior. A diferença é modesta para percentis
baixos, mas para o percentil 95 é mais de 6 anos. Para calcular esses
percentis com precisão, precisaríamos de uma melhor estimativa da relação
real de cor-série.

No entanto, esse modelo é suficiente para responder à pergunta que


começamos: dado um tumor com uma dimensão linear de 15,5 cm, qual é
a probabilidade de que ele tenha se formado há mais de 8 anos?

Aqui está o código:


# cache de classe

def ProbOlder (self, cm, age):


bucket = CmToBucket(cm)
cdf = self. CondicionalCdf(bucket) p =
cdf. Prob (idade)
retornar 1-p
cm é o tamanho do tumor; idade é o limite de idade em anos. ProbOlder
converte tamanho em um número de balde, recebe o Cdf da idade
condicionado no balde, e calcula a probabilidade de que a idade exceda o
valor dado.
13.8. Discussion 157

Sem correlação serial, a probabilidade de um tumor de 15,5 cm ser maior


que 8 anos é de 0,999, ou quase certa. Com correlação de 0,4, tu-mors de
crescimento mais rápido tu- são mais prováveis, mas a probabilidade
ainda é de 0,995. Mesmo com correlação de 0,8, a probabilidade é de 0,978.

Outra fonte provável de erro é a suposição de que os tumores são


aproximadamente esféricos. Para um tumor com dimensões lineares de
15,5 x 15 cm, essa suposição provavelmente não é válida. Se, como parece
provável, um tumor deste tamanho é relativamente plano, ele pode ter o
mesmo volume de uma esfera de 6 cm. Com esse volume menor e
correlação de 0,8, a probabilidade de idade maior than 8 ainda é de95%.

Assim, mesmo levando em conta os erros de modelagem, é improvável


que um tumor tão grande possa ter se formado menos de 8 anos antes da
data do diagnóstico.

13.8 Discussão
Bem, nós passamos por um capítulo inteiro sem usar o teorema de Bayes ou o
Classe de suíte que encapsula atualizações bayesianas. O que é que aconteceu?

Uma maneira de pensar sobre o teorema de Bayes é como um algoritmo


para inverter probabilidades condicionais.
| Dado p(B A), podemos calcular
p(Um B), desde que nós Sei p(A) E p(B). De Curso Este Algoritmo É Só
Útil Se Para alguma razão, é mais fácil calcular p(B|A) Que p(A|B).

Neste exemplo, é. Executando simulações, podemos estimar a distri-


bution de tamanho condicionado à idade, |ou p (idade de tamanho). Mas é
mais difícil obter a distribuição da idade condicionada
| em tamanho, ou
p(tamanho da idade). Então esta parece ser uma oportunidade perfeita para
usar o teorema de Bayes.
A razão pela qual eu não fiz isso é computacional Eficiência.| Para
Estimativa p(Tamanho Idade ) para qualquer Dado Tamanho Você Tem
Para Executar a Muito
| De Simulações. Ao longo O Maneira Você acabam
computando p(Tamanho Idade ) para um monte de tamanhos. Na verdade,
você acaba computando toda a distribuição conjunta de tamanho e idade,
p(Tamanho, Idade).

E Quando Você Tem O Conjunta Distribuição Você Não Realmente


Precisa Bayes o- orem, Você| Cna Extrair p(Idade Tamanho) Por Levar
Fatias De O Conjunta distribuição, como demonstrado em CondicionalCdf.
Então, nós despedimos bayes, mas ele estava conosco em espírito.
158 Capítulo 13. Simulação
Capítulo 14

Um Modelo Hierárquico

14.1 O problema do contador Geiger


Tive a ideia do seguinte problema de Tom Campbell-Ricketts, autor do
blog "Entropia Máxima" na http://maximum-entropy-blog. blogspot.com. E
ele teve a idéia de E. T. Jaynes, autor do clássico Teoria da Probabilidade: A
Lógica da Ciência::

Suponha que uma fonte radioativa emita partículas em direção


a um contador Geiger a uma taxa média de partículas r por
segundo, mas o contador registra apenas uma fração, f , das
partículas que o atingem. Se f é 10% e o contador registra 15
partículas em um intervalo de um segundo, qual é a
distribuição posterior de n, o número real de partículas
queatingem o contador, e r, as partículas de taxa média são
emitidas?

Para começar um problema como este, pense na cadeia de causalidade que


começa com os parâmetros do sistema e termina com os dados
observados:

1. A fonte emite partículas a uma taxa média, r.

2. Durante um dado segundo, a fonte emite n partículas em direção ao


balcão.
3. Dessas n partículas, algum número, k,são contados.

A probabilidade de um átomo decair é a mesma a qualquer momento,


então a decadência radioativa é bem modelada por um processo de
Poisson. Dado r, o distri-bution de n é a distribuição poisson com
parâmetro r.
160 Capítulo 14. Um Modelo
Hierárquico

0.045

0.040
100
250
0.035 400

0.030

0.025

Pmf
0.020

0.015

0.010

0.005

0.000
0 100 200 300 400 500
Número de partículas (n)

Figura 14.1: Distribuição posterior de n para três valores de r.

E se assumirmos que a probabilidade de detecção de cada partícula é


inde-pendente das outras, a distribuição de k é a distribuição binomial
com parâmetros n e f .
Dado os parâmetros do sistema, podemos encontrar a distribuição dos
dados. Assim, podemos resolver o que é chamado de problema futuro. .
Agora queremos ir para o outro lado: dado os dados, queremos a
distribuição dos parâmetros. Isso é chamado de problema inverso. E se
você pode resolver o problema futuro, você pode usar métodos bayesianos
para resolver o problema inverso.

14.2 Comece simples


Vamos começar com uma versão simples do problema onde sabemos o
valor de r. Nos é dado o valor de f, então tudo o que temos que fazer é
estimar n.
Eu defino um Suite chamado Detector que modela o comportamento do
detector e estima n.
detector de classe (thinkbayes. Suíte):

Def __init__(self, r, f, high=500, step=1):


pmf = thinkbayes. MakePoissonPMF(r, alto, step=step) thinkbayes. Suite.__init__(self,
pmf, name=r)
auto.r = r self.f =
f
14.3. Make it hierarchical 161

Se a taxa média de emissão for de partículas r por segundo, a distribuição


de n é Poisson com parâmetro r. alta e etapa determinar o limite superior
para n e o tamanho da etapa entre valores hipotéticos.
Agora precisamos de uma função de probabilidade:
Detector de classes #

def Probabilidade (self, data, hypo): k


= dados
n = hipo
p = self.f

retorno thinkbayes. EvalBinomialPMF(k, n, p)


dados são o número de partículas detectadas, e hypo é o hipotético num-
ber de partículas emitidas, n.
Se há realmente n partículas, e acapacidade prob de detectar qualquer
uma delasé f , a probabilidade de detectar partículas k é dada pela
distribuição binomial.
Isso é tudo para o Detector. Podemos experimentá-lo para uma variedade de valores de r::
f = 0,1
k = 15

para r em [100, 250, 400]:


suíte = Detector (r, f, step=1) suite.
Atualização(k)
suíte de impressão. Máxima Probabilidade()
A Figura 14.1 mostra a distribuição posterior de n para vários valores dados de
r.

14.3 Torná-lo hierárquico


Na seção anterior, presumimos que r é conhecido. Agora vamos relaxar
essa assumção. Eu defino outra Suíte, chamada Emitter,que modela o
comportamento do emissor e estima r::
classe Emissor (thinkbayes. Suíte):

Def __init__(self, rs, f=0.1):


detectores = [Detector(r, f) para r em rs] thinkbayes.
Suite.__init__ (self, detectores)
162 Capítulo 14. Um Modelo
Hierárquico
rs é uma seqüência de valor hipotético para r. detectores é uma seqüência
de objetos detector, um para cada valor de r. Os values na Suíte são Detec-
tors, então o Emitter é uma meta-Suite; ou seja, uma Suíte que contém
outras Suítes como valores.

Para atualizar o Emissor, temos que calcular a probabilidade dos dados


cada valor hipotético de r. Mas cada valor de r é representado por um
Detector que contém uma gama de valores para n.

Para calcular a probabilidade dos dados para um determinado Detector,


fazemos loop através dos valores de n e somamos a probabilidade total de
k. É isso que o SuiteLikelihood faz:
Detector de classes #

def SuiteProbabilidade(self, dados):


total = 0
para hipo, prob em si mesmo. Itens():
como = eu. Probabilidade (dados, hip)
total += prob * como
retorno total
Agora podemos escrever a função Probabilidade para o Emissor:
# emitter classe

def Probabilidade (self, dados, hypo):


detector = hypo
como = detector. Retorno do SuiteLikelihood
(dados) como

Cada hypo é um Detector, então podemos invocar suitelikelihood para


obter a capa dos dados a hipótese.

Depois de atualizar o Emissor, temos que atualizar cada um dos Detectores, também.
# emitter classe

def Update(self, data): thinkbayes. Suite.Update (self,


data)

para detector em si mesmo. Valores(): detector.


Atualização()
Um modelo como este, com vários níveis de Suítes, é chamado hierárquico..
14.4. A little optimization 163

0.06

r posterior
0.05 posterior N

0.04

Pmf
0.03

0.02

0.01

0.00
0 100 200 300 400 500
Taxa de emissão

Figura 14.2: Distribuições posteriores de n e r.

14.4 Um pouco de otimização


Você pode reconhecer SuiteLikelihood; nós vimos na Seção 11.2. Na época,
eu apontei que nós realmente não precisávamos dele, porque a capacidade
prob total prob- calculada pelo SuiteLikelihood é exatamente a
normalização constante computada e devolvida pelo Update.

Assim, em vez de atualizar o Emissor e, em seguida, atualizar os


Detectores, podemos do ambos ospassos ao mesmo tempo, usando o
resultado do Detector.Update como a probabilidade de Emissor.

Aqui está a versão simplificada do


Emissor.Probabilidade: # emissor de classe

def Probabilidade (self, data, hypo): retorno


hipo. Atualização (dados)
E com esta versão do Likelihood podemos usar a versão padrão do Update.
Assim, esta versão tem menos linhas de código, e funciona mais rápido
porque não computa a constante normalizadora duas vezes.

14.5 Extraindo os posteriores


Depois de atualizar o Emissor, podemos obter a distribuição posterior de r
através do looping através dos Detectores e suas probabilidades:
164 Capítulo 14. Um Modelo
Hierárquico
# emitter classe

def DistOfR(self):
itens = [(detector.r, prob) para detector, prob em self. Itens()] retornam
thinkbayes. MakePMFFromItems(itens)
itens é uma lista de valores de r e suas probabilidades. O resultado é o PMF de
r.
Para obter a distribuição posterior de n,temos que calcular a
misturadosDetectores. Podemos usar thinkbayes. MakeMixture, que leva um
meta-PMF que mapeia de cada distribuição para sua probabilidade. E isso
é exatamente o que o Emissor é:
# emitter classe

def DistOfN(self):
retorno thinkbayes. MakeMixture(self)
A Figura 14.2 mostra os resultados. Não surpreendentemente, o valor
mais provável para n é 150. Dado f e n,a contagem esperada é k = f n,
assimdado f e k, o valor esperadode n é k/ f , que é 150.

E se 150 partículas são emitidas em um segundo, o valor mais provável de


r é 150 partículas por segundo. Assim, a distribuição posterior de r
também está centrada em 150.

As distribuições posteriores de r e n são semelhantes; a única diferença é


que estamos ligeiramente menos certos sobre n. Em geral, podemos estar
mais certos sobre a taxa de emissão de longo alcance, r, do que sobre o
número de partículas emitidas em qualquer segundo particular, n.

Você pode baixar o código neste capítulo de http://thinkbayes.com/


jaynes.py. Fou mais informações consulte a Seção 0.3.

14.6 Discussão
O problema do contador Geiger demonstra a conexão entre causa-causa e
modelagem hierárquica. No exemplo, a taxa de emissão r tem um efeito
causal sobre o número deartigosp, n, que tem um efeitocausal na
contagem de partículas, k.

O modelo hierárquico reflete a estrutura do sistema, com causas na parte


superior e efeitos na parte inferior.
14.7. Exercises 165

1. No nível superior, começamos com uma gama de valores hipotéticos para r.

2. Para cada valor de r, temos uma faixa de valores para n, ea


distribuição prévia de n depende de r.

3. Quando atualizamos o modelo, vamos de baixo para cima.


Calculamos uma distribuição poste-rior de n para cada valor de
r,emseguida, computamos a distribuição posterior de r.

Então a informação causal flui pela hierarquia, e a inferência flui para cima.

14.7 Exercícios
Exercício 14.1. O exercício de Thitambém é inspirado por um exemplo em
Jaynes, Probability Theory.

Suponha que você compre uma armadilha de mosquitos que deve reduzir a
população de mosquitos perto de sua casa. Toda semana, você esvazia a armadilha
e conta o num-ber de mosquitos capturados. Naprimeira semana, você conta 30
mosquitos. Depois da segunda semana, você conta 20 mosquitos. Estimar a
mudança percentual no número de mosquitos em seu quintal.

Para responder a essa pergunta, você tem que tomar algumas decisões de
modelagem. Aqui estão algumas sugestões:

• Suponha que a cada semana um grande número de mosquitos, N, é criado


em um pântano perto de sua casa.

• Durante a semana, algumas frações deles, f1, vagueiam pelo seu quintal, e
dessas algumas frações, f2, são pegos na armadilha.

• Sua solução deve levar em conta sua crença prévia sobre o quanto N
provavelmente mudará de uma semana para outra. Você pode fazero chapéu
adicionando um nível à hierarquia para modelar a mudança percentual em
N. can do t
166 Capítulo 14. Um Modelo
Hierárquico
Capítulo 15

Lidando com Dimensões

15.1 Bactérias do umbigo


O Belly Umbigbiodiversity 2.0 (BBB2) é um projeto nacional de ciência
cidadã com o objetivo de identificar espécies bacterianas que podem ser
encontradas em umbigos humanos (http://bbdata.yourwildlife.org). O
projeto pode parecer caprichoso, mas faz parte de um crescente interesse
pelo microbioma humano, o conjunto de microrganismos que vivem na
pele humana e em partes do corpo.

Em seu estudo piloto, os pesquisadores do BBB2 coletaram cotonetes dos


umbigos de 60 voluntários, usaram pirosequenciamento demultiplex para
extrair e seqüenciar frag-ments de 16S rDNA, em seguida, identificaram a
espécie ou gênero de onde os fragmentos vieram. Cada fragmento
identificado é chamado de "leitura".

Podemos usar esses dados para responder a várias perguntas relacionadas:

• Com base no número de espécies observadas, podemos estimar o


número total de espécies no meio ambiente?

• Podemos estimar a prevalência de cada espécie; ou seja, a fração da


população total pertencente a cada espécie?

• Se estamos planejando coletar amostras adicionais, podemos prever


quantas novas espécies provavelmente descobriremos?

• Quantos anúncios adicionaissão necessários para aumentar a fração


de espécies ob-servidas a um determinado limiar?

Essas perguntas compõem o que é chamado de problema das espécies invisíveis..


168 Capítulo 15. Lidando com Dimensões

15.2 Leões, tigres e ursos


Começarei com uma versão simplificada do problema onde sabemos que
existem are exatamente três espécies. Vamos chamá-los de leões, tigres e
ursos. Suponha que visitemos uma reserva de animais selvagens e vejamos
3 leões, 2 tigres e um urso.

Se tivermos uma chance igual de observar qualquer animal na


preservação, o número de cada espécie que vemos é regido pela
distribuição multinomial. Se a prevalência de leões e tigres e ursos é p_lion
e p_tiger e p_bear,, a probabilidade de ver 3 leões, 2 tigres e um urso é
proporcional à
p_lion**3 * p_tiger**2 * p_bear**1
Uma abordagem tentadora, mas não correta, é usar distribuições beta,
como na Seção 4.5, para descrever a prevalência de cada
eciesseparadamente. Por exemplo, vimos 3 leões e 3 não leões; se
pensarmos nisso como 3 "cara" e 3 "coroas", então a distribuição posterior
de p_lion é:
beta = thinkbayes. Beta() beta.
Atualização(((3, 3))
imprimir beta. Máxima Probabilidade()
A estimativa de probabilidade máxima para p_lion é a taxa observada,
50%. Da mesma forma, os MLEs para p_tiger e p_bear são 33% e 17%.

Mas há dois problemas:

1. Usamos implicitamente um anterior para cada espécie que é


uniforme de 0 a 1, mas como sabemos que existem três
especificações,isso anterior não é correto. O direito anterior deve ter
uma média de 1/3, e não deve haver probabilidade zero de que
qualquer espécie tenha uma prevalência de 100%.

2. As distribuições para cada espécie não são independentes, pois as


prevalências devem somar 1. Para capturar essa dependência,
precisamos de uma distribuição conjunta para as três prevalências.

Podemos usar uma distribuição de Dirichlet para resolver esses dois


problemas (ver http://en.wikipedia.org/wiki/Dirichlet_distribution). Da
mesma forma que usamos a distribuição beta para descrever a distribuição
de viés para uma moeda, podemos usar uma distribuição de Dirichlet para
descrever a distribuição conjunta de p_lion, p_tiger e p_bear.

A distribuição de Dirichlet é a generalização multidimensional da


distribuição beta. Em vez de dois resultados possíveis, como cara e coroa,
15.2. Lions and tigers and bears 169

a distribuição de Dirichlet lida com qualquer número de resultados: neste


exame-ple, três espécies.

Se houver n resultados, a distribuição de Dirichlet é descrita por n parame-


ters, escrito α1 a αn.

Aqui está a definição, de thinkbayes.py,de uma classe que representa uma


distribuição de Dirichlet:
classe Dirichlet (objeto):

Def __init__(self, n):


self.n = n
self.params = numpy.ones(n, dtype=numpy.int)
n é o número de dimensões; inicialmente os parâmetros são todos 1. Eu
uso uma matriz numpy para armazenar os parâmetros para que eu possa
tirar proveito de operações de matriz.
Dada uma distribuição de Dirichlet, a distribuição marginal para cada
prevalência é uma distribuição beta,que podemos calcularassim:
def MarginalBeta(self, i): alfa0 =
self.params.sum() alfa =
self.params[i]
retorno Beta (alfa, alfa0-alfa)
i é o índice da distribuição marginal que queremos. alfa0 é a soma dos
parâmetros; alfa é o parâmetro para a determinada espécie.

No exemplo, a distribuição marginal prévia para cada espécie é Beta(1, 2).


Podemos calcular os meios anteriores como este:
dirichlet = thinkbayes. Dirichlet(3) para
i no intervalo(3):
beta = dirichlet. Beta de impressão
marginalbeta(i). Média()
Como esperado, a prevalência média anterior para cada espécie é de 1/3.

Para atualizar a distribuição de Dirichlet, adicionamos as observações aos


param-eters como este:
def Update(self, data): m
= len(dados)
self.params[:m] += dados
Aqui os dados são uma seqüência de contagens na mesma ordem que
params,por isso, neste exemplo, deve ser o número de leões, tigres e ursos.
170 Capítulo 15. Lidando com Dimensões

0.035

Leões
0.030 tigres ursos

0.025

0.020
Prob

0.015

0.010

0.005

0.000
0.0 0.2 0.4 0.6 0.8 1.0
Prevalência

Figura 15.1: Distribuição das prevalências para três espécies.

os dados podem ser mais curtos do que os params;nesse caso, existem


algumas espécies que não foram observadas.

Aqui está o código que atualiza o dirichlet com os dados observados e


calcula as distribuições marginais posteriores.
dados = [3, 2, 1] dirichlet.
Atualização (dados)

para i no intervalo(3):
beta = dirichlet. MarginalBeta(i) pmf
= beta. MakePMF()
imprimir i, PMF. Média()
A Figura 15.1 mostra os resultados. As prevalências médias posteriores
são 44%, 33% e 22%.

15.3 A versão hierárquica


Resolvemos uma versão simplificada do problema: se soubermos quantas
espécies existem, podemos estimar a prevalência de cada uma.

Agora vamos voltar ao problema original, estimando o número total de


espécies. Para resolver esse problema vou definir um meta-Suite, que é
uma Suíte que contém outras Suítes como hipóteses. In Neste caso, o
Conjunto de alto nível contém hipóteses sobre o número de espécies; o
nível inferior contém hipóteses sobre prevalências.
15.3. The hierarchical version 171

Aqui está a definição de classe:


classe Espécies (thinkbayes. Suíte):

Def
__init__(self, ns):
hipos = [thinkbayes. Dirichlet(n) para n em ns] thinkbayes. Suite.__init__(self,
hypos)
__init__ pega uma lista de valores possíveis para n e faz uma lista de
objetos Derichlet.

Aqui está o código que cria a suíte de nível superior:


ns = intervalo (3, 30)
suíte = Espécies(ns)
ns é a lista de valores possíveis para n. Vimos 3 espécies, então tem que
haver pelo menos tantas. many. Escolhi um limite superior que parece
razoável, mas vamos verificar mais tarde que a probabilidade de
ultrapassar esse limite é baixa. E pelo menos inicialmente assumimos que
qualquer valor nesta faixa é igualmente provável.

Para atualizar um modelo hierárquico, você tem que atualizar todos os


níveis. Normalmente você tem que atualizar o nível inferior primeiro e
trabalhar para cima, mas neste caso podemos atualizar o nível superior
primeiro:
#class

def Update(self, data): thinkbayes.


Suite.Update(self, data) for hypo in self.
Valores():
Hipo. Atualização (dados)
Species.Update invoca atualização na classe pai, em seguida, loops através
das sub-hipóteses e atualizá-los.

Agora tudo o que precisamos é de uma função de probabilidade:


# espécies de classe

def Probabilidade (self, data, hypo):


dirichlet = hypo
como = 0
para i no intervalo(1000):
como += dirichlet. Retorno de

probabilidade (dados) como


172 Capítulo 15. Lidando com Dimensões

dados são uma seqüência de contagens observadas; hypo é um objeto de


Dirichlet. object. Species.Likelihood chama Dirichlet.Likelihood 1000 vezes e
retorna o total.
Por que chamar mil vezes? Porque Dirichlet.Likelihood não calcula a
probabilidade dos dados toda a distribuição de Dirichlet. Em vez disso,
retira uma amostra da distribuição hipotética e coloca a probabilidade dos
dados sob o conjunto amostrado de prevalências.
Eis o que parece:
# classe Dirichlet

def Probabilidade (self,


dados): m = len(dados)
se self.n < m:
retorno 0

x = dados
p = self. Random()
q = p[:m]**x return
q.prod()
O comprimento dos dados é o número de espécies observadas. Se vermos
mais espécies do que pensávamos existir, a probabilidade é 0.
Caso contrário, selecionamos um conjunto aleatório de prevalências, p, e
calcular o PMF multi-nomial, que é
x
cX p11 · · · pNxn
pi é a prevalência da espécie i,e xi é o número observado. O primeiro
termo, cx, éo coeficiente multinomial; Deixo isso de fora da computação
porque é um fator multiplicativo que depende apenas dos dados, não da
hipótese, então ele fica normalizado (ver http://en.wikipedia.org/
wiki/Multinomial_distribution).

M é o número de espécies observadas. Nós só precisa do primeiro m


elementos de p; para os outros,
U
xi é 0, então pxEu é 1, e podemos deixá-los
fora do Produto. e

15.4 Amostragem aleatória


Há duas maneiras de gerar uma amostra aleatória de uma destributação
de Dirichlet. Uma delas é usar as distribuições beta marginais, mas nesse
caso você tem que selecionar uma de cada vez e dimensionar o resto para
que eles se somem
15.4. Random sampling 173

0.12

0.10

0.08

Prob
0.06

0.04

0.02

0.00
0 5 10 15 20 25 30
Número de espécies

Figura 15.2: Distribuição posterior de n.

1 (ver number_generation
http://en.wikipedia.org/wiki/Dirichlet_distribution#Random_ ).

Uma maneira menos óbvia, mas mais rápida, é selecionar valores de n


gama distribuções, e então normalizar dividindo-se pelo total. Aquiestá o
código:

# classe Dirichlet

def Random(self):
p = numpy.random.gamma(self.params)
retorno p / p.sum()
Agora estamos prontos para ver alguns resultados. Aqui está o código que
extrai a distribuição posterior de n::
def DistOfN(self):
pmf = thinkbayes. PMF()
para hipo, prob em si mesmo. Itens(): pmf.
Conjunto (hypo.n, prob)
retorno pmf
DistOfN itera através das hipóteses de nível superior e acumula a
probabilidade de cada n.

A Figura 15.2 mostra o resultado. O valor mais provável é 4. Valores de 3


a 7 são razoavelmente prováveis; depois disso, as probabilidades caem
rapidamente. A probabilidade de haver 29 espécies é baixa o suficiente
para ser insignificante; se escolhermos um limite mais alto, obteríamoso
mesmo resultado.
174 Capítulo 15. Lidando com Dimensões

Lembre-se que este resultado é baseado em um uniforme antes de n. Se


tivermos informações de fundo sobre o número de espécies no ambiente,
podemos escolher um antes diferente.

15.5 Otimização
Tenho que admitir que estou orgulhoso deste exemplo. O prob-lem
espécie invisível não é fácil, e eu acho que esta solução é simples e clara, e
leva sur-prisingly poucas linhas de código (cerca de 50 até agora).

O único problema é que é lento. É bom o suficiente para fosão o exemplo


comapenas 3 espécies observadas, mas não o suficiente para os dados do
umbigo, com mais de 100 espécies em algumas amostras.

As próximas seções apresentam uma série de otimizações que precisamos


para fazer essa escala de solução. Antes de entrarmos em detalhes, aqui
está um roteiro.

• O primeiro passo é reconhecer que se atualizarmos as distribuições


de Dirichlet com os mesmos dados, os primeiros parâmetros m são
os mesmos para todos eles. A única diferença é o número de espécies
hipotéticas invisíveis. Portanto, não precisamos de objetos Dirichlet;
podemos armazenar os parâmetros no nível superior da hierarquia.
Species2 implementa essa otimização.

• Species2 também usa o mesmo conjunto de valores aleatórios para


todas as hi-poestes. Isso economiza tempo gerando valores
aleatórios, mas tem um benefício second ond que acaba sendo mais
importante: dando a todas as hipóteses a mesma seleção do espaço
amostral, tornamos o compari-filho entreashipóteses mais justa, por
isso é preciso menos iterações para convergir.

• Mesmo com essas mudanças há um grande problema de


desempenho. À medida que o número de espécies observadas
aumenta, a matriz de preva-lences aleatórias aumenta, e a chance de
escolher uma que é aproximada- mately direita torna-se pequena.
Assim, a grande maioria das iterações produzem pequenas
probabilidades que não contribuem muito para o total, e não
discriminam entre hipóteses.
A solução é fazer as atualizações uma espécie de cada vez. Species4 é
umaimplementação s imple desta estratégia usando objetos Dirichlet
para ressentir-se das subhipóteses.
15.6. Collapsing the hierarchy 175

• Finalmente, Species5 combina as subhipóteses no nível superior e usa


operações de matriz numpy para acelerar as coisas.

Se você não estiver interessado nos detalhes, sinta-se livre para pular para
a Seção 15.9 onde olhamos os resultados dos dados do umbigo.

15.6 Desmoronando a hierarquia


Todas as distribuições de Dirichlet de nível inferior são atualizadas com os
mesmos dados, de modo que os primeiros parâmetros m são os mesmos
para todos eles. Podemos eliminá-los e fundir os medidores parana suíte
de alto nível. Espécies2 implementa esta otimização:
classe Espécies2(objeto):

Def __init__(self, ns):


self.ns = ns
self.probs = numpy.ones(len(ns), dtype=numpy.double) self.params =
numpy.ones (self.high, dtype=numpy.int)
ns é a lista de valores hipotéticos para n;; probs é a lista de probabilidades
correspondentes. E params é a seqüência de parâmetros de Dirichlet,
inicialmente todos 1.
Species2.Update atualiza ambos os níveis da hierarquia: primeiro a
probabilidade de cada valor de n,em seguida, os parâmetros de Dirichlet:
# classe Espécie2

def Update (self, data):


como = numpy.zeros(len(self.ns), dtype=numpy.double)
para i no intervalo(1000):
como += self. A probabilidade da amostra (dados)

self.probs *= como
self.probs /= self.probs.sum()

m = len(dados)
self.params[:m] += dados
SampleLikelihood retorna uma matriz de probabilidades, uma para cada
valor de n. como acumula a probabilidade total de 1000 amostras. self.probs
é mul-tipd mente pela probabilidade total, em seguida, normalizado. As
duas últimas linhas, que atualizam os parâmetros, são as mesmas de
Dirichlet.Update.
176 Capítulo 15. Lidando com Dimensões

Agora vamos olhar para SampleLikelihood. Há duas oportunidades para


opti-mization aqui:

• Quando o número hipotético deespécies, n, excede o número


observado, m, nós apenasneed os primeiros termos m do PMF
multinomial; PMF; o resto são 1.

• Se o número de espécies for grande, a probabilidade dos dados pode


ser muito pequena para ponto flutuante (ver 10,5). Portanto, é mais
seguro calcular as probabilidades de log.

Mais umavez, o PMF multinomial é


x
cx p 1 · · · · pxn
1 n

Assim, a probabilidade de log é

log cx + x1 log p1 + · · · · + xn log pn

que é rápido e fácil de calcular. Novamente, cx é o mesmo para todas as


hipóteses, para que possamos soltá-lo. Aqui está o código:
# classe Espécies2

def SampleLikelihood (self, data):


gammas = numpy.random.gamma(self.params)

m = linha len
(dados) =
gammas[:m]
col = numpy.cumsum (gammas)

log_likes = [] para
n em self.ns:
ps = linha / col[n-1]
termos = dados * numpy.log(ps)
log_like = termos.sum()
log_likes.apêndice(log_like)

log_likes -= numpy.max(log_likes) gosta


= numpy.exp(log_likes)

coefs = [thinkbayes. BinomialCoef(n, m) para n em self.ns] gosta


*= coefs
15.7. One more problem 177

retorno gosta
gammas é uma matriz de valores de uma distribuição gama; seu
comprimento é o maior valor hipotético de n. linha é apenas os primeiros
elementos m de gammas; uma vez que estes são os únicos elementos que
dependem dos dados, eles são os únicos que precisamos.

Para cada valor de n precisamos dividir a linha pelo total dos primeiros
valores n de gama. cumsum calcula essas somas cumulativas e armazena-as
em col.

O loop itera através dos valores de n e acumula uma lista de


probabilidades de log.

Dentro do loop, ps contém a linha de probabilidades, normalizada com a


soma cumulativa apropriada. termos contains os termos da soma, xi log pi,
e log_like contém sua soma.

Após o loop, queremos converter as probabilidades de log em


probabilidades lineares, mas primeiro é uma boa ideia mudá-las para que
a maior probabilidade de log seja 0; dessa forma as capas lineares likelinão
são muito pequenas(ver 10.5).

Finalmente Antes Nós Retorno O Probabilidade Nós Tem Para Aplicar a


Correção Fator que é o número de maneiras que poderíamos ter
observado estes m espécies, se O número total de espécies é n.
BinomialCoeficiente cálculos "n escolher m", que É Escrito ( n ).
M
Como muitas vezes acontece, a versão otimizada é menos legível e mais
propensa a erros do que a original. Mas essa é uma razão pela qual eu
acho que é uma boa idéia começar com a versão simples; podemos usá-lo
para testes de regressão. Plotei os resultados de ambas as versões e
confirmei que eles são aproximadamente iguais, e que convergem à
medida que o número de iterações aumenta.

15.7 Mais um problema


Há mais que podemos fazer para otimizar este código, mas há outro prob-
lem que precisamos corrigir primeiro. À medida que o número de espécies
observadas aumenta, esta versão fica mais barulhento e leva mais
iterações para convergir em uma boa resposta.

O problema é que se asevalências pr que escolhemos a distri-bution de


Dirichlet, o ps,não estão pelo menos aproximadamente certas, a
probabilidade dos dados observados é próxima de zero e quase
igualmente ruim para todos os valores de n.
178 Capítulo 15. Lidando com Dimensões

Assim, a maioria das iterações não fornecem qualquer contribuição useful


para o total likeli-hood. E à medida que o número de espécies observadas,
m,fica grande, a probabilidade de escolher ps com probabilidade não
desprezível fica pequena. Muito pequeno.
Felizmente, há uma solução. Lembre-se que se você observar um conjunto
de dados, você pode atualizar a distribuição anterior com todo o conjunto
de dados, ou você pode dividi-lo em uma série de atualizações com
subconjuntos dos dados, e o resultado é o mesmo de qualquer maneira.
Para este exemplo, a chave é realizar as atualizações de uma espécie de
cada vez. Dessa forma, quando geramos um conjunto aleatório de
ps,apenas um deles afeta a probabilidade computada, então a chance de
escolher um bom é muito melhor.
Aqui está uma nova versão que atualiza uma espécie de cada vez:
classe Espécies4 (Espécies):

def Update(self, data): m


= len(dados)

para i no intervalo(m):
um = numpy.zeros(i+1)
one[i] = data[i]
Species.Update(self, one)
Esta versão herda __init__ de Espécies, por isso representa as hipóteses
como uma lista de objetos de Dirichlet (ao contrário de Species2). Species
A atualização percorre as espécies observadas e faz uma matriz, one,, com
todos os zeros e uma contagem de espécies. Em seguida, ele chama
Atualização na classe pai, que calcula as probabilidades e atualiza as
subhipóteses.
Então, no exemplo de execução, fazemos três atualizações. A primeira é
algo como "Eu vi três leões." "Euvi dois tigres e nenhum leão adicional." E
o terceiro é "Eu vi um urso e não mais leões e tigres."
Aqui está a nova versão de
Likelihood: # class Species4

def Probabilidade (self, data, hypo):


dirichlet = hypo
como = 0
para i no intervalo (auto.iterações):
15.8. We’re not done yet 179

como += dirichlet. Probabilidade (dados)

# correto para o número de espécies invisíveis o novo #


poderia ter sido
m = len(dados)
num_unseen = dirichlet.n - m + 1
como *= num_unseen

retornar como
Isto é quase o mesmo que Species.Likelihood. A diferença é o fac-tor,
num_unseen. Essa correção é necessária porque cada vez que vemos uma
espécie pela primeira vez, temos que considerar que havia algum num-ber
de outras espécies invisíveis que poderíamos ter visto. Para valores
maiores de n there há mais espécies invisíveis que poderíamos ter visto, o
que aumenta a probabilidade dos dados.

Este é um ponto sutil e eu tenho que admitir que eu não fiz certo na
primeira vez. Mas novamente eu fui capaz de validar esta versão
comparando-a com as versões anteriores.

15.8 Ainda não terminamos.


Realizarg as atualizações de uma espécie de cada vez resolve um
problema, mas cria outro. Cada atualização leva tempo proporcional ao
km,onde k é o número de hipóteses e m é o número de espécies
observadas. Então, se fizermos m atualizações, o tempo total de execução é
proporcionalao km2.

Mas podemos acelerar as coisas usando o mesmo truque que usamos na


Seção 15.6: vamos nos livrar dos objetos de Dirichlet e colapsar os dois
níveis do hier-archy em um único objeto. Então, aqui está mais uma
versão de Espécies::
classe Espécies5 (Espécies2):

def Update(self, data): m


= len(dados)
para i em alcance(m): self.
UpdateOne(i+1, data[i])
self.params[i] += data[i]
Esta versão herda __init__ da Espécie2,por isso usa ns e probs para
representar a distribuição de n,e params para representar os parâmetros da
distribuição de Dirichlet.
180 Capítulo 15. Lidando com Dimensões

Atualização é semelhante ao que vimos na seção anterior. Ele faz loops


através das espécies observadas e chama UpdateOne:
# classe Espécies5

def UpdateOne(self, i, count):


likes = numpy.zeros(len(self.ns), dtype=numpy.double) para i
em intervalo (self.iterarations):
gosta de += eu. Probabilidade de amostra(i, contagem)

unseen_species = [n-i+1 para n em self.ns] gosta *=


unseen_species

self.probs *= curtidas
self.probs /= self.probs.sum()
Esta função é semelhante à Species2.Update,com duas alterações:

• A interface é diferente. Em vez de todo o iconjunto de dados, obtemos


oíndice das espécies observadas, e contamosquantas dessas espécies
já vimos.

• Temos que aplicar um fator de correção para o número de espécies


invisíveis, como em Species4.Likelihood. A diferença aqui é que
atualizamos todas as probabilidades de uma só vez com a
multiplicação da matriz.

Finalmente, aqui está a ProbabilidadedaAmostra:


# classe Espécies5

def SampleLikelihood (self, i, count):


gammas = numpy.random.gamma(self.params)

somas = numpy.cumsum(gammas)[self.ns[0]-1:]

ps = gammas[i-1] / somas
log_likes = numpy.log(ps) * contagem

log_likes -= numpy.max(log_likes) gosta


= numpy.exp(log_likes)

retorno gosta
Isso é semelhante ao Species2.SampleLikelihood; a diferença é que cada
atualização inclui apenas uma única espécie, então não precisamos de um
loop.
O tempo de execução desta função é proporcional ao número de hipóteses,
k. Ele roda m vezes, então o tempo de execução da atualização é
proporcional ao km. E o número de iterações que precisamos para obter
um resultado preciso é geralmente pequeno.

15.9 Os dados do umbigo


Chega de leões, tigres e ursos. Vamos voltar à barriga, mas- toneladas.
Para se ter uma noção de como são os dados, considere o sujeito B1242,
cuja amostra de 400 leituras rendeu 61 espécies com as seguintes
contagens:
92, 53, 47, 38, 15, 14, 12, 10, 8, 7, 7, 5, 5,
4 4 4 4 4 4 4 3 3 3 3 3, 3, 3, 2, 2, 2, 2,
, , , , , , , , , , ,
1 1 1 1 1 1 1 1 1 1 1 1, 1, 1, 1, 1, 1, 1,
, , , , , , , , , , ,
1 1 1 1 1 1 1 1 1 1 1 1
, , , , , , , , , , ,
Existem algumas espécies dominantes que compõem uma grande fração
do todo, mas muitas espécies que produziram apenas uma única leitura.
O número desses "sin-gletons" sugere que é provável que haja pelo menos
algumas espécies invisíveis.

No exemplo com leões e tigres, assumimos que cada animal na


preservação é igualmente provável de ser observado. Da mesma forma,
para os dados do umbigo, assumimos que cada bactéria é igualmente
provável de yield uma leitura.
Na realidade, cada etapa do processo de coleta de dados pode introduzir
vieses. Algumas espécies podem ser mais propensas a serem captadas por
um cotonete, ou para produzir amplicons identificáveis. Então, quando
falamos sobre a prevalência de cada espécie, devemos relembraressa fonte
de erro.
Devo também reconhecer que estou usando o termo "espécie" vagamente.
Primeiro, as espécies bacterianas não são bem definidas. Em segundo
lugar, algumas leituras identificam uma espécie partica-ular, outras
apenas identificam um gênero. Para ser mais preciso, eu diria "unidade
taxonômica operacional", ou OTU.
Agora vamos processar alguns dos dados do umbigo. Eu defino uma classe chamada
Sujeito a representar informações sobre cada assunto no estudo:
classe Assunto (objeto):

Def __init__(self, code): self.code


= code self.species = []
Cada assunto tem um código de seqüência, como "B1242", e uma lista de
pares (contagem, nome da espécie), classificados em ordem crescente por
contagem. Assunto fornece vários
0.12

B1242

0.10

0.08

Prob
0.06

0.04

0.02

0.00
60 65 70 75 80 85 90 95 100
Número de espécies

Figura 15.3: Distribuição de n para o sujeito B1242.

métodos para facilitar o acesso a essas contagens e nomes de espécies.


Você pode ver os detalhes em http://thinkbayes.com/species.py. Para obter
mais informações, consulte a Seção 0.3.
O assunto fornece um método chamado Process que cria e atualiza um
Species5 suite, que ressenteas distribuições de n e as prevalências.

E o Suite2 fornece DistOfN,, que retorna a distribuição posterior de


n.
# classe Suite2

def DistN(self):
itens = zip (self.ns, self.probs)
pmf = thinkbayes. MakePmfFromItems(itens)
retorno pmf
A Figura 15.3 mostra a distribuição de n para o sujeito B1242. A
probabilidade de haver exatamente 61 espécies, e nenhuma espécie
invisível, é quase zero. O valor mais provável és 72, com intervalo de 90%
de credibilidade de 66 a 79. Na ponta alta, é improvável que existam até 87
espécies.
Em seguida, calculamos a distribuição posterior da prevalência para cada espécie.
Species2 fornece DistOfPrevalence: #
class Species2

def DistOfPrevalence(self, index):


metapmf = thinkbayes. PMF()
1.0

0.8

0.6

Prob
0.4
1 (92)
2 (53)
3 (47)
0.2 4 (38)
5 (15)

0.0
0.00 0.05 0.10 0.15 0.20 0.25
Prevalência

Figura 15.4: Distribuição das prevalências para o sujeito B1242.

para n, prob em zip(self.ns, self.probs): beta =


self. MarginalBeta(n, índice) pmf = beta.
Faz cpmf() metapmf. Set(pmf, prob)

mix = thinkbayes. MakeMixture


(metapmf) retorno metapmf, mix

índice indica quais espécies queremos. Para cada n,temos uma distribuição
posterior diferente da prevalência.

O loop itera através dos possíveis valores de n e suas probabilidades. Para


cada valor de n ele recebe um objeto Beta representando a distri-bution
marginal para as espécies indicadas. Lembre-se que os objetos Beta
contêm os parâmetros alfa e beta; eles nãoavevalores e probabilidades
como um PMF, mas eles fornecem MakePMF, que gera umaaproximação
discreta para a distribuição beta contínua.

a metapmf é uma meta-PMF que contém as distribuições de prevalência,


condicionadas em n. MakeMixture combina o meta-PMF em mistura,que
combina as distribuições condicionais em uma única distribuição de
prevalência.

A Figura 15.4 mostra os resultados das cinco espécies com mais leituras.
As espécies mais prevalentes são responsáveis por 23% das 400 leituras,
mas como existem espécies ainda mais invisíveis, a estimativa mais
provável para sua prevalência é de 20%, com intervalo de 90% entre 17% e
23%.
10

# espécies 4

2
0 50 100 150 200 250 300 350 400 450
# amostras

Figura 15.5: Curvas simuladas de rarefação para o sujeito B1242.

15.10 Distribuições preditivas


Eu introduzi o problema das espécies ocultas na forma de quatro ques-
tions relacionados. Respondemos aos dois primeiros calculando a
distribuição posterior para n e a prevalência de cada espécie.

As outras duas perguntas são:

• Se estamos planejando coletar leituras adicionais, podemos prever


quantas novas espécies provavelmente descobriremos?

• Quantas leituras adicionais são necessárias para aumentar a fração


de espécies ob-servidas a um determinado limiar?

Para responder a questões preditivas como esta, podemos usar as


distribuições posteriores para simular possíveis eventos futuros e calcular
distribuições preditivas para o número de espécies, e fração do total, é
provável que vejamos.

O núcleo dessaslações simu se parece com isso:

1. Escolha n de sua distribuição posterior.

2. Escolha uma prevalência para cada espécie, incluindo possíveis


espécies invisíveis, utilizando a distribuição de Dirichlet.

3. Gerar uma seqüência aleatória de observações futuras.


15.10. Predictive distributions 185

4. Calcule o número de novas espécies, num_new,em função do número


de leituras adicionais, k.

5. Repita as etapas anteriores e acumule a distribuição conjunta de


num_new e K.

E aqui está o código. RunSimulation executa uma única simulação:


# Disciplina de classe

def RunSimulation(self, num_reads): m,


seen = self. GetSeenSpecies()
n, observações = auto. Gerar observações(num_reads)

curva = []
para k, obs em enumerado(observações): visto.add(obs)

num_new = len (visto) - m


curve.append((k+1, num_new))

curva de retorno
num_reads é o número de leituras adicionais para simular. m é o número
de espécies vistas, e visto é um conjunto de cordas com um nome único
para cada espécie. n é um valor aleatório da distribuição posterior, e
observações é uma seqüência aleatória de nomes de espécies.

Cada vez através do loop, adicionamos a nova observação ao visto e


registramos o número de leituras e o número de novas espécies até agora.

O resultado daSimulação de Execução é uma curva de


rarefação,representada como uma lista de pares com o número de leituras
e o número de novas espécies.

Antes de ver os resultados, vamos olhar para GetSeenSpecies e


Gerar observações. #class
assunto

def GetSeenSpecies(self):
nomes = self. GetNames()
m = len(nomes)
visto = conjunto (SpeciesGenerator (nomes,
m)) retorno m, visto
186 Capítulo 15. Lidando com Dimensões

GetNames retorna a lista de nomes de espécies que aparecem nos arquivos


de dados, mas para muitos assuntos esses nomes não são únicos. Então eu
uso SpeciesGenerator para estender cada nome com um número de série:
def SpeciesGenerator (nomes, num): i
=0
para nome em nomes:
rendimento %s-%d %
' '

(nome, i) i += 1

enquanto i < num:


rendimento invisível -
'

%d % i i += 1
'

Dado um nome como Corynebacterium, SpeciesGenerator rende


Corynebacterium-1. Quando a lista de nomes é esgotada, ela produz nomes
como unseen-62.

Aqui está Gerar Observações::


# Disciplina de classe

def GenerateObservations(self, num_reads):


n, prevalências = self.suite.SamplePosterior()

nomes = eu. GetNames()


name_iter = Gerador de Espécies (nomes, n)

d = dict (zip(name_iter, prevalências)) cdf =


thinkbayes. Observações
makeCdfFromDict(d) = cdf. Amostra
(num_reads)

retorno n, observações
Mais uma vez, num_reads é o número de leituras adicionais para generate. n e
prevalências são amostras da distribuição posterior.

cdf é um objeto Cdf que mapeia nomes de espécies, incluindo os invisíveis,


para probabilidades cu-mulative. O uso de um Cdf torna eficiente gerar
uma seqüência aleatória de nomes de espécies.

Finalmente, aqui está


Species2.SamplePosterior: def
SamplePosterior(self):
pmf = self. DistOfN()
n = pmf. Aleatório()
1.0

0.8

0.6

Prob
0.4

k=100
0.2 k=200 k=400 k=800

0.0
0 2 4 6 8 10 12 14
# nova espécie

Figura 15.6: Distribuições do número de novas espécies condicionadas ao


número de leituras adicionais.

prevalências = auto. AmostraPrevalências(n)


retorno n, prevalências
E Prevalências amostrais,que geram uma amostra de prevalências condi-
conditioned em n:
# classe Espécies2

def SamplePrevalences(self, n):


params = self.params[:n]
gammas =
numpy.random.gamma(params)
gammas /= gammas.sum()
gammas retorno
Vimos este algoritmo para gerar valores aleatórios a partir de uma
destributação de Dirichlet na Seção 15.4.
A Figura 15.5 mostra 100 curvas simuladas de rarefação para o sujeito
B1242. As curvas são "jittered; "Ou seja, eu mudei cada curva por um
deslocamento aleatório para que nem todos se sobreponham. Pela
inspeção, podemos estimar que depois de mais 400 leituras, é provável
que encontremos de 2 a 6 novas espécies.

15.11 Posterior articular


Podemos utilizar essas simulações para estimar a distribuição conjunta de
num_new e k, e a partir disso podemos obter adistribuição de num_new
condicionada a qualquer valor de k.
def MakeJointPredictive(curvas):
articulação = thinkbayes.
Articulação() para curva
emrves:
para k, num_new em curva:
articulação. Incr((k,
num_new))
Conjunta.
Normalizar() conjunto
de retorno
MakeJointPredictive faz um objeto Conjunto, que é um PMF cujos valores
são tuplas.
curvas é uma lista de curvas de rarefação criadas pelo RunSimulation. Cada
curva contém uma lista de pares de k e num_new.
A distribuição conjunta resultante é um mapa de cada par para sua
probabilidade de ocorrer. Dada a distribuição conjunta, podemos usar
joint.conditional obter a distribuição de num_new condicionado em k (ver
Seção 9.6).
Sujeito. MakeConditionals leva uma lista de ks e calcula a distribuição
condicional de num_new para cada k. O resultado é uma lista de objetos
Cdf.
def MakeConditionals(curvas, ks):
articulação = MakeJointPredictive (curvas)

cdfs = [] para
k em ks:
pmf = articulação. Condicional(1,
0, k) pmf.name = k=%d % k
' '

cdf = pmf. MakeCdf()


cdfs.append(cdf)

retorno cdfs
A Figura 15.6 mostra os resultados. Após 100 leituras, a mediana das
previsões de novas espécies é de 2; o intervalo de 90% de credibilidade é
de 0 a 5. Depois de 800 leituras, esperamos ver de 3 a 12 novas espécies.

15.12 Cobertura
A última pergunta que queremos responder é: "Quantas leituras
adicionais são necessárias para aumentar a fração de espécies observadas
para um determinado limiar?"
Para responder a esta pergunta, precisamos de uma versão de
RunSimulation que calcule a fração de espécies observadasrat-la do que o
número de novas espécies.
15.12. Cobertura 189

1.0

1000
0.8

800

Probabilidade
0.6 600

200

0.4

400

0.2

0.0
0.65 0.70 0.75 0.80 0.85 0.90
100
0.95 1.00 1.05
Fração de espécies vistas

Figura 15.7: CDF complementar de cobertura para uma série de leituras


adicionais.

# Disciplina de classe 10

def RunSimulation(self, num_reads): m,


seen = self. GetSeenSpecies()
n, observações = auto. Gerar observações(num_reads)

curva = []
para k, obs em enumerado(observações): visto.add(obs)

frac_seen = len(visto) / float(n)


curve.apêndice((k+1, frac_seen))

recurva de volta
Em seguida, fazemos um loop através de cada curva e fazemos um
dicionário, d,que mapeia desde o número de leituras adicionais, k, até
umalista de fracs; ou seja, uma lista de valores para a cobertura alcançada
após k leituras.
def MakeFracCdfs(self, curvas): d =
{}
para curvas in curvas:
para k,frac na curva: d.setdefault(k,
[]).apêndice(frac)

cdfs = {}
para k, fracs em d.iteritos():
cdf = thinkbayes. MakeCdfFromList(fracs)
cdfs[k] = cdf

retorno cdfs
Então para cada valor de k fazemos um Cdf de fracs;este Cdf representa a
distribuição da cobertura após k leituras.
Lembre-se que o CDF lhe diz a probabilidade de cair abaixo de um
determinado limiar, de modo que o CDF complementar informa a
probabilidade de excedê-lo. A Figura 15.7 apresenta CDFs
complementares para uma gama de valores de k.
Para ler esta figura, selecione o nível de cobertura que deseja alcançar ao
longo do eixo x. Como exemplo, escolha 90%.
Agora você pode ler o gráfico para encontrar a probabilidade de alcançar
90% de cobertura após k leituras. Por exemplo, com 200 leituras, você tem
cerca de 40% chance de obter 90% de cobertura. Com 1000 leituras, você
tem 90% de chance de obter 90% de cobertura.
Com isso, respondemos às quatro perguntas que compõem o problema
das espécies invisíveis. Para validar os algoritmos neste capítulo com
dados reais, tive que lidar com mais alguns detalhes. Mas este capítulo já é
muito longo, então não vou discuti-los aqui.
Você pode ler sobre os problemas, e como eu os abordei, them, em
http://allendowney.blogspot.com/2013/05/ umbigo-
biodiversity-end-game.html.

Você pode baixar o código neste capítulo de http://thinkbayes.com/


species.py. Para obter mais informações, consulte a Seção 0.3.

15.13 Discussão
O problema das espécies invisíveis é uma área de pesquisa ativa, e
acredito que o algoritmo neste capítulo é uma nova contribuição. Então,
em menos de 200 páginas, fizemos isso do básico da probabilidade para a
fronteira da pesquisa. Estoumuito feliz com isso.
Meu objetivo para este livro é apresentar três idéias relacionadas:

• Pensamento bayesiano: A base da análise bayesiana é a ideia de


usar distribuições de probabilidade para representar crenças
incertas, usando dados para atualizar essas distribuições, e usando os
resultados para fazer pré-dicções e informar decisões.
15.13. Discussion 191

• Uma abordagem computacional : A premissa deste livro é que é mais


fácil entender a análise bayesiana usando computação em vez de
matemática, e mais fácil de implementar métodos bayesianos com
blocos de construção reutilizáveis que podem ser reorganizados para
resolveroblems de relações públicas do mundo real rapidamente.

• Modelagem iterativa: A maioria dos problemas do mundo real


envolve modelagem de cisions e trocas entre realismo e
complexidade. Muitas vezes é impossível saber com antecedência
quais fatores devem ser incluídos no modelo e quais podem ser
abstratos. away. A melhor abordagem é a ele- erate, começando com
modelos simples e adicionando complexidade gradualmente, usando
cada modelo para validar os outros.

Essas ideias são versáteis e poderosas; são aplicáveis a problemas naárea


de ciência e engenharia, desde exemplos simples até temas da pesquisa
atual.

Se você chegou até aqui, deve estar preparado para aplicar essas
ferramentas a novos problemas relevantes para o seu trabalho. Espero que
você ache-los úteis; Deixe-me saber como ele vai!
Índice

ABC, 118 carcinoma, 149


tipo abstrato, 18, 58 causalidade, 159, 164
Anaconda, viii CDC, 110
Computação bayesiana Cdf, 28, 54, 61, 86, 186
aproximada, 118 Centros de Controle de
taxa de chegada, 89 Doenças, 110 intervalos de
Axtell, Robert, 26 anos. credibilidade central, 104
bactérias, 167 estimativas clássicas, 111
Fator Bayes, 46, 125, 127, 128, 136 clone, vii
coeficiente de variação, 110
Teorema de Bayes, 3
moedas, 1
derivação, 3
coletivamente exaustivo, 6
forma de probabilidades, 44
Conselho Universitário, 132
Estrutura bayesiana, 13
CDF complementar, 190
Sistema de Vigilância de Fatores de
tipo de concreto, 18, 58
Risco Comportamentais, 110
distribuição condicional, 103, 106,
umbigo, 167
148, 152, 157, 188
Processo bernoulli, 71
probabilidade condicional, 1
distribuição beta, 38, 168
probabilidade conjunta, 2
Objeto beta, 39, 183
conjugado prior, 39
moeda tendenciosa, 125
conjunção, 3
coeficiente binômio, 177
distribuição contínua, 39
distribuição binômio, 134, 160, 161
contribuintes, ix
função de probabilidade binômio,
convergência, 36, 40
39 biodiversidade, 167
problema de biscoito, 3, 12, 44
falso, 113, 126
cookie.py, 13 anos.
Boston, 81
valor aleatório
Boston Bruins, 69
correlacionado, 155
BRFSS, 110, 118
cobertura, 188, 190
balde, 152
crank science, 109
problema de parada de ônibus, 78
intervalo crível, 27, 102
cache, 117, 151 Regra de Cromwell, 41.
calibração, 138 Cromwell, Oliver, 41 anos.
Campbell-Ricketts, Tom, 159 função de distribuição cumulativa,
28, 86
probabilidade acumulada, 155,186 186
Índic 193
e
soma acumulada, 177 Git, vii
GitHub, vii
Davidson-Pilon, Cameron, 56 anos.
análise de decisão, 56, 64, 68, 93 taxa de crescimento, 154
graus de crença, 1
ataque cardíaco, 1
densidade, 57, 59, 63, 111
altura, 110
dependência, 2,103, 104
Heuer, Andreas, 71 anos.
interpretação diacrônica, 5
modelo hierárquico, 162, 164, 170
dados, 11, 21
Hoag, Dirk, 77.
Problema de dados, 21
hóquei, 69
problema de dados, 24
corrida de cavalos, 44
Distribuição de Dirichlet, 168, 184 Horsford, Eben Norton, 109
distribuição, 11, 54, 68 Hume, David, 130
operations, 47 teste de hipóteses, 125
dividir-e-conquistar, 10
tempo de duplicação, 146 implementação, 18, 58
Dungeons and Dragons, 21, 47 independência, 2, 7, 48, 50, 103, 104,
143, 149, 168
eficácia, 136 informativo anterior,
enumeração, 47, 49 30
erro, 60 problema de amostragem de
ESP, 129 insetos, instalação 78, viii
Problema euro, 33, 40, 118, 125 faixa entre quartis, 121
provas, 5, 35, 45, 46, 102, 109, interface, 18, 58
125- intuição, 9
129, 131 problema inverso, 160
exceção, 114 IQR, 121
distribuição exponencial, 71, 75, teoria da resposta ao item, 137
146 modelagem iterativa, 76
exponenciação, 49 iterador, 150
percepção sensorial, 129
Jaynes, E. T., 159
moeda justa, Conjunto, 102, 103, 105, 106, 111
garfo 125, vii
distribuição conjunta, 102, 106, 111, 143,
problema para a frente, 160
151, 153, 157, 168, 185, 187
distribuição gama, 173, 177 Objeto conjunto, 188
Distribuição gaussiana, 57, 58, 61, PMF Conjunto, 98
70,
KDE, 57, 59
110, 118, 121, 133, 138, 139,
estimativa de densidade do
154 núcleo, 57, 59 problema de
Gaussian PDF, 58 tumor renal, 145
Puxa, Steve, 56 anos.
Problema do contador Geiger, 159, menos quadrados se
164 encaixam, 153 problema
gerador, 154, 155, 186 de lâmpada, 78
Problema do tanque alemão, 22, 30
194 Index

Probabilidade, 14 umbigo, 167


probabilidade, 5, 60, 62, 63, 88,
99, 101,
111, 124, 127, 161.
função de probabilidade, 23
razão de probabilidade, 46, 127,
128, 136
linspace, 112
leões e tigres e ursos, 168
loproblema comotivo, 22, 30, 118
escala de registro, 152
log transform, 114
log-probabilidade, 116, 176, 177
logaritmo, 114

Problema M e M, 6, 17
MacKay, David, 33, 45, 95, 125
MakeMixture, 74, 75, 85, 92, 138,
183
distribuição marginal, 102, 106, 169
matplotlib, viii
máximo, 49
probabilidade máxima, 27, 35, 68,
105,
113, 115, 168
erro quadrado médio,
24 Meckel, Johann,
109
mediana, 35
memoização, 117
meta-PMF, 74, 75, 85, 92, 138, 183
meta-Suite, 162, 170
microbioma, 167
mistura, 52, 73-75, 85, 92, 146, 183
modelagem, vi, 30, 40, 76, 123,
131, 147,
148
erro de modelagem, 136, 154, 157
Problema de Monty Hall, 8, 15
Mosteller, Frederick, 22 anos.
Mult, 13 anos.
coeficiente multinomial, 172
distribuição multinomial, 168, 172,
176
mutuamente exclusivo, 6

National Hockey League, 70


NHL, 70 170, 182 Preço é certo, 55
não linear, 92 anterior, 5
distribuição normal, 58 destributação anterior, 13, 25
normalizar, 64
normalização constante, 5, 8, 44, 163
parâmetro incômodo,
142 NumPy, viii
numpy, 59, 61, 65, 70, 90,
112, 138,
169, 173, 175, 176, 178,
180,
18
7

objetividade, 30
viés observador, 83, 93
probabilidades, 43
Faculdade Olin, 81
Problema de sangue de
Oliver, 45 unidade
taxonômica operacional,
181 otimização, 37, 116,
117, 163, 174
OTU, 181
horas extras, 75

Problema de paintball, 97
parâmetro, 39
PDF, 40, 70
Pdf, 57
PEP 8, viii
percentil, 28, 153, 156
PMF, 54, 57
Classe PMF, 11
Métodos pmf, 12
Distribuição de Poisson, 71, 73, 88, 161
Processo poisson, vi, 69, 71, 75, 78, 82,
15
9
po
ste
rio
r,
5
distribuição posterior, 13, 35
direito de poder, 26
distribuição preditiva, 78, 87, 89, 92,
141 de 184
prevalência, 167,
Índic 195
e
Prob, 12 suite, 6
probabilidade, 57 Classe suíte, 16
condicional, 1 estatística sumária, 68, 121, 124
conjunto, 2 pântanog os antecedentes, 36, 40
densidade de probabilidade, 57 interruptor, 9
função de densidade de
probabilidade, 40, 57, método de tabela, 7
70 padrão do método do modelo,
função de massa de 18 probabilidade total, 6
probabilidade, processo 11, distribuição de triângulo, 36, 128
71 trigonometria, 99
enredo pseudocolor, 152 tipo de tumor, 154
piroseqüência, 167 tuplo, 38

decadência radioativa, 159 incerteza, 91


amostra aleatória, 173, 187 subfluxo, 114, 176
curva de rarefação, 185, 188 distribuição uniforme, 174
pontuação bruta, 134 distribuição uniforme, 34, 52, 84
rDNA, 167 anterior uninformativo, 30
Problema da Linha problema espécies invisíveis,
Vermelha, 81 Reddit, 41, 167 Atualização, 14
145
Vancouver Canucks, 69.
r teste de egresssão, vii, 177, 179
Hipótese de variabilidade, 109
renormalizar, 13
Administraçãode Benefícios de
repositório, vii
estimativa robusta, 121
Veteranos,Administration,
viés amostral, 181 148
estatísticas amostrais, 119 volume, 150
SÁB, 131 Distribuição weibull, 79
pontuação frequência de palavras, 11
escalocada, 132
SciPy, viii
scipy, 58, 59, 116
correlação serial, 154, 156
Vitrine, 55
simulation, 47, 49, 52, 148, 150,
184
Sivia, D.S., 97
167, 181
esfera, 150, 154
teste padronizado, 131
vara, 9
velocidade de strafing, 100
prior subjetivo, 6
subjetividade, 30
morte súbita, 75

Você também pode gostar