これはG o o g l ehttp://www53.tok2.com/home/xxxxxxxx/c/26.htmlキャッシュです。
G o o g l eがクロール時にページを保存したものです。
そのため、このページの最新版でない場合があります。こちらから最新のページ(ハイライト表示なし)を参照してください。
このページのリンク又はお気に入りの登録にはこのURLをお使い下さい:http://www.google.com/search?q=cache:he5dzi_WF6MJ:www53.tok2.com/home/xxxxxxxx/c/26.html+%E6%AD%AA%E5%BA%A6+%E8%A8%88%E7%AE%97&hl=ja&ie=UTF-8&inlang=ja


Googleはこのページまたはページ内のコンテンツとは関連ありません。
これらのキーワードがハイライトされています: 歪 度 計算 

C言語で統計解析・第06日目

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 とおくと,共分散は

と表され,相関係数はXY の 2 つのそれぞれの分散 s_Xs_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;
}

 


昨 日
メニュー
ホ ー ム
明 日