中心極限定理が本当か試してみた


昔に本当か？と思ってやった内容です。
当時衝撃を受けたことをふと思い出したので記事にしてみました。


# 中心極限定理とは


> 中心極限定理とは、期待値 $\mu$、分散 $\sigma^2$ の任意の確率分布に従う母集団から$n$個の要素を無作為復元抽出したときの標本平均 $\overline{X_n}$の分布は、$n$が十分大きい時には正規分布$N(\mu,\frac{\sigma^2}{n})$へ近づいていく定理。

簡単に言うと、どんな母集団でもランダムサンプリングした値の平均は正規分布になるというものです。
これを聞いたとき本当にどんな母集団でも成り立つのか？と思った時がありました。


# 実験1. サイコロ（一様分布）

まずは簡単な分布で見てみます。

``` python
import random
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 分布
def sample():
    return random.choice([1, 2, 3, 4, 5, 6])

# 分布のグラフを可視化
x = []
for _ in range(1000):
    x.append(sample())
sns.histplot(x, kde=True)
plt.show()

print("平均", np.mean(x))
print("分散", np.var(x))
print("中心極限定理の予想分散", np.var(x) / 100)

# 中心極限定理
x = []
for _ in range(1000):
    # ランダムサンプリングした値の平均
    n = []
    for _ in range(100):
        n.append(sample())
    x.append(np.mean(n))
sns.histplot(x, kde=True)
plt.show()

print("平均", np.mean(x))
print("分散", np.var(x))
```

![output1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/eacc807c-01f2-0c38-aaf1-b84edd12ca67.png)


```
平均 3.458
分散 2.842236
中心極限定理の予想分散 0.02842236
```


![output2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/dd9b098e-5a1b-347d-e2f3-f77835be37d5.png)


```
平均 3.49769
分散 0.0301697639
```


見事に正規分布に近い形になっていますね。
以降は同じコードで sample 関数のみを変えていきます。



# 実験2. 正規分布+一様分布

２つの異なる分布を混ぜてみます。

``` python
def sample():
    if random.random() < 0.5:
        return np.random.normal(-5, 0.5, 1)[0]
    else:
        return np.random.randint(2, 10)
```

![output3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/eb5e8608-9af0-5fc6-a780-9b50efe019a4.png)

```
平均 1.2720335834082035
分散 20.963113365580693
中心極限定理の予想分散 0.20963113365580693
```

![output4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/388a9a50-d218-e8d3-db1f-1f9583504b9a.png)


```
平均 1.2417630631941023
分散 0.19920439968876935
```

かなり変な分布ですが、中心極限定理後は正規分布になっていますね。


# 実験3. 適当な分布

10%で1、30%で3、60%で7の値を取ります。
離散値のみの分布です。

``` python
def sample():
    r = random.random()
    if r < 0.1:
        return 1
    elif r < 0.4:
        return 3
    return 7
```

![output5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/d3164358-eef8-5fe7-2b77-8af1d0b17b48.png)


```
平均 5.084
分散 5.264944000000001
中心極限定理の予想分散 0.052649440000000006
```

![output6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/d9e197c0-4e69-fe2c-97cd-c765061cc078.png)


```
平均 5.206840000000001
分散 0.05042041440000001
```




# 実験4. 適当な分布２

正規分布ですが、-0.5～0は-10、0～1なら5を取る分布です。

``` python
def sample():
    n = np.random.normal(0, 2.0, 1)[0]
    if -0.5 < n < 0:
        return -10
    if 0 < n < 1:
        return 5
    return n
```

![output7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/7a89e18e-031f-23be-dfc2-215c529aa967.png)

```
平均 0.054707802397646575
分散 16.841994983744684
中心極限定理の予想分散 0.16841994983744685
```

![output8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/c4e98aec-bdbb-9374-54fc-a67b2251108d.png)


```
平均 -0.10518644858242933
分散 0.17155630468517633
```

かなり変な分布ですが中心極限定理後は正規分布っぽくなっていますね。


# 中心極限定理が成り立たない場合（コーシー分布）

どんな母集団でもといっていますが成り立たない場合があり、それは分布が平均と分散を持たない場合らしいです。
例えばコーシー分布は平均や分散を持たないので成り立たないらしいです。


``` python
rng = np.random.default_rng()
def sample():
    return rng.standard_cauchy(1)[0]
```

図は見やすいように-25～25の範囲に限定しています。
また少し時間がかかったのでサンプリング回数を1000×100回から100×100回に減らしています。

``` python
sns.histplot(x, kde=True)
plt.xlim(-25, 25)
plt.show()
```

![output9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/982a19e8-933e-8e03-c7e2-52de80776880.png)


```
平均 0.7673117788880744
分散 526.8258258406837
中心極限定理の予想分散 5.268258258406837
```

![output10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396150/f22c19cb-52bc-7555-ad4d-06341e7d38c9.png)


```
平均 -0.1085017568639298
分散 39.99723980324434
```

見た目は正規分布っぽいですが平均と分散の数字は全然違いますね。
確かに中心極限定理が成り立っていなそうです。


# 参考

[中心極限定理と大数の法則の関係は？二項分布でも得られた平均値が正規分布する？](https://best-biostatistics.com/hypo_test/clt.html)