Capítulo 12.3

Índice

  1. 1. O que é Ciência de Dados?
  2. 2. Causalidade e Experimentos
  3. 3. Progamando em Python
  4. 4. Tipos de Dados
  5. 5. Sequências
  6. 6. Tabelas
  7. 7. Visualização
  8. 8. Funções e Tabelas
  9. 9. Aleatoriedade
  10. 10. Amostragem e Distribuições Empíricas
  11. 11. Testando Hipóteses
  12. 12. Comparando Duas Amostras
  13. 13. Estimação
  14. 14. Por que a Média é Importante
  15. 15. Previsão

from datascience import *
%matplotlib inline
path_data = '../../../assets/data/'
import matplotlib.pyplot as plots
plots.style.use('fivethirtyeight')
import numpy as np

 

Esvaziar

Em 18 de janeiro de 2015, os Indianapolis Colts e os New England Patriots jogaram o jogo do campeonato da American Football Conference (AFC) para determinar qual dessas equipes jogaria no Super Bowl. Após o jogo, surgiram alegações de que as bolas dos Patriots não haviam sido infladas conforme exigido pelos regulamentos; elas estavam mais macias. Isso poderia ser uma vantagem, já que bolas mais macias podem ser mais fáceis de segurar.

Por várias semanas, o mundo do futebol americano foi consumido por acusações, negações, teorias e suspeitas: a imprensa rotulou o tópico como Deflategate, em referência ao escândalo político Watergate dos anos 1970. A National Football League (NFL) encomendou uma análise independente. Neste exemplo, faremos nossa própria análise dos dados.

A pressão é frequentemente medida em libras por polegada quadrada (psi). As regras da NFL estipulam que as bolas de jogo devem ser infladas para ter pressões na faixa de 12,5 psi a 13,5 psi. Cada equipe joga com 12 bolas. As equipes são responsáveis por manter a pressão em suas próprias bolas, mas os oficiais do jogo inspecionam as bolas. Antes do início do jogo da AFC, todas as bolas dos Patriots estavam com cerca de 12,5 psi. A maioria das bolas dos Colts estava com cerca de 13,0 psi. No entanto, esses dados pré-jogo não foram registrados.

Durante o segundo quarto, os Colts interceptaram uma bola dos Patriots. Nas laterais, eles mediram a pressão da bola e determinaram que estava abaixo do limite de 12,5 psi. Imediatamente, informaram aos oficiais.

No intervalo, todas as bolas do jogo foram coletadas para inspeção. Dois oficiais, Clete Blakeman e Dyrol Prioleau, mediram a pressão em cada uma das bolas.

Aqui estão os dados. Cada linha corresponde a uma bola de futebol. A pressão é medida em psi. A bola dos Patriots que havia sido interceptada pelos Colts não foi inspecionada no intervalo. A maioria das bolas dos Colts também não foi inspecionada – os oficiais simplesmente ficaram sem tempo e tiveram que devolver as bolas para o início do segundo tempo.

football = Table.read_table(path_data + 'deflategate.csv')
football.show()
Team Blakeman Prioleau
Patriots 11.5 11.8
Patriots 10.85 11.2
Patriots 11.15 11.5
Patriots 10.7 11
Patriots 11.1 11.45
Patriots 11.6 11.95
Patriots 11.85 12.3
Patriots 11.1 11.55
Patriots 10.95 11.35
Patriots 10.5 10.9
Patriots 10.9 11.35
Colts 12.7 12.35
Colts 12.75 12.3
Colts 12.5 12.95
Colts 12.55 12.15

Para cada uma das 15 bolas inspecionadas, os dois árbitros obtiveram resultados diferentes. Não é incomum que medições repetidas no mesmo objeto produzam resultados diferentes, especialmente quando as medições são realizadas por pessoas diferentes. Então, atribuiremos a cada bola a média das duas medições feitas naquela bola.

football = football.with_column(
    'Combined', (football.column(1)+football.column(2))/2
    ).drop(1, 2)
football.show()
Team Combined
Patriots 11.65
Patriots 11.025
Patriots 11.325
Patriots 10.85
Patriots 11.275
Patriots 11.775
Patriots 12.075
Patriots 11.325
Patriots 11.15
Patriots 10.7
Patriots 11.125
Colts 12.525
Colts 12.525
Colts 12.725
Colts 12.35

À primeira vista, parece evidente que as bolas de futebol dos Patriots estavam sob pressão mais baixa do que as bolas dos Colts. Como alguma deflação é normal durante o jogo, os analistas independentes decidiram calcular a queda na pressão desde o início do jogo. Lembre-se de que todas as bolas dos Patriots começaram em cerca de 12,5 psi, e as bolas dos Colts em cerca de 13,0 psi. Portanto, a queda na pressão das bolas dos Patriots foi calculada como 12,5 menos a pressão no intervalo, e a queda na pressão das bolas dos Colts foi de 13,0 menos a pressão no intervalo.

Podemos calcular a queda de pressão para cada bola de futebol, definindo primeiro uma matriz de valores iniciais. Para isso, precisaremos de uma matriz composta por 11 valores, cada um dos quais é 12,5, e outro composto por quatro valores, cada um dos quais é todos os 13. Usaremos a função NumPy np.ones, que recebe uma contagem como argumento e retorna uma matriz com tantos elementos, cada um dos quais é 1.

np.ones(11)
Out[1]: array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
patriots_start = 12.5 * np.ones(11)
colts_start = 13 * np.ones(4)
start = np.append(patriots_start, colts_start)
start
Out[2]: array([12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5, 12.5,
13. , 13. , 13. , 13. ])

A queda de pressão para cada bola de futebol é a diferença entre a pressão inicial e a medição de pressão combinada.

drop = start - football.column('Combined')
football = football.with_column('Pressure Drop', drop)
football.show()
Team Combined Pressure Drop
Patriots 11.65 0.85
Patriots 11.025 1.475
Patriots 11.325 1.175
Patriots 10.85 1.65
Patriots 11.275 1.225
Patriots 11.775 0.725
Patriots 12.075 0.425
Patriots 11.325 1.175
Patriots 11.15 1.35
Patriots 10.7 1.8
Patriots 11.125 1.375
Colts 12.525 0.475
Colts 12.525 0.475
Colts 12.725 0.275
Colts 12.35 0.65

Parece que as quedas dos Patriots foram maiores que as dos Colts. Vejamos a queda média em cada um dos dois grupos. Não precisamos mais das pontuações combinadas.

football = football.drop('Combined')
football.group('Team', np.average)
Team Pressure Drop average
Colts 0.46875
Patriots 1.20227

A queda média para os Patriots foi de cerca de 1,2 psi, em comparação com cerca de 0,47 psi para os Colts.

A questão agora é por que as bolas dos Patriots tiveram uma queda maior na pressão, em média, do que as bolas dos Colts. Poderia ser devido ao acaso?

As Hipóteses

Como o acaso entra aqui? Nada estava sendo selecionado aleatoriamente. Mas podemos criar um modelo de acaso hipotetizando que as 11 quedas dos Patriots parecem uma amostra aleatória de 11 de todas as 15 quedas, com as quedas dos Colts sendo as quatro restantes. Esse é um modelo de acaso completamente especificado sob o qual podemos simular dados. Portanto, essa é a hipótese nula.

Para a alternativa, podemos considerar que as quedas dos Patriots são grandes demais, em média, para se assemelhar a uma amostra aleatória extraída de todas as quedas.

Estatística de Teste

Uma estatística natural é a diferença entre as duas quedas médias, que iremos calcular como “queda média para Patriots – queda média para Colts”. Valores altos dessa estatística favorecerão a hipótese alternativa.

observed_means = football.group('Team', np.average).column(1)

observed_difference = observed_means.item(1) - observed_means.item(0)
observed_difference
Out[3]: 0.733522727272728

Essa diferença positiva reflete o fato de que a queda média na pressão das bolas de futebol dos Patriots foi maior do que a dos Colts.

Assim como fizemos na seção anterior, escreveremos uma função para calcular a diferença entre as quedas médias nos dois grupos. A função difference_of_means leva dois argumentos:

  • o nome da tabela de dados
  • o rótulo da coluna que contém os dois rótulos de grupo

Ele retorna a diferença entre as quedas médias dos dois grupos. Calcularemos a diferença como as quedas dos Patriots menos as quedas dos Colts, como antes.

def difference_of_means(table, group_label):
    reduced = table.select('Pressure Drop', group_label)
    means_table = reduced.group(group_label, np.average)
    means = means_table.column(1)
    return means.item(1) - means.item(0)
difference_of_means(football, 'Team')
Out[4]: 0.733522727272728

Este é o mesmo valor que encontramos anteriormente como observed_difference.

Prevendo a Estatística sob a Hipótese Nula

Se a hipótese nula fosse verdadeira, então não deveria importar quais bolas de futebol são rotuladas como Patriots e quais são rotuladas como Colts. As distribuições dos dois conjuntos de quedas seriam as mesmas. Podemos simular isso embaralhando aleatoriamente os rótulos dos times.

shuffled_labels = football.sample(with_replacement=False).column(0)
original_and_shuffled = football.with_column('Shuffled Label', shuffled_labels)
original_and_shuffled.show()
Team Pressure Drop Shuffled Label
Patriots 0.85 Patriots
Patriots 1.475 Patriots
Patriots 1.175 Patriots
Patriots 1.65 Colts
Patriots 1.225 Patriots
Patriots 0.725 Patriots
Patriots 0.425 Patriots
Patriots 1.175 Colts
Patriots 1.35 Patriots
Patriots 1.8 Patriots
Patriots 1.375 Colts
Colts 0.475 Patriots
Colts 0.475 Colts
Colts 0.275 Patriots
Colts 0.65 Patriots

Como as médias de todos os grupos se comparam?

difference_of_means(original_and_shuffled, 'Shuffled Label')
Out[5]: -0.5619318181818183
difference_of_means(original_and_shuffled, 'Team')
Out[6]: 0.733522727272728

Os valores médios de queda das duas equipes estão mais próximos quando os rótulos das equipes são atribuídos aleatoriamente às bolas do que estavam para os dois grupos realmente usados no jogo.

Teste de Permutação

É hora de um passo que agora é familiar. Vamos simular repetidamente a estatística de teste sob a hipótese nula.

permutações repetidas das bolas e atribuindo conjuntos aleatórios às duas equipes.

Como de costume, começaremos escrevendo uma função one_simulated_difference que retorna um valor simulado da diferença entre as quedas médias de pressão dos grupos rotulados como Patriots e Colts após permutar aleatoriamente os rótulos das equipes das bolas.

def one_simulated_difference():
    shuffled_labels = football.sample(with_replacement = False
                                                    ).column('Team')
    shuffled_table = football.select('Pressure Drop').with_column(
        'Shuffled Label', shuffled_labels)
    return difference_of_means(shuffled_table, 'Shuffled Label')   

Agora podemos usar um loop for e esta função para criar um array differences que contém 10.000 valores da estatística de teste simulada sob a hipótese nula.

differences = make_array()

repetitions = 10000
for i in np.arange(repetitions):
    new_difference = one_simulated_difference()
    differences = np.append(differences, new_difference)

Conclusão do Teste

Para calcular o p-valor empírico, é importante lembrar da hipótese alternativa, que é que as quedas dos Patriots são grandes demais para serem resultado apenas da variação ao acaso.

Quedas maiores para os Patriots favorecem a hipótese alternativa. Portanto, o p-valor é a probabilidade (calculada sob a hipótese nula) de obter uma estatística de teste igual ao nosso valor observado de 0,733522727272728 ou maior.

A figura abaixo visualiza esse cálculo. Ela consiste na distribuição empírica da estatística de teste sob a hipótese nula, com a estatística observada marcada em vermelho no eixo horizontal e a área correspondente ao valor p sombreada em dourado.

Table().with_column(
    'Difference Between Group Averages', differences).hist(
    left_end = observed_difference
)
plots.ylim(-0.1, 1.4)
plots.scatter(observed_difference, 0, color='red', s=30, zorder=3)
plots.title('Prediction Under the Null Hypothesis')
print('Observed Difference:', observed_difference)
Out[7]: Observed Difference: 0.733522727272728

A olho nu, o valor p parece bem pequeno. Podemos confirmar isso por meio de um cálculo.

empirical_p = np.count_nonzero(differences >= observed_difference) / 10000
empirical_p
Out[8]: 0.0026

Como em exemplos anteriores deste teste, a maior parte da distribuição está centrada em torno de 0. Sob a hipótese nula, as deflações dos Patriots são uma amostra aleatória das 15 deflações, e portanto, as dos Colts também são. Portanto, os dois conjuntos de deflações devem ser aproximadamente iguais em média, e, portanto, sua diferença deve ser em torno de 0.

Mas o valor observado da estatística de teste está bastante distante do centro da distribuição. Por qualquer critério razoável para o que é “pequeno”, o p-valor empírico é pequeno. Portanto, acabamos rejeitando a hipótese nula de aleatoriedade e concluímos que as deflações dos Patriots foram grandes demais para refletir apenas variação ao acaso.

A equipe investigativa independente analisou os dados de várias maneiras diferentes, levando em consideração as leis da física. O relatório final disse,

“[A] queda média de pressão das bolas do jogo dos Patriots excedeu a queda média de pressão das bolas dos Colts em 0,45 a 1,02 psi, dependendo de vários pressupostos possíveis sobre os calibradores usados, e assumindo uma pressão inicial de 12,5 psi para as bolas dos Patriots e 13,0 para as bolas dos Colts.”

Relatório investigativo encomendado pela NFL referente ao jogo do campeonato da AFC em 18 de janeiro de 2015

Nossa análise mostra uma queda média de pressão de cerca de 0,73 psi, o que está próximo do centro do intervalo “0,45 a 1,02 psi” e, portanto, consistente com a análise oficial.

Lembre-se de que nosso teste de hipóteses não estabelece a razão por que a diferença não se deve ao acaso. Estabelecer causalidade geralmente é mais complexo do que realizar um teste de hipóteses.

Mas a pergunta mais importante no mundo do futebol era sobre a causalidade: a questão era se a queda excessiva de pressão nas bolas dos Patriots foi deliberada. Se você estiver curioso sobre a resposta dada pelos investigadores, aqui está o relatório completo.

← Capítulo 12.2 – Causalidade Capítulo 13 – Estimação →