被験者内2要因分散分析
被験者内2要因分散分析<この分散分析のモデルについてはウェブサイトの後半で説明する>を行うプログラム例anova2wthn.exeを作成した。プログラムanova2wthn.exeは.NET Framework3.5対応である。プログラム名anova2wthn.exeをクリックしてダウンロード・実行すると図1のフォームが現れる。
図1
「設定」ボタンのクリックで図2のフォームが現れる。
図2
要因Aが被験者間要因、要因Bが被験者内要因である。各要因の水準数と水準内のデータ数Nを設定して(図3)
図3
「OK」ボタンをクリックすると図1のグリッドが設定値に調整される(図4)。
図4
図4のように要因の水準数と水準内のデータ数を設定した後、データを記入する(図5)。
図5
comboBoxのドロップダウンリストの項目を選ぶとその水準のページが表示される(図6)。
図6
既に用意されているデータを読み込むときは「読込」ボタンをクリックする。
「ラベル変更用ボックス」の文字列を変更すると表示されている水準のラベルが変更される。
「計算」ボタンのクリックで計算が始まるが、まず計算結果などを書き出す出力ファイル名の設定を求めるダイアログ・ボックスが表示される(図7)。
図7
計算が終了して出力用ファイルが閉じられると図8のメッセージ・ウィンドウが表示される。
図8
「OK」ボタンのクリックで図5のフォームに戻るので、「終了」ボタンをクリックしてプログラムの実行終了となる。プログラムの実行終了後、出力ファイルを開くと以下のようになっている。
=================================
要因A:被験者内要因 要因B:被験者内要因
要因A<A1>
Subject B1
B2
1
37
41
2
42
47
3
45
46
4
37
50
5
40
56
6
38
42
-平均-
39.833
47.000
要因A<A2>
Subject
B1
B2
1
46
53
2
48
56
3
48
53
4
47
55
5
46
55
6
49
56
-平均-
47.333
54.667
要因A<A3>
Subject
B1
B2
1
49
59
2
55
59
3
53
53
4
48
57
5
47
59
6
53
62
-平均-
50.833
58.167
SV
SS
df
MS
F
S
49.139
5
9.828
SSw.s
1515.167 30
A
770.389
2
385.194
30.504
AS
126.278 10
12.628
B
476.694
1
476.694
24.878
BS
95.806
5
19.161
AB
0.056
2
0.028
0.006
ABS
45.944 10
4.594
Total
1564.306 35
=================================
F値に対する確率は<エフ分布の計算>に用意したプログラムで求めることができる。
分散分析表の算出は以下のコードで行っている。
double v = 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
double rn = n;
double ss_c = sqr(v) / (rn * a * b);
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++)
v
+= sqr(y[i][j][k]);
double ss_total = v - ss_c;
double ss_a = 0.0;
for (int j = 0; j
< a; j++){
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
ss_a
+= sqr(v);
}
ss_a
= ss_a / (rn * b) - ss_c;
double ss_b = 0.0;
for (int k = 0; k
< b; k++){
v
= 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++)
v
+= y[i][j][k];
ss_b
+= sqr(v);
}
ss_b
= ss_b / (rn * a) - ss_c;
double ss_s = 0.0;
for (int i = 0; i
< n; i++){
v
= 0.0;
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
ss_s
+= sqr(v);
}
ss_s
= ss_s / (a * b) - ss_c;
double ss_ab = 0.0;
for (int j = 0; j
< a; j++)
for (int k = 0; k
< b; k++){
v
= 0.0;
for (int i = 0; i
< n; i++)
v
+= y[i][j][k];
ss_ab
+= sqr(v);
}
ss_ab
= ss_ab / rn - ss_c - ss_a - ss_b;
double ss_as = 0.0;
for (int i = 0; i
< n; i++)
for (int j = 0; j
< a; j++){
v
= 0.0;
for (int k = 0; k
< b; k++)
v
+= y[i][j][k];
ss_as
+= sqr(v);
}
ss_as
= ss_as / b - ss_c - ss_a - ss_s;
double ss_bs = 0.0;
for (int i = 0; i
< n; i++)
for (int k = 0; k
< b; k++){
v
= 0.0;
for (int j = 0; j
< a; j++)
v
+= y[i][j][k];
ss_bs
+= sqr(v);
}
ss_bs
= ss_bs / a - ss_c - ss_b - ss_s;
double ss_abs = ss_total - ss_a - ss_b - ss_s - ss_ab
- ss_as - ss_bs;
fout->WriteLine();
fout->WriteLine();
fout->WriteLine(String("SV").PadLeft(10) + String("SS").PadLeft(15) + String("df").PadLeft(10) + String("MS").PadLeft(15) + String("F").PadLeft(15));
fout->WriteLine(String("S").PadLeft(10) + ss_s.ToString("F3")->PadLeft(15) +
(n-1).ToString()->PadLeft(10) +
(ss_s
/ (n -1)).ToString("F3")->PadLeft(15));
fout->WriteLine(String("SSw.s").PadLeft(10) + (ss_total -
ss_s).ToString("F3")->PadLeft(15)
+ (n * (a * b - 1)).ToString()->PadLeft(10));
fout->WriteLine(String("A").PadLeft(10) + ss_a.ToString("F3")->PadLeft(15) +
(a-1).ToString()->PadLeft(10) +
(ss_a
/ (a - 1)).ToString("F3")->PadLeft(15)
+
((ss_a
/ (a - 1)) / (ss_as / ((a - 1) * (n - 1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("AS").PadLeft(10) + ss_as.ToString("F3")->PadLeft(15) + ((a - 1) * (n -
1)).ToString()->PadLeft(10) +
(ss_as
/ ((a - 1) * (n - 1))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("B").PadLeft(10) + ss_b.ToString("F3")->PadLeft(15) +
(b-1).ToString()->PadLeft(10) +
(ss_b
/ (b - 1)).ToString("F3")->PadLeft(15)
+
((ss_b
/ (b - 1)) / (ss_bs / ((b - 1) * (n - 1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("BS").PadLeft(10) + ss_bs.ToString("F3")->PadLeft(15) + ((b - 1) * ( n -
1)).ToString()->PadLeft(10) +
(ss_bs
/ ((b - 1) * (n - 1))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("AB").PadLeft(10) + ss_ab.ToString("F3")->PadLeft(15) + ((a - 1) * (b -
1)).ToString()->PadLeft(10) +
(ss_ab
/ ((a - 1) * (b - 1))).ToString("F3")->PadLeft(15)
+
((ss_ab
/ ((a - 1) * (b - 1))) / (ss_abs / ((a - 1) * (b - 1) * (n - 1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("ABS").PadLeft(10) + ss_abs.ToString("F3")->PadLeft(15) + ((a - 1) * (b -
1) * (n - 1)).ToString()->PadLeft(10) +
(ss_abs
/ ((a - 1) * (b - 1) * (n - 1))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("Total").PadLeft(10) +
ss_total.ToString("F3")->PadLeft(15)
+ (a * b * n - 1).ToString()->PadLeft(10));
上のプログラムのソースコードファイルなどは圧縮ファイルanova2wthn.zipとしてまとめた。圧縮ファイル名anova2wthn.zipをクリックしてダウンロードしたものをマウスの右ボタンでクリックして表示されるメニュから「展開」あるいは「解凍」を選ぶと解凍することが出来る。解凍したファイルは、Visual C++2008で開くことが出来る。
なお、Visual C++プログラミングの入門書<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>を上梓した。
被験者内2要因分散分析のモデル
被験者内2要因、AおよびB、のモデルにおける平方和を次のように分解する。ただし、は、番目の被験者に対する要因Aの水準、要因Bの水準におけるデータであり、要因Aの水準数は、要因Bの水準数は、被験者数はであるとする。
ここで、
である。
上記の各平方和の平均の期待値は次のようになる。
以上より、分散分析表を表1のように作成する。
表1 分散分析表
変動因 |
平方和 |
自由度 |
平均平方和 |
F比 |
被験者間 |
|
|
|
|
被験者内 |
|
|
|
|
A |
|
|
|
|
残差(A) |
|
|
|
|
B |
|
|
|
|
残差(B) |
|
|
|
|
A×B |
|
|
|
|
残差(A×B) |
|
|
|
|
全体 |
|
|
|
|
分散分析の基礎的なことは<岡本安晴「データ分析のための統計学入門」おうふう>で説明している。