Teste de hipótese — Ep. 1

Teste t não pareado

Bruno Carloto
11 min readMay 20, 2022

Introdução

No universo da Estatística, há diferentes testes de hipótese — testes que validam a normalidade de uma curva, testes que validam se dois grupos de amostra derivam de uma população de mesma média ou mediana, teste de variância etc.

Esses testes auxiliam em conclusões relevantíssimas para empresas e para o meio acadêmico.

Suponhamos que uma empresa queira saber se uma determinada peça torna o seu carro XPTO mais econômico ou não, em termos de combustível. Para isso, ela usa teste de hipótese. Sendo assim, a empresa parte para o teste com a hipótese de que a peça torna seus carros mais econômicos.

Para obter a resposta, ela poderia realizar um experimento. Os carros seriam colocados para rodar, com tanque cheio, inicialmente sem a peça supostamente otimizadora. Posteriormente, colocaria os mesmos carros para rodar com tanque cheio novamente, porém, com a suposta peça otimizadora. O resultado observado seria quantos quilômetros cada carro roda com o tanque cheio antes e depois da implementação da peça.

Se a média de quilômetro do grupo de carros com a peça hipoteticamente otimizadora for estatísticamente menor e significativamente diferente do que a média do grupo de carros sem a peça otimizadora, então, a hipótese é validada, pelo contrário, não há estatisticamente melhoras com a suposta peça otimizadora.

Há a possibilidade ainda de a peça tornar o carro menos econômico.

Sobre seleção do teste de hipótese

A questão é que não há somente uma técnica para esse tipo de teste. Alguns que cito são o teste t de Student, o teste ANOVA e o teste de Mann-Whitney. Mas, qual a diferença?, talvez você se pergunta. Há diferenças e há contextos específicos para se aplicar um e outro. Os dados apresentam distribuição normal? Quantos grupos serão testados? Esses grupos são independentes ou dependentes entre si, isso é, você realizará uma observação ou um experimento? As respostas para essas perguntas guiarão você para decidir por qual técnica aplicar seu teste de hipótese.

Questão de negócio — Caso de estudo

Para melhor compreensão, façamos um estudo de caso. É um cenário hipotético em que uma escola fictícia de nome Arthur Excalibur está interessada em duas informações sobre suas turmas do 1ª ano do ensino médio:

1 — As notas médias das turmas A e B são iguais ou diferentes?

2 — A partir das duas turmas, qual é a estimativa da média para as cinco demais turmas do 1ª ano do ensino médio?

Considerando as duas questões, a segunda questão somente será passível de ser respondida devidamente, a partir das duas primeiras turmas em questão, se suas respectivas notas não forem estatisticamente diferentes, ou seja, ainda que possam apresentar médias diferentes, mediante uma amostra com 20 alunos por turma, se aumentássemos igualmente as amostras, em um dado momento as médias se igualariam.

Na etapa de desenvolvimento do case, avalio quais testes usar e os aplico, buscando as respostas para as questões de negócio.

Ressalto, contudo, que o subtítulo desse artigo evidencia a conclusão sobre qual teste de hipótese foi/é cabível para a resolução do caso de estudo.

Conteúdo

  • Introdução
  • Importação das bibliotecas básicas
  • Descrição estatística
  • Teste de normalidade
  • Teste de variância — homocedasticidade
  • Aplicando o teste t não pareado
  • Aplicando inferência estatística: intervalo de confiança
  • Conclusão

Desenvolvimento do estudo de caso

1. Importação das bibliotecas básicas

Inicio o projeto, importando as bibliotecas de base.

#Importando bibliotecas de base
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

Em seguida, construo um dicionário com as notas das respectivas turmas e gero um dataframe a fim de poder manipular os dados.

#Criando amostras
dicionario_dados = {
'turma_a':[10.0, 8.0, 8.0, 7.0, 5.0, 8.0, 7.0, 7.5, 6.5, 7.0, 5.5, 2.0, 9.0, 9.0, 10.0, 8.5, 9.0, 6.5, 5.5, 3.0],
'turma_b':[10.0, 9.0, 5.0, 7.0, 7.0, 5.0, 4.0, 8.0, 7.0, 7.0, 8.0, 9.0, 5.0, 7.0, 8.0, 9.0, 10.0, 10.0, 6.0, 6.5]
}
#Gerando dataset
dados = pd.DataFrame(dicionario_dados)

Após a geração do dataframe, o visualizo, exibindo somente as 10 primeiras linhas, utilizando a função head.

#Exibindo dataframe
dados

Conforme o retornado, o procedimento foi devidamente sucedido.

2. Descrição estatística

A fim de conhecer os aspectos estatísticos das turmas, utilizo a função describe .

#Resumo estatístico 
dados.describe()

Conforme o retornado, cada turma contém 20 alunos. A média de ambas as turmas está em torno da nota 7, entretanto, a média da turma b se sobressai e apresenta maior consistência, dado que o desvio padrão é menor, sendo no valor aproximado de 1,8, enquanto a turma a apresenta um desvio padrão em torno de 2,1. A turma que apresentou a menor nota, entre ambas, foi a turma a, enquanto a b apresenta nota mínima 4. Metade dos alunos da turma a possui nota no valor de até 7,25, enquanto metade da turma b apresenta nota até 7. A nota máxima de ambas as turmas é 10.

A primeira observação a ser feita é que média e mediana para ambas as turmas estão próximas, indicando que as curvas apresentarão uma proximidade à curva normal. Os quartis também evidenciam essa configuração. A normalidade é importante para, caso as amostras provenham de uma população de mesma média, possa-se inferir, com maior significância estatística, um intervalo de confiança para as demais turmas do 1ª ano do ensino médio da escola fictícia Arthur Excalibur.

Considerando as estatísticas, levanto a hipótese de que a distribuição das notas de cada uma das turmas segue uma distribuição normal.

Sabendo que estou trabalhando com dois grupos independentes e havendo a hipótese de normalidade dos dados, tenho, como hipótese, que o teste a ser utilizado deve ser o teste t não pareado.

Para validar essa hipótese testo alguns aspectos:

1 — A normalidade dos dados

2 — A homocedasticidade das notas das turmas, isso é, se há homogeneidade entre as variâncias das notas das turmas.

3. Teste de normalidade

Para a validação de que a curva das turmas seguem uma distribuição normal, alguns procedimentos são possíveis. O primeiro é a geração e observação de um gráfico de distribuição. Outra possibilidade é através de testes, como o teste de Shapiro-Wilk, por exemplo. Outra forma é pela análise descritiva das curvas, como observação da curtose (achatamento) e do enviesamento da curva.

Inicio pela análise gráfica.

#Gerando gráfico de distribuição
for col in dados.columns:
plt.figure(figsize=(6,4))
sns.distplot(dados[col])
plt.title('Distribuição da {}'.format(col))
plt.ylabel('frequência')
plt.xlabel('nota')
plt.show()

Observando a frequência de ambas as turmas, a curva de distribuição da turma b evidencia-se aproximar mais da curva normal. A curva da turma a não foi passível visivelmente de ser identificada como distribuição normal ou minimamente aproximada.

No entanto, para fundamentar a convicção, aplico o teste de Shapiro-Wilk. Esse teste é um teste de normalidade. Sua escolha deu-se devido ao critério do tamanho da amostra. O teste de Shapiro-Wilk é indicado para uma amostra de até 30 componentes. Ressalto que alguns autores optam por fixar 50 componentes como limite máximo.

Se a amostra ultrapassasse 30 componentes, optaria pelo teste de Kolmogorov-Smirnov (KS).

Para realizar o teste, importo o algoritmo shapiro .

#Importando Shapiro-Wilk
from scipy.stats import shapiro

Em seguida, aplico o algoritmo e aplico uma condição, a fim de obter a resposta se as curvas são ou não são distribuições normais. Se o valor de p-valor for igual ou maior do que 0,05, então, a hipótese nula (H0) será aceita. Pelo contrário, a hipótese nula é rejeitada, sendo aceita a hipótese alternativa (H1).

O primeiro grupo a ser submetido ao teste de normalidade é a turma a.

alfa = 0.05_, p_valor = shapiro(dados.turma_a)if p_valor >= alfa:
print('Aceita H0: A distribuição de notas da turma A é normal')
else:
print('Rejeita H0: A distribuição de notas da turma A é não-normal')

De acordo com o retornado, a distribuição das notas da turma a segue uma distribuição normal.

Em seguida, testo a normalidade da distribuição das notas da turma b.

alfa = 0.05_, p_valor = shapiro(dados.turma_b)if p_valor >= alfa:
print('Aceita H0: A distribuição de notas da turma B é normal')
else:
print('Rejeita H0: A distribuição de notas da turma B é não-normal')

Sendo assim, a distribuição das notas das turmas cumprem com o critério de normalidade dos dados.

O primeiro requisito foi atendido.

4 Teste de variância — homocedasticidade

Aqui, aplico o teste de variância (homocedasticidade). Para isso, importo o algoritmo levene .

#Importando algoritmo levene
from scipy.stats import levene

Após a importação, aplico o algoritmo com diferentes configurações para o parâmetro center. Essas configurações direcionam o algoritmo levene a performar com foco, por exemplo, ou na média ou na mediana.

#Aplicando os testes
teste_levene = levene(dados.turma_a, dados.turma_b, center='mean')
print('Teste de Levene')
print(np.round(teste_levene, 4))
print('')
brown_forsythe_trimmed = levene(dados.turma_a, dados.turma_b, center='trimmed')
print('Teste Brown-Forsythe - Trimmed')
print(np.round(brown_forsythe_trimmed, 4))
print('')
brown_forsythe_mediana = levene(dados.turma_a, dados.turma_b, center='median')
print('Teste Brown-Forsythe - Mediana')
print(np.round(brown_forsythe_mediana, 4))
print('')

Cada um dos testes de variância apresenta dois valores. Focaremos no segundo valor da resposta de cada teste. Esse valor funciona como o p-valor. Se ele for maior ou igual a 0,05, então, aceitamos a hipótese nula, de que as variâncias das notas das turmas são iguais entre si.

Primeiramente, testo o algoritmo levene com a média como parâmetro.

alfa = 0.05
if teste_levene[1] >= alfa:
print('Aceita H0: Os grupos apresentam variâncias iguais.')
elif teste_levene[1] < alfa:
print('Rejeita H0: Os grupos não apresentam variâncias iguais.')

Considerando a média, de acordo com o teste de Levene, as duas turmas apresentam variâncias iguais, em relação à distribuição das notas.

Em seguida, testo a homocedasticidade, utilizando a configuração trimmed para o parâmetro center.

alfa = 0.05
if brown_forsythe_trimmed[1] >= alfa:
print('Aceita H0: Os grupos apresentam variâncias iguais.')
elif brown_forsythe_trimmed[1] < alfa:
print('Rejeita H0: Os grupos não apresentam variâncias iguais.')

De acordo com o teste de Levene, com configuração trimmed, as variâncias das notas das turmas são iguais.

Duas configurações para o teste de Levene geram o mesmo resultado. Por fim, testo a última configuração, em que a mediana se torna o norte de decisão do algoritmo.

alfa = 0.05
if brown_forsythe_mediana[1] >= alfa:
print('Aceita H0: Os grupos apresentam variâncias iguais.')
elif brown_forsythe_mediana[1] < alfa:
print('Rejeita H0: Os grupos não apresentam variâncias iguais.')

Conforme o resultado, a hipótese nula novamente foi aceita. Sendo assim, pode-se concluir que as notas das turmas apresentam variâncias iguais entre si.

Após os testes, temos as respostas para as perguntas acerca dos requisitos:

1 — A normalidade dos dados

2 — A homocedasticidade das notas das turmas, isso é, se há homogeneidade entre as variâncias das notas das turmas.

As notas de ambas as turmas seguem uma distribuição normal e as variâncias das notas das respectivas turmas são iguais entre si. Sabe-se também que os grupos são independentes entre si. Sendo assim, confirma-se a hipótese de que o teste de hipótese a ser utilizado é o teste t não paramétrico.

5 Aplicando o teste t não pareado

Para aplicar o teste t, faz-se necessário compreender a primeira questão de negócio. A pergunta está em torno de a nota média da turma a ser diferente (superior) a da nota média da turma b. O que queremos saber é se há de fato a diferença ou, em algum momento, essas médias se igualam, bastando aumentar, a um determinado nível, o tamanho da amostra.

Sendo assim, a hipótese nula (H0) será “As médias das notas das duas turmas são estatisticamente iguais” e a hipótese alternativa (H1) será “As médias das notas das duas turmas são estatisticamente diferentes”.

Inicialmente, importo o algoritmo ttest_ind , o qual aplica o test t não pareado.

#Importando o ttest_ind
from scipy.stats import ttest_ind

Em seguida, aplico o teste.

#Aplicando o teste
teste_t_ind = ttest_ind(dados.turma_a, dados.turma_b)

Após a aplicação do teste e armazenamento da resposta na variável teste_t_ind, aplico a condição para aceitação ou rejeição da hipótese nula.

Se o p-valor (test_t_ind[1]) for maior do que 0,05, então, aceitamos a hipótese nula.

alfa = 0.05
if teste_t_ind[1] >= alfa:
print('Aceita H0: As médias das notas das duas turmas são estatisticamente iguais.')
elif teste_t_ind[1] < alfa:
print('Rejeita H0: As médias das notas das duas turmas são estatisticamente diferentes.')

Respondendo à primeira questão de negócio

A turma a tem uma nota média estatísticamente superior a da turma b?

Resposta: Com uma significância de 5%, não há evidências de que as notas médias das duas turmas sejam diferentes entre si. Sendo assim, não há evidências de que, se aumentadas igualmente as amostras de ambas turmas, a um dado nível, as médias não se igualem.

Havendo essa igualdade entre as médias, em uma confiança de 95%, podemos trabalhar com inferência estatística, buscando um intervalo de confiança para a nota média populacional das turmas do 1ª ano do ensino médio, da escola Arthur Excalibur.

6 Aplicando inferência estatística: intervalo de confiança

Para inferir um intervalo de confiança, em que se encontre a nota média populacional dos primeiros anos do ensino médio, faz-se necessário concatenar/juntar as notas das duas turmas, já que não há evidências de que sejam diferentes, isso a 5% de significância.

Para isso, uso o recurso concat da biblioteca pandas.

#Concatenando as notas das turmas
dados_unidos = pd.concat([dados.turma_a, dados.turma_b], axis=0)
#Exibindo as primeiras cinco linhas da nova variável
dados_unidos.head()

Após a concatenação, não houve significativa mudança nas estatísticas.

#Gerando describes estatísticos para análise de impacto
print('Estatísticas após concatenação \n', dados_unidos.describe())
print('')
print('Estatísticas da turma A \n', dados.turma_a.describe())
print('')
print('Estatísticas da turma B \n', dados.turma_b.describe())

Agora, gero o intervalo e o armazeno em uma variável.

#Gerando intervalo
intervalos = t.interval(0.95,
20 - 1,
np.mean(dados_unidos),
stats.sem(dados_unidos, ddof=0)
)
#Arredondando os intervalos
intervalos = np.round(intervalos, 2)
#Resultado
intervalos

Respondendo à segunda questão de negócio

A partir das duas turmas, qual é a estimativa da média para as cinco demais turmas do 1ª ano do ensino médio?

Resposta: Com 95% de confiança, a nota média populacional dos primeiros anos do ensino médio, da escola Arthur Excalibur, está entre 6,6 e 7,87.

Conclusão

Através do teste de hipótese, pudemos ver que, ainda que as notas médias das turmas eram/são diferentes entre si, com uma amostra de 20 componentes, estatisticamente não houve/há evidências para defendermos que de fato eram/são.

Sendo assim, comparar médias ou medianas ou outros parâmetros entre si, não é o suficiente para, estatisticamente, defender que de fato são iguais ou diferentes, menores ou maiores. O teste de hipótese nos ajuda justamente a ter uma conclusão estatisticamente mais sólida.

--

--

Bruno Carloto

Bem-vindo ao Deep Analytics, um blog que aborda de forma técnica o mundo Analytics | LinkedIn: www.linkedin.com/in/bruno-rodrigues-carloto