Wie kann ich effizient berechnet die binomiale kumulative Verteilungsfunktion?
Sagen wir mal so, ich weiß, die Wahrscheinlichkeit eines "Erfolg" ist P. ich den test ausführen, N mal, und ich sehe S Erfolge. Der test ist vergleichbar mit dem werfen einer ungleich gewichteten Münze (vielleicht Köpfe ist ein Erfolg, tails ist ein Fehler).
Ich möchte wissen, die Ungefähre Wahrscheinlichkeit des Sehens entweder S Erfolge, oder eine Reihe von erfolgen weniger wahrscheinlich als S-Erfolge.
So zum Beispiel, wenn P ist 0,3, N-100 und ich bekommen, 20 Erfolge, ich bin auf der Suche nach der Wahrscheinlichkeit 20 oder weniger Erfolge.
Wenn auf der anderen hatte, P ist 0,3, N 100, und ich bekomme 40 Erfolge, ich bin auf der Suche nach der Wahrscheinlichkeit, 40 unsere weitere Erfolge.
Ich bin mir bewusst, dass dieses problem bezieht sich auf das finden der Fläche unter einer binomialen Kurve, jedoch:
- Meine Mathe-fu ist nicht bis zu der Aufgabe der übersetzung dieser Kenntnisse in effizienten code
- Ich verstehe zwar einer binomialen Kurve geben würde, ein exaktes Ergebnis, ich habe den Eindruck, es wäre grundsätzlich ineffizient. Eine schnelle Methode zum berechnen einer ungefähren Ergebnis, würde genügen.
Ich sollte betonen, dass diese Berechnung muss schnell sein, und sollte idealerweise definierbar mit standard-64-oder 128-bit-floating-point-Berechnung.
Ich bin auf der Suche nach einer Funktion, P, S, und N - und gibt eine Wahrscheinlichkeit. Als ich bin mehr vertraut mit dem code, als die mathematische Schreibweise ist, würde ich es vorziehen, dass alle Antworten beschäftigen pseudo-code oder code.
InformationsquelleAutor der Frage sanity | 2009-07-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Exakten Binomialen Verteilung
Normalen Schätzen, gut für große n
Poisson-Schätzung: für große n und kleine p
InformationsquelleAutor der Antwort Unknown
War ich an einem Projekt, wo wir benötigt, um in der Lage sein, um die Berechnung der binomial CDF-in einer Umgebung, die nicht über eine Faktoren-oder gamma-Funktion definiert. Es dauerte ein paar Wochen, aber ich landete kommenden up mit dem folgenden Algorithmus berechnet die CDF-genau (d.h. keine Angleichung erforderlich). Python ist im Grunde so gut wie pseudocode, richtig?
Leistung skaliert mit x. Für kleine Werte von x, diese Lösung ist etwa eine Größenordnung schneller als
scipy.stats.binom.cdf
mit ähnlicher Leistung bei etwa x=10,000.Ich gehe nicht in eine vollständige Herleitung dieses Algorithmus, da stackoverflow nicht unterstützt MathJax, aber der Schub ist es zunächst der Identifizierung der folgenden äquivalenz:
sp.misc.comb(n,k) == np.prod([(n-k+1)/k for k in range(1,k+1)])
Können wir umschreiben als:
sp.misc.comb(n,k) == sp.misc.comb(n,k-1) * (n-k+1)/k
oder in eine log-space:
np.log( sp.misc.comb(n,k) ) == np.log(sp.misc.comb(n,k-1)) + np.log(n-k+1) - np.log(k)
Weil die CDF ist eine Summierung von PMFs, wir können mit dieser Formulierung zur Berechnung der binomial-Koeffizienten (log ist
b
in der Funktion oben) für PMF_{x=i} aus den Koeffizienten berechnet wir für PMF_{x=i-1}. Dies bedeutet, dass wir tun können, alles in einer einzigen Schleife mit Akkumulatoren, und wir brauchen nicht zu berechnen, beliebige faktorielle!Der Grund, die meisten der Berechnungen sind im Protokoll-Raum ist die Verbesserung der numerischen Stabilität des Polynoms, D. H.
p^x
und(1-p)^(1-x)
haben das Potenzial zu werden, extrem groß oder extrem klein, was kann die Ursache für Rechenfehler.EDIT: Ist das ein neuartiger Algorithmus? Ich habe herumgestöbert und ausschalten da, bevor ich dies geschrieben, und ich bin immer gefragt, ob ich schreiben soll, das ist mehr formal und senden Sie an eine Zeitschrift.
InformationsquelleAutor der Antwort David Marx
Ich denke, Sie wollen zu bewerten, die unvollständige beta-Funktion.
Gibt es eine schöne Umsetzung mit einer Fortsetzung Bruchteil Darstellung in "Numerical Recipes In C", 6. Kapitel: 'Spezielle Funktionen'.
InformationsquelleAutor der Antwort duffymo
Kann ich nicht ganz bürgen für die Effizienz, aber Scipy hat eine Modul für das
InformationsquelleAutor der Antwort mcstrother
Einen effizienten und vor allem numerisch stabilen Algorithmus ist in der Domäne der Bezier-Kurven verwendet in Computer-Aided Design. Es heißt de Casteljau-Algorithmus bewerten, die Bernstein-Polynome verwendet, um zu definieren, Bezier-Kurven.
Ich glaube, ich darf nur ein link pro Antwort so starten Sie mit Wikipedia - Bernstein-Polynome
Beachten Sie die sehr enge Beziehung zwischen der Binomialverteilung und der Bernstein-Polynome. Dann klicken Sie sich durch den link auf de Casteljau-Algorithmus.
Open-source-code wohl bereits existiert. NURBS-Kurven (Non-Uniform Rational B-spline-Kurven) sind eine Verallgemeinerung von Bézier-Kurven und sind weit verbreitet in CAD. Versuchen openNurbs (die Lizenz ist sehr liberal) oder nicht, die Open CASCADE (eine etwas weniger liberale und undurchsichtig-Lizenz). Beide toolkits sind in C++, obwohl, wenn ich mich Recht erinnere, .NET-Bindungen existieren.
InformationsquelleAutor der Antwort Paul Delhanty
Wenn Sie mit Python, keine Notwendigkeit, code-it-yourself. Scipy haben Sie abgedeckt:
InformationsquelleAutor der Antwort volodymyr
Aus dem Teil deiner Frage "immer mindestens N-Köpfe" Sie wollen die kumulative Binomialverteilung Funktion. Sehen http://en.wikipedia.org/wiki/Binomial_distribution für die Gleichung, die beschrieben wird als in Bezug auf die "regulierte unvollständige beta-Funktion" (wie schon beantwortet). Wenn Sie nur wollen, um zu berechnen, die Antwort, die zimmerreserviereung, ohne das Sie implementieren die gesamte Lösung selbst, die GNU Scientific Library liefert die Funktion: gsl_cdf_binomial_P und gsl_cdf_binomial_Q.
InformationsquelleAutor der Antwort
Den DCDFLIB Projekt hat C# - Funktionen (Wrapper für C-code) zu bewerten, viele CDF-Funktionen, einschließlich der binomial-Verteilung. Sie finden die original-C-und FORTRAN-code hier. Dieser code ist getestet und korrekt.
Wenn Sie wollen, um Ihren eigenen code schreiben, um nicht abhängig von einer externen Bibliothek, Sie könnte verwenden Sie die normale Annäherung an die Binomialverteilung erwähnt in anderen Antworten. Hier sind einige Hinweise auf wie gut die Näherung ist unter verschiedenen Umständen. Wenn Sie diesen Weg gehen und müssen code zum berechnen der normal-CDF, hier ist Python-code tun. Es ist nur etwa ein Dutzend Zeilen code, und könnte leicht portiert werden, um eine andere Sprache. Aber wenn Sie wollen, hohe Genauigkeit und effizienten code, sind Sie besser dran, unter Verwendung von Drittanbieter-code, wie DCDFLIB. Mehrere Mann-Jahre ging in die Produktion, die Bibliothek.
InformationsquelleAutor der Antwort John D. Cook
Versuchen diese eineverwendet in der GMP. Ein weiterer Verweis diese.
InformationsquelleAutor der Antwort lhf
InformationsquelleAutor der Antwort ramakrishnareddy