平均値の差のt検定:対応のあるデータの場合
対応のあるデータの場合の平均値の差のt検定のためのVisual C++プログラムを作成した。このt検定については<岡本安晴「データ分析のための統計学入門」2009、おうふう;第3章:検定>などを参照されたい。プログラムは、ウェブサイト<テキストファイル入出力>で説明したプログラムに下記のようにコードを書き加えて作成した。
===============================================
//
// pos
番目の文字列の取り出し
//
String
^ SeekStr( String ^ str, int pos ){
String
^ vstr = "";
array<wchar_t>
^ separator = { ' ', '\t', ',',' ','/' };
array<String ^> ^ ary_str;
ary_str
= str->Split( separator );
int L = ary_str->Length;
int ckp = -1;
int tmpPos = 0;
do {
if (ary_str[tmpPos]->Length > 0) ckp++;
tmpPos++;
}
while ((ckp != pos) && (tmpPos < L)
);
if (ckp == pos) vstr = ary_str[tmpPos-1];
return vstr;
}
double sqr( double v
){
return v * v;
}
private: System::Void
button1_Click(System::Object^
sender, System::EventArgs^
e) {
//
// 入出力ファイルの名の設定
//
openFileDialog1->Title = "入力データファイル名";
if
(openFileDialog1->ShowDialog() ==
System::Windows::Forms::DialogResult::Cancel) return;
saveFileDialog1->Title = "出力ファイル名";
if
(saveFileDialog1->ShowDialog() ==
System::Windows::Forms::DialogResult::Cancel) return;
using namespace System::IO;
//
// 入力ストリームと出力ストリームの設定
//
StreamReader ^ fin = gcnew StreamReader( openFileDialog1->FileName,
System::Text::Encoding::GetEncoding("shift-jis")
);
StreamWriter ^ fout = gcnew StreamWriter( saveFileDialog1->FileName, false, System::Text::Encoding::GetEncoding("shift-jis") );
fout->WriteLine("Data file..." +
openFileDialog1->FileName);
fout->WriteLine();
String ^s;
while(true){
s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
int n =
0;
while(true){
s = fin->ReadLine();
if (s[0]
== '/') break;
n++;
}
fin->Close();
fin = gcnew
StreamReader( openFileDialog1->FileName,
System::Text::Encoding::GetEncoding("shift-jis")
);
while(true){
s = fin->ReadLine();
if
(s->Length > 0)
if (s[0]
== '/') break;
}
double *
x, * y;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++){
s = fin->ReadLine();
x[i] = double::Parse(SeekStr(s,
0));
y[i] = double::Parse(SeekStr(s,
1));
}
fin->Close();
fout->WriteLine();
fout->WriteLine("データ...");
for (int i = 0; i < n; i++)
fout->WriteLine(String("x[").PadLeft(10) + (i+1).ToString() + "] = " + x[i].ToString()->PadLeft(10)
+
String("y[").PadLeft(15)
+ (i+1).ToString() + "] = " +
y[i].ToString());
double sx
= 0.0, sy = 0.0;
for (int i = 0; i < n; i++){
sx
+= x[i];
sy
+= y[i];
}
double
MeanX = sx / n;
double
MeanY = sy / n;
double
sxx = 0.0, syy = 0.0;
for (int i = 0; i < n; i++){
sxx
+= sqr(x[i] - MeanX);
syy
+= sqr(y[i] - MeanY);
}
double
SDX = Math::Sqrt(sxx / n);
double
SDY = Math::Sqrt(syy / n);
fout->WriteLine();
fout->WriteLine("Xの平均 = " + MeanX.ToString("F5"));
fout->WriteLine("Xの分散 = " + (sxx/n).ToString("F5"));
fout->WriteLine("Xの標準偏差 = " + SDX.ToString("F5"));
fout->WriteLine("Xの不偏分散 = " +
(sxx/(n-1)).ToString("F5"));
fout->WriteLine("Xの不偏分散の平方根= " +
Math::Sqrt(sxx/(n-1)).ToString("F5"));
fout->WriteLine();
fout->WriteLine("Yの平均 = " + MeanY.ToString("F5"));
fout->WriteLine("Yの分散 = " + (syy/n).ToString("F5"));
fout->WriteLine("Yの標準偏差 = " + SDY.ToString("F5"));
fout->WriteLine("Yの不偏分散 = " +
(syy/(n-1)).ToString("F5"));
fout->WriteLine("Yの不偏分散の平方根= " +
Math::Sqrt(syy/(n-1)).ToString("F5"));
double
MeanD = MeanX - MeanY;
fout->WriteLine();
fout->WriteLine("Xの平均- Yの平均= " + MeanD.ToString("F5"));
double
sdd = 0.0;
for (int i = 0; i < n; i++)
sdd += sqr(x[i] - y[i] - MeanD);
double SD
= Math::Sqrt(sdd / n);
double t
= MeanD / (SD / Math::Sqrt(n - 1.0));
fout->WriteLine();
fout->WriteLine("t = " + t.ToString("F5") + " 自由度= "
+ (n-1).ToString());
fout->Close();
MessageBox::Show(saveFileDialog1->FileName
+ " was saved.");
Close();
}
===============================================
このプログラムを実行すると図1のウィンドウが表示される。
図1
「button1」ボタンのクリックで入力データ名設定用ダイアログウィンドウが図2のように表示される。
図2
入力データファイル名を指定して「開く」ボタンをクリックすると、計算結果出力用のファイル名設定を求めるダイアログウィンドウが表示される(図3)。
図3
出力はテキストファイルとして書き出されるので、ファイル名の拡張子は「.txt」としておく。出力ファイル名の設定後、「保存」ボタンをクリックすると計算がはじまり、計算終了後図4のメッセージウィンドウが表示される。
図4
メッセージウィンドウの「OK」ボタンのクリックでプログラムが終了する。
入力データは、図5に示すようにスラッシュ/で始まる行の次の行からデータを1行に一対ずつ書く。
図5
データの最後にスラッシュ/で始まる行を置いて、データの終了を示す。
図5のファイルを入力データとしたときの出力ファイルは次のようになっている。
============ 出力ファイル例:ここから ====================
Data
file...F:\yasuharu\www\LaCoocan\introprg\ttestrep\t_test_rep\t_test_rep\DataRep.txt
データ...
x[1]
=
66
y[1] = 72
x[2]
=
46
y[2] = 41
x[3]
=
87
y[3] = 93
x[4]
=
82
y[4] = 82
x[5]
=
42
y[5] = 41
x[6]
=
72
y[6] = 64
x[7]
= 31
y[7] = 27
x[8]
=
69
y[8] = 68
x[9]
=
84
y[9] = 79
x[10] =
68
y[10] = 67
x[11] =
50
y[11] = 57
x[12] =
90 y[12]
= 90
x[13] =
85
y[13] = 87
x[14] =
29
y[14] = 29
x[15] =
76
y[15] = 75
x[16] =
69
y[16] = 66
x[17] =
84 y[17] = 78
x[18] =
35
y[18] = 31
Xの平均 = 64.72222
Xの分散 = 399.86728
Xの標準偏差 = 19.99668
Xの不偏分散 = 423.38889
Xの不偏分散の平方根= 20.57642
Yの平均 = 63.72222
Yの分散 = 432.97840
Yの標準偏差 = 20.80813
Yの不偏分散 = 458.44771
Yの不偏分散の平方根= 21.41139
Xの平均- Yの平均= 1.00000
t
= 1.00660 自由度= 17
============ 出力ファイル例:ここまで========================
プログラム・ファイルは圧縮ファイルt_test_rep.zipとしてまとめた。ファイル名t_test_rep.zipをクリックしてダウンロードしたものをマウスの右ボタンクリックで表示されるメニュ「解凍」あるいは「展開」などを選ぶと解凍できる。解凍したものはVisual C++などで開いてビルド実行することができる。実行形式ファイルt_test_rep.exeも用意したので、ファイル名t_test_rep.exeをクリックしてダウンロード実行することができる。実行形式ファイルは.NET Framework3.5対応である。
なお、t値に対応する確率を求めるVisual C++プログラムはウェブサイト<ティ分布>に用意した。