PyLearnST 05: 基本統計量によるデータ分析

データは複数の数字の集合で表されることが多いです。この数字の集合は、平均的に大きかったり、ばらついていたり、やたらと小さい数値があったり...、と、いろいろな特徴を備えています。しかし、単に「ばらついているね」だけだと、ただの主観でしかありません。統計学では、これらの特徴を具体的に数字で表します。このように、データの特徴が表された数字のことを、基本統計量(記述統計量、ヒストグラム特徴量など、いろいろな呼び方があります)と言います。ここでは、基本統計量をいくつか紹介し、pythonによる算出方法の例を示します。

PyLearnST04とまったく同じ乱数を生成します。Dat01(赤色)が勉強していなグループの試験得点、Dat02(青色)が勉強しているグループの試験得点です。それぞれ100人分、合計200人分のデータが格納されています。

In [1]:
import numpy as np
import matplotlib.pyplot as plt

# 毎回同じ乱数を生成するためのシード設定
np.random.seed(1)

# 乱数データの生成
Dat01=[]
Dat02=[]
for i in range(0,100):
    Dat01.append(np.random.normal(30, 10))
    Dat02.append(np.random.normal(60, 15))

# 個別の成績
fig1=plt.figure()
plt.plot(np.sort(Dat01), marker="o", label="Dat01", c="red", linewidth=0)
plt.plot(np.sort(Dat02), marker="s", label="Dat02", c="blue", linewidth=0)
plt.title("Academic Scores")
plt.ylabel("Academic Score")
plt.xlabel("Student ID")
plt.legend()
plt.grid(True)

# ヒストグラム    
fig2=plt.figure()
plt.hist(x=[Dat01, Dat02], bins=20, rwidth=0.9,
         color=['red', 'blue'], label=['Not studying group', 'Hard studying group'])
plt.xlabel("Academic Score")
plt.ylabel("Number of Students")
plt.title("histogram")
plt.legend()
plt.grid(True)

上のグラフは、100人分の試験得点をソートさせ、個別に結果を表示したものです。下はそれをヒストグラムにしたものになります。いずれの結果を見ても、勉強していないグループ(赤色)は勉強をしているグループ(青色)よりも点数が低いことがわかります。今回は、この2つのグループで、基本統計量を計算して見ます。算出する統計量は、以下の8つです。かなり定性的に書いています。

平均値(1次モーメント)

おなじみの指標です。それっぽく言うと、ランダムに数値を取り出したときに、最も出やすい値として定義されます。期待値とも言う場合があります。

分散・標準偏差(2次モーメント)

データが平均値からどれだけ離れているか、すなわち、データのばらつきを意味します。値が大きいほど平均値から離れているデータが多い(あるいは平均値から離れている距離が大きい)こと、小さいほどデータが平均値付近に集まっていることを意味します。最小値は0となります。分散がゼロになるときは、データがすべて平均値とまったく同じ値であることを意味しています。なお、標準偏差は分散に平方根をつけたもの、分散は標準偏差の2乗と言う関係があります。データに正規性を仮定すると、平均±標準偏差の間に約70%、平均±2標準偏差の間に約95%の確率でデータが発生します。したがって、(個人的には)標準偏差の方が解釈しやすいです。とはいえ、どちらも意味することは同じなので、好きな方を使ってください。

歪度(わいど)(3次モーメント)

データをヒストグラムとして描き下したとき、左右どちらに裾が長いかを示す尺度です。0のときは完全に左右対称、プラスのときは右に裾が長い、マイナスの場合は左に裾が長いヒストグラムであることを意味しています。

尖度(せんど)(4次モーメント)

データをヒストグラムにしたとき、どれだけ尖っているのかを表す尺度です。この値が大きいほど、ヒストグラムが尖っていることを意味します。

中央値

データをソートさせ、中央にくる値のことを指します。正規性のあるデータの場合は平均値と似たような値になりますが、そうではない場合は、平均値よりもこちらの方が妥当な代表値になることがあります。例えば、データが[0, 1, 2, 2, 2, 3, 3, 3, 3, 81]の平均値は10で、中央値は2となります。どちらが良いというのは人によって異なるでしょうが、中央値の2の方が全体をよく説明できているような気がします。

最小値

データの中で一番小さな値のことです。統計的に重要な値である場合もあれば、計測器の故障による除去すべきデータの可能性もあります。平均-3標準偏差、あるいは、平均-2標準偏差よりも小さな場合は、外れ値の可能性も検討してください。データに正規性を仮定した場合、平均-3標準偏差よりも外側にデータが発生する可能性は、わずか0.1%未満しかありません。0.1%の確率で起きた極めて重要な事象と捉えるか、計測器の故障のため起きた不適切な事象と捉えるかは、検討する必要があります。

最大値

データの中で一番大きな値のことです。最小値の場合と同様に、平均+2, 3標準偏差を超える値の場合は、外れ値として除去することも視野に入れてください。

実際にこれらをpythonを用いて算出して見ます。print関数の中に入れ込んであります。なお、歪度と尖度はscipyをインポートして求める必要があります。

In [2]:
import numpy as np
import scipy.stats as st

print("試験得点の基本統計量を算出します。")
print("Dat01: 勉強していないグループ, Dat02: 勉強したグループ")
print("平均値: Dat01=", np.mean(Dat01),   ", Dat02=", np.mean(Dat02))
print("分散: Dat01=", np.var(Dat01),      ", Dat02=", np.var(Dat02))
print("標準偏差: Dat01=", np.std(Dat01),  ", Dat02=", np.std(Dat02))
print("歪度: Dat01=", st.skew(Dat01),     ", Dat02=", st.skew(Dat02))
print("尖度: Dat01=", st.kurtosis(Dat01), ", Dat02=", st.kurtosis(Dat02))
print("中央値: Dat01=", np.median(Dat01), ", Dat02=", np.median(Dat02))
print("最小値: Dat01=", np.min(Dat01),    ", Dat02=", np.min(Dat02))
print("最大値: Dat01=", np.max(Dat01),    ", Dat02=", np.max(Dat02))
試験得点の基本統計量を算出します。
Dat01: 勉強していないグループ, Dat02: 勉強したグループ
平均値: Dat01= 32.266554447725944 , Dat02= 59.800832773849535
分散: Dat01= 73.80641763655905 , Dat02= 200.14182479191615
標準偏差: Dat01= 8.591066152495804 , Dat02= 14.147148998717592
歪度: Dat01= 0.15956311399919573 , Dat02= -0.2065723150414521
尖度: Dat01= -0.04457227426445476 , Dat02= -0.014072312613066629
中央値: Dat01= 32.141972277455764 , Dat02= 60.57158552645704
最小値: Dat01= 11.420181355532478 , Dat02= 23.477433538392916
最大値: Dat01= 55.28325706806398 , Dat02= 92.80469470461387
  • 平均値より、勉強した方が点数が高いことがわかります。
  • 分散・標準偏差より、勉強した方がばらつきが多いことを確認できます。勉強をすると、良い点数を取れる場合もあれば、悪い点数になる場合もある。勉強をしないと、安定して点数が低い、ということでしょうか。必ずしも勉強をすれば良いわけではないようです。
  • 歪度と尖度を見ると、いずれも0に近く似た値なので、大差はないようです。左右どちらかに偏っている傾向はなさそうです。
  • 中央値はほぼ平均値と一緒ですね。平均値と同じ解釈になります。
  • 最小値より、勉強しないと10点しか取れないようです。しかし、勉強したとしても最小値が23点となりました。効率が悪いとか、範囲外を勉強したとか、そういった理由かもしれません。
  • 最大値より、勉強しなかった場合は、一番良くても55点しか取れないことがわかりました。一方、勉強したグループでは最大で92点取っている人がいるようです。残りの8点分は異様に難しい問題が出たのかもしれません。

...などなど、基本統計量を求めることで、いろいろな考察ができるとともに、定性的(見た目の印象)ではなく、定量的(数字)で状況を把握することができるようになります。

ところで、基本統計量を報告する場合は、必ず四捨五入してくださいね。pythonの場合はroundを使用します。

In [3]:
print("平均値: Dat01=", round(np.mean(Dat01),3), ", Dat02=", round(np.mean(Dat02),3))
平均値: Dat01= 32.267 , Dat02= 59.801