二項分布は試行回数が多くなると階乗周りの計算量が多くなる。一回の事象の発生確率pが十分に小さければ、ポアソン分布で近似ができる。
例えば、5枚の硬貨を投げてすべて表がでるかどうかを64回やったときの分布を二項分布とポアソン分布で比較すると、以下のように高い精度で近似できていることがわかる。
import scala.math.BigInt def factor(n: BigInt): BigInt = if (n <= 1) 1 else n * factor(n - 1) def combi(n: BigInt, m: BigInt): BigInt = factor(n) / factor(m) / factor(n - m) def binomialDistribution(n: Int, p: Double): (Int) => Double = { import scala.math.pow def distribution(x: Int) = combi(n, x).toDouble * pow(p, x) * pow(1 - p, n - x) distribution _ } def poissonDistribution(m: Double): (Int) => Double = { import scala.math.pow def distribution(x: Int) = pow(m, x).toDouble / pow(2.71828, m).toDouble / factor(x).toDouble distribution _ } val n = 64 val p = 1.0 / 32.0 val binomial = binomialDistribution(n, p) val poisson = poissonDistribution(n * p) (0 to 10).foreach {n => println("[n=%d]".format(n)) println("binomial: %.3f".format(binomial(n))) println("poisson: %.3f".format(poisson(n))) }
[n=0] binomial: 0.131 poisson: 0.135 [n=1] binomial: 0.271 poisson: 0.271 [n=2] binomial: 0.275 poisson: 0.271 [n=3] binomial: 0.183 poisson: 0.180 [n=4] binomial: 0.090 poisson: 0.090 [n=5] binomial: 0.035 poisson: 0.036 [n=6] binomial: 0.011 poisson: 0.012 [n=7] binomial: 0.003 poisson: 0.003 [n=8] binomial: 0.001 poisson: 0.001 [n=9] binomial: 0.000 poisson: 0.000 [n=10] binomial: 0.000 poisson: 0.000