今回は、データ分布において、それぞれの値がどの程度散らばっているかを表す尺度について解説します。統計学の考え方と並行して、Pythonで計算する方法も説明していきます。
散らばりの尺度
統計学において散らばりの尺度として用いられる値の代表的なものは、「範囲」、「分散」、「標準偏差」、「絶対偏差」、「変動係数」が挙げられます。順に説明していきます。
範囲
範囲は、データ分布の最小値と最大値がどれくらい離れているか、という値です。つまり、最大値と最小値の差なので、説明するまでもないかもしれませんが下記の式で求めます。
[mathjax] $$最大値 – 最小値$$
Pythonで計算する場合、NumPyを使えば最小値と最大値を取り出すメソッドがあるので簡単です。
import numpy as np
data = np.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
x = data.max() - data.min()
print(x)
# 実行結果
80
分散
分散は、平均と各データを比較した差の平均がどの程度かを表す尺度です。ただし、気をつける点が2つあります。
まず、平均と各データを比較しているためそのまま差の平均を取るとプラスとマイナスが相殺されて必ず0 になってしまいます。そのため、平均と各データの差分を2乗した上で、その平均を計算した値となります。
次に、平均と各データの差分を平均する際に、対象としているデータが母集団なのか標本なのかで、差の合計値をいくつで割るかが変わります。母集団と標本という言葉は重要なので、ここで説明しておきます。
母集団
母集団とは、データ分析を行う時に、調査対象となる全てのデータを指します。例えば、全国の高校生が調査対象である場合、文字通り全国の高校生が母集団となります。
母集団の場合、分散を計算する場合は差分の合計をそのまま、母集団のデータの数で割ります。これは共分散とも呼ばれ、下記の式で計算します。
[mathjax] $$σ^2 = \frac{1}{n}\sum_{i=1}^{n}(x_1 – \bar{x})^2$$
また、母集団の分散はσ(シグマ)二乗で表します。
標本
標本は、母集団からいくつかの値を取り出した集まりを指します。もしも全国の高校生が調査対象である場合、その中から1000人の高校生をランダムに取り出したものが標本です。例えば、全国の労働者の平均年収を調査しようとした時、本当に全国の労働者のデータを収集するのはおそらく不可能でしょう。そのため、統計学を用いてデータ分析を行う場合には、標本をもとに行うことがほとんどです。
標本から分散を計算する場合は、差分の合計を標本の数から1を引いた値で割ります。これは、各データの差分を計算する際に用いる平均が標本の平均、つまり母集団の一部の平均でしかないことに起因します。標本の平均から計算した差分は、母集団の平均から計算した差分よりも小さくなることが多いため、1を引いて計算すると平均的に調整されることが知られています。これは不偏分散と呼ばれ、以下の式で求めます。
[mathjax] $$s^2 = \frac{1}{n-1}\sum_{i=1}^{n}(x_1 – \bar{x})^2$$
標本の分散は、s(エス)二乗で表します。
では、それぞれの分散をPythonで計算します。分散はndarray.varで求めることができます。標本の場合はパラメータddofに1を渡していることに注意してください。
import numpy as np
data = np.array([1, 7, 6, 3, 7])
# 母集団の場合
x1 = data.var()
print('母集団である場合 = ' + str(x1))
# 標本の場合
x2 = data.var(ddof=1)
print('標本である場合 = ' + str(x2))
実行すると下記の結果が表示されます。
母集団である場合 = 5.76
標本である場合 = 7.2
標準偏差
先ほどのプログラムを使って、人間の身長の分散を計算してみましょう。例えば150cm, 172cm, 169cm, 154cmの身長の標本を計算すると、分散は118.35になるはずです。身長の散らばりが118.25と言われても、いまいちピンとこないですよね。これは、分散が平均との差を二乗しているからです。もちろん、単位もcmとは言えません。分散には、その大きさを捉えづらいという欠点があります。そのため、統計学では分散の平方根である標準偏差という尺度も用いられます。標準偏差は下記の式で求めます。
[mathjax] $$s = \sqrt{s^2} = \sqrt{\frac{1}{n – 1}\sum_{i=1}^{n}(x_i – \bar{x})^2}$$
また、対象が母集団の場合も分散の平方根なので、下記の式で求めます。
[mathjax] $$σ = \sqrt{σ^2} = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(x_i – \bar{x})^2}$$
Pythonで実装する場合、ndarray.varで求めた分散の平方根を計算しても良いですが、そのまま標準偏差を計算することができるndarray.stdも用意されています。
import numpy as np
data = np.array([6, 4, 1, 9, 8])
# 標本の場合
x1 = data.std(ddof=1)
print('標本である場合 = ' + str(x1))
# 母集団の場合
x2 = data.std()
print('母集団である場合 = ' + str(x2))
引数はndarray.varと同じく、標本の場合はddof=1を渡します。実行すると下記の結果が出力されます。
標本である場合 = 3.2093613071762426
母集団である場合 = 2.870540018881465
平均絶対偏差
標準偏差は、計算の中で平均と各データの差分を二乗しています。そのため、平均との差が大きい値が存在するデータ分布が1つでも存在すると、その影響を大きく受け流という欠点があります。こういったケースでは、平均との差分の絶対値の平均から求める平均絶対偏差が適しています。
標本の場合は、下記の式で求めます。
[mathjax] $$s_a = \frac{1}{n – 1}\sum_{i=1}^{n}|x_i – \bar{x}| $$
母集団の場合は、下記の式で求めます。
[mathjax] $$σ_a = \frac{1}{n}\sum_{i=1}^{n}|x_i – \bar{x}| $$
では、Pythonで平均絶対偏差を計算します。ただ、NumPyには平均絶対偏差を計算する関数が用意されていません。そこで、NumPyの機能であるブロードキャストを使います。ブロードキャストとは、配列と配列同士の計算を、よしなに実行してくれる賢い機能です。例えば、[10]と[1, 2]を掛けると、[10, 20]という配列を返してくれます。
import numpy as np
data = np.array([6, 4, 1, 9, 8])
# ブロードキャストで平均との差の絶対値を求める
data_abs = abs(np.array([data.mean()]) - data)
# 偏差の絶対値合計を求める
data_abs_sum = sum(data_abs)
# 標本の場合
x1 = data_abs_sum / (len(data) - 1)
print('標本である場合 = ' + str(x1))
# 母集団の場合
x2 = data_abs_sum / (len(data))
print('母集団である場合 = ' + str(x2))
これを実行すると、以下の結果が出力されます。
標本である場合 = 3.1
母集団である場合 = 2.48
変動係数
例えば、標準偏差を用いて、人間の体重の散らばりと、アリの体重の散らばり、どちらが大きいか比較可能でしょうか。人間の平均体重とアリの平均体重には、大きな差があるため、おそらく難しいでしょう。そこで、平均を1として、どの程度散らばっているかを表す値として、変動係数があります。変動係数は、標準偏差を平均で割って求めます。
標本の場合は
[mathjax] $$CV_s = \frac{s}{\bar{x}}$$
母集団の場合は
[mathjax] $$CV_σ = \frac{σ}{\bar{x}}$$
で、それぞれ求めます。
では、Pythonで計算してみましょう。
import numpy as np
data = np.array([3, 2, 4, 5, 6])
# 標本の場合
x1 = data.std(ddof=1) / data.mean()
print('標本である場合 = ' + str(x1))
# 母集団の場合
x2 = data.std() / data.mean()
print('母集団である場合 = ' + str(x2))
実行すると、下記の結果が出力されます。
標本である場合 = 0.39528470752104744
母集団である場合 = 0.3535533905932738
今回のまとめ
今回は代表的な散らばりの尺度である「範囲」、「分散」、「標準偏差」、「平均絶対偏差」、「変動係数」について、それぞれの特徴と、Pythonでの計算方法を見ていきました。それぞれ適している場面や欠点が異なるため、うまく使い分ける必要があります。
次回からは、データ分布をより視覚的に捉えるための図について、Pythonで表示する方法と共に説明していこうと思います。
コメント