この記事は、Pythonを学習するなかで発生した確率の疑問を、
Pythonを使用して解決した事を纏めたものです。

はじめに
G検定の受験を終え、発表までの間、Pythonを覚えようと自習している。
その演習問題を実践している時、いつものごとく疑問が立ち上がった。
それ、気になりますと。
降水確率10%
天気予報で、降水確率が10%という。
降水確率10%とは、10日続けば「1回は雨が降る」と言われることがある。
しかし実際には、1日目の降水確率は10%、2日目も10%であり、
「10日に1回雨が降るくらい確率が低い日が毎日続くだけ」である。
10日に1回雨が降るわけではない。
確率1/10
サイコロの出目は、1〜6。
どの数字も、出る確率は1/6である。
この出目の数字を1〜10に広げると、確率は1/10に低下する。
どの数字も、出る確率は同じである。
Pythonの演習問題の中で、この確率1/10が物議を巻き起こす。
Pythonの演習問題
問題
while と random モジュールを使って、コンピュータが選んだ 1〜10 のランダムな数を当てるゲームを作れ。
数字が当たれば処理終了。ハズレた場合は繰り返す。
要は処理の繰り返し(while)と乱数(random)の使い方を覚えろという問題である。
自分が作ったコードは以下の通りである。
import random
while True:
num = random.randint(1,10)
kazu = int(input('数を入力(1-10)'))
if num == kazu :
print('一致! 処理を終わります')
break
else:
print('残念不一致:', num)
処理の概要は以下の通りだ。
以下の処理を繰り返す
- 1〜10 の範囲でランダムな数字を1つ選ぶ
- 数字を入力する
- ランダムな数字と入力した数字が一致したら処理終了
- 不一致の場合は、ランダムに選んだ数字(正解)を表示
つまり、数字が一致しない限り、処理が終了しない仕組みだ。
ところが、このコードを見せた生成AIが、いちゃもんをつけてきた。
- random を使用するのはループの外じゃないと駄目
- 不正解の時に答えを教えたらゲームにならない
こいつ、何いちゃもんつけているんだ。
「いや、1/10 の確率なら、毎回答えが変わっても変わるでしょ。」
「選んだ数字固定だったら、それこそゲーム性がないじゃん。」
「降水確率10%と一緒だと。」
ところが、演習問題の模範回答も生成AI寄りで、
自分の回答は「間違い」とされてしまった。
納得いかない。
問題(仕様)通りに作ったのに、なぜ間違いなのか。
問題(仕様)が曖昧で悪いというなら仕様変更をよこせと。
仕様あるある
仕事でもよくある話だ。
- 仕様が曖昧なのが原因なのに、作った側が責められる
- 「なぜ問い合わせしなかった」と追及される
- 仕様通りに作ったのに「意図と違う」と言われる
今回の演習問題も、まさにその縮図だった。
この数字が 1〜100 だとするならば、私もランダムに選ぶ数字は1回だけ選ぶようにしただろう。
しかし、1/10の確率であれば、あたりも出るはず。
ゲーム性もあり、問題ない。
と考えた訳だ。
数字が一致する確率
このゲーム、1〜10の数字が出る確率は、1/10。
だから選ぶ数字を固定すれば、数字が一致する確率も 1/10になることはわかる。
この選ぶ数字を毎回変えたら確率はどうなるだろう?
疑問に思った。
なんとなく、1/10 の確率は変わらないという気もする。
しかし、直感が、確率が下がると言っている。
せっかくPythonのコードが書けるようになったので、調べてみることにした。
実験コード
そこで、演習問題から離れて「当たる確率」について考えた。
固定で数字を選んだ場合は、出目の数が当選確率になるはず。
毎回数字を変えた場合は、一致した回数が当選確率になるはず。
Python で検証してみた。
import random
deme = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
ok = 0
print('start')
for i in range(100000):
num1 = random.randint(1,10)
num2 = random.randint(1,10)
deme[num1 -1] += 1
if num1 == num2:
ok += 1
print(deme)
print('ok=', ok)
print('end')
処理の概要は、以下の通り。
この処理を10万回実行する。
検証結果
結果:
start
[9909, 9976, 9944, 9899, 9976, 10035, 9919, 9995, 10124, 10223]
ok= 10015
end
num1の数字は、10万回の 1/10 となる約1万回。
そして、okのカウント数も約1万回。
どちらも、確率は変わらず1/10という事がわかった。
確率とはそういうものだと理解した。
まとめ
簡単なプログラムである。
コードの書き方も稚拙である。
でも動く。
疑問を解決してくれる。
Pythonの乱数が、ほぼ確率通りに数字を選ぶ事がわかる。
Python のコードと確率、二つを学んだ日だった。
そして、投稿記事のネタを提供してくれた日でもあった。
関連投稿