ガチャの確率をPythonで検証しよう

先生、ゲームの5枚入りのカードパックを50個買ったんですけど、狙っているレアカードが全然当たらないんです。確率「1%」って書いてあたんだけど⋯
これって仮説検定で確かめたりできますか?

カードとかゲームのガチャってホント当たんないよね。

確率って書いてあっても、本当にその通りなのか気になるよね。

そうですね。今回はPythonを使って、カードパックの結果をシミュレーションしながら仮説検定を考えてみます。

コンピュータを使うと、同じ実験を何千回、何万回も繰り返すことができます。

繰り返して試行回数を増やせば、本当に確率が正しいのかをより正確に考えることができます。

そうか、プログラムを作ってしまえば何回も実行することができるんだ。

何回も試せれば、「たまたまなのかどうか」も分かりそうですね。

その通りです。

人の手では難しい回数の実験も、コンピュータなら簡単にできるので、 確率のばらつきや結果の珍しさをしっかり確かめることができます。

今回のカードパックは次のような設定とします。

カードパックの設定

・1パック:5枚入り

・レアカードの確率:1%

育人君は50パック買ったので

引いたカード枚数

50パック × 5枚 = 250枚

確率が1%なら、平均的には次のくらいレアカードが出そうです。

期待値

250 × 0.01 = 2.5枚

俺が買ったときはレアカードが0枚だったんだよな⋯。

250枚引いて0枚!?それはかなり運が悪いね。

ここで次の疑問が生まれます。

考えること

これはただ運が悪かっただけ?

それとも確率がおかしい?

この結果は「ただ運が悪かっただけ」なのか、それとも「確率がおかしい」のか検証をしていきましょう!

1. 今日のテーマ

今日のテーマは、Pythonでカードガチャをシミュレーションし、仮説検定で確率を確かめることです。

シミュレーションの結果を見て、「たまたま起こったのか」、「珍しすぎるので何かおかしいのか」を考えます。

学習目標

・シミュレーションで確率のぶれを確かめる

・仮説を立てる

・p値の意味を理解する

・仮説検定の流れをつかむ

これらを踏まえ、今回の仮説(帰無仮説)を次のようにします。

今回の帰無仮説

カード1枚あたりのレアカードの確率は1%である

1. Pythonで1枚引くプログラムを作ろう

Pythonを使用して、ガチャを引くシミュレーションを行います。

プログラムの実行はGoogle Colabで行います。下記のリンクからGoogle Colabを開きましょう。

新しくノートブック「ip0407」を作成してください。

まずは、Pythonで1枚カードを引くプログラムを作ります。レアカードの確率が1%なので、ランダムな数を使って再現します。

次のプログラムを「Google Colab」に入力して実行しましょう。

import random

probability = 0.01
    
if random.random() < probability:
    print("レア")
else:
    print("ノーマル")

プログラムのポイント

・1行目:randomモジュールを読み込み、ランダムな数を使えるようにする

・3行目:probability = 0.01でレアの確率(1%)を設定する

・5行目以降:ランダムな数が0.01より小さいときだけ「レア」、それ以外は「ノーマル」と表示する

短いプログラムだけれど、確率を1%にして実行できるんですね。

はい。3行目で確率を設定しています。ここを変更すれば、いろいろなガチャの確率を再現できますよ。

ここでのポイント

・0.01 = 1%

・乱数を使うと確率をプログラムで表せる

・コンピュータでガチャを再現できる

問題1
10回プログラムを実行して「レア」が出た回数を記入してください。

1%だから、ほとんど「レア」って出なそう⋯

2. 250枚引くシミュレーションをしよう

次は、50パック分の250枚をまとめて引くプログラムにします。レアカードが何枚出たかを数えてみましょう。

次のプログラムを「Google Colab」に入力して実行しましょう。

import random
            
p = 0.01
rare_count = 0
            
for i in range(250):
    if random.random() < p:
        rare_count += 1
            
print("レアカードの枚数:", rare_count)

このプログラムを実行すれば、250枚買ったときにどれくらい当たるか分かるってことか⋯。

その通りです。ただし1回だけでは、たまたまそうなったのかどうかはまだわかりません。

問題2
10回プログラムを実行して、表示された「レアカードの枚数」を記入してください。

※記入例:1回目 2枚、2回目 0枚⋯の場合は「2,0,⋯」と入力してください。

問題3
今回のシミュレーションをした結果を踏まえ、250枚カードを引いてレアカードが0枚の場合はありうるのか、かなりレアな現象だと思うか答えてください。

3. 同じ実験を何度も繰り返そう

250枚を引くシミュレーションを10回行って「レアカードが0枚」だったことは何回ありましたか?

0回でした⋯。これは確率が間違っているんじゃないかと思う!

私は2回でした⋯。10回中2回は結構多いですね。

10回の試行をそれぞれしましたが、レアカードを引けない確率が、育人くんは0%、亜美さんは20%とばらつきましたね。

実験は試行回数が多いほど正しい値に近づきます。

仮説検定では、より正確にシミュレーションを行うために、250枚引く実験を10,000回繰り返します。

import random
            
p = 0.01
trial_count = 10000
zero_count = 0

for _ in range(trial_count):
    rare_count = 0

    for i in range(250):
        if random.random() < p:
            rare_count += 1

    if rare_count == 0:
        zero_count += 1

print("レア0枚になった回数:", zero_count)

10,000回も試せば、0枚になることがどれくらい珍しいかがわかりそうです。

はい。もし0枚がほとんど起こらないなら、「確率1%」という前提を疑いたくなりますね。

問題4 10,000回シミュレーションを行った結果(レア0枚になった回数)を答えてください。

4. シミュレーション結果から考えよう

俺の結果では、レアカードが0枚だったのは843回でした。

私も何回か実行したけど、800回くらいが多かったです。思ったより多い気がします。

結果には多少のばらつきがありますが、だいたいこのくらいの回数になることが多いですね。

10,000回シミュレーションした100回行った結果、レアカードが0枚だった回数が平均817回だったので、この結果を使って検証します。

次の手順で仮説が正しいか確認していきましょう。

確認手順

① シミュレーション結果からp値を求める

② p値と有意水準を比較し、仮説が正しいか判断する

① シミュレーション結果からp値を求める

まずは、実験の結果そのものを整理します。

今回は、10000回のシミュレーションのうち、レアカードが0枚だった回数が817回でした。

この段階では、「多い」「少ない」と判断するのではなく、まず事実として結果を正しく把握することが重要です。

でも、この結果だけ見ても、珍しいのかどうかはよくわからないですね。

たしかに。「817回」という数だけでは判断できないですね。

いいところに気づきましたね。そこで、割合に直して考える必要があります。

この割合が、「仮説が正しいときに今回のような結果が起こる確率」、つまりp値になります。

p値を計算しよう

p値を計算で求めます。
今回はレアカードが0枚の回数が、10,000回中817回でした。
この現象が発生する確率を求めることがp値を求めることになります。

p値を計算するヒント

p値は発生する確率なので次の計算式で求めます。

817 ÷ 10000

問題5
p値の値を答えてください。

② p値と有意水準を比較し、仮説が正しいか判断する

次に、求めたp値を、あらかじめ決めた基準である有意水準と比較します。

今回は、有意水準を0.05(5%)とします。

p値がこの値より小さい場合は「とても珍しい」と判断し、大きい場合は「珍しいとは言えない」と判断します。

つまり、p値と0.05を比べればいいんですね。

p値が小さければ「珍しい」、大きければ「そこまで珍しくない」と考えるんですね。

その通りです。そして、その結果をもとに「仮説が正しいか」を判断します。

判断のしかた

・p値 < 有意水準 → とても珍しい → 帰無仮説を棄却する(仮説が正しくない可能性が高い)

・p値 > 有意水準 → 珍しいとは言えない → 帰無仮説を棄却できない(仮説が間違いとは言い切れない)

なるほど。p値がどちら側かで結論が決まるんですね。

問題6
仮説が正しいかどうかと育人くん結果についての考察を答えてください。

では今回の結果ではどうなるでしょうか。ここまでの内容をもとに、結論を考えてフォームに答えてください。

最大 300 文字

※この再現版では提出は行いません(送信先は未接続です)

Well done!

次のステップに進みましょう!

次のステップに進む

← 前のステップにもどる