2

I'm performing Data Science and am calculating the Log Likelihood of a Poisson Distribution of arrival times.

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

Mathematically, the expression is on the last line:

Text

Is there a more pythonic way to perform this sum? Perhaps in one line?

  • You COULD write that using a comprehension (`ll = sum(... for t in arrival_times)`), but it would take the same time and I'm not convinced it is more readable. – Tim Roberts Oct 03 '21 at 02:52

3 Answers3

3

Seems perfectly Pythonic to me; but since numpy is already here, why not to vectorize the whole thing?

return (
    -_lambda
    + arrival_times * np.log(_lambda)
    - np.log(np.vectorize(np.math.factorial)(arrival_times))
).sum()
Marat
  • 15,215
  • 2
  • 39
  • 48
1

If you have scipy available, use loggamma which is more robust than chaining log and factorial:

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
loopy walt
  • 868
  • 2
  • 6
0

This looks ugly to me but it fits a single line:

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