Python で取引をしましょう!

Python で取引をしましょう!

確率を扱うとき、物事は必ずしも予想通りにはいかないことがあります。私のお気に入りの例は、モンティ・ホール問題です。この名前は、1960年代に初登場したモンティ・ホールが司会を務めたゲーム番組「  Let's Make a Deal」に由来しています。この番組は現在も(司会者は変わりましたが)放送されており、ゲームの流れは変わりません。参加者は3つの閉じたドアの中から1つを選びます。そのうち1つのドアの向こうには賞品があります。

これらのドアに1、2、3とラベルが貼られているとしましょう。プレイヤーはドアを1つ選びます。ここではドア2を選びます。その後、モンティは賞品がないことを示すために、他のドアの1つを開けます (仮にドア1だとします。)ここで、出場者は最初の選択(ドア2)を維持するか、開いていないもう1つのドア(ドア3)に切り替えることができます。さて、あなたならどうしますか?自分の意見を貫き、ドア2を選びますか?それとも、曖昧な態度でドア3を選びますか?(さらに緊張感を高めるために、観客が自分の意見を叫んでいるところを想像してみてください。しかも、テレビに出ているという状況は、常に緊張感を高めます。)

結局、選択肢を変えれば賞品を当てる可能性が高くなるようです。ええ、確かにその通りです。これはあまり意味がないように思います。というのも、最初にドアを選んだ時は、どのドアに賞品が隠されているか分かりませんでした。そしてモンティがハズレのドアを明かした後も、 どのドアが当たりなのかはまだ分かりません。これで、3つではなく2つのドアが残りました。ランダムに1つのドアを選んだからといって、当選確率が上がるとは思えませんが、実際には上がります。最初は3分の1の当選確率ですが、答えを変えれば、当選確率は3分の2になります。 

奇妙に思えるので、自分で試してみたい。いや、実際に試すのは嫌だ 。もちろん、友達にドアをいくつか作ってもらって、その裏に賞品を隠して、私が当てるという方法もある。でも、これを何度も繰り返してみないと、ドアを入れ替えた方が本当に良いのかどうかは分からないし、誰もそんな時間はないだろう。

次善策として、Pythonで問題をモデル化してみるのはいかがでしょうか。有名なモンティにちなんで名付けられた問題を、別の有名なモンティにちなんで名付けられたプログラミング言語(この場合はBBCシリーズ 「空飛ぶモンティ・パイソン」)で解くことができるはずです。

Pythonでこれをモデル化する基本的な手順を順に説明します。1回の試行でうまく動作すれば、1,000回、あるいは10,000回の試行でも同様に簡単に実行できます。 

2 つのことを行う必要があります。ドアを切り替えずにケースをモデル化し、次に切り替えオプションを使用して再度モデル化します。

スイッチなしオプション

このオプションはモデル化が非常に簡単です。乱数ジェネレータを使って賞品が入っているドアを選び、次に参加者の選択に応じて別の乱数を選びます。参加者の選択と賞品が同じであれば、勝ちとなります。 

このモデルでは、Web VPythonというバージョンのPythonを使用します。これは3Dオブジェクトの作成と移動が可能なため、物理演算に最適です。さらに、オンラインで実行できるので、インストールは一切不要です。(ただし、通常のPythonとは異なる処理をいくつか行う点に注意してください。)

最初の課題は、賞品を出すドアをランダムに選ぶことです。0から2までのランダムな整数を使います。つまり、0、1、2の3つの数字です。(多くのプログラミング言語と同様に、Pythonは0からカウントを開始します。) 

その後、参加者が選んだドアを表す数字をランダムに選びます。これも0、1、2のいずれかです。この2つの数字が一致すれば、プレイヤーの勝ちです。これを好きなだけ繰り返し、勝った回数を試行回数で割った数を数えます。これで完了です。コードはこちらです。

以下の埋め込みでは、鉛筆アイコンをクリックするとコードが表示され、矢印アイコンをクリックすると結果が表示されます。

これはライブコードなので、試行回数を変更して再度実行できます。(現在、4行目でN = 1,000に設定されています。)Nが10回や20回など非常に小さい場合、勝率に多少の変動が見られます。1,000回などの大きな数値になると、挙動はより安定し始めます。勝率は33%近く、つまり約3分の1、つまり3分の1の確率で勝てるはずです。

モンティが負けるドアの裏側を見せた後、出場者がドアを変えなければ何も変わりません。出場者は既にドアを選んでいるので、それを維持しても勝率は上がりません。3分の1のままです。

ドアスイッチオプション

正直に言うと、このオプションのモデル化は少し複雑です。賞品のあるドアと出場者の選択肢を選ぶだけでなく、モンティが開ける負けるドアも選び、その後プレイヤーの選択肢を入れ替える必要があるからです。 

以下のコードをご覧になる前に、私は物理学者でありプログラマーではないことをお伝えしておきます。そのため、多少雑な部分があるかもしれません。もっと良い方法があるかもしれませんが、自分で作ったコードなので、理解はしています。これは私のコードです。ボタンを押すだけで答えが返ってくるブラックボックスではありません。つまり、プログラムは完璧である必要はないということです。だからといって、コーディングをやめないでください。 

実際に確認できるのは、数字を大きくして切り替えた場合と切り替えなかった場合の違いだけです。(もう一度、鉛筆と矢印を切り替えて、コードと結果を確認してください。)今回は、モンティがドアを開けた後にプレイヤーがドアを切り替える試行を1,000回実行すると、約3分の2の確率でプレイヤーが勝ちます。これがこの問題の理論的な解です。 

もしこれが奇妙に思えるなら、私も同感です。基本的な説明はこうです。ドアが3つある場合、勝つ確率は3分の1です。モンティがドアの1つを開けると、基本的にはもう1つの選択肢(もしドアを切り替えれば)を与えていることになります。つまり、勝つ確率は3分の2になります。

もし出場者が1,000回ではなく1回だけゲームをしたらどうなるでしょうか?勝率が上がったと実感できるでしょうか?いいえ。1回だけだと、勝つか負けるかのどちらかです。ドアを交換するかどうかの違いが実際にわかるわけではありません。

もし10回プレイしたらどうなるでしょうか? そうすれば、切り替えるかどうかに関わらず、どちらの方法でも半分は勝てるかもしれません。(そして、どうして彼らが番組に出演し続けられるのか、人々は不思議に思うでしょう。)

二人がそれぞれ別々にゲームを100回プレイしたとしましょう。一人は常に交代しますが、もう一人は決して交代しません。二人とも勝った回数を記録し、100回の試行結果をまとめたグラフを作成します。グラフは次のようになります。

グラフ

イラスト: レット・アラン

このシミュレーションでは、4ゲームプレイ後、両者の勝利数は同じであることに注目してください。しかし、100ゲームプレイ後では、ドアを切り替えたプレイヤーは75回勝利しているのに対し、切り替えなかったプレイヤーはわずか35回しか勝利していません。これは理論上の期待値、つまり3分の2対3分の1、つまり67%対33%に非常に近い値です。両者のスコアはまだその比率には達していませんが、その比率に収束しつつあります。

これは大数の法則と呼ばれ、ランダムな値を含む試行回数を増やすと、結果は期待値に近づくというものです。これは、カジノギャンブルのように偶然性が絡む状況において重要な考え方です。ほとんどのカジノゲームでは、プレイヤーが勝つ理論上の確率は50%未満です。つまり、カジノがプレイヤーのお金を受け取る確率は50%以上です。もしカジノにたった1人の客しかおらず、その客が1ゲームしかプレイしなかったとしたら、カジノ側は確かにゲームに負け、結果としてお金を失う可能性があります。しかし、1年間を通して、多くの人々が多くのゲームをプレイすることで、全体的な結果は期待値に近づき、カジノ側が全体的に勝つことになります。

モンティ・ホール問題では、ドアを切り替えた場合の勝率の期待値は50%を超えていることに注目してください。つまり、理論上は、プレイヤーが常にドアを切り替える戦略を採用する場合、時間の経過とともに番組は勝つよりも負けるゲームの数が増えるはずです。正直なところ、これは問題ありません。ゲーム番組はカジノではありません。プレイヤーが勝っても利益を上げることができます。しかし、それは確率のおかげではありません。コマーシャルのおかげです。