第6回の演習問題の解答例¶

../DATA01/IEDA06_02.csvを読み込んで、項目困難度、識別力、その項目を削除した場合の信頼性係数を算出し、DataFrameで表示しなさい。

In [2]:
# データの読み込み
import pandas as pd
data = pd.read_csv("../DATA01/IEDA06_02.csv",index_col=0)

# 困難度の算出
item_diff = data.mean()

# 識別力
import numpy as np

R_pbi = []

SD = data.sum(axis=1).std()

for i in data.columns:
    X_p = data[data[i]==1].sum(axis=1).mean()
    X_q = data[data[i]==0].sum(axis=1).mean()
    p = len(data[data[i]==1])/len(data)
    q = len(data[data[i]==0])/len(data)
    r_pbi = ((X_p - X_q) / SD) * np.sqrt(p*q)
    R_pbi.append(r_pbi)
    
# 項目を抜いた場合の信頼性係数
# 信頼性係数 = 項目数/(項目数 - 1) x (1 - (各項目の分散の合計/合計得点の分散)
A = []

SD = data.sum(axis=1).std()
n_item = len(data.columns) - 1
for i in data.columns:
    data_x = data.drop(i,axis=1)
    item_var = sum(data_x.var())
    total_var = data_x.sum(axis=1).var()
    a = n_item / (n_item -1) * (1 - (item_var / total_var))
    A.append(a)

item_property = pd.DataFrame({"difficulty":item_diff,
                                                         "disc":R_pbi,
                                                         "alpha_if_dropped":A},
                                                         index=data.columns)

item_property.head()
Out[2]:
difficulty disc alpha_if_dropped
Q01 0.771739 0.377088 0.798651
Q02 0.923913 0.115848 0.804462
Q03 0.706522 0.367176 0.799032
Q04 0.891304 0.297505 0.800882
Q05 0.967391 0.309244 0.801474

練習問題が終わったら¶

テストを問題数で半分に分けます(20問で構成されているテストであれば10問ずつに分けます)。半分に分けたテストを部分テストと呼びます。

この2つの部分テストの合計得点の相関係数は、テスト全体の信頼性係数にほぼ等しいと言われています。このように算出した信頼性係数をもとに、以下の式(Spearman-Brownの公式)を利用して折半する前のもとのテストの信頼性係数を算出することができます。

$$ \rho_x = \frac{2r}{1+r} $$

r: 2つの部分テストの相関係数

クロンバックのアルファは折半法を全通り行って算出した信頼性係数の平均値に等しいとも言われています。確かめてみましょう。

../DATA01/IEDA06_01.csvのデータで試してください。問題数が増えると折半法の組み合わせが膨大になりコンピュータが止まってしまいます。

In [3]:
# 使用するパッケージのimport
import pandas as pd
import numpy as np
import itertools

# データの読み込み
data = pd.read_csv("../DATA01/IEDA06_01.csv",index_col=0)

# 10項目から5項目を選ぶ全通りを求める
C = list(itertools.combinations(data.columns,5))

# 上の式にそれぞれの組みを当てはめて計算する
R_sh = []

for i in range(0,252):
    x = data[list(C[i])].sum(axis=1)
    y = data[list(C[-(i+1)])].sum(axis=1)
    r = np.corrcoef(x,y)[0][1]
    r_sh = 2*r / (1+r)
    R_sh.append(r_sh)
    
# 平均値の計算
np.average(R_sh)
Out[3]:
0.48225852154846155
In [4]:
# クロンバックのアルファの計算式で算出
n_item = len(data.columns)
item_var = sum(data.var())
total_var = data.sum(axis=1).var()
alpha = (n_item / (n_item - 1)) * (1 - (item_var / total_var))
alpha
Out[4]:
0.4771499849220057

0.05ぐらいの違いなのでほぼ同じとみなしても良いでしょう。