ロジスティック回帰モデルの操作


12

次のコードが何をしているかを理解したいと思います。コードを書いた人はここではもう働かず、ほとんど完全に文書化されていません。私は「考えて誰かにそれを調査するように頼まれたことは、ベイズロジスティック回帰モデルです

bglm <- function(Y,X) {
    # Y is a vector of binary responses
    # X is a design matrix

    fit <- glm.fit(X,Y, family = binomial(link = logit))
    beta <- coef(fit)
    fs <- summary.glm(fit)
    M <- t(chol(fs$cov.unscaled))
    betastar <- beta + M %*% rnorm(ncol(M))
    p <- 1/(1 + exp(-(X %*% betastar)))
    return(runif(length(p)) <= p)
}

これがロジスティックモデルに適合し、推定された共分散行列のCholseky分解の転置を取り、これにからの描画のベクトルを後から乗算し、モデル推定に追加されていることがわかります。次に、これに設計行列が事前に乗算され、からのドローのベクトルと返された結果のバイナリベクトルと比較して、この逆ロジットがとられます。しかし、これ統計的にどういう意味ですか?U 0 1 N(0,1)U(0,1)


これはおそらく、多くはこれがで使用されている内容フィールドを知るために役立つだろう...
naught101

2
本質的には、関数はデータの(頻出)モデルからデータを生成し、実際のパラメーターに関する不確実性を組み込みます。これは、ベイジアンMCMCルーチンの一部である可能性がありますが、シミュレーションベースの電力分析にも使用できます(nb、不確実性を考慮しない以前のデータに基づく電力分析は、多くの場合楽観的です)。
gung-モニカの復活

どういたしまして、@ PSellaz。他には誰も応答しなかったので、私はそれを「公式」の回答に変えます。
ガン-モニカの復活

回答:


7

関数の機能:
基本的に、関数はデータのモデルから新しい疑似ランダム応答(つまり)データを生成します。使用されているモデルは標準的な頻度モデルです。慣例として、 *データは既知の定数であると想定しています。これらのデータは決してサンプリングされません。この関数の重要な特徴として私が見ているのは、推定されたパラメーターに関する不確実性を組み込んでいることです。 XYX

* 切片を抑制したくない場合(一般的には良い方法ではありません)、関数に入力する前に、行列の左端の列としてベクトルを手動で追加する必要があることに注意してください。X1X

この機能のポイントは何でしたか:
正直なところ、わかりません。これは、ベイジアンMCMCルーチンの一部であった可能性がありますが、1つの部分しかありませんでした。実際にベイジアン分析を実行するには、他の場所でさらにコードが必要になります。私はこれについて決定的にコメントするベイジアン手法の専門家ではないように感じますが、この関数は通常使用されるもののように「感じ」ません。

また、シミュレーションベースの電力分析にも使用できます。(ここで私の回答を参照してください:このタイプの情報については、ロジスティック回帰の電力分析のシミュレーション-計画された実験)。パラメーター推定値の不確実性を考慮しない、以前のデータに基づく電力分析は、多くの場合、注目に値します楽観的。(ここでその点について説明します:望ましい効果のサイズと予想される効果のサイズ)。

この関数を使用する場合:
@whuberがコメントに記されているように、この関数は非効率的です。これを(たとえば)電力分析に使用する場合は、関数を2つの新しい関数に分割します。1つ目はデータを読み取り、パラメータと不確実性を出力します。2番目の新しい関数は、新しい疑似ランダムデータを生成します。以下に例を示します(ただし、さらに改善することは可能です)。 Y

simulationParameters <- function(Y,X) {
                        # Y is a vector of binary responses
                        # X is a design matrix, you don't have to add a vector of 1's 
                        #   for the intercept

                        X    <- cbind(1, X)  # this adds the intercept for you
                        fit  <- glm.fit(X,Y, family = binomial(link = logit))
                        beta <- coef(fit)
                        fs   <- summary.glm(fit)
                        M    <- t(chol(fs$cov.unscaled))

                        return(list(betas=beta, uncertainties=M))
}

simulateY <- function(X, betas, uncertainties, ncolM, N){

             # X      <- cbind(1, X)  # it will be slightly faster if you input w/ 1's
             # ncolM  <- ncol(uncertainties) # faster if you input this
             betastar <- betas + uncertainties %*% rnorm(ncolM)
             p        <- 1/(1 + exp(-(X %*% betastar)))

             return(rbinom(N, size=1, prob=p))
}

4
+1。私にとって奇妙なのは、フィッティングとシミュレートされた予測がすべて単一の関数の本体内で行われることです。通常、このような操作は、最初に近似を計算し(betaM)、次にこの近似に基づいて多数の iidシミュレーションを作成することによって行われます。(それらを同じ関数に入れると、不必要にフィッティングが毎回繰り返され、計算が大幅に遅くなります。)これらのシミュレーションから、非線形または非常に複雑な応答の組み合わせの予測間隔を(とりわけ)回復できます。
whuber

@whuber、同意する。シミュレーションに使用する前に、関数を2つの異なる関数に分割することを提案することを実際に考えていましたが、それが問題の一部であるとは思われませんでした。
ガン-モニカの復活
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.