Ich muss einen Binomial-Test in Python durchführen, der die Berechnung von 'n' Zahlen in der Größenordnung von 10000 ermöglicht.
Ich habe eine schnelle binomial_test-Funktion mit scipy.misc.comb implementiert, allerdings ist sie bei n = 1000 ziemlich begrenzt, ich schätze, weil sie die größte darstellbare Zahl erreicht, während sie faktorielle Elemente oder das Kombinatorische selbst berechnet. Hier ist meine Funktion:
%Vor%Wie könnte ich eine native Python (oder numpy, scipy ...) Funktion verwenden, um diese Binomialwahrscheinlichkeit zu berechnen? Wenn möglich, brauche ich scipy 0.7.2 kompatiblen Code.
Vielen Dank!
Bearbeitet, um diesen Kommentar hinzuzufügen: Bitte beachten Sie, dass, wie Daniel Stutzbach erwähnt, der "Binomientest" wahrscheinlich nicht das ist, wonach das ursprüngliche Poster gefragt hat (obwohl er diesen Ausdruck verwendet hat). Er scheint nach der Wahrscheinlichkeitsdichtefunktion einer Binomialverteilung zu fragen, was ich im Folgenden nicht vorschlage.
Haben Sie scipy.stats.binom_test ausprobiert?
%Vor%Kleiner Link zum Hinzufügen einer Dokumentation: Ссылка
BTW: funktioniert auf scipy 0.7.2, sowie auf aktuellen 0.8 dev.
Jede Lösung, die wie comb(n, k) * 0.5**k * 0.5**(n-k)
aussieht, funktioniert nicht für große n
. Auf den meisten (allen?) Plattformen ist der kleinste Wert, den ein Python-Float speichern kann, etwa 2 ** - 1022. Für große n-k
oder große k
wird die rechte Seite auf 0 gerundet. Ebenso kann comb (n, k) so groß werden, dass es nicht in einen Float passt.
Ein robusterer Ansatz ist die Berechnung der Wahrscheinlichkeitsdichtefunktion als Differenz zwischen zwei aufeinanderfolgenden Punkten in < a href="http://en.wikipedia.org/wiki/Binomial_distribution#Cumulative_distribution_function"> kumulative Verteilungsfunktion , die mit Hilfe der regulalisierten unvollständigen Beta-Funktion berechnet werden kann (siehe SciPy-Paket "special functions"). Mathematisch:
%Vor% Eine weitere Option ist die Verwendung der Normal Approximation , die für große n
recht genau ist. Wenn Geschwindigkeit ein Problem ist, ist dies wahrscheinlich der Weg zu gehen:
Ich habe den Code nicht getestet, aber das sollte Ihnen die allgemeine Idee geben.
GMPY unterstützt auch erweiterte Gleitkomma-Berechnungen. Zum Beispiel:
%Vor%Ich habe eine Fließkomma-Genauigkeit von 256 Bit angegeben. Die Source-Forge-Version ist übrigens nicht mehr aktuell. Die aktuelle Version wird unter code.google.com verwaltet und unterstützt Python 3.x. (Haftungsausschluss: Ich bin der aktuelle Betreuer von gmpy.)
casevh
Ich würde mir das GNU-Multi-Precision-Paket (gmpy) ansehen, mit dem Sie beliebige Präzisionsberechnungen durchführen können: wahrscheinlich tu:
%Vor%aber mit den langen Ganzzahlen von gmpy.
Wenn Sie exakte Ganzzahlberechnungen verwenden, können Sie einfach n = 10000 für den Kombinationsteil erreichen; Dazu müssen Sie Folgendes verwenden:
%Vor% anstelle der Gleitpunktapproximation comb(n, k)
, die überläuft.
Wie jedoch im Original Poster angemerkt wurde, ist die zurückgegebene (lange) Ganzzahl möglicherweise zu lang, um mit einem Gleitkommawert multipliziert zu werden!
Außerdem stößt man schnell auf ein anderes Problem: 0.5**1000
= 9.3 ... e-302 ist schon sehr nahe am float-Unterlauf ...
Zusammenfassend: Wenn Sie wirklich genaue Ergebnisse für alle k
für n~10,000
benötigen, müssen Sie einen anderen Ansatz als die Formel aus dem ursprünglichen Post verwenden, der unter den Einschränkungen der Gleitkommaarithmetik mit doppelter Genauigkeit leidet. Die Verwendung von gmpy wie oben angegeben könnte eine Lösung sein (nicht getestet!).
Nicht speziell eine Python-Lösung, aber wenn Sie mit kleinen Bruchfehlern umgehen können, könnten Sie versuchen, die Approximation von Stirling für n!:
zu verwendenkamm (n, k) = n! / (k! * (n-k)!), wobei n! ist ungefähr sqrt (2 * Pi n) (n / e) ^ n für große n.
Für n & gt; 1000 sollten die Teilfehler sehr klein sein.
Für die Wahrscheinlichkeitsrechnung mit großem n verwenden Sie Logarithmen für Zwischenergebnisse:
log p = log (kamm (n, k)) - n * log (2)
p = exp (log (p))
Tags und Links python binomial-coefficients