見出し画像

【アニメーション編】「未完のゲーム」を終わらせよう〜「数学ガールの秘密ノート/確率の冒険」研究問題5-2

カバー写真はUnsplashKarolina Kołodziejczakが撮影した写真。ダジャレですけど。


数学ガール

結城浩先生の「数学ガールの秘密ノート 確率の冒険」を読んで、巻末の「研究問題」についてあれこれ考えています。

前々回は、偏ったコインを用いた「未完のゲーム」について考えました。そして前回は、これが果たして正しい結果を出してくれているのかについて、Rを用いて検証しました。

今回は、Javascript+p5.jsを使ったアニメーションを用いた、数値シミュレーションをしていきます。

研究問題5-2

研究問題5-2は、こういう問題でした。

第5章〈未完のゲーム〉では、フェアなコインを投げてゲームを行いました。もしも、偏ったコイン(表が出る確率が1/2ではないコイン)を用いた場合は、どのような答えになるでしょうか。

同書より


シミュレーションを体験しよう

数式による回答、Rスクリプトによる検証については前々回と前回をご覧いただくとして、さっそく、シミュレーションをしてみましょう。次のページで体験できます。

まずは「実行」

いつものことですが、まずはそのまま、「実行」ボタンを押して、何が起きるのかを試してください。こんな画面になると思います(疑似乱数を使ったシミュレーションですので、実行するたびに結果が異なることにご注意ください)。

実行中の画面(例)

では、画面に表示されている内容を見ていきます。

  • 左上の赤と緑の円:それぞれのゲームでは、コイン投げをし、表が出たらAが1点(赤い円)、裏が出たらBが1点(緑の円)獲得します。初期設定では、Aがあと2点、Bがあと1点で勝負が決まります。

    • 1行目は裏が出ましたから、2回目のコイン投げをする前にBの勝ちが決まりました。でも、数式との対応関係がよくわかるように、あえて2回目のコイン投げもしています。2回目は表でしたが、時すでに遅し、でした。

    • 2行目は表が出て、Aが1点獲得し、お互いに残り1点になりました。2回目は裏が出たので、またしてもBが勝ちました。

  • 右上の棒グラフ:これまでに、どちらがどのくらい勝ったかを示しています。「2勝0敗」などはAから見た勝敗です。現在、ちょうど4分の1くらい(25%くらい)Aが勝っています。

  • 下の折れ線グラフ:1回目の実験(コイン投げを繰り返して勝者を決めるのを1回の実験とします)からこれまでに、Aの勝率(Aが勝った数÷実験数)を示しています。最初は乱高下していますが、次第に落ち着いて、期待勝率(赤線)に近づいていく様子がわかります。

最終結果は次のようになりました。

実行中の画面:500回のシミュレーションが終わったところ(例)

右上のグラフには、それぞれの勝敗の理論値と実測値(今回のシミュレーションの結果)を示しています。今回は、ほぼ理論値通りの結果でした。
(繰り返しますが、毎回このように理論値に近い結果になるとは限りません。あくまでも、たまたま実行したときにはこうなったという例です。)

設定を変えてみよう

例によって、設定をいくつか変更することが可能です。「リセット」を押してページを再読み込みし、設定変更をしてみましょう。

設定できる項目
  • 勝利までの不足ポイント:プレーヤーAとBが、勝利まであと何点かを設定します。初期値は2と1です。計算を簡単にするための都合上(笑)、1〜4の範囲にしています。要するに「AとBの差が何点か」が勝率に大きく影響するので、あまり大きな数は必要ないかと思いました。

  • 実験回数:初期値は500です。5000まで増やせます。2000くらいまで増やすと、けっこう安定した結果になる感じがします。

  • 表の出る確率:初期値はもちろん0.5です。ここを変えてみたらどうなるか、というのが研究問題で出されていた課題でしたので、ぜひいろんな値で実行してみてください。極端な値には極端な値らしい味わい(笑)があるようです(やればわかります)。

アニメーションを作ってみて

アニメーションを作ってみて感じたことを書き残しておきます。

まず、最初に作ったバージョンでは、勝敗が決まった時点で次の実験に移行し、単純にAが何回勝った、Bが何回勝った、という結果だけを表示するようにしました。ところが、これがちっとも面白くない。なぜかを考えながらRでの検証を始めたのですが、その結果気づいたことが、前回の note の最後に書いたことです。再掲すると、

  • この設定ならこの確率になるはず、という「数式による正解」が直感的にわからない。(計算しなくてはいけない)

  • 計算した答えが、たとえば0.4752のように中途半端な値であるため、シミュレーションの結果がその値に収束していっているのか、とてもわかりにくい。(0.5より少し小さいことくらいしか結局はわからない)

です。これに対してどういう工夫をしたか。

まず1点目。当然のことですが、理論値(勝率を求める計算式通りに求めた値)を、シミュレーション画面に表示するようにしました。これは、整数の階乗や、二項係数を求める関数がかければ簡単でした。
(といっても、整数の階乗を求める関数は実際には書いていなくて、0!から7!までの計算結果を定数として与えているだけです笑。)

そして2点目。単に勝率だけをみていくのではなく、勝負が決まった後もコイン投げを続けて、それも含めて何勝何敗だったかをみていくことで、勝敗の組み合わせとその確率を、二項分布として表現できます。これは、数式を解いていく過程で明らかです。ということは、その二項分布をそのまま途中経過や結果表示に使ってしまえば、わかりやすいだろうと考えました。

ちょっとややこしかったのは、表が出た時に0という値を返した方が、数式との対応がしやすかったことです。統計学で二項分布を扱う時には、成功=1みたいに対応づけているので、頭の中が反転した感じ。
二項分布は左右対称なんだからいいじゃん? というのは確率が0.5のときの話で、偏ったコインの時はそうならないので、何回も値を確認しながらのコーディングでした。(プログラミングよわよわなので笑)

というわけで、研究問題5-2は以上です。ぜひ、ご感想などお聞かせください!