【架け橋】大数の法則:「偶然」が「必然」に変わるとき

Python

私たちは以前の記事(確率②)で、シミュレーションを通じて「確率が収束する瞬間」を目撃しました。
サイコロを1万回も振れば、出目の比率は理論値である \(\displaytyle \frac{1}{6}\) へと吸い寄せられるように近づいていく。
それは言わば、無秩序な偶然の中に、揺るぎない正解が浮かび上がるかのような体験だったかと思います。

しかし、敢えて問いたい、その正解に「根拠」はあったでしょうか?と。

「なぜ100回では不十分なのか?」
「なぜ1万回なら信頼できると言えるのか?」
「一体あと何回繰り返せば、誤差は消えてなくなるのか?」

これまでは「とりあえずたくさん回せば確率は収束していく」という感覚に頼らざるをえませんでしたが、今や私たちは「正解の試行回数」を予測するためのツールを手にしています。
それが、前回記事(統計②)で学んだ「標準偏差」です。

本記事では、偶然に支配された個々の事象が、数の力によって必然的なルールへと昇華していく「大数の法則」の深層に迫ります。
単なるシミュレーションの結果を眺める段階を卒業し、「どれほどのデータがあれば真実に辿り着けるか」を論理的に導き出す、予測の科学への第一歩を踏み出しましょう。

第1章:1万回振れば「正解」に辿り着く……のか?

以前の記事(確率②)でサイコロを1万回振る実験を行った結果、各出目の確率は \(0.166\dots\) (理論値 \(\displaytyle \frac{1}{6}\))に肉薄しました。
この現象を目の当たりにして、「回数を増やせば正解に近づく」という事実に疑いを持つ人はいないでしょう。

しかし、データ分析の現場やビジネスの意思決定において、「とにかくたくさんデータを集めろ」などという曖昧あいまいで無責任な指示を出すわけにはいかないですよね。

1.1. 「1万回」という数字の根拠

もし、あなたが「この新商品の購入率は \(\displaytyle \frac{1}{6}\) です」と上司に報告するとしましょう。
その根拠を問われたとき、どう答えるでしょうか。

  • 「100回試しました」
    • 「たった100回で何がわかる?」と一蹴されるかもしれません。
  • 「1,000万回試しました」
    • 「そんなにコストと時間をかけていられない!」と怒られるかもしれません。

本当に知りたいのは、「100回では足りない」、「1万回やれば十分だろう」といった当てずっぽうな憶測ではなく、「誤差を ±1% 以内に抑えるために、最低限必要な回数は何回か?」という論理的裏付けのある推測です。

1.2. 偶然を「過去の集計」から「未来の推測」へ

これまでの連載では、起きたことの結果をまとめる方法(記述統計)を学びました。

  • 第5回:平均・中央値でデータの中心を捉える
  • 第6回:標準偏差でデータのバラつきを測る

そして第7回目となる本記事は、この「標準偏差」という武器をひっくり返して使います。

「データがこれくらいバラついている(標準偏差)のなら、この程度の回数を集めれば、平均値の振れ幅をここまで抑え込めるはずだ」という考え方です。

このように、「試行回数」と「バラつきの抑制」の関係性を解き明かすことが、大数の法則を「過去の現象の収集」から「強力な予測ツール」へと進化させる鍵となります。

第2章:バラつきを抑え込む「ルート \(n\)」のマジック

サイコロを振れば振るほど確率は理論値へと近づいていきますが、ここで不思議なことが起きています。

サイコロを10回振ったときも、1万回振ったときも、「1回ごとの出目のバラつき(標準偏差)」自体は変わりません。
1が出ることもあれば6が出ることもある、その予測不能な暴れっぷりは同じです。

それなのに、なぜ「平均値」だけは、回数を重ねるごとに動かなくなっていくのでしょうか?

2.1. 打ち消し合う「偏差」

試行回数を増やすことで平均値が理論値に近づいていく秘密は、「偏差(ズレ)の打ち消し合い」にあります。

  • 試行回数が少ないとき:
    • たまたま「1」が連続して出ると、平均値は大きくマイナスに偏ります。これを引き戻すだけの「逆方向のデータ」がまだ足りないからです。
  • 試行回数が多いとき:
    • プラスに大きくズレるデータが出ても、膨大な試行の中では同じくらいマイナスにズレるデータも現れます。回数が増えるほど、これらがお互いを引っ張り合い、結果として平均値へと収束されていくのです。

2.2. 精度を支配する公式

この「凝縮のスピード」を数学的に表したのが、統計学において非常に重要な次の式です。

\(\displaystyle SE = \frac{\sigma}{\sqrt{n}}\)

  • SE: 標準誤差
  • \(\sigma\)(シグマ): 個々のデータの標準偏差
  • \(n\): 試行回数

この数式が教えてくれるのは、「平均値の安定感は、試行回数の『ルート(平方根)』に比例して高まっていく」という事実です。

2.3. 「ルート」が意味する現実的な代償

2.2. の公式で注目すべきは、分母がただの \(n\) ではなく \(\sqrt{n}\) である点です。

  • 精度(安定感)を2倍にしたければ、データ量は \(2^2 =\) 4倍必要。
  • 精度を10倍にしたければ、データ量は \(10^2 =\) 100倍必要。

つまり、データの信頼性を高めるためには、私たちが思うよりも「ずっと多くの追加データ」が必要になるということです。
これが、データ分析の世界における「コストと精度の等価交換」のルールです。

精度が欲しくばコストを差し出せ

このような恐ろしいことを言っているわけですが、プログラミングを使えば、膨大な試行にかかる時間的コストは劇的に削減できます。
次章では、この「ルート \(n\)」の魔法によって、実際にどれくらいの試行回数でバラつきが消えていくのか、Pythonで可視化してみましょう。

第3章:Pythonで「収束のタイミング」を可視化する

さて、ここからが本題です。
「回数を増やすほど平均値が安定する」という大数の法則を、単なる数値ではなく「動き」として捉えてみましょう。

3.1. プログラムの設計:何を描画するのか

今回作成するプログラムの目的は、「数学的な予測範囲」「実際のデータの挙動」を重ね合わせることです。

  1. 標本平均の計算 (np.cumsum): 1回目から1,000回目まで、その都度「現時点での平均値」を算出します。
  2. 標準誤差(\(SE\))の算出: 第2章で示した公式 \(\displaystyle SE = \frac{\sigma}{\sqrt{n}}\) に基づき、各試行回数において「理論上、平均値がどれくらいの範囲に収まるべきか」を計算します。
  3. 可視化: 実際の平均値を「折れ線」で、理論上の範囲(\(\pm 1 SE\))を「塗りつぶされた帯」として描画します。

これらを重ね合わせることで、「何回の試行で、バラつきが許容範囲に収まるのか」というタイミングを視覚的に突き止めます。

3.2. Python による実装

新規Pythonファイル convergence_sim.py を作成し、以下のプログラムをコーディングします。

見出し
import numpy as np
import matplotlib.pyplot as plt

# 試行回数
n_trials = 1000
# サイコロの出目(1~6)
dice_faces = np.array([1, 2, 3, 4, 5, 6])

# 1. 理論値の計算
true_mean = np.mean(dice_faces) # 3.5
true_std = np.std(dice_faces)   # 約1.707

# 2. サイコロをn回振るシミュレーション
# 再現性を確保したい場合は np.random.seed(42) を追加
rolls = np.random.choice(dice_faces, size=n_trials)

# 3. 1回目からn回目までの「その時点での平均値」を計算
# np.cumsum は [a, a+b, a+b+c...] と累積和を出す関数
sample_means = np.cumsum(rolls) / np.arange(1, n_trials + 1)

# 4. 理論上の標準誤差 (SE = sigma / sqrt(n)) を計算
n_range = np.arange(1, n_trials + 1)
standard_error = true_std / np.sqrt(n_range)

# 5. グラフ描画
plt.figure(figsize=(10, 6))
plt.plot(n_range, sample_means, label="Sample Mean (Actual)", color="blue", alpha=0.8)
plt.axhline(true_mean, color="red", linestyle="--", label="True Mean (3.5)")

# 収束の境界線(±1 SEの範囲)を塗りつぶす
plt.fill_between(n_range, 
                 true_mean - standard_error, 
                 true_mean + standard_error, 
                 color='gray', alpha=0.2, label="Expected Variation (±1 SE)")

plt.title("Law of Large Numbers: Convergence Timing")
plt.xlabel("Number of Trials (n)")
plt.ylabel("Mean Value")
plt.legend()
plt.grid(True)
plt.show()

3.3. 実行結果の分析

プログラムを実行すると、以下のようなグラフが表示されます。

実行結果

このグラフが教えてくれる情報を読み解いてみましょう。
英語ラベルの日本語訳と、それぞれの簡単な説明を添えておきます。

  • Sample Mean (Actual)(青線)実際の標本平均。サイコロを振るたびに更新される、生の結果です。
  • True Mean(赤点線)理論上の平均値。サイコロなら3.5という、動かしようのない「真理」の線です。
  • Expected Variation (±1 SE)(グレーの帯)想定されるバラつきの範囲。数学が導き出した「平均値はこの枠内に収まりやすくなるはずだ」という予測範囲です。

グラフを分析することで、重要なポイントが浮かび上がります。

  1. 序盤の「暴れ」と「急降下」
    • \(n=100\) くらいまでは、青い線が枠を大きくはみ出したり、逆に枠の形に沿って急激に 3.5 へ吸い寄せられたりしています。データの少なさが「不確実性」として牙を剥いている状態です。
  2. \(n=400\) 付近の安定
    • このあたりから、青い線がグレーの帯の中にほぼ完全に収まり、かつ帯自体も非常に細くなっているのが読み取れます。
  3. 後半の「伸び悩み」
    • \(n=600\) 以降をよく見ると、帯の細さはそれほど変わっていません。
    • ここからさらに線を真っ直ぐにするには、数百回振った程度では足りないことを示唆しています。

3.4. プログラムコードのポイント解説

このグラフの動きを支えている技術的なポイントは次の2つです。

  • np.cumsum(rolls) / n_range:
    • 「合計値を、その時の回数で割る」という処理を一気に行うことで、1回目から1,000回目までの「進化のプロセス」を配列として保持しています。
  • true_std / np.sqrt(n_range):
    • 第2章の公式を忠実に再現しています。分母が \(\sqrt{n}\) なので、回数が少ないうちは急激に小さくなり、回数が増えると減少が緩やかになるという「ルートの特性」が、あのグレーの帯の形(漏斗のような形)を作っています。

第4章:「必要十分なデータ量」を逆算する

グラフを見ると、400回、600回と回数を増やすほど平均値が安定していくのが分かりました。
しかし、実務では「誤差をあと半分にしたい。そのためには何回追加で振ればいいのか?」という具体的な数字が求められますし、我々が本当に知りたいのもそこではないでしょうか。

本章では、第2章の公式を使い、「目標の精度」から「必要な回数」を逆算によって予測してみましょう。

4.1. 推定の根拠:母集団の「分散」と「標準偏差」

論理的な設計を行うには、対象となるデータの「真のバラつき」を知る必要があります。
サイコロ(1〜6の目が等確率で出る母集団)の場合、分散標準偏差は計算によって一意に定まります。

念のため、前回記事の復習も兼ねて説明しておきましょう。

分散(\(\sigma^2\))とは、「各データの値と母平均の差(偏差)」を2乗し、その平均をとったものです。

サイコロの例で標準偏差までを計算すると、手順は以下のようになります。

  1. 母平均(\(\mu\)): \((1+2+3+4+5+6) \div 6 = 3.5\)
  2. 各データの偏差の2乗:
    • \((1 – 3.5)^2 = 6.25\)
    • \((2 – 3.5)^2 = 2.25\)
    • \((3 – 3.5)^2 = 0.25\)
    • \((4 – 3.5)^2 = 0.25\)
    • \((5 – 3.5)^2 = 2.25\)
    • \((6 – 3.5)^2 = 6.25\)
  3. 分散(\(\sigma^2\)): これらを合計して6で割ると、約 2.917 となります。
  4. 標準偏差(\(\sigma\)): 分散の正の平方根をとると、\(\sqrt{2.917} \approx 1.708\) です。

4.2. 逆算の数式:\(n\) を求める

標準誤差の公式 \(\displaystyle SE = \frac{\sigma}{\sqrt{n}}\) を、\(n\)(試行回数)を求める形に変形すると、次のようになります。

\(\displaystyle n = \left( \frac{\sigma}{SE} \right)^2\)

  • SE: 標準誤差
  • \(\sigma\)(シグマ): 個々のデータの標準偏差
  • \(n\): 試行回数

この式は、どれくらいのズレ(標準誤差:\(SE\))まで許容するか」を決めれば、必要な試行回数 \(n\) が自動的に決まることを意味しています。

4.3. 実践:標準誤差を「0.1以内」に抑えたい場合

サイコロの例で考えてみましょう。
理論上の平均 3.5 に対し、標準誤差(\(SE\))を 0.1以内 に抑えて、ほぼ確実に 3.4 ~ 3.6 の間に着地させたいとします。

  • サイコロの標準偏差 \(\sigma\) :約 1.707
  • 許容する \(SE\) :0.1

これを式に当てはめると次の計算になります。

\(\displaystyle n = \left( \frac{1.707}{0.1} \right)^2\)

\( = (17.07)^2 \approx 291.4\)

つまり、「約 292 回以上振れば、標本誤差は 0.1 の枠内に収まる」と論理的に推定できるのです。

4.4. Python による実装

この推定が妥当であるか、プログラムで検証しましょう。

新規Pythonファイル verification_sim.py を作成し、以下のプログラムをコーディングします。
計算で導いた「292回」の地点に、検証用の境界線を引き込めるでしょうか。

verification_sim.py
import numpy as np
import matplotlib.pyplot as plt

# --- 1. 設定と推定 ---
n_trials = 1000
dice_faces = np.array([1, 2, 3, 4, 5, 6])
true_mean = 3.5
true_std = 1.708  # 母集団の標準偏差(sigma)

target_se = 0.1   # 目標とする標本誤差(SE)
# 必要な試行回数を逆算 (n = (sigma / SE)^2)
required_n = (true_std / target_se)**2

print(f"論理的推定:標本誤差を±{target_se}以内に抑えるには、{required_n:.1f}回以上の試行が必要です。")

# --- 2. 検証(シミュレーション) ---
rolls = np.random.choice(dice_faces, size=n_trials)
n_range = np.arange(1, n_trials + 1)
sample_means = np.cumsum(rolls) / n_range

# --- 3. 描画による証明 ---
plt.figure(figsize=(10, 6))
plt.plot(n_range, sample_means, label="Actual Sample Mean", color="blue", alpha=0.6)
plt.axhline(true_mean, color="red", linestyle="--", label="Population Mean (3.5)")

# 推定した「必要回数」に緑の垂直線を引く
plt.axvline(required_n, color="green", linestyle=":", label=f"Required n ({required_n:.0f})")

# 目標誤差(±0.1)の範囲をオレンジの線で引く
plt.axhline(true_mean + target_se, color="orange", linestyle="--", alpha=0.5, label=f"Target SE (±{target_se})")
plt.axhline(true_mean - target_se, color="orange", linestyle="--", alpha=0.5)

plt.title("Verification: Sample Size Design based on Standard Error")
plt.xlabel("Number of Trials (n)")
plt.ylabel("Mean Value")
plt.legend()
plt.grid(True)
plt.show()

4.5. 実行結果の分析

プログラムを実行すると、以下のようなグラフが表示されます。

実行結果
  • Actual Sample Mean(青線実際の標本平均
  • Population Mean(赤点線母平均(3.5)
  • Required n(縦の緑点線計算で導いた必要回数(292回)
  • Target SE(黄色点線目標とした標準誤差(±0.1)

グラフに出現した緑色の垂直線(292回の地点)に注目してください。
実際の標本平均(青線)が、目標とした標本誤差の範囲(黄色の点線内)に安定して収まり始めるのは、数学的に算出した回数 (292回) を越えたタイミングであることが分かります。
(※ 実行の都度、ある程度のズレは生じます)

これが『偶然を「過去の集計」から「未来の推測」へ』変える統計学の力です。
「とりあえずたくさん」という曖昧な姿勢を捨てて公式を用いることで、最小限のコストで目的の精度を手に入れるための「最適な試行回数」を事前に設計できるようになるのです。

まとめ:確率と統計が手を取り合う場所

今回の記事を通じて、『確率②』の記事で見た「収束」という現象に、「大数の法則」という数学的根拠とコントロール術を与えました。

  • 大数の法則:試行回数を増やすほど、標本平均は母平均に近づく。
  • 標準誤差(\(SE\)):標本平均のバラツキを示す指標。試行回数の平方根に反比例して減少する。
  • 精度の設計:精度を2倍(\(SE\) を半分)にしたければ、データ量は4倍必要になる。

統計学というレンズを通せば、バラバラな偶然も、確実な設計の対象となります。

さて次回は、この「大数の法則」を土台とし、データ分析の王道である「正規分布(ベルカーブ)」の世界へ進みます。
無秩序な偶然が重なるとき、なぜ世界はあの美しい釣鐘状の形を描くのか。その核心に迫りましょう。

コメント

タイトルとURLをコピーしました