医療とテクノロジーの交差点にて【第9話】プログラミングすれば人類最高知能に対抗できる説
台風で予定なくなり引きこもり中、トア・ルドクターです!
本日のテーマは「モンティホール問題」という、知るひとぞ知る数学の奇問です。まずは問題について簡単に説明します(Wikipediaの引用)。
【モンティ・ホール問題】
「プレーヤーの前に閉まった3つのドアがあって、1つのドアの後ろには景品の新車が、2つのドアの後ろには、はずれを意味するヤギがいる。プレーヤーは新車のドアを当てると新車がもらえる。プレーヤーが1つのドアを選択した後、司会のモンティが残りのドアのうちヤギがいるドアを開けてヤギを見せる。ここでプレーヤーは、最初に選んだドアを、残っている開けられていないドアに変更してもよいと言われる。プレーヤーはドアを変更すべきだろうか?」
1990年9月9日発行、ニュース雑誌「Parade」にてマリリン・ボス・サヴァントが連載するコラム「マリリンにおまかせ」で、上記の読者投稿による質問に「正解は『ドアを変更する』である。なぜなら、ドアを変更した場合には景品を当てる確率が2倍になるからだ」と回答した。すると直後から、読者からの「彼女の解答は間違っている」との約1万通の投書が殺到し、本問題は大議論に発展した。
この問題は当時はcontroversialな問題でして、著名な数学者までもが挙って「ドアを変更したって確率かわるわけねーだろ!」と大批判しておりました。実際には、マリリン(世界最高レベルのIQらしい)が正しく「ドアを変更した方が得である」という結論でした。とはいえ、直感的には「ドアを変更したところで当選確率は1/3なのでは?」と思いますよね。
そこで「自分の頭で考えて分からなければ実際にシミュレーションすればよくない?」というのが本記事の趣旨です。こんなときにプログラミングは最強の武器なんです。現実にこの問題を再現しようとしたら日が暮れますが、プログラミングならば机の上でも一瞬で10000回ほど実験できます。そんなPython3コードが次の通りです。
import random as rd
doors = [1,2,3]
trial = 10000
# 選択を変えない場合
win = 0
for _ in range(trial):
# 配列[1,2,3]をシャッフル
rd.shuffle(doors)
# 正解とハズレに分ける
correct, wrongs = doors[0], doors[1:]
# 1-3の数字からランダムに解答
choose = rd.randint(1,3)
# 解答が正解ならばwin
if choose == correct : win += 1
p1 = win / trial
# 選択を変える場合
win = 0
for _ in range(trial):
# 配列[1,2,3]をシャッフル
rd.shuffle(doors)
# 正解とハズレに分ける
correct, wrongs = doors[0], doors[1:]
# 1-3の数字からランダムに解答
choose = rd.randint(1,3)
# ハズレの中から初期解答と違うドアを教えてもらう(ヤギ)
for ele in wrongs:
if ele != choose: yagi = ele ; break
# 初期解答ともヤギとも違うドアに変更
for ele in doors:
if not ele in [choose, yagi]: change = ele
# 変更が正解ならばwin
if change == correct : win += 1
p2 = win / trial
print(p1, p2)
最初に選んだドアをファイナルアンサーにする場合の正解確率がP1であり、ドアを変えた場合の正解確率がp2です。randomモジュールを用いて正解をアトランダムに設定しているためp1, p2の値は毎回異なりますが、概ねp1が0.33...くらい、p2が0.66... くらいです。マリリンの指摘通り「ドアを変更した場合の正解確率が2倍」になります。シミュレーションの結果こうなったわけだから結論は自明ですが、理屈を一切説明しないのも芸がないので簡単に解説を。
【モンティホール問題の解説】
ドアA, B, Cとそれぞれ名前をつける。仮にドアAを選んだ場合、正解確率はシンプルに1/3である。一方「BまたはCが正解である確率は2/3」だ。さて、ここで仮にBがハズレだと神の視点から情報リークされた場合は「BまたはCが正解である確率」=「Cが正解である確率」といえる。つまり「Cが正解である確率は2/3」である。故に、AからCへと変えた方が得なのだ。
腑に落ちない人も多いだろうから更に説明しよう。数学の問題を解く姑息的テクニックとして「極端な場合を考える」ことが時に有効だ。ドア3つだとインパクトにかけるから、ドア100個の中から正解を選ぶ問題としよう。最初に選んでない99個のドアのうち「これら98個のドアはハズレである」と情報リークされたならば、直感的にも「99個のうち残った1つ」を選びたくなるだろう。実際、最初のドアが正解の確率は1/100であり、ドアを変えた場合の正解確率は99/100である。ドアが3個でも100個でも本質は同じ。
内容はこれで以上ですが、あくまで言いたいのは「実践は理屈に勝る」というか、屁理屈ごねるよりコード書く方が楽じゃないかという、プログラミングの有用性です。しかも、コードを書くうえで問題の状況を忠実に再現しようとすると、なんとなく問題の本質が見えてきて、結果的に「ああ、なるほど」と納得できるんですよね。日々のちょっとした疑問を解決したり、ちょっとした作業を効率化させたり、電卓には難しいちょっと高度な計算させたり、プログラミングには有用性・汎用性・可能性が満ちています。
それではまたいつか!
【著者プロフィール】
都内で医師として研鑽する傍ら、独学でプログラミングを学ぶ26歳。趣味は『ギター / バイオリン / 美術鑑賞 / youtube鑑賞 / 創作料理 / 囲碁 / チェス / 折り紙 / スノボ / サーフィン / ドライブ』など枚挙にいとまがない。CIAの格闘武術クラブマガを始める。得意料理はバナナシチュー。ビールと牡蠣は生派だが生セックスは断固せず、経験人数の常用対数は2未満と清純を極める。略歴としては高2で数学全国1位(駿台)、文系で官僚をめざすも、ドラマ『コードブルー』の影響から気づいたら医師に。ディープラーニングG検定、統計検定2級、知的財産検定3級など取得。TOEICは次回900目指す予定(仮)。
【記事アーカイブ】
【第1話】医者なのにプログラミングを勉強してみた話
【第2話】pythonプログラミングの小技(1)ラムダ
【第3話】プログラミング初心者が学ぶべき3つのポイント
【第4話】競技プログラミングのススメ
【第5話】競技プログラミング物語(1)バイトリーダーの苦悩
【第6話】プログラミングで自作する実用アプリ(1)NEVER-NOTE
【第7話】プログラミングで解析したDNA鑑定の精度
【第8話】統計学は最強の学問であるのか?
【第9話】プログラミングすれば人類最高IQに対抗できる説
この記事が気に入ったらサポートをしてみませんか?