|
' );
}
else{
var k = ( Math.floor(Math.random() * 10000))%10000;
document.write( ' |
C言語で統計解析・第06日目
『簡単なデータ分析:それぞれの関数篇』
元となるデータ分析プログラムは データ分析の概要 を参照のこと.分析するデータは以下の input.txt を使うことにする.データは データ番号,身長,体重,性別(女:0,男:1) の順に並んでいる.
1 175 61 1 2 165 62 1 3 162 48 0 4 164 52 1 5 170 55 1 6 169 69 1 7 155 48 0 8 153 44 0 9 162 49 0 10 158 58 0 |
● 平均
データを表す確率変数を X とおくと,平均は
と表される.よって平均を計算する場合は,関数 sum() によってデータを全て足し算してから上の式を関数 mean() で計算すればよい.
double sum (double x[], int n) { int i; double a; a = 0; for (i = 0; i <= n-1; i++) { a = a+x[i]; } return a; } double mean (double x[], int n) { double a, b; a = sum(x, n); b = a/n; return b; } |
● 分散と標準偏差
データを表す確率変数を X とおくと,分散は
と表される.よって分散を計算する場合は,関数 sum() と関数 mean() で計算した値を元に,関数 variance() で上の式を計算すればよい.これを元に関数 stndv() で分散のルートを取れば,標準偏差 s が求まることになる.
( 注 意 )
データは標本データを用いている.よってデータ数を n とすれば自由度は n-1 となるので上の分散は不偏分散を求めていることになる.
double variance (double x[], int n) { double a, b, c; int i; a = mean(x, n); b = 0; for (i = 0; i <= n-1; i++) { b = b+pow(x[i]-a,2); } c = b/(n-1); return c; } double stndv (double x[], int n) { double a,b; a = variance(x, n); b = sqrt(a); return b; } |
● 歪度と尖度
データを表す確率変数を X とおくと,歪度は
と表され,尖度は
と表される.よって上の 2 式を関数 skewness() と kurtosis() でそれぞれ計算すればよい.
( 注 意 )
double skewness (double x[], int n) { double a, b, c, d; int i; a = mean(x, n); b = stndv(x, n); c = 0; for (i = 0; i <= n-1; i++) { c = c+pow(x[i]-a, 3); } d = c*n/(pow(b, 3)*(n-1)*(n-2)); return d; } double kurtosis (double x[], int n) { double a, b, c, d; int i; a = mean(x, n); b = stndv(x, n); c = 0; for (i = 0; i <= n-1; i++) { c = c+pow(x[i]-a, 4); } d = c*n*(n+1)/(pow(b, 4)*(n-1)*(n-2)*(n-3)); d = d-3.0*pow((n-1), 2)/((n-2)*(n-3)); return d; } |
● 中央値・分位点・四分位点
データを表す確率変数を X とおくと,中央値は
と表される.中央値は観測値を小さい順に並べた場合の 50% の点に対応しているのだが,p % の点のことを p パーセント分位点( p percentile)と呼ばれる.ここで m をデータ数と p とを掛け算した値とし,m* を m より大きいか等しい整数であるとすると,p パーセント分位点は
と表される.これより第 1 四分位点( 25% 分位点)と第 3 四分位点( 75% 分位点)が計算できる.以上を関数 quartile() で計算すればよい.
関数 quartile() では,呼び出す側に計算結果を返す必要があるが,戻り値では値を 1 つしか返すことが出来ない.しかし返したい値は 最大値,最小値,第 1 四分位点( 25% 分位点),中央値,第 3 四分位点( 75% 分位点)の 5 つなので,ここではポインタを引数としている.
ところでデータを小さい順(昇順)に並び替える作業を,関数 sort1() で行っている.並べ替えの方法はバブルソートという方法を用いている.これはデータが小さい場合は問題なく並べ替えを行うことが出来るが,データ数が非常に大きい場合は計算時間がかかる方法でもある.データ数が非常に大きい場合は,関数 sort1() をクイックソート等の並べ替えの方法を用いることをお勧めする.
void sort1(double x[], double y[], int n) { int change, i; double a; for (i = 0; i <= n-1; i++) { y[i]=x[i]; } do { change = 0; for (i = 0; i <= n-2; i++) { if (y[i] > y[i+1]) { change = 1; a = y[i]; y[i] = y[i+1]; y[i+1] = a; } } } while(change == 1); } void quartile(double x[], double y[], int n, double *min, double *max, double *q1, double *med, double *q3) { int i, j1, j2; sort1(x, y, n); *min = y[0]; *max = y[n-1]; i = n%2; if (i != 0) { *med = y[(n+1)/2-1]; } else { *med = (y[n/2-1]+y[n/2])/2; } i = n%4; j1 = n/4; j2 = 3*n/4; if (i != 0) { *q1 = y[j1]; *q3 = y[j2]; } else { *q1 = (y[j1-1]+y[j1])/2; *q3 = (y[j2-1]+y[j2])/2; } } |
● 共分散と相関係数
以上で 2 つのデータ(ここでは身長と体重)のそれぞれの統計データが求まった.一方のデータ(身長)を表す確率変数を X ,もう一方のデータ(体重)を表す確率変数を Y とおくと,共分散は
と表され,相関係数はX と Y の 2 つのそれぞれの分散 s_X と s_Y を用いて
と表される.上の 2 式を,以下の 2 つの関数 covar() と correl() を用いて計算すれば共分散と相関係数が得られる.
double covar (double x[], double y[], int n) { double xa, ya, a, b; int i; xa = mean(x, n); ya = mean(y, n); a = 0; for (i = 0; i <= n-1; i++) { a = a+(x[i]-xa)*(y[i]-ya); } b = a/(n-1); return b; } double correl (double x[], double y[], int n) { double covxy, xstndv, ystndv, a; covxy = covar(x, y, n); xstndv = stndv(x, n); ystndv = stndv(y, n); a = covxy/(xstndv*ystndv); return a; } |
' );
}
else{
var k = ( Math.floor(Math.random() * 10000))%10000;
document.write( ' |