繁体   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