かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

R言語で偏差値って

はぁ…数学苦手…。

R言語って統計解析がお得意なんですって。

すべての数字を合計して数で割った平均と、ソートして真ん中の値を取り出す中央値くらいは知ってるけどそれ以上はちょっと…という感じですね。

平均と中央値を出す関数はmeanとmedianという関数として用意されてます。

x <- 1:100

print(mean(x)) # 平均
print(median((x))) # 中央値

んで、次に出てくるのが分散ってやつらしいです。分散って名前からわかる通り、どれくらい値が散らばってるの?というものらしい。求め方は、各値から平均値を引いて2乗して、要素数で割る。R的に書くとこんな感じ。

x <- 1:100

v <- sum((x - mean(x))^2) / length(x)
print(v)

実行するとこんな感じ。

[1] 833.25

個人的にはこれを見てもぱっとどれくらい分散してるのかわかんねーって思うのは修行が足りないからだろう。さて、この分散2乗したものを足し合わせてるんだから√とって2乗を打ち消してやろうという考えが出てくるみたいです。これを標準偏差というらしいです。

x <- 1:100

v <- sum((x - mean(x))^2) / length(x)
print(v)
s <- sqrt(v)
print(s)

実行するとこんな感じ。

[1] 833.25
[1] 28.86607

標準偏差くらいになってくると、それっぽい雰囲気を感じますね。因みに平均+-標準偏差の範囲には大体68%のデータが入るみたいです。

因みに分散を求める関数はvarで標準偏差を求める関数はsdっていうみたいです。

x <- 1:100

v <- sum((x - mean(x))^2) / length(x)
print(v)
s <- sqrt(v)
print(s)

print(var(x))
print(sd(x))

実行するとこんな感じ。

[1] 833.25
[1] 28.86607
[1] 841.6667
[1] 29.01149

自分で計算したのと値が違うのは、自分で手計算したのが標本分散っていうのに対して、関数が計算してくれるのが不偏分散っていうものらしいです。不偏ってついてるのはlength(x)で割るんじゃなくて、その値-1で割ってるところが違う。扱ってる数字の集合がこれで全部なんだ!ってときは標本分散とかのほうを使うけど、集合の一部ってときには不偏分散とかを使うみたい。なんでだろうね?分散の値が異なるから、それを元に計算する標準偏差も値が違うってわけみたいです。ある集合のすべての数字を使うことって少ないので、不偏分散のほうが使うことが多いらしい。

突然のz得点!

さて、標準偏差っていうのが出てきたところで、数値を平均0、標準偏差1に慣らしてしまおうという発想が出てくるらしいですね。やり方は数値から平均を引いて、標準偏差で割る。

x <- 1:100

z <- (x - mean(x)) / sd(x)
print(z) # z得点

# 平均と標準偏差を出してみる
print(mean(z))
print(sd(z))

実行するとこんな感じ。

  [1] -1.70622042 -1.67175132 -1.63728222 -1.60281312 -1.56834402 -1.53387492 -1.49940582 -1.46493672 -1.43046762 -1.39599852 -1.36152943 -1.32706033 -1.29259123
 [14] -1.25812213 -1.22365303 -1.18918393 -1.15471483 -1.12024573 -1.08577663 -1.05130753 -1.01683843 -0.98236933 -0.94790023 -0.91343113 -0.87896203 -0.84449293
 [27] -0.81002384 -0.77555474 -0.74108564 -0.70661654 -0.67214744 -0.63767834 -0.60320924 -0.56874014 -0.53427104 -0.49980194 -0.46533284 -0.43086374 -0.39639464
 [40] -0.36192554 -0.32745644 -0.29298734 -0.25851825 -0.22404915 -0.18958005 -0.15511095 -0.12064185 -0.08617275 -0.05170365 -0.01723455  0.01723455  0.05170365
 [53]  0.08617275  0.12064185  0.15511095  0.18958005  0.22404915  0.25851825  0.29298734  0.32745644  0.36192554  0.39639464  0.43086374  0.46533284  0.49980194
 [66]  0.53427104  0.56874014  0.60320924  0.63767834  0.67214744  0.70661654  0.74108564  0.77555474  0.81002384  0.84449293  0.87896203  0.91343113  0.94790023
 [79]  0.98236933  1.01683843  1.05130753  1.08577663  1.12024573  1.15471483  1.18918393  1.22365303  1.25812213  1.29259123  1.32706033  1.36152943  1.39599852
 [92]  1.43046762  1.46493672  1.49940582  1.53387492  1.56834402  1.60281312  1.63728222  1.67175132  1.70622042
[1] 0
[1] 1

平均が0になって標準偏差が1になってるのがわかります。

偏差値

偏差値って平均が50で標準偏差が10になるように慣らしたものらしいです。なのでz得点にちょちょいと細工すると偏差値になります。

x <- 1:100

z <- (x - mean(x)) / sd(x)
s <- 50 + z * 10
print(s)

print(mean(s))
print(sd(s))

実行するとこんな感じ。

  [1] 32.93780 33.28249 33.62718 33.97187 34.31656 34.66125 35.00594 35.35063 35.69532 36.04001 36.38471 36.72940 37.07409 37.41878 37.76347 38.10816 38.45285 38.79754
 [19] 39.14223 39.48692 39.83162 40.17631 40.52100 40.86569 41.21038 41.55507 41.89976 42.24445 42.58914 42.93383 43.27853 43.62322 43.96791 44.31260 44.65729 45.00198
 [37] 45.34667 45.69136 46.03605 46.38074 46.72544 47.07013 47.41482 47.75951 48.10420 48.44889 48.79358 49.13827 49.48296 49.82765 50.17235 50.51704 50.86173 51.20642
 [55] 51.55111 51.89580 52.24049 52.58518 52.92987 53.27456 53.61926 53.96395 54.30864 54.65333 54.99802 55.34271 55.68740 56.03209 56.37678 56.72147 57.06617 57.41086
 [73] 57.75555 58.10024 58.44493 58.78962 59.13431 59.47900 59.82369 60.16838 60.51308 60.85777 61.20246 61.54715 61.89184 62.23653 62.58122 62.92591 63.27060 63.61529
 [91] 63.95999 64.30468 64.64937 64.99406 65.33875 65.68344 66.02813 66.37282 66.71751 67.06220
[1] 50
[1] 10

ということでさっき平均+-標準偏差の間くらいには68%の人が入るって言ってたけど、偏差値40くらいでも68%の多数派なのでそんなに気にしなくてもいいのかしらとかというどうでもいいことが頭をよぎった。