Análise Estatística
Visão Geral
Conduza testes de hipóteses (testes t, ANOVA, qui-quadrado), regressão, correlação e análises bayesianas com verificação sistemática de pressupostos, tamanhos de efeito e relatórios no estilo APA. O objetivo é uma análise que um revisor não conseguiria desmontar: o teste correto, pressupostos verificados, tamanhos de efeito honestos e um relatório completo.
Quando Usar Esta Habilidade
Use esta habilidade quando:
- Conduzir testes de hipóteses estatísticas (testes t, ANOVA, qui-quadrado, não paramétricos)
- Realizar análises de regressão ou correlação
- Executar análises estatísticas bayesianas
- Verificar pressupostos e diagnósticos estatísticos
- Calcular tamanhos de efeito e conduzir análises de poder
- Relatar resultados estatísticos no formato APA
- Analisar dados experimentais ou observacionais para pesquisa
Instalação
Use o uv para instalar as bibliotecas utilizadas nesta habilidade. Fixe as versões em produção; instalações sem fixação são adequadas para exploração.
# Stack frequentista central (Python 3.10+; 3.12+ recomendado para as versões mais recentes de SciPy/ArviZ)
uv pip install "pingouin>=0.6" "scipy>=1.11" "statsmodels>=0.14.6" pandas matplotlib seaborn
# Modelagem Bayesiana (PyMC 5 + ArviZ)
uv pip install "pymc>=5.0" "arviz>=1.0"
Notas de compatibilidade (verificadas com pingouin 0.6.1, statsmodels 0.14.6, arviz 1.2, 2026):
- Pingouin 0.6.0 renomeou colunas de saída para remover caracteres especiais:
p_val,cohen_d,CI95,p_unc(anteriormentep-val,cohen-d,CI95%,p-uncna versão 0.5.x). Os exemplos abaixo usam os nomes atuais; se estiver preso na versão 0.5.x, use os formulários com hífen. - statsmodels + SciPy: use
statsmodels>=0.14.6comscipy>=1.11para evitar erros de importação_lazywhereno SciPy 1.16+. - ArviZ 1.x:
az.summary()agora usa como padrão intervalos de 89% (colunaseti89) e o parâmetro de largura éci_prob(nãohdi_prob). Para relatar um intervalo de credibilidade convencional de 95%, passeaz.summary(trace, ci_prob=0.95). - Fatores de Bayes unilaterais foram removidos do Pingouin:
pg.ttest(..., alternative='greater')silencia a colunaBF10, epg.bayesfactor_ttestgera um erro para alternativas unilaterais. Para testes bayesianos unilaterais, use o PyMC diretamente (calcule a probabilidade posterior da hipótese direcional) ou o BayesFactor do JASP/R.
Para APIs específicas de modelo (OLS, GLM, ARIMA), consulte a habilidade statsmodels. Para fluxos de trabalho com PyMC, consulte a habilidade pymc.
Fluxo de Trabalho da Análise
Toda análise sólida segue o mesmo arco. Pular etapas é como as análises acabam sendo retratadas, então trabalhe através delas em ordem e diga o que você fez em cada uma.
- Formule a pergunta antes de tocar nos dados. Declare a hipótese, as variáveis de resultado e preditoras, e o desenho (grupos independentes vs. pareados, número de grupos). Comprometa-se com um teste planejado agora — escolher o teste depois de espiar os resultados é p-hacking, mesmo quando feito inocentemente.
- Inspecione os dados. Por grupo: n, média, DP, mediana, valores ausentes. Plote os dados brutos (histogramas ou box plots) antes de qualquer teste. Tamanhos de grupo desiguais, dados ausentes, efeitos teto/chão e outliers todos alteram qual teste é apropriado — apresente-os ao usuário em vez de contorná-los silenciosamente.
- Selecione o teste usando a referência rápida abaixo, ou
references/test_selection_guide.mdpara desenhos além do básico (contagens, tempo até evento, confiabilidade, fatorial). - Verifique os pressupostos com
scripts/assumption_checks.py. Se um pressuposto falhar, mude para o teste corretivo (tabela abaixo) e relate tanto o plano quanto a mudança. - Execute o teste e sempre calcule o tamanho do efeito junto com ele — um valor p diz que um efeito existe; o tamanho do efeito diz se alguém deveria se importar.
- Relate usando os templates APA abaixo, incluindo descritivas, estatísticas exatas, tamanhos de efeito com ICs e as verificações de pressupostos realizadas.
Se o usuário precisar apenas de uma etapa (por exemplo, "quantos participantes eu preciso?"), vá direto para essa seção — mas ainda confirme os pressupostos de desenho nos quais o cálculo se baseia.
Guia de Seleção de Testes
Referência Rápida: Escolhendo o Teste Correto
Use references/test_selection_guide.md para orientação abrangente (contagens, sobrevivência, confiabilidade, desenhos fatoriais). Referência rápida:
Comparando Dois Grupos:
- Independente, contínuo, normal → Teste t independente
- Independente, contínuo, não normal → Teste U de Mann-Whitney
- Pareado, contínuo, normal → Teste t pareado
- Pareado, contínuo, não normal → Teste de Wilcoxon (signed-rank)
- Resultado binário → Qui-quadrado ou teste exato de Fisher
Comparando 3+ Grupos:
- Independente, contínuo, normal → ANOVA de uma via
- Independente, contínuo, não normal → Teste de Kruskal-Wallis
- Pareado, contínuo, normal → ANOVA de medidas repetidas
- Pareado, contínuo, não normal → Teste de Friedman
Relações:
- Duas variáveis contínuas → Correlação de Pearson (normal) ou Spearman (não normal)
- Resultado contínuo com preditor(es) → Regressão linear
- Resultado binário com preditor(es) → Regressão logística
Alternativas Bayesianas:
Todos os testes têm versões bayesianas que fornecem declarações de probabilidade diretas sobre hipóteses, Fatores de Bayes que quantificam evidências e a capacidade de apoiar a hipótese nula. Veja references/bayesian_statistics.md.
Verificação de Pressupostos
Sempre verifique os pressupostos antes de interpretar os resultados dos testes e relate as verificações — os revisores as procuram.
Use o módulo fornecido scripts/assumption_checks.py. Execute o Python a partir do diretório da habilidade (skills/statistical-analysis/) ou adicione scripts/ ao sys.path:
from assumption_checks import comprehensive_assumption_check
# Outliers + normalidade (por grupo) + homogeneidade de variância, com gráficos
results = comprehensive_assumption_check(
data=df,
value_col='score',
group_col='group', # Opcional: para comparações de grupo
alpha=0.05
)
Para verificações direcionadas, importe funções individuais:
from assumption_checks import (
check_normality, # Shapiro-Wilk + gráfico Q-Q + histograma
check_normality_per_group,
check_homogeneity_of_variance, # Teste de Levene + box plots
check_linearity, # gráfico de dispersão + resíduos para regressão simples
check_regression_diagnostics, # diagnósticos completos de OLS (veja Regressão abaixo)
detect_outliers # métodos IQR ou z-score
)
result = check_normality(data=df['score'], name='Test Score', alpha=0.05, plot=True)
print(result['interpretation'])
print(result['recommendation'])
O Que Fazer Quando os Pressupostos São Violados
Normalidade violada:
- Violação leve + n > 30 por grupo → Proceda com teste paramétrico (robusto)
- Violação moderada → Use alternativa não paramétrica
- Violação severa → Transforme os dados ou use teste não paramétrico
Homogeneidade de variância violada:
- Para teste t → Use o teste t de Welch (
pg.ttestaplica-o automaticamente comcorrection='auto') - Para ANOVA → Use ANOVA de Welch (
pg.welch_anova) ou Brown-Forsythe - Para regressão → Use erros padrão robustos ou mínimos quadrados ponderados
Linearidade violada (regressão):
- Adicione termos polinomiais, transforme variáveis ou use modelos não lineares / GAM
Testes formais tornam-se excessivamente sensíveis à medida que n cresce: para n ≥ 100, pese o gráfico Q-Q mais fortemente do que o valor p de Shapiro-Wilk. Veja references/assumptions_and_diagnostics.md para orientação abrangente.
Executando Testes Estatísticos
Bibliotecas principais:
- pingouin: testes fáceis de usar que retornam tamanhos de efeito por padrão — prefira-o para testes padrão
- scipy.stats: testes estatísticos principais
- statsmodels: regressão, diagnósticos, análise de poder
- pymc + arviz: modelagem bayesiana e diagnósticos
Teste T com Relatório Completo
import pingouin as pg
# correction='auto' aplica a correção de Welch quando as variâncias são desiguais
result = pg.ttest(group_a, group_b, correction='auto')
# Nomes de colunas do Pingouin >= 0.6
t_stat = result['T'].values[0]
df = result['dof'].values[0]
p_value = result['p_val'].values[0]
cohens_d = result['cohen_d'].values[0]
ci_lower, ci_upper = result['CI95'].values[0] # IC para a diferença das médias
print(f"t({df:.0f}) = {t_stat:.2f}, p = {p_value:.3f}, d = {cohens_d:.2f}")
ANOVA com Testes Post-Hoc
import pingouin as pg
aov = pg.anova(dv='score', between='group', data=df, detailed=True)
print(aov)
# Tamanho do efeito: eta-quadrado parcial
eta_p2 = aov['np2'].values[0]
# Se for significativo, conduza testes post-hoc (Tukey HSD controla o erro familiar)
if aov['p_unc'].values[0] < 0.05:
posthoc = pg.pairwise_tukey(dv='score', between='group', data=df)
print(posthoc) # inclui g de Hedges por par
Regressão Linear com Diagnósticos
import statsmodels.api as sm
from assumption_checks import check_regression_diagnostics
X = sm.add_constant(X_predictors) # Adiciona intercepto
model = sm.OLS(y, X).fit()
print(model.summary())
# Gráfico de resíduos de 4 painéis + Shapiro-Wilk, Breusch-Pagan, Durbin-Watson, VIF
diag = check_regression_diagnostics(model)
print(diag['interpretation'])
print(diag['vif'])
# Se heterocedasticidade foi sinalizada, relate erros padrão robustos
robust = model.get_robustcov_results('HC3')
Teste T Bayesiano
import pymc as pm
import arviz as az
import numpy as np
with pm.Model() as model:
# Prioris
mu1 = pm.Normal('mu_group1', mu=0, sigma=10)
mu2 = pm.Normal('mu_group2', mu=0, sigma=10)
sigma = pm.HalfNormal('sigma', sigma=10)
# Verossimilhança
y1 = pm.Normal('y1', mu=mu1, sigma=sigma, observed=group_a)
y2 = pm.Normal('y2', mu=mu2, sigma=sigma, observed=group_b)
# Quantidade derivada
diff = pm.Deterministic('difference', mu1 - mu2)
trace = pm.sample(2000, tune=1000)
# ArviZ 1.x usa intervalos de 89% como padrão; solicite 95% explicitamente para relatório
print(az.summary(trace, var_names=['difference'], ci_prob=0.95))
# Declaração de probabilidade direta (é nisso que perguntas unilaterais se tornam)
prob_greater = np.mean(trace.posterior['difference'].values > 0)
print(f"P(mu1 > mu2 | dados) = {prob_greater:.3f}")
# ArviZ 1.x removeu az.plot_posterior; use plot_dist (no 0.x, plot_posterior ainda funciona)
az.plot_dist(trace, var_names=['difference'], ci_prob=0.95)
Escalone as prioris para os dados (por exemplo, sigma=10 é adequado para resultados com DP próximo de 10; use o DP observado como guia) e declare as prioris no relatório.
Tamanhos de Efeito
Tamanhos de efeito quantificam a magnitude; valores p apenas indicam existência. Relate um para cada teste. Veja references/effect_sizes_and_power.md para o guia completo.
Referência Rápida: Tamanhos de Efeito Comuns
| Teste | Tamanho do Efeito | Pequeno | Médio | Grande |
|---|---|---|---|---|
| Teste t | d de Cohen | 0,20 | 0,50 | 0,80 |
| ANOVA | η²_p | 0,01 | 0,06 | 0,14 |
| Correlação | r | 0,10 | 0,30 | 0,50 |
| Regressão | R² | 0,02 | 0,13 | 0,26 |
| Qui-quadrado | V de Cramér | 0,07 | 0,21 | 0,35 |
Os pontos de referência são convenções, não leis — um efeito "pequeno" pode ser enormemente importante (efeitos colaterais de medicamentos) e um "grande" pode ser trivial. Interprete no contexto.
Calculando Tamanhos de Efeito
Pingouin retorna tamanhos de efeito com seus testes (cohen_d de pg.ttest, np2 de pg.anova, hedges de pg.pairwise_tukey; r de pg.corr já é um tamanho de efeito).
Intervalos de Confiança para Tamanhos de Efeito
Relate um IC para o tamanho do efeito para mostrar sua precisão. Use pg.compute_esci (nota: pg.compute_effsize_from_t retorna apenas a estimativa pontual — ela não retorna um IC):
import pingouin as pg
d = pg.compute_effsize(group_a, group_b, eftype='cohen')
ci_lower, ci_upper = pg.compute_esci(stat=d, nx=len(group_a), ny=len(group_b),
eftype='cohen', confidence=0.95)
print(f"d = {d:.2f}, 95% IC [{ci_lower:.2f}, {ci_upper:.2f}]")
Análise de Poder
Análise de Poder a Priori (Planejamento do Estudo)
Determine o tamanho amostral necessário antes da coleta de dados:
from statsmodels.stats.power import tt_ind_solve_power, FTestAnovaPower
# Teste t: Qual n por grupo é necessário para detectar d = 0,5?
n_required = tt_ind_solve_power(
effect_size=0.5,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"n necessário por grupo: {n_required:.0f}")
# ANOVA de uma via: Qual n é necessário para detectar f de Cohen = 0,25?
# Notas: o parâmetro é k_groups; effect_size é f de Cohen (f = sqrt(eta2/(1-eta2)));
# e solve_power retorna o TAMANHO TOTAL da amostra, não n por grupo.
import math
anova_power = FTestAnovaPower()
n_total = anova_power.solve_power(
effect_size=0.25,
k_groups=3,
alpha=0.05,
power=0.80
)
print(f"N total necessário: {math.ceil(n_total)} ({math.ceil(n_total / 3)} por grupo)")
Análise de Sensibilidade (Pós-Estudo)
Determine qual tamanho de efeito o estudo poderia detectar:
# Com n=50 por grupo, qual efeito poderíamos detectar com 80% de poder?
detectable_d = tt_ind_solve_power(
effect_size=None, # Resolver para este
nobs1=50,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"O estudo poderia detectar d >= {detectable_d:.2f}")
Nota: O "poder observado" post-hoc (calcular o poder a partir do efeito observado) é circular e enganoso — é uma função determinística do valor p. Se um estudo for concluído e alguém perguntar sobre poder, execute uma análise de sensibilidade.
Veja references/effect_sizes_and_power.md para orientação detalhada.
Relatando Resultados
Siga references/reporting_standards.md para o estilo APA. Cada relatório precisa de:
- Estatísticas descritivas: M, DP, n para todos os grupos/variáveis
- Estatísticas de teste: Nome do teste, estatística, gl, valor p exato (
p = 0,034, nãop < 0,05; usep < 0,001apenas abaixo de 0,001) - Tamanhos de efeito: Com intervalos de confiança
- Verificações de pressupostos: Quais testes foram executados, resultados e ações tomadas
- Todas as análises planejadas: Incluindo resultados não significativos — omiti-los é cherry-picking
Modelos de Relatório de Exemplo
Teste T Independente
O Grupo A (n = 48, M = 75,2, DP = 8,5) pontuou significativamente mais alto do que
o Grupo B (n = 52, M = 68,3, DP = 9,2), t(98) = 3,42, p = 0,001, d de Cohen = 0,78,
IC 95% [0,37, 1,19].
ANOVA de Uma Via
Uma ANOVA de uma via revelou um efeito significativo do grupo na pontuação,
F(2, 147) = 5,23, p = 0,006, η²_p = 0,07. Testes post-hoc de Tukey indicaram que
o Grupo A (M = 75,2, DP = 8,5) pontuou significativamente mais alto do que o Grupo C
(M = 68,1, DP = 9,8), g de Hedges = 0,76, IC 95% [0,30, 1,22], p = 0,004. Nenhuma
outra diferença foi significativa (ps > 0,10).
Correlação
Houve uma correlação positiva moderada entre os anos de experiência e a pontuação
de proficiência, r(128) = 0,38, IC 95% [0,22, 0,52], p < 0,001.
Regressão
O modelo de regressão linear foi significativo, F(2, 97) = 12,45, p < 0,001,
R² = 0,20, R² ajustado = 0,19. Anos de experiência (β = 0,31, p < 0,001) e
horas de treinamento (β = 0,22, p = 0,015) foram preditores significativos.
O VIF para ambos os preditores foi < 1,5, indicando baixa multicolinearidade.
Resolução de Problemas
Problema: Pingouin retorna p-val em vez de p_val
Solução: Você está usando Pingouin 0.5.x. Atualize com uv pip install "pingouin>=0.6" ou use os nomes de coluna com hífen.
Problema: Erro de importação _lazywhere
Solução: Atualize SciPy e statsmodels: uv pip install "scipy>=1.11" "statsmodels>=0.14.6".
Problema: ArviZ retorna intervalos de 89% em vez de 95%
Solução: Passe ci_prob=0.95 explicitamente em az.summary() e az.plot_dist().
Problema: Testes de normalidade ou homogeneidade são significativos para amostras grandes
Solução: Para n ≥ 100, foque em inspeções visuais (gráfico Q-Q, box plots) em vez de apenas no valor p.
Problema: Código PyMC é lento para compilar
Solução: Certifique-se de que o PyMC 5.x esteja instalado. A primeira compilação de modelo é mais lenta; execuções subsequentes são mais rápidas. Amostragem com draws=500, tune=500 para iterações rápidas de prototipação.
Leitura Adicional
Consulte references/ para:
test_selection_guide.md— Guia abrangente de seleção de testesassumptions_and_diagnostics.md— Tratamento detalhado de pressupostoseffect_sizes_and_power.md— Guia completo de tamanhos de efeito e poderbayesian_statistics.md— Introdução às alternativas bayesianasreporting_standards.md— Modelos de relatório no formato APA
Licença
MIT