O CrossValidated tem várias perguntas sobre quando e como aplicar a correção de viés de evento raro por King e Zeng (2001) . Estou procurando algo diferente: uma demonstração mínima baseada em simulação de que o viés existe.
Em particular, o rei e o estado de Zeng
"... em dados de eventos raros, os desvios nas probabilidades podem ser substancialmente significativos com tamanhos de amostra na casa dos milhares e estão em uma direção previsível: as probabilidades estimadas de eventos são muito pequenas."
Aqui está minha tentativa de simular esse viés no R:
# FUNCTIONS
do.one.sim = function(p){
N = length(p)
# Draw fake data based on probabilities p
y = rbinom(N, 1, p)
# Extract the fitted probability.
# If p is constant, glm does y ~ 1, the intercept-only model.
# If p is not constant, assume its smallest value is p[1]:
glm(y ~ p, family = 'binomial')$fitted[1]
}
mean.of.K.estimates = function(p, K){
mean(replicate(K, do.one.sim(p) ))
}
# MONTE CARLO
N = 100
p = rep(0.01, N)
reps = 100
# The following line may take about 30 seconds
sim = replicate(reps, mean.of.K.estimates(p, K=100))
# Z-score:
abs(p[1]-mean(sim))/(sd(sim)/sqrt(reps))
# Distribution of average probability estimates:
hist(sim)
Quando executo isso, tendem a obter escores z muito pequenos, e o histograma de estimativas está muito próximo da verdade p = 0,01.
o que estou perdendo? Será que minha simulação não é grande o suficiente para mostrar o verdadeiro viés (e evidentemente muito pequeno)? O viés exige que algum tipo de covariável (mais que a interceptação) seja incluído?
Atualização 1: King e Zeng incluem uma aproximação aproximada para o viés de na equação 12 de seu artigo. Observando o denominador, reduzi drasticamente a ser e refiz a simulação, mas ainda não é evidente nenhum viés nas probabilidades estimadas do evento. (Eu usei isso apenas como inspiração. Note-se que a minha pergunta acima é sobre probabilidades de eventos estimados, não β 0 ).N
N
5
Atualização 2: Seguindo uma sugestão nos comentários, incluí uma variável independente na regressão, levando a resultados equivalentes:
p.small = 0.01
p.large = 0.2
p = c(rep(p.small, round(N/2) ), rep(p.large, N- round(N/2) ) )
sim = replicate(reps, mean.of.K.estimates(p, K=100))
Explicação: Eu me usei p
como a variável independente, onde p
é um vetor com repetições de um valor pequeno (0,01) e um valor maior (0,2). No final, sim
armazena apenas as probabilidades estimadas correspondentes a e não há sinal de viés.
Atualização 3 (5 de maio de 2016): Isso não altera visivelmente os resultados, mas minha nova função de simulação interna é
do.one.sim = function(p){
N = length(p)
# Draw fake data based on probabilities p
y = rbinom(N, 1, p)
if(sum(y) == 0){ # then the glm MLE = minus infinity to get p = 0
return(0)
}else{
# Extract the fitted probability.
# If p is constant, glm does y ~ 1, the intercept only model.
# If p is not constant, assume its smallest value is p[1]:
return(glm(y ~ p, family = 'binomial')$fitted[1])
}
}