簡體   English   中英

考慮剩余時間的泊松分布

[英]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 )

tl;博士解決方案

因此,長話短說,您只需要按比例縮小xghxga ,以便它們反映剩余時間內的預期目標數量。

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)

其他的建議

zip

在此期間,由於有一個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,jphs[i]×pas[j]的任務。 這是product的一個很好的用法。

但是,由於您有 2 個 arrays,並且您打算從這些phs[i]×pas[j]構建一個 numpy 數組,所以讓 numpy 來完成這項工作。 它會更有效率。

prod_table = np.array(phs).reshape(-1,1)*np.array(pas)

直接從泊松獲取 arrays

這導致了另一個優化。 如果目標是將phspha轉換為 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM