stMind

about Tech, Computer vision and Machine learning

ビショップ本 分散・共分散

分散(variance)

f(x)の分散は、f(x)f(x)の期待値の差の二乗の期待値(ややこしいな)。

\mbox{var}[f] = \mbox{E} \left[(f(x)-\mbox{E}[f(x)])^2 \right]

平均値\mbox{E} [f(x)]からの値のばらつきがどれくらいかがわかる。

この式を展開すると、

\mbox{var}[f] = \mbox{E} [(f(x)^2] - \mbox{E} [f(x)]^2

となり、f(x)f(x)^2の期待値を用いて表す事が出来る。

共分散(covariance)

2つの確率変数xyの共分散は、xyの積の期待値から、xの期待値とyの期待値の積を引いたもの。

\mbox{cov} [x,y] = \mbox{E} [xy] - \mbox{E} [x] \mbox{E} [y]

プログラミングしてみた

平均、分散、標準偏差、共分散を求めるコードを書いてみた。
実際に書いてみると、理解した気になっていただけのところがわかって有益だな。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define NUM_SAMPLES 10
#define MAX_VALUE 100

// 乱数をセットする関数
void setRandVal(int *val)
{
    int i;

    for(i=0; i<NUM_SAMPLES; i++) {
     val[i] = rand() % MAX_VALUE;
    }

}

// 平均を計算する関数
float calcAve(int *val)
{
    int i;
    int sum = 0;

    for(i=0; i<NUM_SAMPLES; i++){
     sum += val[i];
    }

    return ((float)(sum) / NUM_SAMPLES);
}

// 分散を計算する関数
float calcVar(int *val)
{
    int i;
    float ave = 0.0;
    float sum = 0.0;

    ave = calcAve(val);

    for(i=0; i<NUM_SAMPLES; i++) {
     sum += ( (val[i] - ave) * (val[i] - ave) );
    }
   
    return (sum / NUM_SAMPLES);
}

// 共分散を計算する関数
float calcCov(int *val1, int *val2)
{
    int i;
    float ave1 = 0.0;
    float ave2 = 0.0;
    float sum = 0.0;

    ave1 = calcAve(val1);
    ave2 = calcAve(val2);

    for(i=0; i<NUM_SAMPLES; i++) {
     sum += ( (val1[i] - ave1) * (val2[i] - ave2) );
    }

    return (sum / NUM_SAMPLES);
   
}

int main( int argc, char *argv[])
{
    int n, rnd;
    float Xave = 0.0;
    float Yave = 0.0;
    float Xvar = 0.0;
    float Yvar = 0.0;
    float Cov = 0.0;
   
    // 確率変数
    int x[NUM_SAMPLES];
    int y[NUM_SAMPLES];

    srand(time(NULL));

    // 乱数で値を代入する
    setRandVal(x);
    setRandVal(y);

    // 変数を表示
    printf("Original Value:\n");
    printf("x = { ");
    for(n=0; n<NUM_SAMPLES; n++) {
     printf("%d ", x[n]);
    }
    printf("}\n");

    printf("y = { ");
    for(n=0; n<NUM_SAMPLES; n++) {
     printf("%d ", y[n]);
    }
    printf("}\n\n");

    // 平均を計算
    Xave = calcAve(x);
    Yave = calcAve(y);

    // 平均を表示
    printf("Average:\n");
    printf("Xave = %f\n", Xave);
    printf("Yave = %f\n", Yave);
    printf("\n");

    // 分散を計算
    Xvar = calcVar(x);
    Yvar = calcVar(y);

    // 分散を表示
    printf("Variance:\n");
    printf("Xvar = %f\n", Xvar);
    printf("Yvar = %f\n", Yvar);
    printf("\n");

    // 標準偏差を表示
    printf("standard variation:\n");
    printf("Xsd = %f\n", sqrt(Xvar));
    printf("Ysd = %f\n", sqrt(Yvar));
    printf("\n");

    // 共分散を計算
    Cov = calcCov(x, y);

    // 共分散を表示
    printf("Covariance:\n");
    printf("Cov = %f\n", Cov);
    printf("\n");
   
    return 0;
}