【ITパスポートなど】選択式試験の合格率計算【Python】

この記事では、**Python言語によるモンテカルロシミュレーション**を用いて、選択肢問題の合格率を計算します。モンテカルロといっても、選択肢問題を勘で当てるか当てないかをしてるだけで簡単です。

**概要**
- 【数式】6割合格試験は「**100問中47問確実に正答**すれば合格」
- 【期待値】実は「100問中47問確実に正答すれば合格」する**確率は50%**
- 【Python】「**1000回受験したら**何%で合格する？」
- 【確実】**合格率90%**になる確実正答は**52問**
- 【裏技】確実正答47問でも、**勘問題を3択にしたら合格率93%**

## 選択肢問題の合格率計算「何問確実に正解したら合格が期待できるか」
**「何問を確実に正解して、何問を勘で答えたら、合格するだろう」**

と考えることはないでしょうか。

以下の条件で数式を立ててみます。
- 問題数 N
- 確実に正解できる問題数 a
- 選択肢は4個
（たぶん聡明な方は、立てられる数式と「からくり」にこの時点で気づかれましたねｗ）

以下のように解くと「47%」。

```math
a + (N - a) \times 0.25 \geqq N \times 0.6 \\
```
```math
0.75a + 0.25N \geqq 0.6N \\
```
```math
0.75a \geqq 0.35N
```
```math
a \geqq 0.4666666… \times N
```

※(N - a) × 0.25は、勘で正答する問題数です。

つまりITパスポートは100問なので、

「47問確実に正解すれば、残り53問は勘で解けば合格」が**期待**されます。


**「47問だから半分以下の正解で良いんだ！」とちょっと嬉しい**ですね。

しかし、

**これが確率の落とし穴。**

（「期待」って言葉でピンと来た方もいらっしゃることでしょう。ニヤニヤしましょｗ）


## 確率計算の落とし穴「47問確実に正解しても合格率は50%」
「期待」とわざわざ書いたのでお察しの通り「期待値」だからです。

なぜなら、「1/4の確率で当てる勘」が働く時と働かない時がありますよね。「1/4以上正答する勘」が働く確率は50%、「1/4未満しか正答しない勘」になる確率が50%なんです。

つまり、

**「100問中47問確実に正解して、残り52問を勘で答えて、合格する確率は50%」です。**

## プログラムソース「1000回受験したら何%で合格する？」
Pythonでモンテカルロシミュレーションをしてみましょう。
（すでにこの一文が超カッコイイですw）

単に「正解を乱数で決めて、回答を乱数で決めて、一致したかしなかったか」を見てるだけです。

※すみません。プログラムを教える職業ですが、素人です。プロの方々から見ると、色々ヤバイと思いますがご容赦ください。入門者の方には悪くない例かなと思います。

```Python
### パラメータ
ANS_NUM =   4  # 選択肢
QUE_NUM = 100  # 問題数
KNO_NUM =  47  # 必ず正解する問題数
LOOP_NUM= 1000 # シミュレーション回数

import random as rand
def monte_ans():
  ans_num = ANS_NUM
  stu = rand.randint(1,ans_num)
  ans = rand.randint(1,ans_num)
  if stu == ans:
    result = 1
  else:
    result = 0
  return result
  
def calc_correct_num():
  const_que_num = QUE_NUM - KNO_NUM
  correct_cnt = 0
  for i in range(0, const_que_num):
    result = monte_ans()
    correct_cnt = correct_cnt+result
  return correct_cnt

def judge_pass():
  const_que_num = QUE_NUM
  const_kno_num = KNO_NUM
  correct_num = calc_correct_num()
  if correct_num + const_kno_num >= const_que_num * 0.6:
    result_pass = 1
  else:
    result_pass = 0
  return result_pass

def calc_pass_rate():
  const_loop_num = LOOP_NUM
  cnt_pass       = 0
  for i in range(1, const_loop_num):
    result_pass = judge_pass()
    if result_pass == 1:
      cnt_pass = cnt_pass + 1
  rate_pass = cnt_pass / const_loop_num
  return rate_pass

print(calc_pass_rate()*100)
```

google colaboratoryで実行してます。
「KNO_NUM =  47  # 必ず正解する問題数」としたときの実行結果
```Python
58.9
```
「KNO_NUM =  46  # 必ず正解する問題数」としたときの実行結果
```Python
47.9
```
値はちょっと変動します。
「LOOP_NUM= 1000 # シミュレーション回数」を増やすと精度良くなります。

## 合格率90%を超える問題数は52問
**「47問確実正解で合格率50%」は分かったとして、「じゃぁ合格率90%にするには、何問確実に正答すればいいの？」と気になります。**

「KNO_NUM =  52  # 必ず正解する問題数」と数値を変えると、90%を確実に超えます。

ここで「52問だから結局半分超えるのか」と、「60問確実に正解すれば100%合格」なのに、**なぜかガッカリ**しちゃいます。気持ちは分かりますよ。

次は、**合格率をぐーーーーーーんと上げる方法を計算**します。

## 勘で答える問題を3択にしたら
実際は、**「勘で答える」と言っても「すべて4択から勘」ってわけではないですよね。**

「ア か ウ のどっちだろう」「ウは絶対違うから、3択から選ぶか」なんて、択を減らすことはよくあります。

ここでは「勘で答える問題を3択」にして計算してみます。
```Python
### パラメータ
ANS_NUM =   3  # 選択肢 ←ここを変更!!!!!!
QUE_NUM = 100  # 問題数
KNO_NUM =  47  # 必ず正解する問題数
LOOP_NUM= 1000 # シミュレーション回数
```
```Python
93.3
```

「93%」を超えてきましたね。

つまり、

**「100問中47問確実に正解して、残り52問を<<3択にして>>勘で答えて、合格する確率は93%超え」**

という結果となりました。

夢のある話です。

とはいえ、実際は「4択勘」「3択勘」「2択勘」の混合ですけどね。



## まとめ
この記事は、私がIT専門学校で学生さんを励ますために伝えていることです。

とはいえ難しい話ですし、「夢」も与えたいので、

**最初は「47問正解すれば、残り勘で合格するよ！」だけしか伝えません。**

みんなが理解するわけでも、あなたのように確率や計算に興味があるわけではないですからね。（めんどくせぇとか言われたことがあります・・・）

ある程度合格点が取れるようになってから、「賢い学生さん」「用心深い学生」だけに期待値の話をしています。

私の学生さんはなぁんかギリギリを狙います。ギリギリで落ちて凹んで、ギリギリで受かって喜んでます。

「60問確実に答えれば100%合格」するんだから、「70問や80問正解したるわ！」って意気込みが欲しいです。チキンレースでもギリギリ狙いゲームでもないので。

90点だろうが60点ギリギリだろうが、合格すれば履歴書に書けます。

「90点取って損した」と思うかは分かりませんが、

**「勘込みで60点ギリギリってことは、確実に理解してるの半分切ってる、のに90点の人と同じ理解度だと見なされる」とピリピリ**して欲しいなぁとも思います。

以前「自分が電車に乗った後にドアが閉まると時間効率が良かった！満足！」って方がいました。ともすれば乗り遅れたかもしれないし、途中で人が倒れてたら助ける余裕もありません。

試験代は7,500円。合格したらしっかり理解したと見なされる。そんな試験に「ギリギリ合格したやったぁ！」と手離しに喜んで良いですが、ふと冷静になって振り返って「次」に向かって欲しいなぁといつも思って話しています。

お説教・愚痴になってごめんなさいでした。

## 余談
実は、ギリギリになってしまうのは「勉強不足」だけではありません。

実は「確実に正解する問題数」が増えると「勘で答える問題数」が減ります。「勘を働かせる回数が少なくなる」ため、確率がだんだん効かなくなります。もちろん、現実的には「難しい問題」が残っているってのもあります。

今回は解説は割愛しますが、「高得点になるほど、択を減らしても点数は伸びなくなります」。（プログラムの確実正答数をスイープさせるなどするとと分かります）

よって、**100点は目指すけど、実現するまで頑張らないでください。**

経験上85点ぐらいで安定しれば、当たれば90点後半、外れても75点前後で確実に合格します。

それではまた機会があれば。

p.s.
コードの書き方など、ご指摘・ご指導頂けましたら幸甚です。

p.s.
日頃は>>[「専門学校やIT就職」のブログ](https://sennaki.com/)<<をやってます。