東大の演習問題に挑戦(3) - 平均・標準偏差・偏差値編

そういえば統計の問題を殆んどやったことが無い。今日の問題はコレダ!!

アルゴリズムとデータ構造演習 C入門第3回

課題3-B:
2:次の関数を実装し、main中で呼び出して動作確認せよ。

double average (double *data, int n) { dataの前部n個の平均値を求める }
double sd (double *data, int n) { dataの前部n個の標準偏差を求める }

簡単そうだけど、標準偏差ってのがよくわかんねぇ。

ヒョウジュンヘンサってナンダヨ・・・・ググってみると。

平均と標準偏差

おぉ。わかりやすい〜。

標準偏差について

テストで考えてみると、

平均はこう。

平均 = 点数の合計 / 人数

偏差ってのは、平均点からどれくらい離れてるかというのが出るらしい。

偏差 = 点数 - 平均

ナルホド。

標準偏差は偏差の二乗の平均の平方根

標準偏差 = sqrt(偏差の二乗の合計 / 人数)

二乗しないとゼロになっちゃうから激しく意味が無い。点数がどれくらい分散してるかという指標になるらしい。

平均から離れてる奴がいっぱいいると標準偏差がでかくなる。みんなオンナジ点数なら標準偏差はゼロだ。平均だけではわからない「バラツキ」がわかるようになるわけだ。標準偏差スゲー。

で、みんなを苦しめる偏差値は、

偏差値 = 50 + 10 * (点数 - 平均) / 標準偏差

へぇぇ。偏差値ってこうやって出すのか。勉強になった。

実装してみる

標準偏差がわかった所で、平均、標準偏差、偏差値を出してみたい。

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

double avg(int data[], int n)
{
    int i = 0;
    int sum = 0;

    for (i = 0; i < n; i++)
        sum += data[i];

    return sum / n;
}

double sd(int data[], int n)
{
    int i, x;
    double a = avg(data, n);
    double sum = 0;

    for (i = 0; i < n; i++) {
        x = data[i] - a;
        sum += x * x;
    }

    return sqrt(sum / n);
}

void hensach(int data[], int n)
{
    int i, x;
    double a = avg(data, n);
    double s = sd(data, n);

    printf("\n 点 : 偏差値\n");
    for (i = 0; i < n; i++)
        printf("%3d : %.1f\n", data[i], 50 + 10 * (data[i] - a) / s);
}

int main(void)
{
    int data[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};

    printf("avg : %.1f\n", avg(data, 10));
    printf("sd  : %.1f\n", sd(data, 10));
    hensach(data, 10);

    return EXIT_SUCCESS;
}

はい。

実行すると、

avg : 55.0
sd  : 28.7

 点 : 偏差値
 10 : 34.3
 20 : 37.8
 30 : 41.3
 40 : 44.8
 50 : 48.3
 60 : 51.7
 70 : 55.2
 80 : 58.7
 90 : 62.2
100 : 65.7

うは、懐かしい〜。ちなみに・・・僕の偏差値は・・・ごにょごにょ・・・東大生と同じ問題が解けるってのは楽しいっすね!!

(誤魔化してる)

バグ

全員おんなじ点数だと、ゼロ除算でエラーになります。