稀有事件逻辑回归偏差:如何用一个最小的例子模拟被低估的p?


19

CrossValidated对于何时以及如何应用King和Zeng(2001)的罕见事件偏差校正有几个问题。我正在寻找与众不同的东西:一个基于模拟的最小演示,证明存在偏差。

特别是国王和曾国

“……在极少数事件数据中,几千个样本量的概率偏差可能实际上是有意义的,并且处于可预测的方向:估计的事件概率太小。”

这是我尝试模拟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)

当我运行此命令时,我倾向于获得非常小的z得分,并且估计的直方图非常接近以p = 0.01为中心的中心。

我想念什么?我的模拟不够大,显示出真实的(并且显然很小)偏差吗?偏差是否需要包含某种协变量(大于截距)?

更新1: 国王和曾包括的偏置粗略估计在他们的论文中的公式12。注意分母中的,我大幅度地将其简化为,然后重新运行了模拟,但是在估计的事件概率上仍然没有偏差。(我用这只作为灵感。需要注意的是上面我的问题是关于估计事件的概率,而不是β 0)。β0NN5β^0

更新2:根据评论中的建议,我在回归中包括了一个自变量,得出了相同的结果:

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))

说明:我将p自己用作自变量,其中p是一个向量,其重复值小(0.01)而大(0.2)。最后,sim仅存储对应于的估计概率,没有偏差的迹象。p=0.01

更新3(2016年5月5日): 这不会显着改变结果,但是我新的内部模拟功能是

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])
    }
}

p=0


3
我很高兴您正在为此工作,并期待其他人的评论。即使存在偏差,偏差校正也可能会充分增加方差,从而提高估计的均方误差。
Frank Harrell,2015年

3
@ FrankHarrell,King和Zeng也断言“我们处在令人高兴的情况下,减少偏见也会减少差异。”
zkurtz

1
好。偏差量是否足够大值得担忧,还有待观察。
Frank Harrell,2015年

什么是“稀有”?例如,每年0.001%的违约率与AAA信用等级相关。这对您来说足够稀有吗?
阿克萨卡(Aksakal)

1
@Aksakal是我最喜欢的“稀有”选择,它最清楚地表明了King和Zeng所写的偏见。
zkurtz

Answers:


4

这是一个有趣的问题-我已经在下面进行了一些模拟,以期激发更多的讨论。

首先,一些一般性评论:

  • 您引用的论文是关于罕见事件偏见的。我之前还不清楚(也针对上面的评论),如果您有10/10000而不是10/30的观测值,是否还有特殊之处。但是,经过一些模拟,我会同意。

  • 我想到的一个问题(我经常遇到这个问题,并且最近在《生态学和进化论的方法》中有一篇论文,但是我找不到参考)是,您可以在小数据中获取带有GLM的退化案例。在这种情况下,MLE远离真值,甚至处于-/ +无穷大(由于我想是非线性链接)。对我来说,尚不清楚应该如何在偏差估计中处理这些情况,但是从我的模拟中,我会说它们似乎是罕见事件偏差的关键。我的直觉是要删除它们,但是还不清楚要删除它们有多远。也许需要记住一些偏差校正。

  • 同样,这些退化的情况似乎容易引起数值问题(因此,我提高了glm函数的maxit值,但也可以考虑增加epsilon以确保实际报告了真实的MLE)。

无论如何,这里有一些代码用于计算逻辑回归中截距,斜率和预测的估计值与真值之间的差,首先是针对样本量较小/中等发生率的情况:

set.seed(123)
replicates = 1000
N= 40
slope = 2 # slope (linear scale)
intercept = - 1 # intercept (linear scale)

bias <- matrix(NA, nrow = replicates, ncol = 3)
incidencePredBias <- rep(NA, replicates)

for (i in 1:replicates){
  pred = runif(N,min=-1,max=1) 
  linearResponse = intercept + slope*pred
  data = rbinom(N, 1, plogis(linearResponse))  
  fit <- glm(data ~ pred, family = 'binomial', control = list(maxit = 300))
  bias[i,1:2] = fit$coefficients - c(intercept, slope)
  bias[i,3] = mean(predict(fit,type = "response")) - mean(plogis(linearResponse))
}

par(mfrow = c(1,3))
text = c("Bias intercept", "Bias slope", "Bias prediction")

for (i in 1:3){
  hist(bias[,i], breaks = 100, main = text[i])
  abline(v=mean(bias[,i]), col = "red", lwd = 3)  
}

apply(bias, 2, mean)
apply(bias, 2, sd) / sqrt(replicates)

截距,斜率和预测的最终偏差和标准误差为

-0.120429315  0.296453122 -0.001619793
 0.016105833  0.032835468  0.002040664

我可以得出结论,尽管有很好的证据表明,截距中有轻微的负偏差,而斜率中有轻微的正偏差,但是从绘图结果看,与估计值的方差相比,偏差很小。

在此处输入图片说明

如果我将参数设置为罕见情况

N= 4000
slope = 2 # slope (linear scale)
intercept = - 10 # intercept (linear scale)

我对截距有较大的偏见,但在预测上仍然没有

   -1.716144e+01  4.271145e-01 -3.793141e-06
    5.039331e-01  4.806615e-01  4.356062e-06

在估计值的直方图中,我们看到了退化参数估计的现象(如果我们这样称呼它们的话)

在此处输入图片说明

让我们删除截距估计值小于20的所有行

apply(bias[bias[,1] > -20,], 2, mean)
apply(bias[bias[,1] > -20,], 2, sd) / sqrt(length(bias[,1] > -10))

偏差减小了,图中的情况变得更加清晰了-参数估计值显然不是正态分布的。我想知道这是否意味着所报告的配置项的有效性。

-0.6694874106  1.9740437782  0.0002079945
1.329322e-01 1.619451e-01 3.242677e-06

在此处输入图片说明

我可以得出结论,截距上的稀有事件偏差是由稀有事件本身驱动的,即稀有,极小的估计。不知道我们是否要删除它们,不知道截止值是多少。

不过,要注意的重要一点是,无论哪种方式,响应规模的预测似乎都没有偏差-链接函数只是吸收了这些极小的值。


1
是的,仍然很感兴趣。+1是一个不错的讨论,并且可以找到与我的相似的结果(无明显的预测偏差)。假设我们都是对的,我最终希望看到对预测偏差真正值得关注的情况的描述(即至少是一个例子),或者对King and Zeng论文的弱点进行解释。他们夸大了纠正偏差的重要性。
zkurtz

±20

1

稀有事件偏差仅在存在回归变量时发生。它不会像此处模拟的那样在仅拦截模型中发生。有关详情,请参见此帖子:http : //statisticalhorizo​​ns.com/linear-vs-logistic#comment-276108


3
嗨,保罗。如果您扩展答案以使其独立并且不需要访问外部网站(例如,有时可能不可用),则将是更可取的。
帕特里克·库洛姆贝

还要注意OP中的“更新2”。单个回归变量也不会出现偏差。
zkurtz

根据King&Zeng的方程式(16)和图7,偏差是回归变量X的函数。如果X小,则不存在偏差,这是OP在更新2中考虑的情况。 X较大时产生偏差。我还建议尝试复制King&Zeng的模拟。
保罗·冯·希佩尔

以下是King-Zeng论文的链接:gking.harvard.edu/files/0s.pdf
Paul von Hippel,

1

本文中的图7似乎最直接地解决了预测中的偏差问题。我不完全理解该图(具体来说,“估计的事件概率太小”的解释似乎过于简化了),但我根据第6.1节中对模拟的简短描述,设法重现了类似的内容:

n_grid = 40
x_grid = seq(0, 7, length.out = n_grid)
beta0 = -6
beta1 = 1

inverse_logit = function(x) 1/(1 + exp(-x))

do.one.sim = function(){
    N = 5000
    x = rnorm(N)
    p = inverse_logit(beta0 + beta1*x)
    # 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(rep(0, n_grid))
    }else{
        # Extract the error
        mod = glm(y ~ x, family = 'binomial')
        truth = inverse_logit(beta0 + beta1*x_grid)
        pred = predict(mod, newdata = data.frame(x = x_grid),
            type = 'response')
        return(pred - truth)
    }
}
mean.of.K.estimates = function(K){
    rowMeans(replicate(K, do.one.sim()))
}

set.seed(1)
bias = replicate(10, mean.of.K.estimates(100))
maxes = as.numeric(apply(bias, 1, max))
mins = as.numeric(apply(bias, 1, min))

par(mfrow = c(3, 1), mar = c(4,4,2,2))
plot(x_grid, rowMeans(bias), type = 'l',
    ylim = c(min(bias), max(bias)),
    xlab = 'x', ylab = 'bias')
lines(x_grid, maxes, lty = 2)
lines(x_grid, mins, lty = 2)
plot(x_grid, dnorm(x_grid), type = 'l',
    xlab = 'x', ylab = 'standard normal density')
plot(x_grid, inverse_logit(beta0 + beta1*x_grid),
    xlab = 'x', ylab = 'true simulation P(Y = 1)',
    type = 'l')

第一张图是我对他们的图7的复制,并加上虚线代表了10项试验的全部结果。

根据论文,x这是从标准法线得出的回归中的预测变量。因此,如第二幅图所示,观测的相对频率x > 3(在第一幅图中最明显的偏差出现)的相对频率逐渐减小。

第三幅图显示了生成过程中作为的函数的“真实”模拟概率x。似乎最大的偏差发生在x罕见或不存在的地方。

综上所述,这些建议表明,OP通过将“罕见事件”(即x > 3)与“其事件P(Y = 1)很小” 混淆,从而完全误解了论文的核心主张。据推测,本文关注的是前者而不是后者。

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.