前回の記事で「データのばらつきを表す指標」である散布度の必要性を説明しました.
散布度には前回の記事で説明した範囲と,四分位数を使ったIQR(四分位範囲)およびQD(四分位偏差)を解説しました.
これらはシンプルなんですが,全部のデータが指標の計算に使われていないという欠点がありました.
そこで,今回はこれらの欠点を補った散布度として以下を紹介します.特に分散と標準偏差は統計学において最重要事項の1つなので必ず押さえておきましょう!
- 平均偏差
- 分散
- 標準偏差
これらを1つずつ見ていきます.その後にPythonでの計算の仕方と,不偏分散について触れます.それではみていきましょう〜!
(追記)全16時間の統計学動画講座を公開しました!☆4.8の超高評価をいただいている講座です.こちらの記事に講座の内容とクーポン情報を書いていますので是非チェックしてください.
目次
平均偏差
前回の記事で紹介した範囲やIQR, QDは全てのデータが指標の計算に使われていないので,データ全体の散布度を示す値としては十分ではないという話をしました.全てのデータを使って散布度を求めようとした時,一番シンプルに思いつく方法はなんでしょうか?
データの「ばらつき」を表現したいのであれば,各値が平均からどれくらい離れているかを足し合わせた値が使えそうです.
「各値が平均からどれくらい離れているか」を偏差と呼び,偏差を普通に足し合わせると0になるという話は第2回でお話ししました.
それは当然,偏差\((x_i – \bar{x})\)が正になったり負になったりして,プラマイすると0になるからですね.散布度では正だろうと負だろうと「どれだけ離れているか」の絶対値に興味があるので.偏差の絶対値\(|x_i – \bar{x}|\)を足し合わせたら良さそうです.この偏差の絶対値の合計値をデータ数で割ってあげたら,散布度として使える指標になると思います.(ただ単に偏差の絶対値を合計しただけだと,データ数によって大小が変わってしまいますからね)
つまり「偏差の絶対値の平均」が散布度として使えます.この値を平均偏差(mean deviation)とか平均絶対偏差(mean absolute deviation)と呼び,よく\(MD\)で表します.
数式で表すと
$$MD=\frac{1}{n}{(|x_1-\bar{x}|+|x_2-\bar{x}|+\cdots+|x_n-\bar{x}|)}=\frac{1}{n}\sum_{i=1}^{n}{|x_i-\bar{x}|}$$
これだったらデータのばらつきを表すのにめちゃくちゃわかりやすいですよね?各データがばらついてたら当然それぞれの値の偏差の絶対値は大きくなるのでMDは大, 小さければMDは小となる.
全ての値が同じ値だった時にMDは0になります.その場合当然「ばらつき0」なわけです!
平均偏差の基準値して今回は平均を用いていますが,中央値を用いる場合もあります
これこそ「最強の散布度」と言えそうですが,,,
1つ問題があるんです....それは...
絶対値を含んでいること
MDに限らず,統計学では全体的に絶対値を避ける傾向があります.なぜかって?値の正負で計算が変わるから面倒なんです.
値が負の場合は,計算した値にマイナスを掛けないといけません.
じゃぁどうするか?→2乗する.2乗すれば値が正だろうが負だろうが正になりますからね!
この,偏差の絶対値をとる代わりに2乗したのが分散です.
分散と標準偏差
分散(variance)は,偏差の2乗の平均をとります.平均偏差では絶対値だったところを2乗にしているだけです.(上の平均偏差\(MD\)と見比べてみてください)
$$分散=\frac{1}{n}{((x_1-\bar{x})^2+(x_2-\bar{x})^2+\cdots+(x_n-\bar{x})^2)}=\frac{1}{n}\sum_{i=1}^{n}{(x_i-\bar{x})^2}$$
これでめんどくさい絶対値はなくなってめでたしめでたし
なんですが,,,2乗しちゃうと元の値の尺度とずれてしまう.(例えば平均の重さが10kgで,偏差が2kgだとしましょう.2乗すると4kgになってしまって,値の解釈がわかりにくくなってしまいますよね?)
尺度を合わせるために,分散の平方根をとれば良さそうですよね?分散の平方根をとったもの.それが標準偏差(standard deviation)です!標準偏差はstandard deviationの頭文字の\(s\)を使うことが多いです.(一般的に,母集団の標準偏差には\(\sigma\)(シグマ)を使い,標本の標準偏差には\(s\)を使います.)
$$s=\sqrt{\frac{1}{n}\sum_{i=1}^{n}{(x_i-\bar{x})^2}}$$
です.標準偏差\(s\)を二乗すると分散\(s^2\)になるということです.
標準偏差と分散は,最もよく用いられる散布度です.統計学の理論上非常に重要なのでしっかり押さえておきましょう!
Pythonを使って分散と標準偏差を求めよう!
こちらの記事でNumPyの .std() を使って標準偏差を求めましたね!NumPyの. std() 関数が本当に上の式になるか確認してみましょう!また,分散はNumPyの .var() 関数を使って同じように求めることができます.合わせて確認しましょう!
まず,分散を計算する関数を以下のようにStepByStepに書いてみます.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import numpy as np def get_variance(samples): # 平均を計算 mean = np.mean(samples) # 偏差を計算 deviations = samples - mean # 偏差を2乗 square_deviations = deviations * deviations # 偏差の2乗の合計 sum_square_deviations = np.sum(square_deviations) # 偏差の2乗の合計をデータ数で割る(分散) variance = sum_square_deviations/len(samples) return variance |
少し長いですが,やっていることはそんなに難しくありません.1つ1つ確認してみください.不安な人はJupyterLabを使って一行一行結果をみてみましょう!(Pythonが苦手という人は,DataScienceHubというコミュニティで毎週プログラミングの課題を出しています.コードレビュー もしていますので是非参加してコードの書き方を学んでください!)
試しに適当なリストで計算してみましょう
1 2 3 4 5 |
samples = [10, 10, 11, 14, 15, 15, 16, 18, 18, 19, 20] # 自作の関数で分散を計算 print(get_variance(samples)) # NumPyの関数で分散を計算 print(np.var(samples)) |
1 2 |
11.537190082644628 11.537190082644628 |
同じ値になりましたね.同様にして標準偏差もみてましょう!
1 2 3 4 |
# 自作の関数で分散を計算し,その分散をルートする print(np.sqrt(get_variance(samples))) # NumPyの関数で標準偏差を計算 print(np.std(samples)) |
1 2 |
3.3966439440489826 3.3966439440489826 |
同じ値になっているのがわかると思います.
NumPy以外にも,PandasやSciPyのstatsを使って計算することもできます.まずは scipy.stats からみてましょう.
SciPyでは,分散と標準偏差にはそれぞれ scipy.stats.tvar() と scipy.stats.tstd() という関数を使います.この’t’というのはtrimmedのtです.外れ値などに対応できるように,計算に使用する値の範囲を指定することができます(データの端をtrimするイメージですね!).今回はそのまま使います.
1 2 3 4 5 |
from scipy import stats # 分散を計算 print(stats.tvar(samples)) # 標準偏差を計算 print(stats.tstd(samples)) |
1 2 |
12.690909090909091 3.562430222602134 |
...あれ?値が違いますね?
上のNumPyの結果と比べてみてください.NumPyでは分散が11.5,標準偏差が3.4だったのに対し,SciPyでは分散が12.7,標準偏差が3.6と少し高い値になってます.
同じ分散と標準偏差なのに値が違うのはなんででしょう??
分散と不偏分散
実はこれは,SciPyのstatsモジュールのtvar()関数とtstd()関数は,不偏分散という値を分散の計算に使っているからです.
わかります.
不偏分散って聞いただけで難しそうな単語,もうイヤになりますよね??
大丈夫です.今回の記事ではそこまで扱いません!次回に丸投げします(爆)
ただ1つだけ言っておくと,不偏分散というのは,上の計算でnで割っていたところがn-1になります.つまり,
$$不偏分散=\frac{1}{n-1}{((x_1-\bar{x})^2+(x_2-\bar{x})^2+\cdots+(x_n-\bar{x})^2)}=\frac{1}{n-1}\sum_{i=1}^{n}{(x_i-\bar{x})^2}$$
ということです.
「えっなんで??」って思ったあなた.その反応は普通です.
今はなんでかわからなくてOKです.この辺りが初学者が最初に統計学を諦めてしまう難所だと思うので,次回の記事でちゃんと解説します.(だから,頑張って付いてきてください!)
scipy.stats.tvar() と scipy.stats.tstd() の結果が np.var() と np.std() より少し大きかったのは, n で割るところを n-1 で割っていたからなんですね. n で割った分散を計算するのか n-1 で割った分散を計算するのかは使うツールやライブラリによって異なります.ちなみにPandasでも不偏分散が計算されます.以下がコード例です.(分散は .var() , 標準偏差は .std() で求めることができます.)
1 2 3 4 5 |
import pandas as pd samples = [10, 10, 11, 14, 15, 15, 16, 18, 18, 19, 20] df = pd.DataFrame({'sample':samples}) print(df['sample'].var()) print(df['sample'].std()) |
1 2 |
12.690909090909093 3.5624302226021345 |
scipy.stats をお使った時と同じ結果になっているのがわかると思います.(Pandasの使い方についてはこの辺りで解説していますので,忘れている人は参考にしてくださいね!また,この辺りのライブラリを体系的に学習したい方は是非動画講座で学習ください!)
なぜscipy.statsとPandasではn-1で割った不偏分散が使われ,NumPyではnで割った分散が使われるのでしょうか?そもそもなぜ2種類あるのか?不偏分散とはなんなのか?
次の記事で詳しく解説していきたいと思います!
まとめ
今回は,散布度として平均偏差,分散,標準偏差を紹介しました.
これらは,前回の記事で紹介した範囲や四分位数を使ったIQRおよびQDと違って,原則全てのデータを計算に使用しているという特徴があります.
特に分散と標準偏差は統計学の理論上最重要項目の1つなので必ず押さえておきましょう!
- 平均偏差(\(MD\)):偏差の絶対値(\(|x_i-\bar{x}|\))の平均.絶対値の取り扱いが厄介
- 分散(\(s^2\)):偏差の2乗(\((x_i-\bar{x})^2\))の平均.平均偏差の「厄介な絶対値」を2乗することで解決.2乗したが故に尺度が変わってしまうのが厄介
- 標準偏差(\(s\)):分散の正の平方根(ルート)をとったもの.ルートをとることで分散で変わってしまった尺度を元に戻している
- np.var() および np.std() で分散と標準偏差を求めることができる
- scipy.stats.tvar()およびscipy.stats.tstd()で分散と標準偏差を求めることができるが,計算結果は不偏分散になる
- 不偏分散は分散の式においてnで割っていたところをn-1で割ったもの
少し長くなってしまいましたが,今回の内容は超超重要事項です.範囲→IQR/QD→MD→分散→標準偏差までのストーリーを押さえておくといいと思います.
それでは!!
追記)次回の記事はこちら!