見出し画像

「数学の言葉で世界を見たら」をPython で見たら… Vol.3 賭けに勝って帰れる確率

第1話「不確実な情報から判断する」

書籍の著者 大栗博司 先生


書籍「数学の言葉で世界を見たら」第1話「不確実な情報から判断する」の Python写経活動記録 です。 

第2節「ギャンブルで負けない方法」を Python でシミュレーションします。
ギャンブルの数学的なモデルに惹かれました。

では書籍を開いて数学の旅に出発です🚀


はじめに


このブログシリーズは、書籍「数学の言葉で世界を見たら」(幻冬舎)で学んだ「数学の楽しさ」を「Python 写経の形式」でご紹介いたします。

【引用表記】
この記事は、出典に記載の書籍に掲載された文章とデータを引用し、適宜、掲載文章・データを改変して書いています。
【出典】
「数学の言葉で世界を見たら」 第3刷、著者 大栗博司、幻冬舎

2 ギャンブルで負けない方法


学びポイント

賭けの対象の出現確率をほんの少し変えることで、ギャンブルに勝って帰れる確率が大きく変わることを体感できます。

この記事で用いるライブラリをインポートします。

## インポート
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Meiryo'  # または import japanize_matplotlib

ギャンブルの内容

書籍 p.18 のギャンブルの内容は:

  • コイン投げをして表が出る確率を $${p}$$、裏が出る確率を $${q}$$ とする

  • 表が出たら1貰えて、裏が出たら1取られる賭けをする

  • 持ち金 $${m}$$が目標金額 $${N}$$ に達するか、持ち金がゼロになって破産するまで、賭けは続く

勝って帰れる確率 $${P(m, N)}$$ は次のようになるそうです。

$$
P(m, N) = 
\begin{cases}
\cfrac{1-(q/p)^m}{1-(q/p)^N} & p\neq1/2 かつ q\neq 1/2 \\
\\
m/N & p=q=1/2 \\
\end{cases}
$$

書籍の数式を引用

ギャンブル・シミュレーション

書籍の2つのケースで勝って帰れる確率を算出します。

「勝って帰れる確率」算出関数を定義します。

### 勝って帰れる確率の関数定義  ※ P(n, N) = (1 - (q/p)^m) / (1 - (q/p)^N)
# 引数 p: 表が出る確率, m: 元金, N: 目的金額

def win_prob(p, m, N):

    ## 設定と準備
    # 結果を格納するnumpy配列の初期化
    probs = np.zeros_like(p)

    ## p==0.5の計算
    # p==0.5 のマスクを作成
    mask = np.isclose(p, 0.5)
    # m/N を設定
    probs[mask] = m / N

    ## P!=0.5の計算
    # 比率 q/p の算出
    ratio = (1 - p[~mask]) / p[~mask]
    # 確率値を設定
    probs[~mask] = (1 - ratio**m) / (1 - ratio**N)

    # 戻り値:目的金額Nを達成できる確率
    return probs

【実行結果】なし

1️⃣ $${p=q=1/2,\ m=100,\ N=200}$$ の場合

## 設定
# 表の出る確率
ps = np.array([0.50])
# 元金
m = 100
# 目標金額
N = 200

## 確率の計算
probs = win_prob(ps, m, N)
print(f'p={ps[0]:.2f}, m={m}, N={N} のとき、勝って帰れる確率は {probs[0]:.3f} です')

【実行結果】
表が出る確率が $${50\%}$$ だと、勝って帰れる確率も破産する確率も $${50\%}$$ です。

2️⃣ $${p=0.49,\ q=0.51,\ m=100,\ N=200}$$ の場合
表が出る確率が $${49\%}$$ という、少々、不利な条件になった場合に、勝って帰れる確率はどうなるでしょう?

## 設定
# 表の出る確率
ps = np.array([0.49])
# 元金
m = 100
# 目標金額
N = 200

## 確率の計算
probs = win_prob(ps, m, N)
print(f'p={ps[0]:.2f}, m={m}, N={N} のとき、勝って帰れる確率は {probs[0]:.3f} です')

【実行結果】
なんと勝って帰れるのは約 $${2\%}$$!
破産する確率が約 $${98\%}$$ です。
表の出る確率が $${1\%}$$ 小さくなっただけで、ほぼ破産するのです!

先生は「ちょっとでも不利なギャンブルは、してはいけない」と警鐘を鳴らしています。

3️⃣ $${p=0.51,\ q=0.49,\ m=100,\ N=200}$$ の場合
表が出る確率が $${51\%}$$ という、少々、有利な条件になった場合に、勝って帰れる確率はどうなるでしょう?

## 設定
# 表の出る確率
ps = np.array([0.51])
# 元金
m = 100
# 目標金額
N = 200

## 確率の計算
probs = win_prob(ps, m, N)
print(f'p={ps[0]:.2f}, m={m}, N={N} のとき、勝って帰れる確率は {probs[0]:.3f} です')

【実行結果】
ご想像どおり、勝って帰れる確率は約 $${98\%}$$ です。
ほぼ勝って帰れます!

先生は「ほんの少しでも有利なときに、十分お金を持って始めれば、ほとんど確実に勝てる」がギャンブル必勝法と教えてくれます。

表が出る確率と勝って帰れる確率の関係

表が出る確率を変えてみて、勝って帰れる確率がどんな変化を見せるのか、可視化で確認しましょう。

1️⃣ 元金 $${m=100}$$、目標金額 $${N=200}$$ の場合

### 勝って帰れる確率の計算

## 設定
# 表の出る確率
ps = np.linspace(0.48, 0.52, 1001)
# 元金
m = 100
# 目標金額
N = 200

## 確率の計算
probs = win_prob(ps, m, N)

## 可視化
# 確率曲線の描画
plt.plot(ps, probs)
# 修飾
plt.title(f'元金 {m}, 目標金額 {N} の場合')
plt.xlabel('表が出る確率 $p$', fontsize=12)
plt.ylabel('目標金額を達成する確率', fontsize=12)
plt.ylim(-0.1, 1.1)
plt.grid(lw=0.5, alpha=0.5);

【実行結果】
表が出る確率が $${0.48}$$ で勝って帰れる確率がほぼ0になります。
表が出る確率が $${0.52}$$ で勝って帰れる確率がほぼ1になります。
ほんの少し、表が出る確率が変わることで、トータルの勝ち・負けが大きく変わる様子がわかりました。

2️⃣ 元金 $${m=100}$$、目標金額 $${N=1000}$$ の場合
$${10}$$ 倍を目指してみます。

### 勝って帰れる確率の計算

## 設定
# 表の出る確率
ps = np.linspace(0.48, 0.52, 1001)
# 元金
m = 100
# 目標金額
N = 1000

## 確率の計算
probs = win_prob(ps, m, N)

## 可視化
# 確率曲線の描画
plt.plot(ps, probs)
# 修飾
plt.title(f'元金 {m}, 目標金額 {N} の場合')
plt.xlabel('表が出る確率 $p$', fontsize=12)
plt.ylabel('目標金額を達成する確率', fontsize=12)
plt.ylim(-0.1, 1.1)
plt.grid(lw=0.5, alpha=0.5);

【実行結果】
表が出る確率が僅かに小さくなっただけで、勝って帰れる確率が0になります。
表が出る確率が大きくなる場合は、1️⃣ と似た形状になっています。
欲を出すと…ですね…

3️⃣ 元金 $${m=100}$$、目標金額 $${N=100}$$ の場合
ギャンブルする時間を楽しめれば良くて、トントンで帰ることを考えます。

### 勝って帰れる確率の計算

## 設定
# 表の出る確率
ps = np.linspace(0.001, 0.999, 1001)
# 元金
m = 100
# 目標金額
N = 100

## 確率の計算
probs = win_prob(ps, m, N)

## 可視化
# 確率曲線の描画
plt.plot(ps, probs)
# 修飾
plt.title(f'元金 {m}, 目標金額 {N} の場合')
plt.xlabel('表が出る確率 $p$', fontsize=12)
plt.ylabel('目標金額を達成する確率', fontsize=12)
plt.ylim(-0.1, 1.1)
plt.grid(lw=0.5, alpha=0.5);

【実行結果】
こ、こ、これは…?
「賭けをしないで帰りなさい」という意思決定が合理的、なのですね。
楽しい時間を過ごさせてくれませんw

おわり


シリーズの記事

次の記事

前の記事

目次

ブログの紹介


note で7つのシリーズ記事を書いています。
ぜひ覗いていってくださいね!

1.のんびり統計

統計検定2級の問題集を手がかりにして、確率・統計をざっくり掘り下げるブログです。
雑談感覚で大丈夫です。ぜひ覗いていってくださいね。
統計検定2級公式問題集CBT対応版に対応しています。
Python、EXCELのサンプルコードの配布もあります。

2.実験!たのしいベイズモデリング1&2をPyMC Ver.5で

書籍「たのしいベイズモデリング」・「たのしいベイズモデリング2」の心理学研究に用いられたベイズモデルを PyMC Ver.5で描いて分析します。
この書籍をはじめ、多くのベイズモデルは R言語+Stanで書かれています。
PyMCの可能性を探り出し、手軽にベイズモデリングを実践できるように努めます。
身近なテーマ、イメージしやすいテーマですので、ぜひぜひPyMCで動かして、一緒に楽しみましょう!

3.実験!岩波データサイエンス1のベイズモデリングをPyMC Ver.5で

書籍「実験!岩波データサイエンスvol.1」の4人のベイジアンによるベイズモデルを PyMC Ver.5で描いて分析します。
この書籍はベイズプログラミングのイロハをざっくりと学ぶことができる良書です。
楽しくPyMCモデルを動かして、ベイズと仲良しになれた気がします。
みなさんもぜひぜひPyMCで動かして、一緒に遊んで学びましょう!

4.楽しい写経 ベイズ・Python等

ベイズ、Python、その他の「書籍の写経活動」の成果をブログにします。
主にPythonへの翻訳に取り組んでいます。
写経に取り組むお仲間さんのサンプルコードになれば幸いです🍀

5.RとStanではじめる心理学のための時系列分析入門 を PythonとPyMC Ver.5 で

書籍「RとStanではじめる心理学のための時系列分析入門」の時系列分析をPythonとPyMC Ver.5 で実践します。
この書籍には時系列分析のテーマが盛りだくさん!
時系列分析の懐の深さを実感いたしました。
大好きなPythonで楽しく時系列分析を学びます。

6.データサイエンスっぽいことを綴る

統計、データ分析、AI、機械学習、Pythonのコラムを不定期に綴っています。
統計・データサイエンス書籍にまつわる記事が多いです。
「統計」「Python」「数学とPython」「R」のシリーズが生まれています。

7.Python機械学習プログラミング実践記

書籍「Python機械学習プログラミング PyTorch & scikit-learn編」を学んだときのさまざまな思いを記事にしました。
この書籍は、scikit-learnとPyTorchの教科書です。
よかったらぜひ、お試しくださいませ。

最後までお読みいただきまして、ありがとうございました。

いいなと思ったら応援しよう!

ネイピア DS 応援ありがとうございます。これからもがんばって記事を作成します!

この記事が参加している募集