Nesta aula vamos trabalhar com o conceito de intervalo de confiança, aplicado a médias amostrais.
Vamos explorar o que significa estimar um valor, e como podemos melhorar essa estimativa usando intervalos em vez de apenas um ponto.
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# Simular população com média conhecida
pop = np.random.normal(loc=100, scale=15, size=100000)
mu = np.mean(pop)
sigma = np.std(pop)
# Sorteando uma amostra
np.random.seed(42)
amostra = np.random.choice(pop, size=50)
media = np.mean(amostra)
erro_padrao = sigma / np.sqrt(len(amostra))
# Intervalo de confiança 95%
z = 1.96
lim_inf = media - z * erro_padrao
lim_sup = media + z * erro_padrao
print(f"Estimativa pontual da média: {media:.2f}")
print(f"Intervalo de confiança 95%: [{lim_inf:.2f}, {lim_sup:.2f}]")
print(f"Média real da população: {mu:.2f}")
Estimativa pontual da média: 103.10
Intervalo de confiança 95%: [98.94, 107.25]
Média real da população: 100.04
# Comparar diferentes níveis de confiança
for conf, z in [(90, 1.645), (95, 1.96), (99, 2.576)]:
lim_inf = media - z * erro_padrao
lim_sup = media + z * erro_padrao
print(f"{conf}% de confiança: [{lim_inf:.2f}, {lim_sup:.2f}]")
90% de confiança: [99.61, 106.58]
95% de confiança: [98.94, 107.25]
99% de confiança: [97.64, 108.55]
# Comparar intervalos com diferentes tamanhos de amostra
for n in [10, 30, 100, 500]:
amostra = np.random.choice(pop, size=n)
m = np.mean(amostra)
ep = sigma / np.sqrt(n)
z = 1.96
li = m - z * ep
ls = m + z * ep
print(f"n={n:<3} -> IC 95%: [{li:.2f}, {ls:.2f}], largura: {ls-li:.2f}")
n=10 -> IC 95%: [90.83, 109.40], largura: 18.57
n=30 -> IC 95%: [95.69, 106.41], largura: 10.72
n=100 -> IC 95%: [96.73, 102.60], largura: 5.87
n=500 -> IC 95%: [97.50, 100.13], largura: 2.63
import pandas as pd
# Carregando dados reais
df = pd.read_csv("ipeadata[31-03-2025-03-06].csv", header=1)
df = df[['Município', '2022']].dropna()
df.columns = ['Municipio', 'Populacao']
pop_real = df['Populacao'].values
# Amostragem
amostra_real = np.random.choice(pop_real, size=50)
media_real = np.mean(amostra_real)
erro_padrao_real = np.std(amostra_real, ddof=1) / np.sqrt(50)
# Intervalo de confiança
z = 1.96
lim_inf = media_real - z * erro_padrao_real
lim_sup = media_real + z * erro_padrao_real
print(f"IC 95% da média populacional (amostra): [{lim_inf:.2f}, {lim_sup:.2f}]")
print(f"Média total da população: {np.mean(pop_real):.2f}")
IC 95% da média populacional (amostra): [-3553.18, 78194.06]
Média total da população: 36459.74
# Repetir o cálculo do intervalo de confiança 100 vezes e ver quantos contêm a média real
# Caso com Populacao do Brasil
n = 50
mu_real = np.mean(pop_real)
acertos = 0
for _ in range(100):
a = np.random.choice(pop_real, size=n)
m = np.mean(a)
ep = np.std(a, ddof=1) / np.sqrt(n)
li = m - 1.96 * ep
ls = m + 1.96 * ep
if li <= mu_real <= ls:
acertos += 1
print(f"Número de intervalos que contêm a média real: {acertos}/100")
print(f"Cobertura empírica: {acertos}%")
Número de intervalos que contêm a média real: 69/100
Cobertura empírica: 69%
# Repetir o cálculo do intervalo de confiança 100 vezes e ver quantos contêm a média real
# Caso com dados em Gaussiana
pop = np.random.normal(loc=100, scale=15, size=100000)
n = 50
mu_real = np.mean(pop)
acertos = 0
for _ in range(100):
a = np.random.choice(pop, size=n)
m = np.mean(a)
ep = np.std(a, ddof=1) / np.sqrt(n)
li = m - 1.96 * ep
ls = m + 1.96 * ep
if li <= mu_real <= ls:
acertos += 1
print(f"Número de intervalos que contêm a média real: {acertos}/100")
print(f"Cobertura empírica: {acertos}%")
Número de intervalos que contêm a média real: 94/100
Cobertura empírica: 94%