メインコンテンツへスキップ
見出し画像
Photo byomori55

Python で味わう、意外な確率

     前の記事で「Python で関数を定義してグラフを描くまで」やりました。ここでは Python で確率計算することを通じて、ちょっと意外な確率、直感に合わないかも、ちょっと驚くかもしれない確率を味わってみましょう。2つお届けします。

    ありふれた偶然

    40人のクラスで同じ誕生日の人がいる(誰かと誰かの誕生日が同じである)確率は、どれくらいでしょうか。
     (ア) 10%  (イ) 30%  (ウ) 50%  (エ) 70%  (オ) 90%

     nn人の誕生日がすべて異なる確率をpnp_n ,nn人の中の誰かと誰かの誕生日が一致する確率をqnq_nとします。このときpn+qn=1p_n+q_n=1が成り立ちます。ただし、ここではうるう年を考えずに、誕生日を 365 種類として計算します。
     まずp0=1 , p1=1p_0=1\:,\:p_1=1とq0=0 , q1=0q_0=0\:,\:q_1=0は明らかです。最低でも 2人いないと、誕生日が一致することはあり得ませんから。またn>365n>365のときpn=0 , qn=1p_n=0\:,\:q_n=1も明らかです。
     p2p_2は2人目の誕生日が1人目の誕生日と異なる日であると考えてp2=p1×364/365p_2=p_1\times364/365で計算できます。同様に p3=p2×363/365  ,  p4=p3×362/365  ,  …p_3=p_2\times363/365\;,\;p_4=p_3\times362/365\;,\;…となります。
     一般化するとpn+1=pn×(365−n)/365p_{n+1}=p_n\times(365-n)/365(⇔pn=pn−1×(365−n+1)/365p_n=p_{n-1}\times(365-n+1)/365)となります。またqn=1−pnq_n=1-p_nです。
     さて、これを手計算するのは現実的ではありませんから、計算は Python に任せましょう。では、どうぞ。

    席替えしたのにまた同じ席になっちゃう確率

     nn人のクラスで席替えをします。その際に「席替えしたのにまた同じ席になっちゃったよ」という人が、クラスの中に1人以上いる確率はどれくらいでしょうか?

     何はともあれ、計算してみましょう。「nn人の人が席替えしたとき、また同じ席になっちゃう人がいる確率」をpnp_nとします。

    • 1人で席替えしたら必ず同じ席になりますから、p1=1p_1=1です。

    • 2人で席替えする場合、全部で 2 通りのうちの 1 通り → p2=12p_2=\frac{1}{2}

    • 3人で席替えする場合、全部で 3 ! = 6 通りのうちの 4 通り → p3=46p_3=\frac{4}{6}

    • (一応書いておくと、p0=0p_0=0です。)

    と、このように順番に数えていってはキリがないので、ここから先は漸化式を立てましょう。
    「nn人の人が席替えしたとき、全員が前と異なる席になる場合の数」をana_nとすると、「全員が前と異なる席になる確率」はqn=an÷n!q_n=a_n\div{n!}で、「nn人の人が席替えしたとき、また同じ席になっちゃう人がいる確率」はpn=1−qnp_n=1-q_nです。このとき、

    • ana_nについてan+2=(n+1)(an+1+an)a_{n+2}=(n+1)(a_{n+1}+a_n)… (1) が成り立ち、

    • qnq_nで書き換えると(n+2)qn+2=(n+1)qn+1+qn(n+2)q_{n+2}=(n+1)q_{n+1}+q_n… (2) となり、

    • pnp_nで書き換えると(n+2)pn+2=(n+1)pn+1+pn(n+2)p_{n+2}=(n+1)p_{n+1}+p_n… (3) となります。

     高校数列のテクニックでこの漸化式が解けようが解けまいが、私たちには Python という武器がありますから、計算は Python にやらせましょう。では、どうぞ。
    ※ (1) の計算法や考え方は「完全順列」というワードでネットで検索すれば何かと分かるかもしれません。

    《解答編》

     以下、私が作ったコードです。これが必ずしも良いものではないこと、再度申し上げます。

    # ありふれた偶然
    import matplotlib.pyplot as plt
    p=1                     # p:全員の誕生日が異なる確率
    for i in range(100):
        p=p*(365-i+1)/365
    plt.scatter(i,1-p)      # q:誰かと誰かの誕生日が一致する確率
    plt.show()
    画像

     「クラスに同じ誕生日の人がいる確率」はq40=0.891q_{40}=0.891となりました。というわけで、冒頭の問いの答えは(オ)90% です。意外に高い確率だと思いませんか?
     クラスの中に同じ誕生日の人がいるのは、偶然でも珍しいことでも何でもないんですね。むしろみんなの誕生日が違うことの方がよっぽど珍しいことなんです。

     次に「nn人の人が席替えしたとき、また同じ席になっちゃう人がいる確率」pnp_nについて、初期条件p0=0 , p1=1p_0=0\:,\:p_1=1と漸化式(n+2)pn+2=(n+1)pn+1+pn(n+2)p_{n+2}=(n+1)p_{n+1}+p_n… (3) を使ってp10p_{10}まで求めました。

    import matplotlib.pyplot as plt
    p=[0,1,0,0,0,0,0,0,0,0,0]               # p0=0,p1=1は実際の確率。p2以降はダミー
    for n in range(9):                      # ┐ 漸化式(3)を使って
        p[n+2]=(p[n+1]*(n+1)+p[n])/(n+2)    # ┘ p2〜p10の値を計算した。
    for n in range(11):                     # ┐ p0とp1を含めて、
        print("p",n,"=",p[n])               # │ p0〜p10の値を表示して、
        plt.scatter(n,p[n])                 # ┘ グラフの点をとった。
    plt.show()
    画像

     結果は上の通りで、実は4人以上のクラスであれば人数に関わらず、その確率は約63%に(正確に言うと,その確率を四捨五入して小数第2位までで表すと0.63に)なります。ところで、その状況は次のケースと同じです。「クリスマス会のプレゼント交換で、みんなが持ち寄ったプレゼントを一人に1個ずつ配ったら、自分が用意したものが自分のところに来ちゃう。クリスマス会に参加したうちの誰かがそういう目にあう」、そうなる確率が約63%だということです。
     この値、意外と大きいと思うんじゃないでしょうか。しかもそれが人数に因らないということも意外なんじゃないでしょうか。

    ※ ついでながら、nnを限りなく大きくしていくと、この値は1−1e=0.63212055…1-\dfrac{1}{e}=0.63212055…に近づいていきます。そう、こんなところにネイピア数が現れるんです。それはそれで不思議ですね。

    ◇      ◇      ◇

    〜 Python でグラフを描く 〜 
    ▷ 関数を定義してグラフを描くまで       
    ▷ Python で味わう、意外な確率          
    ▷ 再帰関数  ▷ シェルピンスキーのギャスケット

     
     
    情報科・数学科教員にして   作家・旅人・芸人 AI評論家・火山ハンター

    あなたへのおすすめ