Pythonで統計学入門―偏差値とは?Pythonで計算してみよう― | SiTest (サイテスト) ブログ

メニューボタン閉じるボタン

Pythonで統計学入門―偏差値とは?Pythonで計算してみよう―

統計学の考え方として「平均」の次くらいに馴染み深く、かつよくわからないものにテストの成績でおなじみの「偏差値」があります。今回は Python (3系)を使って、偏差値を求めてみます。

スポンサーリンク

偏差値とはなんだろう?―偏差値は100点満点とは全然関係ない

偏差値とは「その集団の中の平均をどれくらい上回っているか(下回っているか)を示した値」です。偏差値としてよく見かける値が大体30〜70くらいなので、100点満点のテストの点数と大きな関連がありそうですが、そうではありません。

例えば1000点満点で、平均点が500点であっても極端にできるひとや、できないひとが数多くいない限り、偏差値はおよそ30〜70くらいがよくみられる値となります。

「100点満点のテスト」から離れて考えるために、偏差値をちょっと違う数字で表現してみましょう。

偏差値において基準となる値は50ですが、これには必然性はありません。ですので、試しに基準となる値を0にしてみます。すると基準がずれるので偏差値40は、「-10」。偏差値65は「+15」となります。

さらに1〜30くらいの数でプラス・マイナスする必要もないので思い切って数字を1/10にして、偏差ポイントと呼んでみます(この記事以外では通用しない呼び方です)。偏差値40は、「-1偏差ポイント」。偏差値65は「+1.5偏差ポイント」となります。

では、偏差ポイントが「1ポイント増える(普通の偏差値でいうと10増える)」と具体的にテストの点数は何点増えるのでしょうか?あるいは1ポイント減ると具体的に何点減るのでしょうか?言い換えれば、1偏差ポイントには実際のテストにおける何点分の価値があるのでしょうか?

この値を求めることが偏差値の計算のほぼすべてといっても言い過ぎではありません。この1偏差ポイントのことを、ちゃんとした統計学の言葉では「標準偏差」といいます。

グラフを作ってデータの全体像をみてみる

では、Python をつかって、ある学年の国語のテスト成績から「標準偏差」を求め、最後にAさん(51点)の偏差値を求めてみましょう。

標準偏差を求めるには、学年全員のテストの点数を知る必要があります(一部だけを抽出するやり方もありますが、100人程度でしたら、全員分の点数で計算したほうがよいでしょう)。

まず、今回使うテストの点数を配列で表してみます。Aさんの学年は100人いるので以下のような感じになります。

scores = [62, 75, 82, 43, 81, 71, 56, 49, 54, 14, 79, 64, 76, 81, 51, 70, 82, 88, 62, 66, 100, 45, 53, 63, 60, 72, 90, 72, 22, 74, 55, 77, 100, 36, 54, 79, 64, 70, 84, 65, 47, 58, 32, 81, 77, 38, 71, 26, 68, 41, 44, 54, 67, 45, 34, 48, 51, 44, 89, 25, 98, 99, 39, 56, 57, 55, 57, 46, 56, 45, 55, 73, 29, 63, 68, 28, 45, 78, 70, 93, 36, 61, 52, 77, 81, 70, 55, 65, 82, 56, 76, 39, 61, 75, 66, 72, 55, 50, 56]

これだとよくわからないので、ちょっと横道にそれて、だいたいどれくらいの点数の生徒が多いのか、ヒストグラムというグラフにしてみます。

偏差値をもとめることがテーマなので説明は省きますが、matplotlib というライブラリを使うとデータからグラフを簡単に作成できます。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
mpl.rcParams['font.family'] = 'Kozuka Gothic Pr6N'

np_scores = np.array(scores)
plt.hist(np_scores)
plt.title('とある学年の国語の点数(ヒストグラム)')
plt.xlabel('点数')
plt.ylabel('人数')
plt.xticks( np.arange(0, 110, 5) )
plt.yticks( np.arange(0, 20, 2) )
plt.show()

50点前後の生徒が一番多く、次に多いのが、80点前後の生徒です。大体この間にほとんどの生徒が位置するようです。逆に0点や一桁の点数の生徒はいないようですね。

平均点と標準偏差をNumpyで求める

では、「標準偏差」を Python で求めるにあたり、まずは平均点を求めてみましょう

グラフを作るときにすでに使ってしまったのですが、統計関係の計算は Numpy というライブラリを使うと簡単にできます。様々な Python 環境に付いてくるので、もう入っているかもしれませんが、ない場合はインストールします。

pip install numpy

平均点を求めるソースは以下です。簡単ですね!

import numpy as np

scores = [62, 75, 82, 43, 81, 71, 56, 49, 54, 14, 79, 64, 76, 81, 51, 70, 82, 88, 62, 66, 100, 45, 53, 63, 60, 72, 90, 72, 22, 74, 55, 77, 100, 36, 54, 79, 64, 70, 84, 65, 47, 58, 32, 81, 77, 38, 71, 26, 68, 41, 44, 54, 67, 45, 34, 48, 51, 44, 89, 25, 98, 99, 39, 56, 57, 55, 57, 46, 56, 45, 55, 73, 29, 63, 68, 28, 45, 78, 70, 93, 36, 61, 52, 77, 81, 70, 55, 65, 82, 56, 76, 39, 61, 75, 66, 72, 55, 50, 56]

#通常の配列をより高性能なNumpy配列に変換します。
np_scores = np.array(scores)

#numpy.mean メソッドだけで算術平均(いわゆる平均)が求められます。
mean = np.mean(np_scores)

print(“とある学年の国語の平均点:"+str(mean))

出力は以下です

とあるクラス学年の国語の平均点:61.3737373737

高めの平均点ですね。
さらに標準偏差を求めてみます。実は Numpy をつかえば、実質1行で求めることができます。

#Numpy配列に変換するコードは省略します

#numpy.std メソッドだけで標準偏差が求められます。
std = np.std(np_scores)

print("とある学年の国語の標準偏差:"+str(std))
とある学年の国語の標準偏差:18.3576069932

というわけで、この学年のこの国語のテストでは、「標準偏差」、すなわち1偏差ポイントが約18点の価値を持っていることがわかりました。平均点が約61点なので、61点を取れば0偏差ポイント(偏差値50)です。

+1偏差ポイント(偏差値60)なら 61 + 18 = 79 なので約79点、-0.5偏差ポイント(偏差値45)なら 61- (18 ÷ 2) = 52で約52点 であることがわかります。

いよいよ、Pythonで偏差値をもとめます

では、いよいよAさん(51点)の偏差値を Pythonで求めてみましょう。偏差値を求めるには、すでに求めた平均と標準偏差、そして得点を偏差値のフォーマットに当てはめるだけです。
以下が完成版のコードです。

import numpy as np

scores = [62, 75, 82, 43, 81, 71, 56, 49, 54, 14, 79, 64, 76, 81, 51, 70, 82, 88, 62, 66, 100, 45, 53, 63, 60, 72, 90, 72, 22, 74, 55, 77, 100, 36, 54, 79, 64, 70, 84, 65, 47, 58, 32, 81, 77, 38, 71, 26, 68, 41, 44, 54, 67, 45, 34, 48, 51, 44, 89, 25, 98, 99, 39, 56, 57, 55, 57, 46, 56, 45, 55, 73, 29, 63, 68, 28, 45, 78, 70, 93, 36, 61, 52, 77, 81, 70, 55, 65, 82, 56, 76, 39, 61, 75, 66, 72, 55, 50, 56]

#通常の配列をより高性能なNumpy配列に変換します。
np_scores = np.array(scores)

#numpy.mean メソッドだけで算術平均(いわゆる平均)が求められます。
mean = np.mean(np_scores)
print("とある学年の国語の平均点:"+str(mean))

#numpy.std メソッドだけで標準偏差が求められます。
std = np.std(np_scores)
print("とある学年の国語の標準偏差:"+str(std))

#Aさんの得点
score_a = 51

#Aさんの得点、学年の平均と標準偏差を偏差値のフォーマットに当てはめて計算します。
#(得点 - 平均点) / 標準偏差  でAさんの「平均と比べて標準偏差いくつ分の差があるか」が求まります。
deviation = (score_a - mean) / std

#その値を10倍し、50を足すと「偏差値」になります。本文でも述べたように、
#これには「わかりやすくするため」以外の必然性はありません。
deviation_value = 50 + deviation * 10

print("Aさんの国語の点数:"+str(51))
print("Aさんの国語の偏差値:"+str(deviation_value))

出力結果

とある学年の国語の平均点:61.3737373737
とある学年の国語の標準偏差:18.3576069932
Aさんの国語の点数:51
Aさんの国語の偏差値:44.3490797152

さて、Aさんの偏差値が求まりました。51点取っているのに全体の平均点が高いため、真ん中を指す50よりも低くなっています。

今回、いちばん大事な「標準偏差」の意味や求め方については Python(Numpy) 任せにしてしまいました。きちんと知りたい場合は、統計学の本を読むのをおすすめします。下記の本がわかりやすかったです。

マンガでわかる統計学