分散と不偏分散について
統計ばかりではなく、機械学習でもで分散や標準偏差は重要な指標になります。
PythonのライブラリでNumpyやPandasのメソッドを使うと簡単に分散や標準偏差の値を求めることができます。
NumpyとPandasで同じ名前の関数が用意されていますが、デフォルト値が違いますので注意が必要です。
これは分散には標本分散と不偏分散があり、それぞれ微妙に計算式が違うことが原因しています。
- 標本分散は標本=母数の時に使います
- 標本が母数の一部の場合は不偏分散を使います
Numpyはデフォルト値で標本分散が求まり、pandasでは不偏分散の値が求まるようになっています。
標本分散の公式
$$
s^2 = \frac{1}{n}\sum_{i=1}^{n} (x_i – \bar{x})^2
$$
不偏分散の公式
$$
s^2 = \frac{1}{n-1}\sum_{i=1}^{n} (x_i – \bar{x})^2
$$
不偏分散は標本の分散を求めるときに使います。
偏差の二乗の総和から個数を割る式の個数から1を引くだけなのですが、その計算で母数の分散が求まるためです。
これは標本分散が母数分散に比べて過小評価されるためです。
こちらの動画がわかりやすいです。標準偏差の疑問、なぜN-1で割るのかをついに解説!【これで、スッキリだぜ】
分散を求める関数
Numpyの分散を求める関数
- a:分散を求める配列
- ddof:初期値0 分散を計算する際、平均との偏差の2乗の和をN-ddofで割ります。初期値ではddof=0なのでデータ数であるNで割ることになる
Pandasの分散を求める関数
- ddof:初期値1 分散を計算する際、平均との偏差の2乗の和をN-ddofで割ります。初期値ではddof=1なのでデータ数である N-1 で割ることになる
サンプルコード
import numpy as np import pandas as pd list_ = [ 25, 30, 35, 40, 45, 48, 55, 58, 98, 100] data_np = np.array(list_) data_pd = pd.Series(list_) # numpyの分散を求める関数var()を活用 print(np.var(data_np)) # 615.64 # pandasの分散を求める関数var()を活用 print(data_pd.var()) # 684.0444444444444 # 不偏分散にする引数 ddof=0 print(np.var(data_np, ddof=1)) # 684.0444444444444 # 標本分散にする引数 ddof=0 print(data_pd.var(ddof=0)) # 615.64
標準偏差を求める関数
分散に不偏分散があるように、標準偏差にも不偏標準偏差があります。
Numpyのstd()
Parameters
a:標準偏差を求めたいデータ
ddof: int、デフォルト1
不偏標準偏差を求めたい場合はこれを使います。デフォルトでは、ddofはゼロで標準偏差が求まります。不偏標準偏差にしたい場合は1を指定します。
Pandasのstd()
ddof int、デフォルト1
標準偏差を求めたい場合はこれを使います。デフォルトでは、ddofは1で不偏標準偏差が求まります。標準偏差にしたい場合は0を指定します。
標準偏差の式
$$
s = \sqrt{\frac{1}{n}\displaystyle \sum_{ i = 1 }^{ n } (x_i-\overline{x})^2}
$$
不偏標準偏差の式
$$
S = \sqrt{\frac{1}{n-1}\displaystyle \sum_{ i = 1 }^{ n } (x_i-\overline{x})^2}
$$
標準偏差もNumpyとPandasではデフォルト値が違いますので注意しましょう。
# numpy std()は標本分散をもとにしている print(np.std(data_np)) # 24.812093825390875 # Pandas std()は不偏標準偏差 print(data_pd.std()) # 26.154243335345114 # numpy std()は標本分散をもとにしている print(np.std(data_np, ddof=1)) # 26.154243335345114 # ddof=0を指定すると標本分散をもとにする print(data_pd.std(ddof=0)) # 24.812093825390875 <h3>Pandas describe()メソッド</h3> Pandasの便利なdescribe()のstdの値は不偏標準偏差です。 data_pd.describe()
結果
count 10.000000
mean 53.400000
std 26.154243
min 25.000000
25% 36.250000
50% 46.500000
75% 57.250000
max 100.000000
dtype: float64