Loading [MathJax]/jax/input/TeX/config.js

2018年11月23日金曜日

アントワーヌ・ゴンボーの疑問をPythonで検証してみる

確率論の始まりの話でよく出てくるアントワーヌ・ゴンボーの疑問

17世紀、フランスの貴族シュバリエ・ド・メレ卿(アントワーヌ・ゴンボー)という人はギャンブル好きだった。
彼は、サイコロのギャンブルが好きで、
1つのサイコロを4回投げて、6が出れば勝ちというゲームをした時は2/3の確率で勝つと考えた。
勝率は予想に届かなったが、勝ち越すことは出来た。
そして、2つのサイコロを24回投げて、6,6のゾロ目が出れば勝ちというダブルシックスも同じように、6,6のゾロ目が出る確率は1/36なのだから24回投げれば2/3で勝てるはずと考えた。
しかし、実際は予想に反してあまり勝てなかった。
そこで、ゴンボーは数学者パスカルに、何がおかしいか相談してみた。
パスカルはゴンボーの考え違いを見抜き、出る目から計算するのでなく、出ない目から計算するのが正しいと答えたそう。

さてそれをPythonで検証してみましょう。

まずは1つのサイコロから6の目が出れば勝つというゲーム
4回投げてどれくらいの確率で勝つかrandomを使って試してみましょう。

  1. #! /usr/bin/env python  
  2.   
  3. # -*- coding: utf-8 -*-  
  4.   
  5. import random  
  6.   
  7. print("[probability]")  
  8.   
  9. #試行回数  
  10. trial = 10000  
  11.   
  12. #投げる回数  
  13. roll = 4  
  14.   
  15. #勝った回数  
  16. win = 0  
  17.   
  18. def dice(trial, roll):  
  19.     win = 0  
  20.     reset = False  
  21.     for i in range(trial):  
  22.         reset = False  
  23.         for j in range(roll):  
  24.             if reset == False:  
  25.                 #サイの目をランダムに出す  
  26.                 pip = random.randrange(17)  
  27.                 #目が6なら勝ち  
  28.                 if pip == 6:  
  29.                     win += 1  
  30.                     reset = True  
  31.     return win  
  32.   
  33. win = dice(trial, roll)  
  34. print("試行回数: ", trial)  
  35. print("勝った回数: ", win)  
  36. print("勝率: ", (win / trial))  

結果:
[probability]
試行回数:  10000
勝った回数:  5218
勝率:  0.5218

[probability]
試行回数:  10000
勝った回数:  5184
勝率:  0.5184

[probability]
試行回数:  10000
勝った回数:  5140
勝率:  0.514

[probability]
試行回数:  10000
勝った回数:  5144
勝率:  0.5144

[probability]
試行回数:  10000
勝った回数:  5222
勝率:  0.5222


2/3には届きませんが勝ち越すことは出来ます。
次に、2つのサイコロを24回投げ、6,6のゾロ目が出たら勝ちというゲーム


  1. #! /usr/bin/env python  
  2.   
  3. # -*- coding: utf-8 -*-  
  4.   
  5. import random  
  6.   
  7. print("[probability]")  
  8.   
  9. #試行回数  
  10. trial = 10000  
  11.   
  12. #投げる回数  
  13. roll = 24  
  14.   
  15. #勝った回数  
  16. win = 0  
  17.   
  18. def dice(trial, roll):  
  19.     win = 0  
  20.     #ゲームリセットフラグ  
  21.     reset = False  
  22.     for i in range(trial):  
  23.         reset = False  
  24.         for j in range(roll):  
  25.             if reset == False:  
  26.                 #サイの目をランダムに出す  
  27.                 pip1 = random.randrange(17)  
  28.                 pip2 = random.randrange(17)  
  29.                 #print("({}, {})".format(pip1, pip2), end=" ")  
  30.                 #目が6, 6なら勝ち  
  31.                 if pip1 == 6 & pip2 == 6:  
  32.                     win += 1  
  33.                     reset = True  
  34.                     #print()  
  35.   
  36.     return win  
  37.   
  38. win = dice(trial, roll)  
  39. print("試行回数: ", trial)  
  40. print("勝った回数: ", win)  
  41. print("勝率: ", (win / trial))  

結果:

試行回数:  10000
勝った回数:  4939
勝率:  0.4939

[probability]
試行回数:  10000
勝った回数:  4997
勝率:  0.4997

[probability]
試行回数:  10000
勝った回数:  4900
勝率:  0.49

[probability]
試行回数:  10000
勝った回数:  4957
勝率:  0.4957

[probability]
試行回数:  10000
勝った回数:  4961
勝率:  0.4961

10000万回試行した結果では勝率5割を割りました。
パスカルの計算したとおりですね。
ポイントは勝った場合にゲームリセットすることです。
これが無いと一つのゲームに複数勝利することになりますので2/3に近い数字が出ます。

パスカルの計算式
1つのサイコロを4回投げて6が出たら勝つゲームの勝率
1 - (5/6) ^4 = 0.5177469

2つのサイコロを24回投げて6, 6のゾロ目が出たら勝つゲームの勝率
1 - (35/36) ^4 = 0.491403876

実際にランダムに試行した結果も計算に近い数字が出ましたね。

Pythonで地図空間データを扱う⑤

ベースの地図が出来た所で、他のデータを被せてみます。 国土地理院の  500mメッシュ別将来推計人口データ  を使用します。 同じく神奈川県のデータ  500m_mesh_suikei_2018_shape_14.zip をダウンロードします。 ベースの地図データと同じ場所に展開...