一般化線形モデル入門 第7章 解答例
https://zenn.dev/honwakasan/articles/b9ae08fd8a694e の第7章の解答例です.
演習問題 7.1
説明変数を放射線量, 目的変数を白血病での死亡率 ( = 白血病死亡者数 / 合計死亡者数 ) として, 単変量ロジスティック回帰モデル
つまり,
を構築する. 元のデータセットは以下で作成した.
df = pd.DataFrame(
[
[13, 5, 5, 3, 4, 18],
[378, 200, 151, 47, 31, 33]
]
)
df.columns = [f"放射線量_{v}" for v in ["0", "1-9", "10-49", "50-99", "100-199", "200+"]]
df.index = ["白血病", "その他のがん"]
df.index.name = "死因"
| 死因 | 放射線量_0 | 放射線量_1-9 | 放射線量_10-49 | 放射線量_50-99 | 放射線量_100-199 | 放射線量_200+ |
|---|---|---|---|---|---|---|
| 白血病 | 13 | 5 | 5 | 3 | 4 | 18 |
| その他のがん | 378 | 200 | 151 | 47 | 31 | 33 |
| 合計 | 391 | 205 | 156 | 50 | 35 | 51 |
説明変数と目的変数の設定
なお、ここでは各放射線量ごとの死亡率をそのまま使用し, 「1-9と10-49をまとめて1-49の1つのbinにする」といった処理はせずにモデル構築することを考える.[1] 実際には, 被曝放射線量と白血病死亡率の間には, 「多量の放射線を浴びたかどうか」が関連していると思われるが, そういったことは今は考慮せずにモデルを作ってみる. 以下のコードで, 説明変数と目的変数に分割する.
df_tmp = df.T
y = (df_tmp["白血病"] / df_tmp["合計"]).values
X = np.stack([np.ones(len(y)), list(range(1, 7))])
次に, 対数尤度関数のスコア及び情報行列を求める.
スコアの算出
各被曝放射線量における白血病死亡者数を
となる. 二行目の展開は, ロジスティック回帰モデルであることより従う. パラメータ
となる.
情報行列の算出
情報行列
\begin{aligned} \mathfrak{J}_{jk} &= E[U_j U_k] \\ &= \sum_{i = 1}^N \frac{x_{ij} x_{ik}}{Var(Y_i)} \left( \frac{\partial \mu_i}{\partial \eta_i} \right)^2 \end{aligned}
であるような行列であった.[1:1] ここでは, 少し注意が必要である. 本文では, 上記のように記載されているのだが, これはあくまで一般化線形モデルの条件を満たす確率変数
今回の問題のように白血病死亡者数
つまり,
であるため, リンク関数と期待値の関係も
となる. 故に, 上記の情報行列も
のように修正される. 偏微分の項については
となり, 分散の項は,
を得る. 以上を修正された情報行列に代入することで,
を得る. 線形成分は定数項を含むので,
更新式の定義
パラメータの更新式として, 次の(4.21)を採用する.
\begin{aligned} \mathbb{b}^{(m)} &= \mathbb{b}^{(m - 1)} + (\mathfrak{J}^{(m - 1)})^{-1}U^{(m - 1)} \\ \end{aligned}
Pythonでのパラメータ最適化
以上で準備が整ったので, 以下のコードで係数を推定する.
def pred_pi(beta, X):
z = beta @ X
return np.exp(z) / (1 + np.exp(z))
# 初期値
beta = np.array([0.0, 0.0])
for _ in range(10):
# piの推定
pi = pred_pi(beta, X) # shape (N,)
# スコアの推定 (2,)
U = np.sum((y - n*pi) * X, axis=1) # Xの各行で重み付き和
# 情報行列の推定 (2x2)
W = n * pi * (1 - pi) # shape (N,)
J = X @ (W[:, None] * X.T) # 2xN @ N×2 = 2x2
beta = beta + np.linalg.inv(J)@U
betaの出力結果は以下になった.
| beta_0 | beta_1 |
|---|---|
| -10.81132773 | 0.97888537 |
係数値が正の値を取ることから, 放射線被曝量と白血病死亡率との間には関連がありそう.[2]
-
https://routledge.com/downloads/C9500/C9500_Solutions.pdf には3つの被曝放射線量帯を定義してロジスティック回帰を実行しているため, ここで載せている結果と異なっている. ↩︎ ↩︎
-
本当は標準誤差を求めて係数が0かどうかの検定もやった方が良いのだが, 面倒なので省略 ↩︎
Discussion