- ホーム
- コラム
- YDC Labコラム
- データ解析ならPythonが最高!第3回

データ解析ならPythonが最高!第3回
Lab研究員 北山
今回のテーマは分散と標準偏差です。
初回の記事「データ解析ならPythonが最高! 第1回」はこちら
前回の記事「データ解析ならPythonが最高! 第2回」はこちら
■統計量(分散、標準偏差)
分散、標準偏差
分散、標準偏差はバラツキの大小を表すパラメータです。
建物の高さを合計5回測量したところ、5回とも測量誤差により結果が異なりました。
前回は、5回の測量結果がいずれも10m前後なのだから、実際の建物の高さが12mだということはまずなさそうだという結論でした。
では、次の測量結果B(下図)ではどうでしょうか。
測量結果AもBも平均はほぼ同じ 9.9m ですが、測量結果Bでは真の建物の高さが 12m もありそうな気がします。測量値と平均との差が大きくバラついているからです。
平均というパラメータだけではデータの全体像を捉えられないということです。
バラツキの大小を表すパラメータとして「分散」や「標準偏差」が使われます。
標本値と平均の差を平均偏差、あるいは単に偏差といいます。
偏差の平方の総和をとったものが偏差平方和です。
偏差平方和を標本数で除したものが標本の分散、分散を平方根すると標準偏差です。
測量結果AとBの分散を比べてみると
測量結果Bの分散が大きいことが分かります。
測量誤差は、正規分布と呼ばれるものに従うと考えられています。
正規分布は、次のように母平均を中心とした左右対称にすそ野を広げた形状をもち、広がりの幅を母分散が決定します。
例えば、母分散が分かると、仮に建物の高さが 12m (次の上段グラフ)とすると、測定結果は中心から大きく外れており、このような測定結果が得られるとは考えにくく、一方で、真の建物の高さが 9.9m(下段グラフ)とすると、測量結果は分布の中心近辺にあり、このような測定結果でも不思議ではない、十分ありえそうだ、ということを判断できます。
不偏分散
分散の計算式は、標本数 n で割る式と n-1 で割る式の二種類を目にします。
Excelの分散の関数にも VAR.Pと VAR.S があります。
標本の分散を式(2)で計算すると、その期待値は母分散よりも小さくなることがわかっています。
なぜ、母分散より小さくなるかというと、式(2)は母平均ではなく標本平均との偏差で求めるからです。標本平均にはバラつきがあるため、標本平均のバラつきを考慮しないと、その分だけ分散が小さくなってしまいます。
式(3)を用いてn-1で割ると、分散の偏りを補正することができます。
偏りがないという意味で「不偏分散」と呼びます。
不偏分散を「標本分散」と呼ぶことがあります。
標本から母集団の分散を推定するときは不偏分散を用います。
NumPy の関数にも ddof という自由度を指定するオプションがありますので要注意です。
以降では説明しやすさを優先して n で割る分散と標準偏差を用いていますが、母数を推定するデータ解析では通常、n-1 で割る不偏分散を用いるので適宜読み替えてください。
スカラーからベクトルへ
次のテスト結果について
ベクトルの内積を用いて分散と標準偏差を求めます。
ベクトルの内積は
でした。自身との内積をとると
となり、内積で平方和を計算することができます。
これを用いて偏差平方和を求めます。
上式の a に偏差のベクトルをあてはめると
偏差平方和が求まります。
これより分散と標準偏差は
テスト結果の分散と標準偏差を計算すると
標準化
平均をゼロとし、バラツキのスケールを合わせるために標準偏差と分散が1となるように、次式で規格化することを標準化といいます。
ここで zi を標準得点といいます。
標準化のイメージは、平均が原点になるように平行移動(中心化)し、分散が1となるようにスケールを変更するということです。
例えば、20個の箱の寸法を計測した結果、
幅 (平均 6.9cm, 標準偏差 0.5)
高さ(平均 8.0cm, 標準偏差 2.0)
を、それぞれ標準化すると次のように縦長の楕円状であったバラツキが円状になります。
Pythonで分散、標準偏差と標準化
測量結果の分散と標準偏差を求めます。
ここまで説明が長くなりましたが、分散と標準偏差を求めるコードはたったの6行です。
import numpy as np
# 測量結果<
x = np.array([[9.7], [10.2], [9.4], [10.1], [10.1]])
# 標本数
n = x.shape[0]
# 平均
xbar = np.mean(x, axis=0)
# 分散
v = (x - xbar).T.dot(x - xbar) / n
# 標準偏差
= np.sqrt(S)
print(u'測量結果 A')
print(u'平均 %s' % xbar)
print(u'分散 %s' % v)
print(u'標準偏差 %s' % s)
(実行結果)
測量結果 A
平均 [ 9.9]
分散 [[ 0.092]]
標準偏差 [[ 0.303]]
次は偏差平方和を標本数 n で割り分散を求めています。
> # 分散
> v = (x - xbar).T.dot(x - xbar) / n
上のコードは次式と等価です。
分散の各要素の平方根をとると標準偏差です。
平方根は sqrt関数を使います。
> # 標準偏差
> s = np.sqrt(S)
標準化
平均と標準偏差から測量結果を標準化します。
(前のコードの続き)
# 標準化 z = (x - xbar) / s
print('標準得点')
print(z)
(実行結果)
標準得点
[[-0.659]
[ 0.989]
[-1.648]
[ 0.659]
[ 0.659]]
> # 標準化
> z = (x - xbar) / s
は次式と等価です。
分散、標準偏差、標準得点の関数
分散、標準偏差、標準得点はNumPyの関数で求めることができます。
ここでは不偏分散を求めます。このため前の実行結果とは結果が異なります。
import numpy as np
from scipy import stats
np.set_printoptions(precision=3)
# 測量結果A
x = np.array([[9.7], [10.2], [9.4], [10.1], [10.1]])
# 分散
v = np.var(x, axis=0, ddof=1)
# 標準偏差
s = np.std(x, axis=0, ddof=1)
# 標準得点
z = stats.zscore(x, axis=0, ddof=1)
print(u'分散 %s' % v)
print(u'標準偏差 %s' % s)
print('標準得点')
print(z)
(実行結果)
分散 [ 0.115]
標準偏差 [ 0.339]
標準得点
[[-0.59 ]
[ 0.885]
[-1.474]
[ 0.59 ]
[ 0.59 ]]