ベイズ推定により受講者の理解度を評価

# はじめに
通常、学習者の理解度を評価するためには、試験を実施して、その得点（合計得点）を利用します。便利で簡単な方法ですが、学習者に「真の理解」がなくても受験上のテクニックや偶然により、合格点をクリアしてしまうことがあります。別に、その場合も合格は合格なので構わないのですが、合格だからと安心して放置していると後になって学習者が大きくつまずくことがあります。

ここでは、ベイズ推定を使用して、試験の結果（各問題の正解／不正解）から学習者の理解度を推定する方法について紹介します。

ベイズ推定は、**講師の主観が取り込まれるため正式な評価には使用することは難しいですが**、合計得点という従来の指標と組み合わせて使用することで、効果的な学習支援ができる可能性があります。


# 問題設定

次のような問題を考えていきます。

>英文法の「過去形」に関する講義を行なった。その後、学習者の理解度を確認するために、全5問の試験を実施した。試験の各問題の正解／不正解から、受講者が「過去形」について十分な理解をしているか否かを**推定**したい。
>
> なお、講師は、これまでの経験に基づき、次のような考えを持っているものとする。問1については過去形を十分に理解していれば $90\%$ の確率で正解、そうでなくとも（偶然等により）$30\%$ の確率で正解する可能性がある。また問2については十分に理解していれば $80\%$ の確率で正解、そうでなくとも $15\%$ の確率で正解・・・

上記に示ように「学習者が英語の過去形について十分な理解を持っているか」を**ベイズ推定**により求めてきます。Wikipediaでは、ベイズ推定を次のように説明しています。

> ベイズ推定とは、ベイズ確率の考え方に基づき、観測事象（観測された事実）から、推定したい事柄（それの起因である原因事象）を、確率的な意味で推論することを指す。

この説明と、ここでの問題設定の対応は、次のようになります。

- **観測事象（観測された事実）**とは、試験の各問題の採点結果である '**正解**' または '**不正解**' です。
- **推定したい事柄（それの起因である原因事象）**とは、学習者が '**過去形を理解しているか**' ということです。
- **確率的な意味で推論**とは「学習者は $X \%$ の確率（確信の度合い）で '過去形を理解している' と考えられる」 のように推論するということです。

# ベイズの定理

ベイズ推定は、**ベイズの定理**に基づいて行ないます。ベイズの定理とは次式に示されるものです。なお、これがどのように導出されるかは、ここでは扱いません（[「天気の子」を題材にゼロから学ぶ「ベイズの定理」](https://qiita.com/code0327/items/7b673b70f2546369b6d9) などを参照してください）。ここでは、数学的に正しいことが分かっている便利な道具として扱います。

$$P(H|D) = \frac {P(D|H)\, P(H)}{P(D)} $$

# ベイズの定理を適用

ベイズの定理を構成する要素が意味することを、現在の問題設定に対応させて説明していきます。ただし、話を分かりやすくするために**試験問題は全1問**であるとします（最後に、全5問の設定に戻します）。

ところで、試験が全1問であれば、次のような疑問が思い浮かぶかもしれません。

> '**正解**' なら過去形を '**理解している**' 、'**不正解**' なら '**理解していない**' でよいのではないか？

しかし、問題が<font color='red'>**記号選択形式**であれば偶然によって「過去形を理解していなくても正解する」ことがあります</font>。また、問題が<font color='red'>**英作文形式**であれば「過去形を理解していても、語彙力不足やスペルミスで不正解になる」こともありえます</font>。

ベイズの定理の説明に戻ります。まず、$D$ と $H$ は次のことを表します。

- $D$（Data）：観測された**事象**を表します。具体的には '**正解**' もしくは '**不正解**' のいずれかをとります。
- $H$（Hypothesis）：データが観測された**原因**を表します。具体的には、過去形を理解している（'**理解**'と表記）もしくは 理解していない（'**不理解**'と表記）のいずれかをとります。「$H$ が原因で $D$ が観測される（例：'**不理解**' が原因で '**不正解**' が観測される）」といった関係にあるものだと考えてください。

ところで、$H$ を **原因** としましたが、少し視点を変えると「**仮説** $H$ の成立により $D$ が観測される」とも言えます。そのため $H$ について「**仮説**」という扱いもします（仮説という言葉を使ったほうが、ベイズの定理を理解しやすいです）。

次に、ベイズの定理の**左辺** $P(H|D)$ について説明します。

- $P(H|D)$：これは**条件付き確率**というもので「データ $D$（'正解' or '不正解'）が得られたときに、仮説 $H$（'理解' or '不理解'）が正しい**確率**（確信の度合い）」を表しています。今回の場合、$D$ と $H$ の組み合わせによって、次のような 4パターン が考えられます。
- $P( $'理解'$ | $'正解'$ )$：正解だったときに、過去形を理解している確率（可能性・確信の度合い）
- $P( $'理解'$ | $'不正解'$ )$：不正解だったときに、過去形を理解している確率
- $P( $'不理解'$ | $'正解'$ )$：正解だったときに、過去形を理解していない確率
- $P( $'不理解'$ | $'不正解'$ )$：不正解だったときに、過去形を理解していない確率

上記に 4パターン を列挙しましたが、ここで推定したいことは「過去形を理解しているか（つまり、'**理解**' という仮説が成立する確率はどの程度なのか）」です。そして、観測されるのは '**正解**' または '**不正解**' のいずれかです。よって、実際に考えるものは $P( $'理解'$ | $'正解'$ )$ か $P( $'理解'$ | $'不正解'$ )$ のどちらかになります。


ここからは、具体的なほうが分かりやすいので '**正解**' が観測されたものとして進めます。よって、いまから考えるものは $P( $'**理解**'$ | $'**正解**'$ )$ 、つまり「正解だったときに過去形を理解している確率」になります。

ところで、仮説 $H$ の事象 $H_1$、$H_2$、$\cdots$、$H_k$、$\cdots$、$H_n$ が互いに**背反**（同時に起こらない事象）で、その和事象が全事象になるとき（全事象 $\Omega=H_1+H_2+\cdots+H_n$）、ベイズの定理は次のように展開できます。


```math:
\begin{align}
P(H_k|D) & = \frac {P(D|H_k)\, P(H_k)}{P(D)} \\
            & = \frac {P(D|H_k)\, P(H_k)}{P(D|H_1)P(H_1)+P(D|H_2)P(H_2)+\cdots+P(D|H_k)P(H_k)+\cdots+P(D|H_n)P(H_n)}
\end{align}
```


ここで扱っている問題の仮説 $H$ の事象 '**理解**' と '**不理解**' は（当然）背反事象であり、それらの和は全事象になります。これも踏まえて $P( $'**理解**'$ | $'**正解**'$ )$ は、次のようになります。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152805/297e1404-825e-4da9-c2de-f4931c47835a.png)

この式の**右辺**の要素に適切な数値を代入すると、$P( $'理解'$ | $'正解'$ )$ が計算できます。右辺分子の構成要素から説明します。

- $P($'正解'|'理解'$)$：'**理解**' という仮説が正しいときに '**正解**' が得られる確率を意味します。この値は、問題設定のなかで <font color='red'>$\mathbf{0.9}$</font> と与えられています。

- $P($'理解'$)$：データを観測する以前において、仮説 '**理解**' が正しいと考えられる確率です（**事前確率**といいます）。この値は問題設定のなかでは与えられていません。<font color='blue'>このようなときには、主観で恣意的に設定することができます</font>。
 - 例えば、講師からみて学習者が「理解しているとも、そうではないとも、どちらとも確信がない」とき $P( $'理解'$ )=0.5$、$P( $'不理解'$ )=0.5$ とします（**理由不十分の原則**）。あるいは、講義中の様子からみて「理解している可能性が高そう」と考えれば $P( $'理解'$)=0.7$、$P( $'不理解'$)=0.3$ とも設定することができます。ここでは、$P( $'理解'$ )=$<font color='red'>$\mathbf{0.5}$</font> を採用します。

これらを掛けた $P($'正解'|'理解'$)\,P($'理解'$) = 0.9\times 0.5 = \mathbf{0.45}$ が右辺の分子となります。また、同時にこれは、右辺分母の第1項にもなります。

分母の第2項は、次の要素から成ります。

- $P($'正解'|'不理解'$)$：'**不理解**' という仮説が正しいときに '**正解**' が得られる確率を意味します。この値は、問題設定のなかで <font color='red'>$\mathbf{0.3}$</font> と与えられています。

- $P($'不理解'$)$：データを観測する以前において、仮説 '**不理解**' が正しいと考えられる確率です。$P( $'不理解'$)=1.0-P($'理解'$ )=$<font color='red'>$\mathbf{0.5}$</font> となります。

これより、問1が正解だったときに、受講者が過去形を理解している確率 $P($'正解'|'理解'$)$ は、次のように計算できます。

$$ \frac{0.9\times 0.5}{0.9\times 0.5 + 0.3\times 0.5}=\frac{0.45}{0.45+0.15}=0.75$$

学習者が過去形を理解している確率は $75\%$ であると推論できました。

つづいて **試験が全2問** であった場合に拡張します。そして、問2は **'不正解'** だったものとします。

もともと講師のなかにあった「学習者が過去形を理解している」の確率（確信の度合い） $50\%$ が、問1の **'正解'** により <font color='red'>$75\%$ に更新された</font>ので、今度は、これを **事前確率** $P($'理解'$)$ として計算します。このようにすることで、問1が **'正解'** だったということを考慮しながら、問2が **'不正解'** だったときに過去形を理解している確率を求めることができます（これを **ベイズ更新** といいます）。

今度は、'**不正解**' が観測されたので次式で計算します。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152805/16976e63-70e6-9021-55d7-b7856806b45e.png)


問題設定で「問2については理解していれば $80\%$ の確率で正解、そうでなくとも $15\%$ の確率で正解」としていますので、$P($'不正解'|'理解'$)=1-0.8=$ <font color='red'>$\mathbf{0.2}$</font>、$P($'不正解'|'不理解'$)=1-0.15=$ <font color='red'>$\mathbf{0.85}$</font> となります。

また、$P($'理解'$)=$ <font color='red'>$\mathbf{0.75}$</font>、$P($'不理解'$)=1-0.75=$ <font color='red'>$\mathbf{0.25}$</font> を代入すれば、次のようになります。

$$ \frac{0.2\times 0.75}{0.2\times 0.75 + 0.85\times 0.25}=0.413..$$


これより、試験で「問1 **'正解'** 、問2 **'不正解'**」であった学習者が過去形を理解している確率は $43\%$ と推定することができました。

# 全5問のケースについて計算（Python利用）

問題設定を **試験が全5問** に戻します。'**理解**' と '**不理解**' を仮定した場合に、**各問題に正解する確率（確信の度合い）**が次のように考えられるとします。

| 問題番号 | 理解を仮定 | 不理解を仮定 |
| :------: | :----------: | :----------: |
|    1     |     0.90     |     0.30     |
|    2     |     0.80     |     0.15     |
|    3     |     0.90     |     0.25     |
|    4     |     0.70     |     0.30     |
|    5     |     0.60     |     0.05     |

そして、試験が次のような結果であったとします。

| 問題番号 | 採点結果 |
| :------: | :----------: |
|    1     |     正解     |
|    2     |     不正解     |
|    3     |     正解     |
|    4     |     正解     |
|    5     |     不正解     |


手計算では大変なのでプログラムを使って計算します。

```Python:Python
p  = 0.5 # 事前確率：P(理解)
d  = [  1,   0,   1,   1,   0] # 学習者の試験結果（1:正解、0:不正解）
pA = [.90, .80, .90, .70, .60] # 理解の場合の想定正解率
pB = [.30, .15, .25, .30, .05] # 不理解の場合の想定正解率

m  = ['不正解','正解  '] # 出力表示用

print(f'試験前     -> {p:>5.1%}')

for i in range(0,len(d)) :
    if d[i] == 1 :
        p = ( pA[i]*p )/( ( pA[i]*p )+( pB[i]*(1-p) ) )
    else :
        p = ( (1-pA[i])*p )/( ((1-pA[i])*p)+((1-pB[i])*(1-p)) )
        
    print(f'問{i+1} {m[d[i]]} -> {p:>5.1%} に更新')

print(f'\n試験結果から学習者が過去形を理解していると考えられる確率 = {p:>5.1%}')
```

```:実行結果
試験前     -> 50.0%
問1 正解   -> 75.0% に更新
問2 不正解 -> 41.4% に更新
問3 正解   -> 71.8% に更新
問4 正解   -> 85.6% に更新
問5 不正解 -> 71.4% に更新

試験結果から学習者が過去形を理解していると考えられる確率 = 71.4%
```

最終的に、$71.4\%$ という結果になりました。

通常の採点（合計点評価）に加えて、このようなスコアも確認することで、効果的な学習指導ができる可能性があります。