発熱するマイナー魂

隠れた名作の発掘が生きがい。サブカル作品の感想とIT技術メモ中心のブログです。

JavaScriptでモンティ・ホール問題をシミュレーション!


スポンサードリンク

「モンティ・ホール問題」の解答がなかなか理解できないです。


終物語』に出てきた確率の問題です。3つの閉まったドアのうち1つだけあるアタリのドアを開ける問題なのですが、この解答が直感的に理解がしがたい内容です。問題の詳細は以下の通り(Wikipediaより抜粋)。

「プレーヤーの前に閉まった3つのドアがあって、1つのドアの後ろには景品の新車が、2つのドアの後ろには、はずれを意味するヤギがいる。プレーヤーは新車のドアを当てると新車がもらえる。プレーヤーが1つのドアを選択した後、司会のモンティが残りのドアのうちヤギがいるドアを開けてヤギを見せる。
ここでプレーヤーは、最初に選んだドアを、残っている開けられていないドアに変更してもよいと言われる。プレーヤーはドアを変更すべきだろうか?」


(1) 3つのドアに1つのアタリと2つのハズレがランダムにある
(2) プレーヤーはドアを1つ選ぶ
(3) 司会者は残りのドアからハズレのドアを1つ開ける
(4) プレイヤーはドアを変更した方が良いだろうか?


直感的には「(3)の段階でドアが2つに絞られるので、どちらを開けようが1/2で当たる確率は変わらないのでは?」と思うのですが、ドアを変更した方がアタリを引く確率が高くなります。回答を調べ回ったのですが、確率音痴なので「何でドアを変更した方が確率が高くなるのか?」がなかなか理解できないです。。


確率は苦手だけれどプログラミングはそこそこできるので、もうシミュレーションで確認です。JavaScriptでモンティ・ホール問題をシミュレーションして、ドアを変更した方が確率が高くなることを確認します。


目次:

シミュレーション

プログラム

問題の(1)〜(3)をまず処理します。その後、(1)で選択したドアに対して(A) 選択を変えない、(B) 選択を変える、の戦略をとった場合のそれぞれで正解した数を集計します。試行回数は10万回。

var DOOR_COUNT = 3;
var TRY_COUNT = 100000;
var hitCountWithNoChange = 0; // (A) 最初にした選択を変えない戦略で正解した数
var hitCountWithChange = 0; // (B) 最初にした選択を変える戦略で正解した数

// 勝負をTRY_COUNTの数だけ試行
for (var count = 0; count < TRY_COUNT; count++) {
    // ドアの候補を作成。ひとつだけ当たり(=true)
    var doors = new Array(DOOR_COUNT);
    for (var i = 0; i < DOOR_COUNT; i++) {
        doors[i] = false;
    }
    var bingo = Math.floor(Math.random() * DOOR_COUNT);
    doors[bingo] = true;
    
    // プレイヤーはドアを一つ選ぶ
    var choice = Math.floor(Math.random() * DOOR_COUNT); 
    
    // 司会者は、プレイヤーが選んだドア以外からハズレのドアをランダムに一つ選択し、プレイヤーに開示する
    var missList = [];
    for (var i = 0; i < DOOR_COUNT; i++) {
        if (i === choice) {
            continue;
        }
        if (doors[i] === false) {
            missList.push(i);
        }
    }
    var openedDoor = missList[Math.floor(Math.random() * missList.length)];
    
    // (A) 選択を変えない場合
    if (doors[choice] === true) {
        hitCountWithNoChange = hitCountWithNoChange + 1;
    }
    
    // (B) 選択を変える場合 (自分が選択したドア以外で未オープンのドアからランダムに一つドアを選択)
    var otherDoors = [];
    for (var i = 0; i < DOOR_COUNT; i++) {
        if (i === choice || i === openedDoor) {
            continue;
        }
        otherDoors.push(i);
    }
    var reChoice = otherDoors[Math.floor(Math.random() * otherDoors.length)];
    if (doors[reChoice] === true) {
        hitCountWithChange = hitCountWithChange + 1;
    }
}

// 結果表示
console.log("hitCountWithNoChange = ", hitCountWithNoChange);
console.log("hitCountWithChange = ", hitCountWithChange);

シミュレーション結果

戦略 当たった回数 当たった割合
(A) 選択を変えない 33299 33.3 %
(B) 選択を変える 66701 66.7 %


たしかに、選択を変えた方が、選択を変えないよりも確率が高い!

だんだんと分かってきた確率の解釈

選択を変えない場合にアタリを引く確率

司会者がハズレのドアを開ける前は1/3でアタリ。司会者がハズレのドアを開けたとしても、1/3のアタリの確率は変わらない。

選択を変えた場合にアタリを引く確率

ABCのドアがあり、最初にプレイヤーはAを選択する。この時、Aがアタリの確率は1/3。BCにアタリがある確率は2/3。司会者がBのドア(ハズレ)を開いた時、Cのドアが自動的にアタリとなる。そのため、2/3でアタリとなる。

ドアが5つある場合を考える

理解度の確認のため、次の応用問題を考えてみます。

・ドアが5つある
・プレイヤーはドアを1つ選択する
・司会者は残り4つのドアからハズレのドアを1つ開く

この時、プレイヤーが選択を変えた時と変えなかった時の確率を求めてみます。

選択を変えない場合にアタリを引く確率

司会者がハズレのドアを開ける前は1/5でアタリ。司会者がハズレのドアを開けたとしても、1/5のアタリの確率は変わらない。

選択を変えた場合にアタリを引く確率

ABCDEのドアがあり、最初にプレイヤーはAを選択する。この時、Aがアタリの確率は1/5。BCDEにアタリがある確率は4/5。


司会者がBのドア(ハズレ)を開いた時、CDEのドアのいずれかにアタリがある。そのため、BCDEにアタリがある確率 × CDEでアタリを引く確率 = (4/5) * (1/3) = 4/15 (約 26.7 %)

シミュレーション結果

シミュレーションプログラムのドアの数を5に変更(DOOR_COUNT = 5)にして実行した結果、次のようになりました。

戦略 当たった回数 当たった割合
(A) 選択を変えない 19875 19.9 %
(B) 選択を変える 26658 26.7 %


どうやら解釈は間違っていなさそうだ!

まとめ

モンティ・ホール問題のシミュレーションを通じてやっと自分なりに解答を理解できました。ベイズの定理を深く理解していれば、もっとスマートに解けるのかなー。


関連:
minor.hatenablog.com