Aula 11 — Módulo 2: Inferência Estatística
Quando uma diferença observada é grande demais para atribuir apenas ao acaso?
Exemplo da aula: taxa de pedidos entregues depois da data prevista.
Um limite operacional considera aceitável uma taxa de atraso de 8%.
Há evidência de que a taxa de atrasos excede 8%?
Precisamos separar diferença real de variação amostral.
late, igual a 1 quando a entrega supera a data prevista;A amostra de 1.200 pedidos será usada para testar uma referência operacional de 8%.
Para cada pedido:
\[ Y_i= \begin{cases} 1, & \text{entregue depois da data prevista}\\ 0, & \text{entregue até a data prevista} \end{cases} \]
O parâmetro \(p=P(Y=1)\) é a taxa populacional de atraso.
\[ \widehat{p}=\frac{1}{n}\sum_{i=1}^{n}Y_i \]
Em uma amostra de 1.200 pedidos:
\[ k=115, \qquad \widehat{p}=115/1200=0{,}0958 \]
Observamos 9,58% de atrasos.
Uma diferença observada precisa ser comparada a essa variabilidade.
prop_means = np.array([rng.choice(late, size=1200, replace=True).mean() for _ in range(5000)])
plt.figure(figsize=(9, 5.2))
sns.histplot(prop_means, bins=30, color=BLUE)
plt.axvline(p_late, color=ORANGE, lw=3, label=f"p = {p_late:.3f}")
plt.xlabel("Proporção de pedidos atrasados")
plt.ylabel("Frequência")
plt.title("A taxa de atraso também varia entre amostras")
plt.legend()
finish("distribuicao-taxa-atraso.png")
# Amostra observada usada na Aula 11.
obs = np.random.default_rng(13).choice(late, 1200, replace=False)
k_obs = int(obs.sum())
p_hat = obs.mean()
p0 = .08
se0 = np.sqrt(p0 * (1 - p0) / len(obs))
z_obs = (p_hat - p0) / se0“A taxa parece alta” é ambíguo.
Um teste exige:
A hipótese nula representa o valor de referência:
\[ H_0:p=0{,}08 \]
Ela é o modelo que usamos para calcular quão surpreendente é a amostra.
Nossa pergunta é direcional:
\[ H_1:p>0{,}08 \]
Se a pergunta fosse “diferente de 8%”, usaríamos:
\[ H_1:p\neq0{,}08 \]
Sob \(H_0\), o número de atrasos segue:
\[ K\sim\operatorname{Binomial}(n=1200,p=0{,}08) \]
Logo:
\[ E[\widehat{p}]=0{,}08, \quad \operatorname{SE}_0=\sqrt{\frac{0{,}08(0{,}92)}{1200}} \]
\(K\) é o número de atrasos em \(n\) pedidos; \(p_0=0{,}08\) é o valor imposto por \(H_0\); \(\widehat p=K/n\) é a proporção amostral. O índice zero em \(\operatorname{SE}_0\) indica que o erro padrão é calculado sob a hipótese nula.
O valor observado está à direita do centro previsto por \(H_0\).
null_props = rng.binomial(len(obs), p0, size=12000) / len(obs)
plt.figure(figsize=(9, 5.2))
sns.histplot(null_props, bins=30, color=BLUE)
plt.axvline(p_hat, color=ORANGE, lw=3, label=f"p̂ observado = {p_hat:.3f}")
plt.axvline(p0, color=INK, lw=2, ls="--", label="H0: p = 0,08")
plt.xlabel("Proporção de atrasos sob H0")
plt.ylabel("Simulações")
plt.title("A hipótese nula prevê resultados possíveis")
plt.legend()
finish("distribuicao-nula.png")Padronizamos a distância até o valor nulo:
\[ Z=\frac{\widehat{p}-p_0} {\sqrt{p_0(1-p_0)/n}} \]
\(Z\) mede quantos erros padrão separam a amostra de \(H_0\): \(\widehat p\) é a taxa observada, \(p_0\) é a taxa nula e \(n\) é o tamanho amostral. Sob \(H_0\) e condições adequadas, \(Z\approx N(0,1)\).
\[ Z= \frac{0{,}0958-0{,}08} {\sqrt{0{,}08(0{,}92)/1200}} =2{,}02 \]
Se \(H_0\) fosse verdadeira, a estimativa estaria 2,02 erros padrão acima do esperado.
Para o teste unilateral:
\[ p\text{-valor}=P(Z\ge2{,}02\mid H_0) \]
Neste exemplo:
\[ p\text{-valor}\approx0{,}0216 \]
A probabilidade é calculada assumindo \(H_0\). O evento \(Z\ge2{,}02\) reúne resultados pelo menos tão favoráveis a \(H_1\) quanto o observado; não é a probabilidade de \(H_0\) ser verdadeira.
Contamos resultados tão ou mais favoráveis a \(H_1\) que o observado.
counts, bins = np.histogram(null_props, bins=30)
centers = (bins[:-1] + bins[1:]) / 2
plt.figure(figsize=(9, 5.2))
colors = [ORANGE if c >= p_hat else BLUE for c in centers]
plt.bar(centers, counts, width=np.diff(bins), color=colors, align="center")
plt.axvline(p_hat, color=INK, lw=3)
plt.xlabel("Proporção de atrasos sob H0")
plt.ylabel("Simulações")
plt.title("O p-valor é a cauda tão extrema quanto o observado")
finish("pvalor-cauda.png")É uma probabilidade calculada assumindo \(H_0\).
Um valor-p de 0,02 significa que:
Escolhemos antes do teste um limite \(\alpha\) para o erro tipo I.
Regra comum:
\[ p\text{-valor}<\alpha\quad\Rightarrow\quad\text{rejeitar }H_0 \]
Com \(\alpha=0{,}05\), rejeitaríamos \(H_0\) neste exemplo.
Reduzir \(\alpha\) exige uma estatística mais extrema.
xz = np.linspace(-4, 4, 500)
pdf = np.exp(-xz**2 / 2) / np.sqrt(2 * np.pi)
fig, axes = plt.subplots(1, 2, figsize=(11, 4.5), sharey=True)
for ax, cutoff, alpha in [(axes[0], 1.645, "5%"), (axes[1], 2.326, "1%")]:
ax.plot(xz, pdf, color=BLUE, lw=3)
ax.fill_between(xz, 0, pdf, where=xz >= cutoff, color=ORANGE, alpha=.65)
ax.axvline(cutoff, color=INK, ls="--")
ax.set_title(f"α = {alpha}")
ax.set_xlabel("Estatística z")
axes[0].set_ylabel("Densidade sob H0")
fig.suptitle("Reduzir α exige evidência mais extrema", fontweight="bold")
finish("regioes-rejeicao.png")Conclusão adequada:
Os dados fornecem evidência contra uma taxa de atraso de 8%, em favor de uma taxa maior.
Evite:
Provamos que a taxa verdadeira é maior que 8%.
Um resultado não significativo pode ocorrer porque:
“Ausência de evidência” não é “evidência de ausência”.
Em um teste bilateral com \(\alpha=5\%\):
O intervalo acrescenta uma faixa de efeitos plausíveis.
Sob \(H_0\):
\[ K\sim\operatorname{Binomial}(1200,0{,}08) \]
O p-valor exato unilateral é:
\[ P(K\ge115\mid p=0{,}08) \]
Não precisamos aproximar uma variável discreta por uma Normal.
Podemos usar a Normal quando os números esperados de sucessos e falhas são suficientes:
\[ np_0\ge10, \qquad n(1-p_0)\ge10 \]
Aqui: 96 atrasos e 1.104 não atrasos são esperados sob \(H_0\).
A aproximação é melhor no centro e com contagens esperadas grandes.
n_small, p_small = 30, .5
k = np.arange(n_small + 1)
from math import comb
pmf = np.array([comb(n_small, int(i)) * p_small**i * (1-p_small)**(n_small-i) for i in k])
normal = np.exp(-((k-n_small*p_small)/np.sqrt(n_small*p_small*(1-p_small)))**2/2)
normal = normal / normal.sum()
plt.figure(figsize=(9, 5.2))
plt.vlines(k, 0, pmf, color=BLUE, lw=4, label="Binomial exata")
plt.plot(k, normal, color=ORANGE, lw=3, label="aproximação Normal")
plt.xlabel("Número de caras em 30 lançamentos")
plt.ylabel("Probabilidade")
plt.title("A Normal aproxima a Binomial no centro")
plt.legend()
finish("binomial-normal.png")
print(f"Figuras geradas em {OUT}")
print(f"N={len(orders)}; média={mu:.3f}; sigma={sigma:.3f}; atraso={p_late:.5f}")
print(f"Amostra teste: n={len(obs)}, k={k_obs}, p_hat={p_hat:.5f}, z={z_obs:.3f}, p-valor={1-normal_cdf(z_obs):.4f}")Também podemos gerar muitas amostras com \(p=0{,}08\):
Simulação torna a lógica visível e generaliza para estatísticas complexas.
| Método | Vantagem | Limite |
|---|---|---|
| Exato | sem aproximação | pode ser difícil |
| Normal/TCL | fórmula rápida | depende de condições |
| Simulação | flexível e visual | tem erro Monte Carlo |
Resultados próximos aumentam nossa confiança na implementação.
| Realidade | Não rejeitar \(H_0\) | Rejeitar \(H_0\) |
|---|---|---|
| \(H_0\) verdadeira | decisão correta | erro tipo I |
| \(H_1\) verdadeira | erro tipo II | decisão correta |
Não existe regra que elimine os dois erros simultaneamente.
Rejeitar \(H_0\) quando ela é verdadeira.
No contexto:
Concluir que a taxa excede 8% quando ela é exatamente 8%.
Sua probabilidade é controlada por \(\alpha\).
Com \(H_0\) verdadeira, cerca de 5% dos testes rejeitam por acaso quando \(\alpha=5\%\).
rejections = []
running = []
for i in range(1, 5001):
ph = rng.binomial(1200, p0) / 1200
z = (ph - p0) / se0
rejections.append(z > 1.645)
running.append(np.mean(rejections))
plt.figure(figsize=(9, 5.2))
plt.plot(running, color=BLUE, lw=2)
plt.axhline(.05, color=ORANGE, lw=3, ls="--", label="α = 5%")
plt.xlabel("Número de testes simulados sob H0")
plt.ylabel("Fração de rejeições")
plt.title("Sob H0, rejeitamos cerca de alpha das vezes")
plt.legend()
finish("erro-tipo-i.png")Um \(\alpha\) menor:
A escolha deve refletir o custo dos erros.
Não rejeitar \(H_0\) quando \(H_1\) é verdadeira.
No contexto:
Não detectar uma taxa realmente superior a 8%.
Sua probabilidade é \(\beta\).
\[ \text{poder}=1-\beta \]
Aqui, \(\beta=P_{\theta_1}(\text{não rejeitar }H_0)\) é a probabilidade de erro tipo II sob um valor alternativo específico \(\theta_1\). Portanto, \(1-\beta=P_{\theta_1}(\text{rejeitar }H_0)\).
O poder depende do valor verdadeiro sob a alternativa.
Mantendo \(p_0=8\%\), \(p_1=10\%\) e \(\alpha=5\%\), aumentar \(n\) estreita as duas distribuições. A área de \(H_1\) além do limiar crítico cresce de 37% para 79%.
p0, p1, alpha = .08, .10, .05
z_critical = norm.ppf(1 - alpha)
fig, axes = plt.subplots(1, 2, figsize=(13.2, 5.3), sharex=True)
common_x = np.linspace(.02, .16, 800)
for ax, n in zip(axes, [300, 1200]):
se0 = np.sqrt(p0 * (1-p0) / n)
se1 = np.sqrt(p1 * (1-p1) / n)
critical = p0 + z_critical * se0
x = common_x
y0, y1 = norm.pdf(x, p0, se0), norm.pdf(x, p1, se1)
power = norm.sf(critical, p1, se1)
ax.plot(100*x, y0, color=BLUE, lw=3, label=r"Sob $H_0$: $p=8\%$")
ax.plot(100*x, y1, color=ORANGE, lw=3, label=r"Sob $H_1$: $p=10\%$")
mask = x >= critical
ax.fill_between(100*x[mask], 0, y1[mask], facecolor="#f6c49a",
edgecolor=ORANGE, alpha=.65, hatch="///",
label=f"Poder = {power:.0%}")
ax.axvline(100*critical, color=INK, ls="--", lw=2,
label="limiar crítico")
ax.set(title=f"n = {n} pedidos",
xlabel="Proporção amostral de atrasos (%)")
ax.set_xlim(2, 16)
ax.set_yticks([]); ax.legend(frameon=False)
plt.tight_layout()
finish("poder-duas-distribuicoes.png")Na figura, o efeito permanece de 8% para 10%, mas \(n\) cresce de 300 para 1.200. Por que o poder aumenta?
É mais fácil detectar 12% que 8,5% de atrasos.
true_ps = np.linspace(.05, .13, 33)
critical = p0 + 1.645 * se0
power = []
for p in true_ps:
simulated = rng.binomial(1200, p, size=5000) / 1200
power.append(np.mean(simulated > critical))
plt.figure(figsize=(9, 5.2))
plt.plot(true_ps, power, color=BLUE, lw=3)
plt.axvline(p0, color=INK, ls="--", lw=2)
plt.axhline(.8, color=ORANGE, ls="--", lw=2, label="80% de poder")
plt.xlabel("Taxa verdadeira de atraso")
plt.ylabel("Probabilidade de rejeitar H0")
plt.title("O poder cresce quando o efeito se afasta de H0")
plt.legend()
finish("curva-poder.png")Com mais observações:
Planejar \(n\) exige definir o menor efeito relevante.
A diferença observada foi:
\[ 0{,}0958-0{,}08=0{,}0158 \]
Ou 1,58 ponto percentual.
Pergunta operacional: essa diferença justifica uma ação?
O resultado seria raro sob \(H_0\)?
O efeito tem magnitude e consequência relevantes?
Sempre reporte estimativa e intervalo, não apenas p-valor.
Se fazemos 20 testes independentes com \(\alpha=5\%\):
\[ P(\text{ao menos um falso positivo}) =1-0{,}95^{20}\approx64\% \]
Pré-registo, correções e validação externa ajudam a controlar o problema.
Use unilateral somente quando:
Caso contrário, prefira o teste bilateral.
Verifique:
Em 800 pedidos, 76 atrasaram. Teste \(H_0:p=0{,}08\) contra \(H_1:p>0{,}08\).
Inferência não elimina a incerteza; ela torna explícito como decidimos dentro dela.
Boas conclusões combinam desenho, estimativa, intervalo, p-valor e consequência prática.
olistbr/brazilian-ecommerce.ICD: Aula 11 — Testes de hipótesesvoltar para a Aula