мультиномиальный pmf в python scipy/numpy

Есть ли встроенная функция в scipy/numpy для получения PMF многочлена? Я не уверен, что binom правильно обобщает, например.

# Attempt to define multinomial with n = 10, p = [0.1, 0.1, 0.8]
rv = scipy.stats.binom(10, [0.1, 0.1, 0.8])
# Score the outcome 4, 4, 2
rv.pmf([4, 4, 2])

Каков правильный способ сделать это? Благодарю.


person Community    schedule 16.12.2012    source источник
comment
Просто для полноты в scipy был класс scipy.stats.multinomial, который реализует полиномиальное распределение, начиная с версии 0.19.0 (март 2017 г.). Вот ссылка на документы: docs.scipy. org/doc/scipy/reference/generated/   -  person L_W    schedule 27.01.2021


Ответы (1)


Насколько мне известно, встроенной функции нет, и биномиальные вероятности не обобщаются (вам нужно нормализовать другой набор возможных результатов, поскольку сумма всех подсчетов должна быть равна n, о чем не будет заботиться независимые биномы). Однако довольно просто реализовать себя, например:

import math

class Multinomial(object):
  def __init__(self, params):
    self._params = params

  def pmf(self, counts):
    if not(len(counts)==len(self._params)):
      raise ValueError("Dimensionality of count vector is incorrect")

    prob = 1.
    for i,c in enumerate(counts):
      prob *= self._params[i]**counts[i]

    return prob * math.exp(self._log_multinomial_coeff(counts))

  def log_pmf(self,counts):
    if not(len(counts)==len(self._params)):
      raise ValueError("Dimensionality of count vector is incorrect")

    prob = 0.
    for i,c in enumerate(counts):
      prob += counts[i]*math.log(self._params[i])

    return prob + self._log_multinomial_coeff(counts)

  def _log_multinomial_coeff(self, counts):
    return self._log_factorial(sum(counts)) - sum(self._log_factorial(c)
                                                    for c in counts)

  def _log_factorial(self, num):
    if not round(num)==num and num > 0:
      raise ValueError("Can only compute the factorial of positive ints")
    return sum(math.log(n) for n in range(1,num+1))

m = Multinomial([0.1, 0.1, 0.8])
print m.pmf([4,4,2])

>>2.016e-05

Моя реализация полиномиального коэффициента несколько наивна и работает в пространстве журнала, чтобы предотвратить переполнение. Также имейте в виду, что n лишний параметр, так как он задается суммой значений (и один и тот же набор параметров работает для любого n). Кроме того, поскольку это быстро потеряет значение для умеренной n или большой размерности, вам лучше работать в пространстве журнала (logPMF также предоставляется здесь!)

person Ben Allison    schedule 20.12.2012