[英]Plotting the PMF of the Poission Distribution of Columns from a csv Dataframe
[英]Poission Distribution considering time left
我想計算在n
分鍾的足球比賽中每個結果的剩余概率。
在這種情況下,我預計70
分鍾時主隊的進球數為2.69
,客隊的進球數為1.12
,目前的結果是2-1
代碼
from scipy.stats import poisson
from itertools import product
import numpy as np
import pandas as pd
xgh = 2.69
xga = 1.12
minute = 70
hg, ag = 2,1
phs=[]
pas=[]
for i, l in zip(range(0, 6), range(0, 6)):
ph = poisson.pmf(mu=xgh, k=i, loc=hg)
phs.append(ph)
pa = poisson.pmf(mu=xga, k=l, loc=ag)
pas.append(pa)
prod_table = np.array([(i*j) for i, j in product(phs, pas)])
prod_table.shape = (6, 6)
prob_df = pd.DataFrame(prod_table, index=range(0,6), columns=range(0, 6))
這返回2-1
最終結果的概率為2.21%
,這是相當低的,考慮到只剩下20
分鍾,我預計概率很高
泊松分布是一個事件在給定時間范圍內發生 k 次的概率,已知該事件平均應該在同一時間范圍內發生 μ 次。
泊松分布的假設是事件是完全獨立的。 所以它已經發生了多少次是沒有意義的。 並且它們是均勻分布的(如果我可以使用這個令人困惑的詞,因為這不是均勻分布)。
大多數時候,泊松的用途是計算 k 個事件在時間幀 T 內發生的概率,當我們知道 μ 個事件平均發生在時間幀 τ 內(與第 1 句話的區別在於 T 和 τ 不相同)。
但這是容易的部分:因為事件是均勻分布的,如果 μ 事件平均發生在時間范圍 τ 內,那么 μ×T/τ 事件平均應該發生在時間范圍 T 內(理解:如果我們要實驗數百萬個時間幀 T,那么平均而言,每個時間幀中應該有 μT/τ 事件)。
因此,要計算事件在時間幀 T 中發生 k 次的概率,知道它在時間幀 τ 中發生 μ 次,您只需回答問題“事件在時間幀 T 中發生了多少次 k 次,知道它在該時間范圍內發生 μT/τ 次”。 這是泊松可以回答的問題。
在 python 中,答案是poisson.pmf(k, μT/τ)
。
在您的情況下,您知道 μ,即 90 分鍾時間范圍內預期的目標數量。 你知道剩下的得分時間是 20 分鍾。 如果在 90 分鍾的時間范圍內預計有 2.69 個進球,那么在 20 分鍾的時間范圍內預計會有 0.5978 個進球(至少,泊松假設事情是這樣進行的)。 因此,該團隊在該時間范圍內沒有進球的概率是poisson.pmf(0, 0.5978)
。 或者,使用您的關鍵字樣式poisson.pmf(mu=0.5978, k=0)
。 或者使用loc
,使目標poisson.pmf(mu=0.5978, k=2, loc=2)
(但這只是裝飾性的。有一個 loc 參數只需用k-loc
替換 k )
因此,長話短說,您只需要按比例縮小xgh
和xga
,以便它們反映剩余時間內的預期目標數量。
for i, l in zip(range(0, 6), range(0, 6)):
ph = poisson.pmf(mu=xgh*(90-minute)/90, k=i, loc=hg)
phs.append(ph)
pa = poisson.pmf(mu=xga*(90-minute)/90, k=l, loc=ag)
pas.append(pa)
在此期間,由於有一個python
標簽,對代碼進行了一些評論
for i, l in zip(range(0, 6), range(0, 6)):
print(i,l)
產生
0 0
1 1
2 2
3 3
4 4
5 5
所以不使用單個變量是很奇怪的。 特別是如果你認為你無法使用不同的范圍( zip
必須與相同長度的迭代一起使用。我們不知道在什么情況下,我們需要,例如, i 從 0 增長到 5 , 而 l 將從 0 增長到 10)
所以就
for k in range(0, 6):
ph = poisson.pmf(mu=xgh*(90-minute)/90, k=k, loc=hg)
phs.append(ph)
pa = poisson.pmf(mu=xga*(90-minute)/90, k=k, loc=ag)
pas.append(pa)
我推測,特別是因為下一個評論的 object 是什么,曾幾何時,在您意識到這是多次計算完全相同的pmf
之前,有一個product
而不是那個zip
。
product 的使用可能已經簡化為計算所有i,j
的phs[i]×pas[j]
的任務。 這是product
的一個很好的用法。
但是,由於您有 2 個 arrays,並且您打算從這些phs[i]×pas[j]
構建一個 numpy 數組,所以讓 numpy 來完成這項工作。 它會更有效率。
prod_table = np.array(phs).reshape(-1,1)*np.array(pas)
這導致了另一個優化。 如果目標是將phs
和pha
轉換為 arrays,以便我們可以將它們相乘(一個作為行,另一個作為列)得到表格,為什么不讓 numpy 直接構建該數組。 和 numpy function 一樣, pmf
可以讓 k 是一個列表而不是標量,然后返回一個列表而不是標量。
所以
phs=poisson.pmf(mu=xgh*(90-minute)/90, k=range(6), loc=hg)
pas=poisson.pmf(mu=xga*(90-minute)/90, k=range(6), loc=ag)
所以,一共
prod_table=poisson.pmf(mu=xgh*(90-minute)/90, k=range(6), loc=hg).reshape(-1,1)*poisson.pmf(mu=xga*(90-minute)/90, k=range(6), loc=ag)
優化 | 時間(微秒) |
---|---|
沒有 | 1647 微秒 |
和 | 329微秒 |
因此,它不僅是最緊湊和可讀的。 它也(幾乎正好)快了 5 倍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.