平均値・分散・標準偏差の計算
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
なお、度数分布のグラフを描くプログラムも別のウェブサイトに用意している。