クロンバックの α,標準化されたクロンバックの α,Kuder-Richardson の方法についても述べる。
1. クロンバックの α
順序尺度変数やリッカート法により得られる回答データにも対応しているので,後述する "Kuder-Richardson の式 20" より優れている。
1.1. 定義
- k:質問項目数
- xj:質問j への回答
- t:回答の合計 t = sum(x)
- cov(xi, xj):質問i への回答と質問j への回答の不偏共分散
- var(xi), var(t):質問iへの回答,回答の合計の不偏分散
https://www.real-statistics.com/reliability/internal-consistency-reliability/cronbachs-alpha/cronbachs-alpha-basic-concepts/
Cronbach’s Alpha Basic Concepts
1.2. 計算例
data = [1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 0 1 0
1 0 1 1 1 1 1 1 1 0 0
1 1 1 0 1 1 0 1 1 0 0
1 1 1 1 1 0 0 0 1 0 0
0 1 1 0 1 1 1 1 0 0 0
1 1 1 1 0 0 1 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0
0 1 0 1 1 0 0 0 0 1 0
1 0 0 1 0 1 0 0 0 0 0
1 1 1 0 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0 0 0 0];
k = size(data, 2)
11
t = sum(data, dims=2)
12×1 Matrix{Int64}:
11
9
8
7
6
6
5
5
4
3
3
2
varx = var(data, dims=1) # 不偏分散でも分散でも,以下と統一していればどちらでも可
1×11 Matrix{Float64}:
0.151515 0.204545 0.204545 0.204545 … 0.242424 0.204545 0.0833333
Σvarx = sum(varx)
2.3409090909090913
vart = var(t) # 不偏分散でも分散でも,上と統一していればどちらでも可
7.113636363636363
α = k / (k-1) * (1 - Σvarx / vart)
0.7380191693290735
1.3. Julia の関数として定義
using LinearAlgebra, Statistics
function alpha0(x)
k = size(x, 2)
VarCovMat = cov(x)
Sy2 = sum(VarCovMat)
Sj2 = sum(diag(VarCovMat))
k / (k - 1) * (1 - Sj2 / Sy2)
end
alpha0 (generic function with 1 method)
上式の 2 番目の式を関数化する。
using Statistics
function alpha(x)
k = size(x, 2)
varx = var(x, dims=1)
y = sum(x, dims=2)
k / (k - 1) * (1 - sum(varx) / var(y))
end
alpha (generic function with 1 method)
1.4. 計算例
alpha0(data)
0.7380191693290735
alpha(data)
0.7380191693290735
以下のデータは 3 件法での回答を求めたものである。
data2 = [1 1 1
2 1 1
2 1 2
3 2 1
2 3 2
2 3 3
3 2 3
3 3 3
2 3 2
3 3 3];
alpha0(data2)
0.7734375
alpha(data2)
0.7734375000000003
ちなみに,R では,psych::alpha で計算できる。
using RCall
R"""
library(psych)
results = alpha($(data2))
options(digits=16)
print(results$total$raw_alpha)
""";
[1] 0.7734375
なお,psych::alpha( ) は相関係数を与えるオプションもあるが,粗データを与えた場合と結果が違う。
using RCall
R"""
library(psych)
results2 = alpha(cor($(data2)))
options(digits=16)
print(results2$total$raw_alpha)
""";
[1] 0.7742910373931703
オンラインヘルプを見ると,
When calculated from the item variances and total test variance, as is done here, raw alpha is sensitive to differences in the item variances. Standardized alpha is based upon the correlations rather than the covariances.
というくだりがある。つまり,変数(質問への回答)を標準化する方がよいとのことである。そこで,元データを標準化して alpha( ) に与えてやると確かに同じ値になる。
using RCall
R"""
library(psych)
scaled = scale($(data2))
results2 = alpha(scaled)
options(digits=16)
print(results2$total$raw_alpha)
""";
[1] 0.7742910373931704
1.5. 相関係数を与えて標準化されたクロンバックの α を求める
https://towardsdatascience.com/cronbachs-alpha-theory-and-application-in-python-d2915dd63586
Cronbach’s Alpha: Theory and Application in Python
1.6. 定義
- k:質問項目数
- r:質問項目間の相関係数の平均値(相関係数行列の対角要素を含まない上三角行列の相関係数 r(i, j), i < j の平均値)
注意:元の Web ページのどこにも書いていないが,αst と記述されている点に注意。つまり「標準化されたクロンバックのα)の意なのだ。
Web ページには Python での関数が示されている。
def cronbach_alpha(df):
# 1. Transform the df into a correlation matrix
df_corr = df.corr()
# 2.1 Calculate N
# The number of variables equals the number of columns in the df
N = df.shape[1]
# 2.2 Calculate R
# For this, we'll loop through the columns and append every
# relevant correlation to an array calles "r_s". Then, we'll
# calculate the mean of "r_s"
rs = np.array([])
for i, col in enumerate(df_corr.columns):
sum_ = df_corr[col][i+1:].values
rs = np.append(sum_, rs)
mean_r = np.mean(rs)
# 3. Use the formula to calculate Cronbach's Alpha
cronbach_alpha = (N * mean_r) / (1 + (N - 1) * mean_r)
return cronbach_alpha
これを Julia に書き換える。
using Statistics
function cronbach_alpha(df)
# 1. Transform the df into a correlation matrix
r = cor(df)
# 2.1 Calculate N
# The number of variables equals the number of columns in the df
N = size(df, 2)
# 2.2 Calculate R
# For this, we'll loop through the columns and append every
# relevant correlation to an array calles "r_s". Then, we'll
# calculate the mean of "r_s"
r_s = []
for i = 1:N-1
for j = i+1:N
append!(r_s, r[i, j])
end
end
mean_r = mean(r_s)
# 3. Use the formula to calculate Cronbach's Alpha
(N * mean_r) / (1 + (N - 1) * mean_r)
end
cronbach_alpha (generic function with 1 method)
cronbach_alpha(data2)
0.7742910373931706
確かに,psych::alpha( ) の結果と一致した。
標準化というのは全ての変数の分散を同じにする(全ての変数を同格に扱う)ということである。
普通にクロンバックの α が使われる状況は,質問項目の回答の分散が大きく変わることはない(ほとんどの質問項目は 5 件法,ある項目は 0 ~ 100 の満足度などというのはあり得ない)。
なので,標準化されたクロンバックの α も,通常のクロンバックの α もほとんど同じ値になるだろう。
クロンバックの α の応用法として,ある質問項目を除いたら α がどれぐらい変化するかを検討することがある。この場合に使うのは標準化されないクロンバックの α である。
ということで,伝統的な(標準化しない)クロンバックの α を使う方がよいだろう。
2. Kuder and Richardson Formula 20
質問項目への回答が二値データ(たとえば 0/1)の場合には,"Kuder-Richardson の式 20" を適用することができ,クロンバックの α と全く同じ結果が得られる。
2.1. 定義
- k:質問項目数
- pj:質問j に正解であった回答者数
- qj:質問j に不正解であった回答者数
- σ²:回答者ごとの得点(正解数)の分散(不偏分散ではない)
ρKR20 は 0 ~ 1 の範囲の値をとり,値が大きいことは信頼性があることを示す。しかし,あまりにも大きい数値(たとえば 0.9 以上)の場合は,質問紙が均質である(悪い意味で「それぞれの質問はほとんど同じ」)ことを示す。
https://www.real-statistics.com/reliability/internal-consistency-reliability/kuder-richardson-formula-20/
Kuder and Richardson Formula 20
2.2. 計算例
n, k = size(data)
(12, 11)
p = sum(data, dims=1) ./ n
1×11 Matrix{Float64}:
0.833333 0.75 0.75 0.75 0.666667 … 0.416667 0.333333 0.25 0.0833333
q = 1 .- p
1×11 Matrix{Float64}:
0.166667 0.25 0.25 0.25 0.333333 … 0.583333 0.666667 0.75 0.916667
pq = p .* q
1×11 Matrix{Float64}:
0.138889 0.1875 0.1875 0.1875 0.222222 … 0.222222 0.1875 0.0763889
Σpq = sum(pq)
2.1458333333333335
using Statistics
σ² = var(totalscores, corrected=false) # 注:不偏分散ではない
6.520833333333333
ρKR20 = (1 - Σpq / σ²) * k / (k - 1)
0.7380191693290734
2.3. Julia の関数として定義
using Statistics
function KR20(x)
n, k = size(x)
p = sum(data, dims=1) ./ n
q = 1 .- p
pq = p .* q
Σpq = sum(pq)
σ² = var(totalscores, corrected=false)
(1 - Σpq / σ²) * k / (k - 1)
end
KR20 (generic function with 1 method)
前節の計算例のような 0/1 回答のデータに対して計算される "Kuder-Richardson の式 20" は,クロンバックの α と全く同じである。
alpha0(data)
0.7380191693290735
alpha(data)
0.7380191693290735
KR20(data)
0.7380191693290734