第113回医師国家試験を項目反応理論で解析します(予告)、の予備実験

MikuHatsune2018-12-17

予備実験用の解答サンプルシートはこちら
第112回から適当に20問とってきたもの。

https://docs.google.com/forms/d/e/1FAIpQLSfiLVA-1m7NC5SMmyi0X1ftSYJzhWuOac6kr-WMR8gKgFLWVA/viewform
shiny 上でその20問の項目反応理論(IRT)

https://yfujii08.shinyapps.io/medicalexamltm/
 
※重要な話なので先頭にもってきました※ 
データを集めるわけだが、某予備校や解答収集サービスのようにセキリュティ強固なサーバーを持っているわけではなくむしろ予算 ゼ ロ 円解析なので、グーグルアンケートフォームにひたすらみなさんの善意でポチポチやってもらえれば、と思っています。
予備実験では20問、たぶん1問1分くらいかかって15−20分くらい時間を使わせてしまいます。
本番では400問あるので、受験者が1万人、上記サービスで7000人くらい入力しているらしいので、ネット宣伝と口コミで希望者・入力者を募りつつ、サーバー負荷やセキリュティ問題はgoogle 様やshiny 様に丸投げしようと思います。個人の特定はできないようにします。
※以下から本文※ 
 
医師国家試験とは、2日間(昔は3日間)にわたって400問をマークシートで解く。
そのほとんどは5択から1つ正解を選べ、だが、2つ選べや3つ選べ、計算結果を数値を塗りつぶして答えろ、1問1点の場合と3点の場合がある、A-F の6ブロックある、一般/臨床問題と必修問題の両方を合格基準を超えないといけない、禁忌肢という選んでしまったらそれだけで不合格となる問題や選択肢がある、といったレギュレーションがある。
そこで受験生は、ひたすら問題を解くわけだが、合格率90% を誇る試験で、たいていの問題は正答率100% に近かったりするわけだが、割問という「2択ないしは複数選択肢に解答が割れる」という問題がある。
これが毎年話題になる。
 
受験生としては、自分が答えた問題の正答が気になるので、○ECとかTECO○とか○んコレとかに解答を登録したりするわけだが、ここらでいう割問というのは、「その問題単体で見た時の、解答のばらつき」しか見ていない。
 
さて、項目反応理論(IRT) というのは、マルチョイ問題において、受験者個人の能力値(すべての問題への正答率を考慮している)、問題の難易度(その個々人が、どの問題を正答できて、どの問題を誤答したかという情報を考慮する)といったパラメータを定量的に推定する。
 
ここで、mirt パッケージにあるSAT12 という試験解答サンプルを使ってみる。SAT12 は600人32問題の解答パターンをもつ。
これを正解したかしてないかの1/0 バイナリデータにする。IRT 自体はltm パッケージを使うことにして、IRT により各問題の難しさや識別能の推定はltm 関数を、各個人の能力はfactor.scores 関数で得られる。

# 先頭の15人、8問目まで
   Item.1 Item.2 Item.3 Item.4 Item.5 Item.6 Item.7 Item.8
1       1      4      5      2      3      1      2      1
2       3      4      2      8      3      3      2      8
3       1      4      5      4      3      2      2      3
4       2      4      4      2      3      3      2      4
5       2      4      5      2      3      2      2      1
6       1      4      3      1      3      2      2      3
7       1      4      5      2      2      2      2      2
8       2      4      1      5      3      2      2      5
9       5      1      2      3      2      2      4      4
10      5      3      4      2      3      2      4      5
11      2      1      4      5      2      3      2      4
12      3      1      3      4      2      2      2      2
13      4      5      5      4      2      2      4      1
14      1      4      3      2      3      2      2      5
15      3      4      3      5      5      2      2      2
library(ltm)
library(mirt)
key <- c(1,4,5,2,3,1,2,1,3,1,2,4,2,1,5,3,4,4,1,4,3,3,4,1,3,5,1,3,1,5,4,5)  # 正解
data <- key2binary(SAT12, key=key)                                         # バイナリ化
l <- ltm(data ~ z1)                                                        # IRT
ans <- t(mapply(function(z) table(factor(SAT12[,z], 1:5)), 1:ncol(SAT12)))
plot(l)

32問分の難しさはこんな感じで出力される。

 
さて、各問題について見てみる。32問分の解答分布、正答、IRTの推定値は以下のとおりである。

cbind(round(ans/nrow(SAT12), 3), key, l$coefficients)
            1     2     3     4     5 key (Intercept)        z1
Item.1  0.283 0.203 0.267 0.232 0.013   1  -1.0458445 0.8018208
Item.2  0.212 0.022 0.070 0.568 0.127   4   0.4361887 1.5040666
Item.3  0.165 0.183 0.260 0.098 0.280   5  -1.1425458 1.0746489
Item.4  0.165 0.378 0.148 0.172 0.128   2  -0.5309422 0.5845126
Item.5  0.093 0.143 0.620 0.093 0.048   3   0.6044634 0.9900492
Item.6  0.160 0.582 0.107 0.043 0.108   1  -2.0509622 1.1494988
Item.7  0.025 0.760 0.007 0.190 0.017   2   1.3818932 1.0042941
Item.8  0.202 0.205 0.207 0.250 0.133   1  -1.5090070 0.6927192
Item.9  0.065 0.010 0.885 0.033 0.007   3   2.1427139 0.5328306
Item.10 0.422 0.215 0.165 0.028 0.167   1  -0.3615247 1.0086219
Item.11 0.003 0.983 0.008 0.003 0.002   2   5.2441772 1.7296232
Item.12 0.072 0.082 0.218 0.415 0.205   4  -0.3455723 0.1611497
Item.13 0.110 0.662 0.070 0.118 0.040   2   0.8507691 1.1074704
Item.14 0.723 0.027 0.108 0.022 0.117   1   1.1727517 1.0370366
Item.15 0.035 0.062 0.060 0.025 0.817   5   1.9224593 1.2930864
Item.16 0.070 0.105 0.413 0.215 0.195   3  -0.3825038 0.7263422
Item.17 0.008 0.005 0.010 0.963 0.013   4   4.1603459 1.5479738
Item.18 0.303 0.033 0.165 0.352 0.142   4  -0.8530572 1.7008815
Item.19 0.548 0.053 0.358 0.030 0.010   1   0.2363424 0.8403153
Item.20 0.012 0.002 0.105 0.873 0.007   4   2.6034887 1.5311169
Item.21 0.050 0.008 0.915 0.013 0.012   3   2.5167030 0.6058270
Item.22 0.028 0.005 0.935 0.017 0.015   3   3.4736774 1.5369172
Item.23 0.290 0.177 0.128 0.313 0.087   4  -0.8505416 0.6379289
Item.24 0.728 0.162 0.042 0.022 0.045   1   1.2673661 1.2051755
Item.25 0.240 0.170 0.375 0.065 0.142   3  -0.5674927 0.7713010
Item.26 0.020 0.227 0.030 0.262 0.460   5  -0.1728073 1.5352022
Item.27 0.862 0.093 0.012 0.020 0.010   1   2.7575590 1.9045292
Item.28 0.082 0.010 0.530 0.337 0.037   3   0.1722115 1.0711318
Item.29 0.340 0.295 0.205 0.085 0.067   1  -0.7508683 0.8350190
Item.30 0.150 0.110 0.107 0.183 0.440   5  -0.2484688 0.3855356
Item.31 0.075 0.020 0.012 0.833 0.058   4   2.7738863 2.3285203
Item.32 0.125 0.183 0.443 0.075 0.162   5  -1.6516711 0.1291500

 
IRTの推定値をプロットするとこうなる。

i1 <- c(10, 12, 16, 26, 30)
i2 <- c(2, 17, 20, 22, 26)

plot(l$coefficient,type="n")
abline(v=mean(l$coefficients[i1, 1]), lty=3, col="blue", lwd=3)
abline(h=mean(l$coefficients[i2, 2]), lty=3, col="green", lwd=3)
text(l$coefficients[,1], l$coefficients[,2], 1:ncol(SAT12), font=2)

似たようなintercept を持つがz1 が異なる10, 12, 16, 26, 30 番の問題を取り上げてみると(青の垂直線、下図のひだり側)、いずれも割問である。しかし、赤の12番が平たい曲線なのに比べ、青の26番はいくぶん急峻な曲線である。
これは、前者が高得点者でもそんなに得点率が上昇しないのに比べて、後者はある得点水準から得点率が急上昇するので、その境界線の能力の受験者を分けるのにはよい。
12番と26番を見てみると、どちらも正答率は40%半ばであるが、問題の性能としてはずいぶん違う。26番は良問だが、12番はクソ問。

            1     2     3     4     5 key (Intercept)        z1
Item.10 0.422 0.215 0.165 0.028 0.167   1  -0.3615247 1.0086219
Item.12 0.072 0.082 0.218 0.415 0.205   4  -0.3455723 0.1611497
Item.16 0.070 0.105 0.413 0.215 0.195   3  -0.3825038 0.7263422
Item.26 0.020 0.227 0.030 0.262 0.460   5  -0.1728073 1.5352022
Item.30 0.150 0.110 0.107 0.183 0.440   5  -0.2484688 0.3855356

 
似たようなz1 を持つがintercept が異なる2, 17, 20, 22, 26 番の問題を取り上げてみると(緑の水平線、下図のみぎ側)、どれも似たような急斜面の曲線だが、左右に位置がずれている。正答率を見ると、赤の17番の問題で96%、水色の26番の問題で46%であり、みぎにいくほど正答率が低い難問である。

            1     2     3     4     5 key (Intercept)       z1
Item.2  0.212 0.022 0.070 0.568 0.127   4   0.4361887 1.504067
Item.17 0.008 0.005 0.010 0.963 0.013   4   4.1603459 1.547974
Item.20 0.012 0.002 0.105 0.873 0.007   4   2.6034887 1.531117
Item.22 0.028 0.005 0.935 0.017 0.015   3   3.4736774 1.536917
Item.26 0.020 0.227 0.030 0.262 0.460   5  -0.1728073 1.535202

 

 
各問題の難易度や良問具合がわかったので、次に、受験者個人の成績や能力値をどう定量化するかであるが、これはfactor.scores という関数で得られる。ここから結果を見ると、32問題の正答/誤答パターンが600人中どれくらいあったか(Obs) というデータから、z1(正規化した分布における確率点)が推定されるので、ここが自分(の解答から得られる正誤パターンにおける)の能力値(同一試験を受けた他の受験者全員をひっくるめた集団での)になる。
SAT12 データセットでは、全問正解が3人いるようである。
ここからz1 を拾ってきて横軸を定め、元のIRT 曲線に垂線を引くと、自分の能力で各問題をどれくらいの確率で正答できたのかが確率的にわかる。

f <- factor.scores(l)
f$score.dat
   Item.1 Item.2 Item.3 Item.4 Obs          Exp        z1     se.z1
1       0      0      0      0   1 7.320352e-07 -1.125597 0.3501032
2       0      0      0      0   1 1.192118e-05 -1.035763 0.3510456
3       0      0      0      0   1 7.614205e-06 -1.268032 0.3503369
4       0      0      0      0   1 2.158900e-04 -1.578284 0.3585213
5       0      0      0      0   1 1.354704e-03 -2.044771 0.3858258
6       0      0      0      0   1 7.785685e-06 -1.299507 0.3506911
7       0      0      0      0   1 2.653074e-04 -1.303414 0.3507428
8       0      0      0      0   1 9.714099e-05 -1.137476 0.3500392
9       0      0      0      0   1 2.220848e-05 -1.500034 0.3555113
10      0      0      0      0   1 2.611964e-04 -1.573319 0.3583131
.
.
.
598      1      1      1      1   3 4.027146e-02  2.590108 0.6140229 ← 全問正解が Obs = 3

 
データはどう集めるか問題があるが、実は某サービスが始まったときにデータを打診したらゴニョゴニョがあったので今回の解析を断念していたが、google 様とshiny 様のお力を借りて出来そう、と思い立ったのでネットで宣伝してN数稼げたらいいなあ…と思う。冒頭に書いた。