平均偏差、分散、標準偏差

訳あって統計の勉強をしています。統計の基礎の基礎といえる標準偏差について Python で調べたので書きます。
[絶対にわかる分散と標準偏差(超重要)【統計学入門⑤】](https://datawokagaku.com/var_std/) を参考にしました。

本日のライブラリ:


```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```

例えばここに足のサイズのリスト footsize1 = `[25, 23, 24, 27, 26]` があるとします。この足のサイズのバラツキ加減を示す指標がいくつかあるので順に調べます。ようするに、バラつかず全部同じ値ならゼロで、バラければバラけるほど、つまり平均から離れれば離れるほど大きくなる数を考えれば良いという事です。また、平均からの距離が二倍になればバラツキも二倍になって欲しいです。

という事で、雰囲気を見るために足のサイズをグラフにしてみます。


```python
footsize1 = pd.Series([25, 23, 24, 27, 26])
footsize1.plot(figsize=(8,2), label='footsize1', legend=True)
plt.hlines(footsize1.mean(), 0, len(footsize1) - 1, linestyle='--');
```
![output_3_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35350/6dc44ed5-300a-1add-23fe-1742835114c4.png)

### 平均偏差

最も簡単なバラツキの指標は「平均偏差」です。平均偏差とは、単に偏差 (= 値の平均との差分) の絶対値をデータの個数で割った物です。するとこの例では 1.2 cm となりました。平均して 1.2 cm ほど値の中心から外れているという意味になります。


```python
np.mean(np.abs(footsize1 - np.mean(footsize1)))

def show_mean_deviation(samples):
    mean = np.mean(samples)
    print('平均:', mean)
    deviations = samples - mean
    print('偏差:', list(deviations))
    abs_deviations = np.abs(deviations)
    print('偏差の絶対値:', list(abs_deviations))
    mean_abs_deviations = np.mean(abs_deviations)
    print('平均偏差 = 偏差の絶対値の平均:', mean_abs_deviations)
    return mean_abs_deviations
show_mean_deviation(footsize1);
```

    平均: 25.0
    偏差: [0.0, -2.0, -1.0, 2.0, 1.0]
    偏差の絶対値: [0.0, 2.0, 1.0, 2.0, 1.0]
    平均偏差 = 偏差の絶対値の平均: 1.2


## 分散

平均偏差とは偏差の絶対値の平均でしたが、偏差の絶対値の代わりに偏差の二乗を平均したものが「分散」です。
なぜ二乗するかというと、正規分布と組み合わせると便利だからだそうですが、ここでは深入りしません。

二乗するので「分散」は「平均偏差」よりも偏差の大きい値の影響を受けやすいと言えます。numpy には `np.var()` という分散を計算する関数が用意されているので、検算に使います。

この場合分散は 2.0 という事になりました。


```python
def show_variance(samples):
    mean = np.mean(samples)
    print('平均:', mean)
    deviations = samples - mean
    print('偏差:', list(deviations))
    square_deviations = deviations ** 2
    print('偏差の二乗:', list(square_deviations))
    variance = np.mean(square_deviations)
    print('分散 = 偏差の二乗の平均:', variance)
    return variance

show_variance(footsize1)
print('np.var() で検算:', np.var(footsize1))
```

    平均: 25.0
    偏差: [0.0, -2.0, -1.0, 2.0, 1.0]
    偏差の二乗: [0.0, 4.0, 1.0, 4.0, 1.0]
    分散 = 偏差の二乗の平均: 2.0
    np.var() で検算: 2.0


### 標準偏差

分散はそれぞれの値を二乗して求めるので、単位を揃えるために平方根を取った物を「標準偏差」と言います。numpy で標準偏差を求める `np.std()` で検算します。

単位を揃える事によって、平均からの距離が二倍になれば標準偏差も二倍になります。
この場合 1.41 なので、足のサイズのバラツキ具合は 1.41 cm だという事になります。この数字の意味ですが、もしもバラツキが正規分布 (= もっともよくある分布) に従うと値の 68% がプラスマイナス 1.41 cm 以内に収まるという意味らしいです。


```python
def show_std_deviation(samples):
    variance = show_variance(samples)
    std = np.sqrt(variance)
    print('標準偏差 = 分散の平方根:', std)
    return std

show_std_deviation(footsize1)
print()
print('np.std() で検算:', np.std(footsize1))
```

    平均: 25.0
    偏差: [0.0, -2.0, -1.0, 2.0, 1.0]
    偏差の二乗: [0.0, 4.0, 1.0, 4.0, 1.0]
    分散 = 偏差の二乗の平均: 2.0
    標準偏差 = 分散の平方根: 1.4142135623730951
    
    np.std() で検算: 1.4142135623730951


試しにもう少しバラツキの小さな例で試します。先ほどの足のデータに比べてバラツキを半分にしたデータ footsize2 = `[25, 24, 24.5, 26, 25.5]`　(オレンジの線) を用意します。


```python
footsize2 = pd.Series([25, 24, 24.5, 26, 25.5])
footsize1.plot(figsize=(8,2), label='footsize1', legend=True)
footsize2.plot(figsize=(8,2), label='footsize2', legend=True)
plt.hlines(footsize1.mean(), 0, len(footsize2) - 1, linestyle='--', color='lightgray');
```

![output_11_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35350/f02db554-7923-2dfe-50ca-79e970b9bdf4.png)

確かに指標は小さくなります。footsize2 の平均偏差 (0.6 cm) と標準偏差 (0.7 cm) は footsize1 のピッタリ半分になりました。


```python
show_mean_deviation(footsize2)
print()
show_std_deviation(footsize2)
print()
print('np.std() で検算:', np.std(footsize2))
```

    平均: 25.0
    偏差: [0.0, -1.0, -0.5, 1.0, 0.5]
    偏差の絶対値: [0.0, 1.0, 0.5, 1.0, 0.5]
    平均偏差 = 偏差の絶対値の平均: 0.6
    
    平均: 25.0
    偏差: [0.0, -1.0, -0.5, 1.0, 0.5]
    偏差の二乗: [0.0, 1.0, 0.25, 1.0, 0.25]
    分散 = 偏差の二乗の平均: 0.5
    標準偏差 = 分散の平方根: 0.7071067811865476
    
    np.std() で検算: 0.7071067811865476