Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

正規累積モデル

正規累積モデル(normal ogive model) は基本的なIRTの考え方を示すモデル。正規累積モデルは概念上のわかり易さがある一方で、計算量の問題もあり、伝統的にはロジスティック・シグモイド関数により近似したロジスティックモデルが活用されてきた。そのため実際のところ最も基本的なIRTモデルはロジスティックモデルだが、そのベースになるのが正規累積モデル。

モデルの考え方

ii番目の被験者のjj番目の項目の値yijy_{ij}が二値yij{0,1}y_{ij}\in\{0, 1\}であるとする(例えば正解・不正解だったり、アンケートの「あてはまる」「あてはまらない」という2件法など)。

yijy_{ij}の背後には潜在的な能力の連続量θiR\theta_i \in \mathbb{R}が存在し、θi\theta_iが閾値bjb_jを超えていたら1、超えていなければ0が観測されるとする。つまりyijy_{ij}が以下のように決まるとする。

yij={0 if θi<bj1 if θibjy_{ij} = \begin{cases} 0 & \text{ if } \theta_i < b_j\\ 1 & \text{ if } \theta_i \geq b_j\\ \end{cases}

しかし、実際には被験者iiの体調や運(たまたま正解できた)などにより、常にこのようにきれいに正解・不正解が決まるわけではないと考えられる。こうした誤差を表すパラメータεijN(0,σε2)\varepsilon_{ij} \sim N(0, \sigma^2_{\varepsilon})も追加して

yij={0 if (θiεij)<bj1 if (θiεij)bjy_{ij} = \begin{cases} 0 & \text{ if } (\theta_i - \varepsilon_{ij}) < b_j\\ 1 & \text{ if } (\theta_i - \varepsilon_{ij}) \geq b_j\\ \end{cases}

とする。誤差が確率変数のため、yijy_{ij}のとる値も確率変数として考えることができるようになる。bjb_jを移項すると

yij={0 if (θiεijbj)<01 if (θiεijbj)0y_{ij} = \begin{cases} 0 & \text{ if } (\theta_i - \varepsilon_{ij} - b_j) < 0\\ 1 & \text{ if } (\theta_i - \varepsilon_{ij} - b_j) \geq 0\\ \end{cases}

となる。θiεijbjN(θibj,σε2)\theta_i - \varepsilon_{ij} - b_j \sim N(\theta_i - b_j, \sigma^2_{\varepsilon})である。 εij\varepsilon_{ij}を移項すれば

yij={0 if (θibj)<εij1 if (θibj)εijy_{ij} = \begin{cases} 0 & \text{ if } (\theta_i - b_j) < \varepsilon_{ij}\\ 1 & \text{ if } (\theta_i - b_j) \geq \varepsilon_{ij}\\ \end{cases}

でもあるので「yij=1y_{ij}=1となるのは誤差εij\varepsilon_{ij}θibj\theta_i - b_j以下のとき」とわかる。

Source
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
epsilon = np.linspace(-4, 4, 1000)
y = norm.pdf(epsilon)
fig, ax = plt.subplots(figsize=[4,2])
ax.plot(epsilon, y, 'k-')

c = 1

ax.fill_between(epsilon, y, where=(epsilon < c), color='blue', alpha=0.3, label=r'$P(y_{ij} = 1)$')
ax.fill_between(epsilon, y, where=(epsilon >= c), color='red', alpha=0.3, label=r'$P(y_{ij} = 0)$')
ax.axvline(x=c, color='grey', linestyle='--', label=r'$\theta_i - b_j$')
ax.set(
    title=r'$\varepsilon_{ij} \sim N(0, 1)$',
    xlabel=r"$\varepsilon_{ij}$",
    ylabel="density"
)
ax.legend()
ax.grid(True)
fig.show()
<Figure size 400x200 with 1 Axes>

1パラメータ正規累積モデル

仮にεij\varepsilon_{ij}が標準正規分布(σε2=1\sigma^2_{\varepsilon} = 1の正規分布)に従うならば、特性値θi\theta_iの人が項目jjに当てはまると回答する確率は

P(yij=1)=P(εijθibj)=(θibj)12πexp(z22)dz\begin{aligned} P(y_{ij} = 1) &= P(\varepsilon_{ij} \leq \theta_i - b_j)\\ &= \int_{-\infty}^{\left(\theta_i-b_j\right)} \frac{1}{\sqrt{2 \pi}} \exp \left(-\frac{z^2}{2}\right) d z \end{aligned}

となる(最後のは、εij\varepsilon_{ij}が従う標準正規分布のうち -\infty から θibj\theta_i-b_j までの範囲の面積がP(εijθibj)P(\varepsilon_{ij} \leq \theta_i - b_j)ということ)。

Source
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
x = np.linspace(-4, 4, 1000)

fig, ax = plt.subplots(figsize=[4, 2], ncols=1)

def icc(x, a, b):
    return norm.cdf(x, loc=b, scale=1/a)

a = 1
for b in [-1, 0, 1]:
    ax.plot(x, icc(x, a, b), label=r"$b$ = " + f"{b}")
ax.set(xlabel=r"$\theta_i$", ylabel=r"$P(y_{ij} = 1)$", xticklabels=[], yticklabels=[])
ax.legend()
ax.grid(True)
<Figure size 400x200 with 1 Axes>

2パラメータ正規累積モデル

σε2\sigma^2_{\varepsilon}が項目ごとに異なる場合を考える。σε2=1/aj\sigma^2_{\varepsilon}=1/a_jとすると、誤差の確率分布は

εijN(0,1aj)\varepsilon_{ij} \sim N\left(0, \frac{1}{a_j}\right)

となる。両辺をaja_j倍すると、ajεijN(0,1)a_j \varepsilon_{ij} \sim N(0, 1)と表すことができ、引き続き標準正規分布を使うことができる。そのためモデルはaia_iが追加され

P(yij=1)=P(ajεijθibj)=aj(θibj)12πexp(z22)dz\begin{aligned} P(y_{ij} = 1) &= P(a_j \varepsilon_{ij} \leq \theta_i - b_j)\\ &= \int_{-\infty}^{ a_j (\theta_i-b_j)} \frac{1}{\sqrt{2 \pi}} \exp \left(-\frac{z^2}{2}\right) d z \end{aligned}

となる。

Source
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
x = np.linspace(-4, 4, 1000)

fig, axes = plt.subplots(figsize=[8, 2], ncols=2)

def icc(x, a, b):
    return norm.cdf(x, loc=b, scale=1/a)

a = 1
for b in [-1, 0, 1]:
    axes[0].plot(x, icc(x, a, b), label=r"$b$ = " + f"{b}")
axes[0].set(xlabel=r"$\theta_i$", ylabel=r"$P(y_{ij} = 1)$", xticklabels=[], yticklabels=[])
axes[0].legend()
axes[0].grid(True)

b = 0
for a in [0.5, 1, 2]:
    axes[1].plot(x, icc(x, a, b), label=r"$a$ = " + f"{a}")
axes[1].set(xlabel=r"$\theta_i$", ylabel=r"$P(y_{ij} = 1)$", xticklabels=[], yticklabels=[])
axes[1].legend()
axes[1].grid(True)
<Figure size 800x200 with 2 Axes>

なお横軸にθi\theta_i、縦軸にP(yij=1)P(y_{ij}=1)をとったグラフは 項目特性曲線 (item characteristic curve: ICC) と呼ばれる。

因子分析との関係