13

多項分布のPMFを取得するための組み込み関数がscipy/numpyにありますか?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])

これを行う正しい方法は何ですか?ありがとう。

4

1 に答える 1

9

私が知っている組み込み関数はなく、二項確率は一般化されません(すべてのカウントの合計は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もここで提供されます!)

于 2012-12-20T14:39:08.220 に答える