被験者間1要因・被験者内1要因分散分析
被験者間1要因・被験者内1要因分散分析<この分散分析のモデルについてはウェブサイトの後半で説明する>を行うプログラム例anova1btwn1wthn.exeを作成した。プログラムanova1btwn1wthn.exeは.NET Framework3.5対応である。プログラム名anova1btwn1wthn.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>
B1
B2
5
6
4
8
6
7
-平均-
5.000
7.000
要因A<A2>
B1 B2
8
9
6
7
7
8
-平均-
7.000
8.000
要因A<A3>
B1
B2
3
5
1
3
2
6
-平均-
2.000
4.667
SV
SS
df
MS
F
Between S
63.778
8
A
53.444
2
26.722
15.516
S/A
10.333
6
1.722
Within
S
22.500
9
B
16.056
1 16.056
22.231
AB
2.111
2
1.056
1.462
SB/A
4.333
6
0.722
Total
86.278
17
=================================
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_btwn = 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_btwn
+= sqr(v);
}
ss_btwn
= ss_btwn / b - 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_sa = ss_btwn - ss_a;
double ss_wthn = ss_total - ss_btwn;
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_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_sba = ss_wthn - ss_b - ss_ab;
double * sum;
sum
= new double[b];
fout->WriteLine();
fout->WriteLine();
fout->WriteLine("要因A:被験者間要因 要因B:被験者内要因");
for (int j = 0; j
< a; j++){
fout->WriteLine();
fout->WriteLine("要因A<" + FctrALabel[j] + ">");
fout->Write(
String("
").PadLeft(15) );
for (int k = 0; k
< b; k++)
fout->Write(FctrBLabel[k]->PadLeft(15));
fout->WriteLine();
double * sum;
sum
= new double[b];
for (int k = 0; k
< b; k++) sum[k] = 0.0;
for (int i = 0; i
< n; i++){
fout->Write(
String("
").PadLeft(15) );
for (int k = 0; k
< b; k++){
fout->Write(y[i][j][k].ToString()->PadLeft(15));
sum[k]
+= y[i][j][k];
}
fout->WriteLine();
}
fout->WriteLine("-平均-");
fout->Write(
String("
").PadLeft(15) );
for (int k = 0; k
< b; k++)
fout->Write((sum[k]/n).ToString("F3")->PadLeft(15));
fout->WriteLine();
}
fout->WriteLine();
fout->WriteLine();
fout->WriteLine(String("SV").PadLeft(15) + String("SS").PadLeft(15) + String("df").PadLeft(10) + String("MS").PadLeft(15) + String("F").PadLeft(15));
fout->WriteLine(String("Between S").PadLeft(15) +
ss_btwn.ToString("F3")->PadLeft(15)
+ (a*n-1).ToString()->PadLeft(10));
fout->WriteLine(String("A").PadLeft(15) + ss_a.ToString("F3")->PadLeft(15) +
(a-1).ToString()->PadLeft(10) + (ss_a/(a-1)).ToString("F3")->PadLeft(15) +
((ss_a/(a-1))
/ (ss_sa/(a*(n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("S/A").PadLeft(15) + ss_sa.ToString("F3")->PadLeft(15) +
(a*(n-1)).ToString()->PadLeft(10) + (ss_sa/(a*(n-1.0))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("Within S").PadLeft(15) +
ss_wthn.ToString("F3")->PadLeft(15)
+ (a*n*(b-1.0)).ToString()->PadLeft(10));
fout->WriteLine(String("B").PadLeft(15) + ss_b.ToString("F3")->PadLeft(15) +
(b-1).ToString()->PadLeft(10) +
(ss_b/(b-1)).ToString("F3")->PadLeft(15) + ((ss_b/(b-1)) /
(ss_sba/(a*(b-1)*(n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("AB").PadLeft(15) + 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_sba/(a*(b-1)*(n-1.0)))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("SB/A").PadLeft(15) + ss_sba.ToString("F3")->PadLeft(15) +
(a*(b-1)*(n-1)).ToString()->PadLeft(10) +
(ss_sba/(a*(b-1)*(n-1))).ToString("F3")->PadLeft(15));
fout->WriteLine(String("Total").PadLeft(15) +
ss_total.ToString("F3")->PadLeft(15)
+ (a*b*n - 1).ToString()->PadLeft(10));
上のプログラムのソースコードファイルなどは圧縮ファイルanova1btwn1wthn.zipとしてまとめた。圧縮ファイル名anova1btwn1wthn.zipをクリックしてダウンロードしたものをマウスの右ボタンでクリックして表示されるメニュから「展開」あるいは「解凍」を選ぶと解凍することが出来る。解凍したファイルは、Visual C++2008で開くことが出来る。
なお、Visual C++プログラミングの入門書<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>を上梓した。
被験者間1要因・被験者内1要因分散分析のモデル
被験者間1要因A、および被験者内1要因Bのモデルを次のようにおく。
ここで、主効果A
主効果B
交互作用AB
ij番目の被験者固有の効果
AjとBkとの交互作用による効果を調整した、ij番目の被験者と要因Bの水準kとの交互作用
である。
データ値の平方和を次のように分解する。
ここで
、
ただし、
である。
これらの平方和の期待値は以下のようになる。
ここで、
である。
以上より、分散分析表は表1のように作成される。
表1 分散分析表
変動要因 |
平方和 |
自由度 |
平均平方和 |
F比 |
被験者間 |
|
|
|
|
A |
|
|
|
|
残差(A) |
|
|
|
|
被験者内 |
|
|
|
|
B |
|
|
|
|
A×B |
|
|
|
|
残差(B) |
|
|
|
|
全体 |
|
|
|
|
分散分析の基礎的なことは<岡本安晴「データ分析のための統計学入門」おうふう>で説明している。