はじめに
「宝くじは儲かるのか?」という問いですが、結論から言います。
儲かりません。
宝くじは、主催者側の利益が極めて大きい事業です。当選金額の還元率は50%を下回ります1。これは競馬、競輪、競艇、オートレースの75%前後と比べて圧倒的に低い値です。しかも、当選はランダムに決まる為、競馬の様な予想も不可能です。作家の橘玲氏はこれを「愚か者に課せられた税金」と表現しています。
しかしながら、勝算があるとすれば、当選金額のランダムな揺らぎが大きい小口で買う場合でしょう。確率論に「大数の法則」というものがあります。ある確率分布から標本を抽出して平均を出す時、その平均は確率分布の真の平均に収束していくという法則です。では、**標本数が小さい場合であれば、ランダムな揺らぎにより元が取れる可能性が高まるのではないか?**これを確かめてみようと思います。
環境
- Windows 10
- Python 3.8.3
- Jupyterlab Version 2.1.5
実験
宝くじにも色々ありますが、今回はLOTO7を選びました。理由は一等が極めて高額で話題性が高く、いかにも「宝くじらしい」からです。また、一般的な例について検討したかったので、キャリーオーバーは今回は考えませんでした。当選口数による当選金額の変動も考えていません。下に、Loto7の当選金額を計算するクラスを作成しました。
import numpy as np
class Loto7:
"""
Loto7の当選金額を計算するクラス
"""
def __init__(self, main_nums, bonus_nums):
self.main_nums = set(main_nums) # 本数字
self.bonus_nums = set(bonus_nums) # ボーナス数字
def prize_amount(self, nums=None):
nums = self.rand() if nums is None else set(nums)
diff_main = self.main_nums & nums
len_main = len(diff_main) # 本数字との一致数
diff_bonus = self.bonus_nums & nums
len_bonus = len(diff_bonus) # ボーナス数字との一致数
if len_main == 7: # 1st prize
return 600_000_000
if len_main == 6: # 2nd and 3rd
return 7_300_000 if len_bonus == 1 else 730_000
if len_main == 5: # 4th
return 9_100
if len_main == 4: # 5th
return 1_400
if len_main == 3 and len_bonus > 0: # 6th
return 1_000
else:
return 0
def rand(self): # ランダムな数字を選択
r = np.random.choice(np.arange(1,38), 7, replace=False)
return set(r)
上で定義したクラスを使って、ランダムに数字を選んで当選金額を計算します。計算の仕方は、以下です。
- 宝くじをランダムな番号でn本買ったとして、当選金額の合計を出す
- それをnで割って一本当たりの金額を出す
- 上記を決まった数だけ繰り返して、一本当たりの当選金額の分布を出す
- 上記について、nを色々な値で試す
また、当選番号である本数字とボーナス数字は固定にしました。実際の手続きとして、これらの番号はランダムに決まると考えられるので、購入者が決める番号との関係で考えれば、固定でも差し支えないと考えました。
lt7 = Loto7([1,2,3,4,5,6,7], [8,9]) # 当選番号である本数字とボーナス数字は固定
n_lots = list(range(1,10)) + list(range(10,30,2)) + [30, 100, 300, 1000] # 買う宝くじの本数
reps = 1000 # 購入の繰り返しの回数
prize_amounts = [sum([lt7.prize_amount() for i in range(n)]) / n for n in n_lots for r in range(reps)]
prize_amounts = np.array(prize_amounts).reshape(len(n_lots), reps)
これで計算が済みました。では、LOTO7の一枚の購入価格300円以上の当選金額があるケースはどのくらいあるのでしょうか?以下に、購入枚数と「元が取れた割合」の関係を示したグラフを描きます。
recovery_rate = np.apply_along_axis(lambda x: (x >= 300).sum() / len(x), 1, prize_amounts)
plt.plot(n_lots, recovery_rate);
plt.xscale('log')
plt.xlabel('number of LOTO7 tickets')
plt.ylabel('recovery rate')
plt.show()
print(n_lots)
print(recovery_rate)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 100, 300, 1000]
# [0.042 0.083 0.104 0.062 0.018 0.024 0.022 0.025 0.019 0.014 0.018 0.017
# 0.022 0.012 0.009 0.024 0.024 0.024 0.024 0.028 0.002 0.008 0.011]
これから分かることは、以下の二つです。
- 最も「元が取れる」購入枚数は3枚
- その場合、10%程度の確率で元が取れる
結論。
儲かりません。
賢明な人は宝くじは止めましょう!
以上。