【问题标题】:Pythonic way to calculate cumulative sum with complex math over numpy array在 numpy 数组上使用复杂数学计算累积和的 Pythonic 方法
【发布时间】:2021-11-24 00:51:43
【问题描述】:

我正在执行数据科学并正在计算到达时间的泊松分布的对数似然。

def LogLikelihood(arrival_times, _lambda):
  """Calculate the likelihood that _lambda predicts the arrival_times well."""
  ll = 0
  for t in arrival_times:
    ll += -(_lambda) + t*np.log(_lambda) - np.log(factorial(t))
  return ll

数学上,表达式在最后一行:

有没有更 Pythonic 的方式来执行这个求和?也许在一行?

【问题讨论】:

  • 您可以使用推导式 (ll = sum(... for t in arrival_times)) 来编写它,但这需要同样的时间,而且我不相信它更具可读性。

标签: python numpy data-science log-likelihood


【解决方案1】:

在我看来完全是 Pythonic;但是既然numpy 已经在这里了,为什么不把整个东西向量化呢?

return (
    -_lambda
    + arrival_times * np.log(_lambda)
    - np.log(np.vectorize(np.math.factorial)(arrival_times))
).sum()

【讨论】:

  • 啊哈,我的意思是“矢量化”而不是“一行”!我正在寻找这样的东西!
【解决方案2】:

如果您有可用的 scipy,请使用 loggamma,它比链接 logfactorial 更强大:

from scipy import special

def loglikeli(at,l):
    return (np.log(l)*at-l-special.loggamma(at+1)).sum()

### example 
rng = np.random.default_rng()
at = rng.integers(1,3,10).cumsum()
l = rng.uniform(0,1)

### check against OP's impementation
np.isclose(loglikeli(at,l),LogLikelihood(at,l))
# True

【讨论】:

  • 我认为这是一个比我更好的答案
【解决方案3】:

这对我来说看起来很丑,但它适合一行:

def LogLikelihood(arrival_times, _lambda):
    return np.cumsum(list(map(lambda t: -(_lambda) + t*np.log(_lambda) - np.log(factorial(t)),arrival_times)))[-1]

【讨论】:

    猜你喜欢
    • 2017-08-03
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2017-04-02
    • 2020-08-07
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多