東大の演習問題に挑戦(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
うは、懐かしい〜。ちなみに・・・僕の偏差値は・・・ごにょごにょ・・・東大生と同じ問題が解けるってのは楽しいっすね!!
(誤魔化してる)
バグ
全員おんなじ点数だと、ゼロ除算でエラーになります。