Up

2変量記述統計量

共分散と相関係数

 

2変量記述統計量として共分散と相関係数を求める。Win32コンソールアプリケーションの新規作成については<Win32コンソールアプリケーションの新規作成>で、C++の標準入出力(コンソール入出力)については<標準入出力cincout>で、C++におけるテキストファイル入出力については<テキストファイル入出力>で説明している。

 プログラムの実行例を図1に示す。

図1

 

入力ファイルはプログラム・ソースコード・ファイル*.cppと同じフォルダに用意する。

入力データファイル設定のソースコードは以下のようになっている。

 

              cout << "入力データファイル = ";

              string ifnm;

              cin >> ifnm;

              ifstream fin( ifnm );

              if ( ! fin){                                                        //                          入力ファイルの設定が失敗するとfinfalseを返す。

                                          cout << "入力ファイルエラー" << endl;

                                          cout << "何か文字を入力して終了。" << endl;

                                          string s;

                                          cin >> s;

                                          return 9;

              }

 

入出力ストリーム・オブジェクトの変数finを条件式に用いると、ストリームに何かエラーがあるとfalseが返される。

 

入力ファイルは図2の形式で用意する。

図2

 

第1行目に基準値を置く。2行目からデータを1行に1組ずつ書く。最後のデータの次の行に基準値より小さい値を置いてデータの終わりであることを示す。データの終わりを示す数値の後の行は読み込みの対象とはならないので、コメントを自由に書くことができる。

エディタでデータを新しく用意したときは、保存してからプログラムで読み込む。エディタの画面に打ち込んだだけでは、その内容はファイルに反映されない。

次のコードによってデータ数を数えている。

 

              double c;

              fin >> c;                                           //            基準値の設定

              int n = 0;

              double v;

              do{

                            fin >> v;

                            if (v < c) break;                 //            基準値より小さい値が読み込まれた。

                            fin >> v;

                            n++;                                  //            データ数のカウント

              }while(true);

              fin.close();                                       //            入力ファイルを一旦閉じる

 

計算を終えて結果の書き出しが終了すると「何か文字キーを押してからEnterキーを押して下さい」と表示されるので、適当な文字キーを押してEnterキーを押すとプログラムの終了となる。この部分は以下のコードによって処理されている。

 

              fout.close();

              cout << "計算終了!" << endl;

              cout << "何か文字キーを押してからEnterキーを押して下さい" << endl;

              string ckstr;

              cin >> ckstr;

              return 0;

 

 

 

出力ファイルもファイル名を図1のように設定すると、プログラムソースコードファイル*.cppと同じフォルダ内に作成される。図2のデータでプログラムを実行したときの出力ファイルをVisualC++のエディタで開くと図3のようになっている。

図3

 

共分散と相関係数(岡本安晴「データ分析のための統計学入門」おうふう)は、2乗和を

 

              double ssx = 0.0, ssy = 0.0, sxy = 0.0;

              for (int i = 0; i < n; i++){

              ssx += sqr(x[i] - MeanX);

              ssy += sqr(y[i] - MeanY);

              sxy += (x[i] - MeanY) * (y[i] - MeanY);

              }

 

と求めてから、次のコードで算出している。

              double cov = sxy / n;

              fout << "共分散  = " << cov << endl << endl;

 

              double r = sxy / ::sqrt(ssx * ssy);  

              fout << "相関係数  = " << r << endl;

 

プログラムソースコード全体は以下の通りである。

 

==============================================

#include "stdafx.h"                         //            Visual C++が勝手に用意するもの。削除するとエラーになる

 

#include <iostream>                       //            cin, coutの使用のため

#include <fstream>                        //            ifstream, ifstreamの使用のため

#include <string>                           //            string型の使用のため

 

using namespace std;                     //            cin, coutなどが属する名前空間

 

double sqr( double v ){

                            return  v * v;

}

 

int _tmain(int argc, _TCHAR* argv[])

{

              //

              //                          入力データファイルの設定

              //

              cout << "入力データファイル = ";

              string ifnm;

              cin >> ifnm;

              ifstream fin( ifnm );

              if ( ! fin){                                                        //                          入力ファイルの設定が失敗するとfinfalseを返す。

                                          cout << "入力ファイルエラー" << endl;

                                          cout << "何か文字を入力して終了。" << endl;

                                          string s;

                                          cin >> s;

                                          return 9;

              }

 

              double c;

              fin >> c;                                                         //                          基準値の設定

              int n = 0;

              double v;

              do{

                            fin >> v;

                            if (v < c) break;                               //                          基準値より小さい値が読み込まれた。

                            fin >> v;

                            n++;                                                //                          データ数のカウント

              }while(true);

              fin.close();                                                     //                          入力ファイルを一旦閉じる

              double * x, * y;

              x = new double[n];

              y = new double[n];

              fin.open( ifnm );                                            //                          入力ファイルをオープン

              fin >> v;

              for (int i = 0; i < n; i++){

                            fin >> x[i] >> y[i];                                         //                          データの読み込み

              }

              //

              //                          出力ファイルの設定

              //

              cout << "出力ファイル名 = ";

              string ofnm;

              cin >> ofnm;

              ofstream fout( ofnm );

              //

              //                          入力データの書き出し

              //

              fout << "入力データファイル = " << ifnm << endl << endl;

              fout << "データ..." << endl;

              for (int i = 0; i < n; i++){

                            fout << i+1 << ":  x = " << x[i] << "  y = " << y[i] << endl;

              }

              //

              //                          平均値の計算

              //

              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;

              //

              //                          2乗和などの計算

              //

              double ssx = 0.0, ssy = 0.0, sxy = 0.0;

              for (int i = 0; i < n; i++){

              ssx += sqr(x[i] - MeanX);

              ssy += sqr(y[i] - MeanY);

              sxy += (x[i] - MeanY) * (y[i] - MeanY);

              }

              double SDX = ::sqrt(ssx / n);

              double SDY = ::sqrt(ssy / n);

 

              fout << endl;

              fout << "Xの平均      = " << MeanX << endl;

              fout << "Xの分散      = " << ssx/n << endl;

              fout << "Xの標準偏差  = " << SDX << endl;

              fout << "Xの不偏分散  = " << ssx/(n-1) << endl;

              fout << "Xの不偏分散の平方根 = " << ::sqrt(ssx/(n-1)) << endl << endl;

              fout << "Yの平均      = " << MeanY << endl;

              fout << "Yの分散      = " << ssy/n << endl;

              fout << "Yの標準偏差  = " << SDY << endl;

              fout << "Yの不偏分散  = " << ssy/(n-1) << endl;

              fout << "Yの不偏分散の平方根 = " << ::sqrt(ssy/(n-1)) << endl << endl;

 

              //

              //           共分散     

              //

              double cov = sxy / n;

              fout << "共分散  = " << cov << endl << endl;

 

              //

              //           相関係数     

              //

              double r = sxy / ::sqrt(ssx * ssy);  

              fout << "相関係数  = " << r << endl;

 

              fout.close();

              cout << "計算終了!" << endl;

              cout << "何か文字キーを押してからEnterキーを押して下さい" << endl;

              string ckstr;

              cin >> ckstr;

              return 0;

}

==============================================

 

 プログラムソースコードファイルなどをまとめたものは圧縮ファイルstat2vars.zipとして用意した。圧縮ファイル名stat2vars.zipをクリックしてダウンロードすることが出来る。ダウンロードした圧縮ファイルstat2vars.zipはマウスの右ボタンクリックで表示されるメニュから「展開」あるいは「解凍」を選ぶと解凍できる。解凍したファイルはVisual C++2010で開くことができる。

 

 Visual C++プログラミングの入門書として<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>を上梓した。

 

Up