検定試験とシミュレーション

難易度バイアスを設けた得点シミュレーション

今度はシミュレーションで検定試験の得点を試算してみます。次のような仮定をおきます。

 1.問題の抽出はそれぞれ独立試行である
 2.回答者はどの問題も緑解答(満点解答)できる
 3.SSランクが解禁されており、出題難易度の上限がない(ものとする)
 4.登録されている問題の難易度の分布は未知ではあるが、
  こちらが与える適当な分布で代用できる
 5.問題形式の分布は一様

それぞれ見てみましょう。1は鉄則となる前提で、たぶん違う可能性もありますが、話を簡単にすすめるためにこのように縛っちゃいます。簡単に言うと、前半が難しかったからって、後半が簡単になるか難しいままかは関係ないよということ。
 23は検定試験の特定の条件にあわせたもので、もちろんこの前提を外すこともできるのですが、だいたいこんな推測が必要になってくるのは、ほぼ全答できてあとは問題の引き次第になってるランカーぐらいなので。これで回答時間と獲得ランクのパラメーターを落とせます。
 45は登録されている問題の性質に関するもの。詳しくは後述。難易度だけバイアスのパラメーターを入れて、得点の取りづらい検定・取りやすい検定をそれぞれ見ることができます。問題の形式の偏りはとりあえず無視しちゃいます(うまい与え方が思いつかなかった)。

ある1問において、★1~★5難易度を引くということを次のように定めましょう。

 X=0.00 → ★1を引く
 X=0.25 → ★2を引く
 X=0.50 → ★3を引く
 X=0.75 → ★4を引く
 X=1.00 → ★5を引く

Xのとる値は0から1までの0.25刻みとします。ここでXがこの範囲の数であるときに、対応する★を引く確率をp(x)としましょう。そして、p(x)を

 p(x) = 0.4kx + 0.2(1 - k)
 ただし-1≦k≦1


とします。これは実質的に確率密度関数になるので、ちゃんと密度関数の基準を満たしているか調べましょう。

 X = {X1,…,Xi,…,X5} = {0,0.25,0.5,0.75,1}

 Σ[i=1:5]{p(x=Xi)}
  = 0.4k(0 + 0.25 + 0.5 + 0.75 + 1) + 0.2(1-k)*5
  = k + 1-k
  = 1

kに依存せずに確率の合計が1になるのでOK。p(x)の意味に振り返ると、これはkが難易度のパラメーターになっています。

X/k -1 -0.5 0 0.5 1
0 0.4 0.3 0.2 0.1 0
0.25 0.3 0.25 0.2 0.15 0.1
0.5 0.2 0.2 0.2 0.2 0.2
0.75 0.1 0.15 0.2 0.25 0.3
1 0 0.1 0.2 0.3 0.4


例えばk=0なら、p(x=X1) = …… = p(x=X5) = 0.2となり、どの難易度も同じ確率で引くことになります。逆にk=1とすると、★5を引く確率は40%、★4は30%、……、★1は0%となり、かなり難しめの問題セットが期待されます。逆にk=-1とすれば、★5は0%、……、★1は40%となり、ぬるぬる難易度です。xは0から1までの0.25刻みにしか定められませんが、kは-1から1までの間なら自由に定めることができます。このkが問題の難易度のばらつきを表しているといっても良いでしょう。


これをシミュレーションにぶち込んでみます。このシミュレーションはとても単純で、まるまる検定試験25問分の問題抽出を乱数でシミュレートしてみるものです。もちろん乱数のシミュレーションなので、多少ぶれは出ますが、回数をこなせばだんだん誤差が小さくなることを期待します。Rでやるとこんな感じ(追記参照)。

これでk=-1, 0 ,1の100万回ぶんのシミュレートができます(10分ぐらいかかるかも)。とりあえずグラフ書くとこんな感じ。

graph.png

kの値によって満点時の得点の分布が変わります。問題の難易度が難しいほうに偏るほど、得点が高くなるという当たり前の結果。kの値をもう少し細かく分類して、kの値ごとのクォンタイルを求めてみると↓の通り。

https://docs.google.com/spreadsheet/pub?key=0AtDlw4zQ29lwdG5YVXI5cmFtWkZjeGRKZ1lXWG9FYkE&output=html

また、6000点以上とれる確率をkごとにみると、↓こんな感じに。

prob60.png

先ほど表とあわせてみると、一般的な検定試験だと体感的にk=0.5前後?このとき6000点以上とれる確率は4.7%程度だそうです。


ke<-seq(40,70,5) #形式別点数
pmult<-c(1,2,3,4.4,5.6) #点数の難易度倍率
kenteisim<-function(k){
  #k 難易度のパラメーター
  px<-0.4*k*seq(0,1,0.25)+0.2*(1-k) #難易度の密度関数
  rand.d<-runif(25) #難易度の乱数
  rand.s<-runif(25,max=7) #チョイスの乱数
  prob.d<-sapply(c(rand.d,1-rand.d),function(x){
            return(sum( c(0,cumsum(px)[-5]) <x))
          }) #難易度
  prob.s<-ceiling(c(rand.s,7-rand.s)) #形式
  score<-ke[prob.s]*pmult[prob.d]
  return(c(sum(score[1:25]),sum(score[26:50])) )
}

n<-500000
result.minus<-sapply(rep(-1,n),kenteisim) #k=-1を100万回
result.zero<-sapply(rep(0,n),kenteisim) #k=0を100万回
result.plus<-sapply(rep(1,n),kenteisim) #k=1を100万回

スポンサーサイト
プロフィール

こしあん

Author:こしあん
(:3[____]
【TwitterID : koshian2】
【ほしい物リスト】http://goo.gl/bDtvG2

Twitter
カウンター
天気予報

-天気予報コム- -FC2-
カテゴリ
月別アーカイブ
最新記事
最新トラックバック
検索フォーム
リンク