データアナリストのメモ帳

データアナリストのメモ帳

IT企業で働くデータアナリストのブログ

中心極限定理の気持ちをPythonで表現してみる

中心極限定理の気持ちをPythonで書いてみます。 中心極限定理とは、独立同分布に従う確率変数列の部分和は正規分布に分布収束するという定理です。 言い換えると、標本サイズが大きくなるに従って、標本平均は正規分布に近づくと解釈できます。

ここで、サイコロを例に考えると、𝑛 個のサイコロの出目の平均値の分布を求めると、𝑛 が大きくなるに従ってサイコロの出目の平均の分布が正規分布っぽくなる、ということです。実際にPythonで書いてみます。

サイコロ2個を10,000回投げる

まずはサイコロ2個を10,000回投げる操作を考えましょう。
このとき、2個の出目の平均値(2と3なら2.5、6と6なら6、...)を記録しておき、10,000個の平均値をヒストグラムにします。

from scipy import stats
import numpy as np
import pandas as pd
import random

# 2個のサイコロを10,000回振る
# 2個の出目の平均値(2と3なら2.5、6と6なら6、...)を記録しておき、10,000個の平均値をヒストグラムにする
n = 2

avg_dice_value = []
for k in range(10000):
    dice_value = []
    for i in range(n):
        dice_value.append(random.randint(1,6))
    avg_dice_value.append(np.mean(dice_value))

pd.DataFrame(avg_dice_value).rename(columns={0: 'Avg. Dice Value Distribution'}).hist(bins=100)

結果はこんな感じ。まあ...正規分布っぽくはないかな?

サイコロ3個を10,000回投げる

次に、サイコロの数を3個に増やします。

# 3個のサイコロを10,000回振る
n = 3

avg_dice_value = []
for k in range(10000):
    dice_value = []
    for i in range(n):
        dice_value.append(random.randint(1,6))
    avg_dice_value.append(np.mean(dice_value))

pd.DataFrame(avg_dice_value).rename(columns={0: 'Avg. Dice Value Distribution'}).hist(bins=100)

結果、ちょっと正規分布っぽさが増しました。

サイコロ4個を10,000回投げる

サイコロが4個の場合。

# 4個のサイコロを10,000回振る
n = 4

avg_dice_value = []
for k in range(10000):
    dice_value = []
    for i in range(n):
        dice_value.append(random.randint(1,6))
    avg_dice_value.append(np.mean(dice_value))

pd.DataFrame(avg_dice_value).rename(columns={0: 'Avg. Dice Value Distribution'}).hist(bins=100)

おお、かなり正規分布っぽいぞ!

サイコロ5個を10,000回投げる

# 5個のサイコロを10,000回振る
n = 5

avg_dice_value = []
for k in range(10000):
    dice_value = []
    for i in range(n):
        dice_value.append(random.randint(1,6))
    avg_dice_value.append(np.mean(dice_value))

pd.DataFrame(avg_dice_value).rename(columns={0: 'Avg. Dice Value Distribution'}).hist(bins=100)

5個まで増やすとかなり正規分布に近い。

サイコロ10個を10,000回投げる

最後にサイコロを10個に増やします。

# 10個のサイコロを10,000回振る
n = 10

avg_dice_value = []
for k in range(10000):
    dice_value = []
    for i in range(n):
        dice_value.append(random.randint(1,6))
    avg_dice_value.append(np.mean(dice_value))

pd.DataFrame(avg_dice_value).rename(columns={0: 'Avg. Dice Value Distribution'}).hist(bins=100)

もうほとんど正規分布に見えます。

まとめ

𝑛 個のサイコロの出目の平均値の分布をPythonで描いてみました。 サイコロ2個だと正規分布に似ているとは言えませんでしたが、2個から3個, 4個, ...と増やしていくと、だんだん正規分布に近づいていく様子がわかりました。たった10個まで増やしただけで、かなり正規分布に近い分布になったのはちょっと驚きでしたね。