A intuição por trás do p-valor

Eduarda Oliveira
5 min readMay 4, 2020

--

Se você já teve alguma aula sobre testes de hipótese, provavelmente se lembra — ou teve que decorar — que usamos o p-valor para rejeitar ou não a hipótese nula (a hipótese que tentamos provar falsa num teste de hipótese).

Se o nível de significância é maior do que o tal p-valor, rejeitamos a hipótese nula. Se sua hipótese nula é, por exemplo, que duas médias são iguais — ou seja, não há diferença significativa entre as duas — , a hipótese é rejeitada caso o nível de significância seja maior do que o p-valor, podendo concluir que há diferença significativa.

Mas o que realmente significa o p-valor em si? Formalmente, é a probabilidade de obtermos um efeito no mínimo tão extremo quanto os observados nos dados amostrais (assumindo que H0, a hipótese nula, seja verdadeira).

Vamos exemplificar: suponha que eu tenha comprado uma fazenda para começar minha própria plantação de batatas. Para fertilizar as batatas, resolvi fazer um teste com fertilizantes de duas marcas diferentes. Em cada um dos grupos, no período de colheita, obtive como resultado 3 mil batatas. No grupo que foi fertilizado com o adubo A, eu tenho 189 ótimas batatas e 2811 batatas normais. Já no grupo fertilizado com o adubo B, eu tenho 172 ótimas batatas e 2828 batatas normais. Isso significa que:

  • No grupo A, a taxa de batatas ótimas foi de 6,3% (0,063)
  • No grupo B, a taxa de batatas ótimas foi de 5,73% (0,0573)

Parece ótimo, certo? Uma taxa 10% maior no grupo A em relação ao grupo B! Mas será a diferença entre os dois grupos é realmente significante? Ou será que foi obra do acaso?

Para responder essas perguntas, podemos começar a partir de um teste de permutação — uma técnica de reamostragem — para obter uma representação gráfica das possibilidades do acaso.

Um teste de permutação¹ [ao acaso] é um procedimento de criação de novas amostras a partir dos dados existentes, ignorando os grupos escolhidos para qualquer tipo de teste pré-definido (considerando a fazenda de batatas, os grupos A e B) — portanto, selecionando os elementos aleatoriamente, e nesse caso, sem reposição. Isso nos permite verificar, para n rodadas de reamostragem, se conseguimos, de forma aleatória, alcançar números tão altos quanto os alcançados pelo grupo A.

Para isso, criei o dataset batatas para representar o meu conjunto de batatas, com 6 mil linhas (uma para cada batata) e 2 colunas, sendo elas:

  • Resultado: indica se a batata é ótima (1) ou regular (0)
  • Grupo: indica se aquela batata pertence ao grupo A ou ao grupo B

O teste de permutação funciona do seguinte modo: agrupamos todas as informações num único dataset (ou ignoramos a variável de grupo), selecionamos de modo aleatório amostras com o mesmo número de observações das amostras originais (cada amostra, portanto, terá 3 mil observações), e por fim calculamos a mesma estatística utilizada para a pergunta original. Para obter uma distribuição, reproduzimos o processo de reamostragem aleatória n vezes. Quanto maior o n, mais próxima de uma distribuição teórica será a distribuição obtida.

n = 1000 # número de rodadas# dataframe para armazenar as taxas das amostras de cada rodada
testePermutacao <- data.frame(taxaA = rep(as.numeric(NA), n),
taxaB = NA)
for(i in seq(1, n)) {amostra = sample(seq(1, nrow(batatas)), 3000)testePermutacao$taxaA[i] <- batatas[amostra,] %>%
summarise(taxa = sum(resultado)/n()) %>%
pull()
testePermutacao$taxaB[i] <- batatas[-amostra,] %>%
summarise(taxa = sum(resultado)/n()) %>%
pull()
}testePermutacao <- testePermutacao %>%
mutate(diferenca = taxaA - taxaB)

O código acima faz justamente isso: após determinar um n (o número de rodadas de reamostragem), é criado um dataframe que será preenchido com a taxa da primeira amostra e a taxa da segunda amostra (sem reposição), e com a diferença delas, para cada uma das rodadas (cada rodada é representada por uma linha no dataframe).

Podemos plotar essa diferença, para visualizar a distribuição:

# histograma da diferença de taxas
ggplot(testePermutacao, aes(x = diferenca)) +
geom_histogram(aes(y =..density..),
fill = "lightblue",
col = "black") +
stat_function(fun = dnorm,
col = "red",
args = list(mean = mean(testePermutacao$diferenca),
sd = sd(testePermutacao$diferenca))) +
geom_vline(xintercept = (0.063 - 0.0573),
col = "red",
linetype = "dashed") +
theme_minimal() +
labs(x = "Diferença de taxas entre grupos A e B",
y = "Densidade",
title = "Histograma da diferença de taxas para 1000 rodadas de permutação")) +
theme(plot.title = element_text(hjust = 0.5))

A linha vertical tracejada representa o onde se localiza a diferença entre a taxa A e a taxa B originais (0.063-0.0573), e a curva vermelha contínua representa a distribuição normal. Podemos verificar através do gráfico que existem várias situações onde reamostragens aleatórias apresentam uma diferença de taxas maior do que as originalmente obtidas pelos grupos A e B do teste — toda a área azul à direita da linha vertical tracejada.

Mais precisamente, nas 1000 rodadas de permutações realizadas, 19,3% das situações simuladas apresentaram resultado ao menos tão extremo quanto o original — o que, no final das contas, é o significado de p-valor. É importante observar que a depender das amostras, até pelo seu caráter aleatório, esse número não será sempre 19,3%; se eu rodar novamente esse código, ele provavelmente gerará uma outra porcentagem, que girará ao redor do p-valor real, às vezes para mais, às vezes para menos.

Para fins de comparação, podemos usar a função prop.test(), do pacote stats, — cujo objetivo é testar se as proporções (probabilidade de sucesso) entre grupos é a mesma — , para obter o p-valor, confrontando com sua aproximação via teste de permutação:

prop.test(x = c(189, 172), n = c(3000, 3000), 
alternative = "greater")

Que gera um p-valor de 19,25%, e nos permite concluir que a aproximação via n testes de permutação é bastante razoável. Nesse caso, não rejeitamos a hipótese nula de que as duas médias são estatisticamente iguais (hipótese padrão do teste), o que significa que o grupo A não tem taxa [significativamente] maior do que o grupo B — afinal, quase 20% das amostras aleatórias apresentam valores mais extremos.

Poderíamos, no final das contas, para essa situação específica que conhecemos a distribuição (uma distribuição binomial), ter apenas escrito uma linha de código usando a função prop.test() (que é um teste de hipótese para distribuição binomial) e respondido a questão sobre o fertilizante das batatas, porém nem sempre a distribuição será conhecida. Além disso, através do gráfico de distribuição das estatísticas que escolhemos testar (a diferença das taxas), podemos obter uma representação visual da resposta à nossa pergunta, o que geralmente é de ótimo auxílio.

¹ Aqui, estou abreviando para “teste de permutação” o teste de permutação de Monte Carlo. Poderíamos fazer também de modo exaustivo sem reposição, usando todas as permutações possíveis, mas para fins de simplificação, foi determinada uma quantidade n de rodadas, tornando o teste não-exaustivo.

--

--

Eduarda Oliveira

Economist & data person. I like to plot cool graphs and eat italian food.