Binomial-Test in Python für sehr große Zahlen

8

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!

    
Morlock 16.06.2010, 18:38
quelle

6 Antworten

9

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.

    
rbp 16.06.2010, 18:53
quelle
6

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:

%Vor%

Ich habe den Code nicht getestet, aber das sollte Ihnen die allgemeine Idee geben.

    
Daniel Stutzbach 16.06.2010 20:07
quelle
3

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

    
casevh 17.06.2010 04:10
quelle
1

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!).

    
EOL 16.06.2010 19:09
quelle
0

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 verwenden

kamm (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))

    
pwaldron 16.06.2010 18:45
quelle
-1
%Vor%     
user4561593 12.02.2015 23:53
quelle

Tags und Links