Published Date : 2020年11月25日10:47

1/2 Pythonを使った期待値を計算する簡単なアプリ
1/2 ​Simple app that calculates expectations using Python


This blog has an English translation


YouTubeにアップした動画、「【日本語解説】1/2 Pythonを使った期待値を計算する簡単なアプリ」の補足説明の記事です。

Here's a little more about the 「【Python】1/2 ​Simple app that calculates expectations using Python」 video I uploaded to YouTube.

字幕を付けるなら、英語音声と日本語音声の二つに分けたほうが良いと思ったので、今回から同じ動画だが音声が日本語と英語に分かれたものをアップしました。

I thought it would be better to separate the video into English audio and Japanese audio instead of adding subtitles to the video, so I uploaded the same video with Japanese and English audio separately.

ページの頭に日本語解説動画、ページの最後に英語解説動画のリンクが貼られてます。

There is a Japanese explanation video at the top of the page, and an English explanation video link at the end of the page.


目次

Table of Contents




① 動画の説明
① Video Description



例えば、サイコロの出た目によって賞金が異なるゲームを何回か行うとします。

For example, suppose you play a game several times with different prize money depending on the number shown on the dice.

サイコロの目が1か6なら3円、3か4なら1円、2か5なら0円といった具合です。

​If the number of the dice is 1 or 6, it is 3 yen, if 3 or 4, it is 1 yen, if 2 or 5, it is 0 yen, and so on.

このとき、サイコロの数の1から6まで出る確率はそれぞれ1/6です。

​In this case, the probability of 1 to 6 of the number of dice is 1/6 each.

このゲームの期待値を求めて、参加費が2円の場合、このゲームに参加するのが得か損かを決めていきます。

Looking at the expected value of this game, if the participation fee is 2 yen, we will decide whether it is profitable or not to participate in this game.

期待値の求め方は単純で、確率分布表といわれるものを作り、各確率に賞金を掛けてそれぞれの期待値を求めて、期待値の合計を導き出します。

The calculation of the expected value is simple. A probability distribution table is created, and each probability is multiplied by a prize money to obtain each expected value, and the sum of the expected values is obtained.

その合計された期待値に対して、参加費用を引いた数がマイナスならその勝負は引き受けないほうが無難でしょう。

​If the total expected value minus the participation fee is negative, it would be better not to accept the match.

それではJupyter Notebookを開いて、Pythonスクリプトでテストしてみましょう。必要なモジュールをインポートしてください。

​Now let's ​open the Jupyter Notebook and test it with a Python script. ​Import the required modules.

> jupyter-notebook

宝くじの当選本数と、当選金額等をあらかじめまとめたCSVファイルを読み込みます。

The number of winning prizes and the amount of winning prizes are collected in advance, made into CSV file, and it is read.

df = pd.read_csv('csvfile.csv')

今回の1ユニットは2,000万枚の設定です。

This time, each unit is set to 20 million.

unit = 2000 * 10000

24ユニット。

24 units.

units = 24

宝くじ一枚の販売価格(300円)。

​the selling price of a lottery ticket (300 yen).

price = 300

1ユニット(2000万枚)あたりの当選本数。

​Number of winning units per unit (20 million sheets).

nw_upu = df['本数'].apply(lambda x: int(x.replace('本',''))) /  units

1ユニット(2000万枚)あたりの当選本数とそれに対応する賞金額。

​Number of winning prizes per unit (20 million sheets) and corresponding prize money amount.

nw_upu_cpma = df['当せん金'].apply(lambda x: int(x.replace('円','')))

1ユニット(2000万枚)当たりの賞金総額。

Total award amount per 1 unit (20 million sheets).

print(f'{int(np.sum(nw_upu * nw_upu_cpma)):,}')

宝くじ一枚あたり300円掛ける一ユニット(2000万枚)。

Lottery tickets [300 yen] times [1 unit] (20 million sheets).

print(f'{price*unit:,}')
print(df[['等級等','当せん金']])

当選金は上から順に1等賞が7億円、1等前後賞が1億5千万円、1等の組違い賞が10万円、

in order from the top, The prize money is 700 million yen for the first prize, 150 million yen for the numbers before and after the first prize, It is the number of the first prize, but if the letter is different, it is 100,000 yen,

2等賞が1千万円、3等賞が百万円、4等賞が10万円、5等賞が1万円、6等賞が3000円、7等賞が300円です。

Then, 10 million yen for the second prize, 1 million yen for the third prize, 100,000 yen for the fourth prize, 10,000 yen for the fifth prize, 3000 yen for the sixth prize and 300 yen for the seventh prize.

総販売数は24ユニットだが、単純に24倍なので、1ユニットで計算しても確率は変わりません。なので分かりやすくするため、1ユニットで計算します。

​The total number of units sold is 24, but it is simply 24 times, so the probability won't change even if you calculate with 1 unit. ​So, to make it easier to understand, I calculate by 1 unit.

ps = nw_upu/unit
print(ps)

まずは確率分布表を作る。

First, create a probability distribution table.

1ユニット(2000万枚)あたりの当選本数から、各賞金ごとの確率を計算する。

​The probability of each prize money is calculated from the number of winning prizes per 1 unit (20 million sheets).

指数表記にしたく無い場合はデフォルトの6の桁数を、一番小さい値に合わせて増やせばいい。

If you do not want to use exponential notation, increase the default value of 6 to match the minimum value in the table.

print(pd.options.display.precision)
pd.options.display.precision = 8

一等が当たる確率は1億分の5。つまり2000万分の一の確率です。

The chance of winning the first prize is one in 20 million.

因みにこの確率は、同じ部屋にいる105人の誕生日がみんな違う確率より低確率です。

For your information, this probability means that the birthdays of 105 people in the same room are all less likely than different probabilities.

例えば1クラスで60人いる場合99%以上の確率で、同じ誕生日の組があることになります。

​For example, if there are 60 students in 1 class, the probability is 99% or more that there are the same birthday pairs.

a = 365 ** 105
print(a)
b = np.array([i for i in range(365-104, 365+1)], dtype=np.object)
print(b)
c = np.prod(b)/a
print(c)

ではこの確率に当選金額を掛け合わせます。

Then I will multiply this probability by the winning amount.

各期待値。

​each expected value

each_ev = ps * nw_upu_cpma
print(each_ev)

そして期待値の合計を計算します。

​It then calculates the sum of the expected values.

ev = each_ev.sum()
print(ev)

これはつまり、宝くじ一枚を300円で購入すると、期待値として147円が得られるだろうと考えます。

​This means that if you buy a lottery ticket for 300 yen, you will get an expected 147 yen.

これが得か得ではないかは各自の考えに委ねます。

I'll leave it up to you to decide whether this is good or bad.

temp_df = pd.concat([ps, each_ev], axis=1)
print(temp_df)

ではこれをpandasのdataframeにして、表としてまとめます。

Let's turn this into a dataframe for pandas and summarize it as a table.

最後にデータフレームをCSVファイルとして保存します。

​Finally, save the data frame as a CSV file.

temp_df.columns = ['確率','期待値']
print(temp_df.columns)
ps_ev_df = pd.concat([df, temp_df], axis=1)
print(ps_ev_df)
ps_ev_df.to_csv('ev.csv', index=None)


以上です。お疲れ様です。

That's all. Thank you for your hard work.