まれなイベントロジスティック回帰バイアス:最小限の例で過小評価されたpをシミュレートする方法は?


19

CrossValidatedには、King and Zeng(2001)によるまれなイベントバイアス修正をいつ、どのように適用するかに関するいくつかの質問があります。私は別の何かを探しています。バイアスが存在するという最小限のシミュレーションベースのデモンストレーションです。

特に、王とZenの状態

「...まれなイベントデータでは、確率のバイアスはサンプルサイズが数千単位で実質的に意味があり、予測可能な方向にあります。推定イベント確率は小さすぎます。」

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: KingとZengには、論文の式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])
    }
}

説明:yがゼロの場合のMLEは存在しません(ここでの注意事項のコメントのおかげです)。Rは、その「正の収束許容値」が実際に満たされるため、警告をスローできません。もっと自由に言えば、MLEは存在し、対応するマイナス無限大です。したがって、私の機能が更新されます。私が考えることができる他の唯一の首尾一貫したことは、yがまったくゼロであるシミュレーションの実行を破棄することです。p=0


3
あなたがこれに取り組んでいて、他の人のコメントを楽しみにしています。バイアスがある場合でも、バイアス補正により分散が十分に増加し、推定値の平均二乗誤差が大きくなる可能性があります。
フランクハレル

3
@ FrankHarrell、King、Zengは、「バイアスを減らすことで分散も減るという幸福な状況にいる」と主張しています。
-zkurtz

1
良い。偏りの量が心配するほど大きいかどうかはまだ不明です。
フランクハレル

あなたにとっての「レア」とは何ですか?たとえば、0.001%の年間デフォルト率は、クレジットAAA格付けに関連付けられています。これはあなたにとって十分なレアですか?
アクサカル

1
@Aksakal、私のお気に入りの「レア」の選択は、KingとZengが書いたバイアスを最も明確に示すものです。
-zkurtz

回答:


4

これは興味深い質問です。これがさらなる議論を刺激することを期待して、以下に投稿するいくつかのシミュレーションを行いました。

まず、いくつかの一般的なコメント:

  • あなたが引用する論文は、まれなイベントのバイアスに関するものです。以前に私にもはっきりしていなかったのは(上記のコメントに関しても)、10/30の観測ではなく10/10000の観測がある場合について特別なことがあるかどうかです。しかし、いくつかのシミュレーションの後、私はそこに同意するでしょう。

  • 私が念頭に置いていた問題(これに頻繁に出会ったことがあり、最近、「生態学と進化の方法」の論文がありましたが、参考文献が見つかりませんでした) MLEが真実から離れたFAAARである場合、または-/ +無限大でさえある状況(私が推測する非線形リンクのため)。バイアス推定でこれらのケースをどのように扱うべきかは私には明確ではありませんが、私のシミュレーションから、それらはまれなイベントのバイアスの鍵と思われます。私の直観はそれらを削除することですが、その後、それらを削除する必要があるかどうかは明確ではありません。たぶん、バイアス補正のために心に留めておくべき何か。

  • また、これらの縮退したケースは、数値の問題を引き起こす傾向があります(したがって、glm関数のmaxitを増やしましたが、実際に真の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))

バイアスが減少し、図で物事がもう少し明確になります-パラメーター推定値は明らかに正規分布していません。それは、報告されるCIの有効性を意味するのだろうか。

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

ここに画像の説明を入力してください

インターセプトのレアイベントバイアスは、レアイベント自体、つまりレアで非常に小さい推定値によって駆動されると結論付けます。それらを削除するかどうか、カットオフがどうなるかわからない。

しかし、注意すべき重要なことは、どちらの場合でも、応答スケールでの予測にはバイアスがないように見えることです。リンク関数は、これらの非常に小さな値を単純に吸収します。


1
はい、まだ興味があります。素敵な議論と私のものに似た結果を見つけるために+1(明らかな予測バイアスなし)私たちが両方とも正しいと仮定すると、最終的には、予測バイアスに関する真の懸念に値する状況の特徴づけ(すなわち、少なくとも例)、または王とKingの論文の​​弱点の説明を見たいバイアス補正の重要性を誇張するために。
zkurtz

±20

1

まれなイベントバイアスは、リグレッサがある場合にのみ発生します。ここでシミュレートしたようなインターセプトのみのモデルでは発生しません。詳細については、この投稿をご覧ください:http : //statisticalhorizo​​ns.com/linear-vs-logistic#comment-276108


3
こんにちはポール。スタンドアロンであり、外部Webサイトへのアクセスを必要としないように(たとえば、ある時点で利用できなくなる可能性があるように)回答を拡張した場合が望ましいでしょう。
パトリッククーロンベ

OPの「更新2」にも注意してください。バイアスは、単一のリグレッサーでも表示されませんでした。
zkurtz

King&Zengの式(16)と図7によると、バイアスはリグレッサーXの関数です。Xが小さい場合、バイアスはありません。これは、更新2のOPで考慮される状況です。 Xが大きい場合のバイアス。King&Zengのシミュレーションを再現することもお勧めします。
ポールフォンヒッペル


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ここに標準法線から引き出された回帰の予測変数があります。したがって、2番目のプロットに示されているように、x > 3(最初のプロットで最も目に見えるバイアスが発生する)観測値の相対頻度は小さくなります。

3番目のプロットは、生成プロセスにおける「真の」シミュレーション確率をの関数として示していますxxまれまたは存在しない場所で最大のバイアスが発生するようです。

まとめると、これらはOPが「まれな出来事」(すなわちx > 3)を「P(Y = 1)非常に小さい出来事」と混同することにより、論文の中心的主張を完全に誤解したことを示唆している。おそらく、この論文は後者の代わりに前者に関するものです。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.