문제

말하자는 내가 알고 확률"성공은"P.나는 테스트를 실행 N 시간,그리고 나는 참 S 성공이라고 할 수 있습니다.시험에 가깝게 던지는 고르지 않게 가중 동전(아마도 머리를 성공,꼬리,실패).

를 알고 싶 대략적인 확률을 보거나 들의 성공,또는 다수의 성공 가능성이 적 S 성공이라고 할 수 있습니다.

그래서 예를 들어,만약 P0.3,N 은 100,그리고 나는 20 성공,내가 찾는 점점 확률 20 또는 더 적게 성공이라고 할 수 있습니다.

는 경우,다른지 않았다면,P0.3,N 은 100,그리고 내가 40 성공,내가 찾는 점점 확률 40 우리의 더 많은 성공이라고 할 수 있습니다.

내가 알고 있는 이 문제에 관한 것을 찾는 지역에서 이항 curve,그러나:

  1. 나학-푸는 작업을하지 않습의 번역하고 이 지식으로 효율적인 코드
  2. 는 동안 내가 이해 이항 곡선을 제공하는 정확한 결과,나는 느낌을 얻을 것이라고 본질적으로 비효율적이다.빠른 방법을 계산하면 대략적인 결과 충분합니다.

나는 스트레스를 이 계산을 빠르고 하는 것이 이상적 보유하고 표준 64 또는 128 비트가 있습니다.

내가 찾는 함수,P,S,N-반환하는 확률입니다.내가 더 잘 알고 코드보다 수학적 기법,내가 선호하는 어떠한 답변을 고용 의사 코드 또는 코드입니다.

도움이 되었습니까?

해결책

정확한 이항 분포

def factorial(n): 
    if n < 2: return 1
    return reduce(lambda x, y: x*y, xrange(2, int(n)+1))

def prob(s, p, n):
    x = 1.0 - p

    a = n - s
    b = s + 1

    c = a + b - 1

    prob = 0.0

    for j in xrange(a, c + 1):
        prob += factorial(c) / (factorial(j)*factorial(c-j)) \
                * x**j * (1 - x)**(c-j)

    return prob

>>> prob(20, 0.3, 100)
0.016462853241869437

>>> 1-prob(40-1, 0.3, 100)
0.020988576003924564

정상 추정치, 큰 n에 좋습니다

import math
def erf(z):
        t = 1.0 / (1.0 + 0.5 * abs(z))
        # use Horner's method
        ans = 1 - t * math.exp( -z*z -  1.26551223 +
                                                t * ( 1.00002368 +
                                                t * ( 0.37409196 + 
                                                t * ( 0.09678418 + 
                                                t * (-0.18628806 + 
                                                t * ( 0.27886807 + 
                                                t * (-1.13520398 + 
                                                t * ( 1.48851587 + 
                                                t * (-0.82215223 + 
                                                t * ( 0.17087277))))))))))
        if z >= 0.0:
                return ans
        else:
                return -ans

def normal_estimate(s, p, n):
    u = n * p
    o = (u * (1-p)) ** 0.5

    return 0.5 * (1 + erf((s-u)/(o*2**0.5)))

>>> normal_estimate(20, 0.3, 100)
0.014548164531920815

>>> 1-normal_estimate(40-1, 0.3, 100)
0.024767304545069813

Poisson 추정 : 큰 N 및 작은 p에 적합

import math

def poisson(s,p,n):
    L = n*p

    sum = 0
    for i in xrange(0, s+1):
        sum += L**i/factorial(i)

    return sum*math.e**(-L)

>>> poisson(20, 0.3, 100)
0.013411150012837811
>>> 1-poisson(40-1, 0.3, 100)
0.046253037645840323

다른 팁

나는 우리가 계승이나 감마 기능이 정의되지 않은 환경에서 이항 CDF를 계산할 수 있어야하는 프로젝트에있었습니다. 몇 주가 걸렸지 만, 나는 CDF를 정확하게 계산하는 다음 알고리즘을 생각해 냈습니다 (즉, 근사치가 필요 없음). 파이썬은 기본적으로 의사 코드만큼 좋습니다.

import numpy as np

def binomial_cdf(x,n,p):
    cdf = 0
    b = 0
    for k in range(x+1):
        if k > 0:
            b += + np.log(n-k+1) - np.log(k) 
        log_pmf_k = b + k * np.log(p) + (n-k) * np.log(1-p)
        cdf += np.exp(log_pmf_k)
    return cdf

x와의 성능 스케일. X의 작은 값의 경우이 솔루션은 scipy.stats.binom.cdf, x = 10,000 정도의 유사한 성능으로.

StackoverFlow가 Mathjax를 지원하지 않기 때문에이 알고리즘을 완전히 도출하지 못하지만 그 추력은 먼저 다음 동등성을 식별합니다.

  • 모든 k> 0에 대해 sp.misc.comb(n,k) == np.prod([(n-k+1)/k for k in range(1,k+1)])

우리는 다음과 같이 다시 작성할 수 있습니다.

  • sp.misc.comb(n,k) == sp.misc.comb(n,k-1) * (n-k+1)/k

또는 로그 공간에서 :

  • np.log( sp.misc.comb(n,k) ) == np.log(sp.misc.comb(n,k-1)) + np.log(n-k+1) - np.log(k)

CDF는 PMF의 요약 이므로이 제형을 사용하여 이항 계수를 계산할 수 있습니다 (로그는 b 위의 함수에서) pmf_ {x = i}에 대한 of pmf_ {x = i-1}에 대해 계산했습니다. 이것은 우리가 축적기를 사용하여 단일 루프 내부에서 모든 것을 할 수 있음을 의미하며, 우리는 Factorials를 계산할 필요가 없습니다!

로그 공간에서 대부분의 계산이 수행되는 이유는 다항식 용어의 수치 안정성을 향상시키기 때문입니다. p^x 그리고 (1-p)^(1-x) 매우 크거나 매우 작을 가능성이있어 계산 오류가 발생할 수 있습니다.

편집 : 이것은 새로운 알고리즘입니까? 나는 이것을 게시하기 전에 그 이후로 튀어 나오고 있었고, 이것을 더 공식적으로 작성하고 저널에 제출 해야하는지 점점 궁금합니다.

나는 당신이 평가하고 싶다고 생각합니다 불완전한 베타 기능.

"C의 수치 레시피", 6 장 : '특별 함수'에서 지속적인 분수 표현을 사용하여 좋은 구현이 있습니다.

나는 효율성을 완전히 보증 할 수는 없지만 Scipy는 이것을위한 모듈

from scipy.stats.distributions import binom
binom.cdf(successes, attempts, chance_of_success_per_attempt)

효율적이고 더 중요한 것은 수치 안정 알고리즘이 도메인에 존재합니다. 베 지어 곡선 컴퓨터 보조 디자인에 사용됩니다. 그것은이라고 De Casteljau의 알고리즘 평가하는 데 사용됩니다 번스타인 다항식 베 지어 곡선을 정의하는 데 사용됩니다.

답변 당 하나의 링크 만 허용된다고 생각합니다. Wikipedia -Bernstein 다항식

이항 분포와 Bernstein 다항식 사이의 매우 밀접한 관계를 주목하십시오. 그런 다음 De Casteljau의 알고리즘 링크를 클릭하십시오.

특정 동전으로 머리를 던질 확률이 P입니다. 동전을 던지고 최소한 머리를 얻을 확률은 무엇입니까?

  • n = t를 설정하십시오
  • I = 0의 경우 베타 [i] = 0, ... S -1을 설정합니다.
  • i = s에 대해 베타 [i] = 1을 설정합니다. ... T
  • t = p를 설정하십시오
  • de casteljau를 사용하여 B (t)를 평가하십시오

아니면 대부분의 머리?

  • n = t를 설정하십시오
  • 베타 설정 [i] = 1 i = 0, ... S를 설정합니다.
  • i = s + 1의 경우 베타 [i] = 0을 설정합니다. ... T
  • t = p를 설정하십시오
  • de casteljau를 사용하여 B (t)를 평가하십시오

오픈 소스 코드는 이미 존재할 것입니다. NURBS 곡선 (비 균일 한 합리적 B- 스플라인 곡선)는 Bezier 곡선의 일반화이며 CAD에서 널리 사용됩니다. OpenNurbs (라이센스는 매우 자유 롭습니다) 또는 열린 캐스케이드 (다소 자유롭고 불투명 한 라이센스)를 사용하지 못합니다. 두 툴킷 모두 C ++이지만 IIRC, .NET 바인딩이 존재합니다.

Python을 사용하는 경우 직접 코딩 할 필요가 없습니다. Scipy는 당신을 덮었습니다.

from scipy.stats import binom
# probability that you get 20 or less successes out of 100, when p=0.3
binom.cdf(20, 100, 0.3)
>>> 0.016462853241869434

# probability that you get exactly 20 successes out of 100, when p=0.3
binom.pmf(20, 100, 0.3)
>>> 0.0075756449257260777

"적어도 S 헤드를 얻는"질문의 일부에서 누적 이항 분포 기능을 원합니다. 보다 http://en.wikipedia.org/wiki/binomial_distribution 방정식의 경우, "정규화되지 않은 베타 함수"(이미 대답 한대로)의 관점에서 설명됩니다. 전체 솔루션을 직접 구현하지 않고 답을 계산하려면 GNU Scientific Library는 기능을 제공합니다. GSL_CDF_BINOMIAL_P 및 GSL_CDF_BINOMIAL_Q.

DCDFLIB 프로젝트 는 C#능(래퍼 C 코드)을 평가하는 많은 CDF 기능을 포함하여항 분포.당신을 찾을 수 있습니다 원래는 C 프로그램 코드 .이 코드를 테스트하고 정확합니다.

당신이 쓰고 싶은 경우에 당신의 자신의 코드를 방지하는 것은 외부 라이브러리를 사용할 수 있습니다 일반적인 근사치를 이항에서 언급한 다른 답변이 있습니다.여기에 몇 가지에서 노트 얼마나 좋은 근사 다양한 상황에서.만약 당신이 갈 경로 및 필요한 코드 계산 정상적인 누적분포함수,기 Python 코드 을 위해 하는 것입니다.그것은 단지에 대해 다스 라인의 코드와할 수 쉽게 이식이 다른 언어입니다.하지만 당신이 원하는 경우 높은 정확도와 효율적인 코드에,당신은 나를 사용하여 타사 코드를 다음과 같 DCDFLIB.몇 년 들어갔을 생산하는 라이브러리입니다.

노력하다 이 하나, GMP에 사용됩니다. 또 다른 참조입니다 이것.

import numpy as np
np.random.seed(1)
x=np.random.binomial(20,0.6,10000) #20 flips of coin,probability of 
                                 heads percentage and 10000 times 
                                  done.
sum(x>12)/len(x)

The output is 41% of times we got 12 heads.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top