Up

平均値・分散・標準偏差の計算

Javaプログラミング

 

平均値・分散・標準偏差を求めるプログラムをリスト1のように作成してみた。リスト1のプログラムにファイル入出力の操作を加えて変更したものはこのウェブサイトの後半に示す。

================== リスト1(始まり) ==================

package CalcMean;

 

public class CalcMean {

 

        static double sqr( double x ){

                        return x * x;

        }

 

        public static void main(String args[]){

                double data[] = { 1, 2, 3, 4, 5 };                              //              データの設定

                int n = data.length;                                            //              データの個数

                double sum = 0.0;

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

                        sum += data[i];                                         //              データの和

                        System.out.println("data[" + i + "] = " + data[i]);

                }

                double mean = sum / n;                                          //              平均

                System.out.println("Mean = " + mean);

                double ssum = 0.0;

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

                        ssum += sqr(data[i] - mean);                            //              2乗和

                double variance = ssum / n;                                     //              分散

                System.out.println("Variance = " + variance);

                double sd = Math.sqrt(variance);                                //              標準偏差

                System.out.println("SD = " + sd);

        }

}

================== リスト1(終わり) ==================

ここで、平均(mean)、分散(variance)、標準偏差(standard deviation; SD)は次式で与えられるものである。

詳しくは、<岡本安晴「データ分析のための統計学入門」おうふう>などを参照されたい。

リスト1のファイルCalcMean.javaは、圧縮ファイルCalcMean.zipにまとめている。ファイル名CalcMean.zipをクリック・ダウンロード展開すれば、エディタで開くことが出来る。なお、圧縮ファイル内のソースコードはWindows上で作成されたものであるので、ubuntuなどで使用するときはコード変換が必要である。コード変換については別のウェブサイトで説明している。

リスト1のプログラムでは、データは配列の初期値としてプログラム内で与えられている。

実行時のコンソール画面は図1のようである。

図1

 

他のデータで計算するときは、配列の初期値設定

              double data[] = { 1, 2, 3, 4, 5 };     

の部分をデータに合わせて書き換えればよい。

 

 

テキストファイル入出力

 上のリスト1のプログラムを、データをファイルから読み込み、計算結果をテキストファイルに書き出すプようにし、若干の変更を加えたものをリスト2に示す。

 

============================ リスト2(始まり) ===========================

package CalcMeanF;

 

import java.io.*;

import RC_double.*;

 

public class CalcMeanF {

 

        static double sqr( double x ){

                        return x * x;

        }

 

        //

        //                              n 個のデータ x[] に対して平均、分散、標準偏差を求める

        //

        static void calcStats( double x[], int n, RC_double mean, RC_double variance, RC_double sd ){

                        double sum = 0.0;

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

                                sum += x[i];                            //              和を求める

                        }

                        mean.v = sum / n;                               //              平均

                        sum = 0.0;

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

                                sum += sqr(x[i] - mean.v);              //              2乗和を求める

                        }

                        variance.v = sum / n;                           //              分散

                        sd.v = Math.sqrt(variance.v);           //              標準偏差

        }

 

        public static void main(String args[]){

                double data[] = new double[1000];               //              1000 個までのデータを格納できる配列

                int n = 0;                                                              //              データの個数の初期値

                try{

                        //

                        //                              cin をキーボードからの入力用に設定

                        //

                        BufferedReader cin = new BufferedReader(                                //                バッファー付き入力に設定

                                                 new InputStreamReader(System.in)               //                キーボードを入力ストリームに設定

                                                                                  );

                        //

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

                        //

                        System.out.print("Input Data File = ");

                        String fin_nm = cin.readLine();

                        BufferedReader fin = new BufferedReader( new FileReader(fin_nm));

       

                        while(true){

                                String s = fin.readLine();

                                if(s.length() > 0)

                                        if (s.charAt(0) == '/')

                                                break;

                        }

                        while(true){

                                String s = fin.readLine();

                                if (s.charAt(0) == '/') break;

                                data[n++] = Double.parseDouble(s);

                        }

                        fin.close();   

 

                        //

                        //                      出力用テキストファイルの設定

                        //

                        System.out.print("Output File Name = ");

                        String fout_nm = cin.readLine();

                        PrintWriter fout = new PrintWriter( new BufferedWriter( new FileWriter(fout_nm)));

 

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

                                System.out.println("data[" + i + "] = " + data[i]);

                                fout.println("data[" + i + "] = " + data[i]);

                        }

                       

                        /* ********************************************************

                                                public class RC_double {

                                                        public double v;

                                                        public RC_double( ){ v = 0.0; }

                                                        public RC_double( double tv ){  v = tv; }

                                }

                        *********************************************************** */

                        RC_double rc_mean = new RC_double(), rc_variance = new RC_double(), rc_sd = new RC_double();

                        //

                        //                              関数 calcStats の結果を rc_mean, rc_variance, rc_sd に設定

                        //

                        calcStats( data, n, rc_mean, rc_variance, rc_sd );

 

                        //

                        //                              書式付きの書き出し

                        //

                        String s = String.format("Mean = %-9.5f", rc_mean.v);

                        System.out.println(s);

                        fout.println(s);

                        s = String.format("Variance = %-9.5f", rc_variance.v);

                        System.out.println(s);

                        fout.println(s);

                        s = String.format("SD = %-9.5f", rc_sd.v);

                        System.out.println(s);

                        fout.println(s);

 

                        fout.close();

                        System.out.println(fout_nm + " was saved.");

                }

                catch(Exception e){

                        System.out.println("Exception..." + e);

                        System.exit(1);

                }

 

               

        }

}

============================ リスト2(終わり) ===========================

 

パッケージRC_doubleはリスト3に示す内容である。

============================ リスト3(始まり) ===========================

package RC_double;

 

        public class RC_double {

                        public double v;

                        public RC_double( ){ v = 0.0; }

                        public RC_double( double tv ){  v = tv; }

        }

============================ リスト3(終わり) ===========================

 

クラス型 RC_double は、次の関数 calcStats の引数の型に用いられている。

static void calcStats( double x[], int n, RC_double mean, RC_double variance, RC_double sd )

クラス型の中に変数を用意することにより、関数内での計算結果が取り出せるようにしている。

リスト2およびリスト3のプログラムファイルをまとめた圧縮ファイルCalcMeanF.zipを用意した。圧縮ファイル名CalcMeanF.zipをクリックしてダウンロード展開すればエディタで開くことが出来る。なお、圧縮ファイル内のソースコードはWindows上で開発されているので、ubuntuなどで使用するときはコード変換が必要である。コード変換については別のウェブサイトで説明している。

プログラムを図2のように実行すると、入力データファイル名の設定が求められる。

図2

 

入力でデータファイルは図3のように用意する。

図3

 

スラッシュ / で始まる行(図3では2行目)の次の行から1行に1つずつデータを書き、最後はスラッシュ / で始まる行(図3では8行目)で終える。

入力データファイル名を設定後、Enterキーを押すと、次に計算結果などを書き出す出力用テキストファイル名の設定が求められる(図4)。

図4

 

適当なファイル名(拡張子は「.txt」とするのがよい)を設定後、Enterキーを押すと、計算が始まり、コンソールに出力が表示される(図5)。

図5

 

プログラムの実行終了後、出力ファイルを開くと図6のようになっている。

図6

 

なお、度数分布のグラフを描くプログラムもウェブサイトに用意している。

 

Up