permutation_test#
- scipy.stats.permutation_test(data, statistic, *, permutation_type='independent', vectorized=None, n_resamples=9999, batch=None, alternative='two-sided', axis=0, rng=None)[Quelle]#
Führt einen Permutationstest einer gegebenen Statistik auf bereitgestellten Daten durch.
Bei unabhängigen Stichprobenstatistiken ist die Nullhypothese, dass die Daten zufällig aus derselben Verteilung gezogen werden. Bei gepaarten Stichprobenstatistiken können zwei Nullhypothesen getestet werden: dass die Daten zufällig gepaart werden oder dass die Daten zufällig Stichproben zugewiesen werden.
- Parameter:
- dataIterable von Array-ähnlichen Objekten
Enthält die Stichproben, von denen jede ein Array von Beobachtungen ist. Die Dimensionen der Stichproben-Arrays müssen kompatibel für Broadcasting sein, außer entlang axis.
- statisticaufrufbar
Statistik, für die der p-Wert des Hypothesentests berechnet werden soll. statistic muss eine aufrufbare Funktion sein, die Stichproben als separate Argumente akzeptiert (z. B.
statistic(*data)) und die resultierende Statistik zurückgibt. Wenn vectorized aufTruegesetzt ist, muss statistic auch ein Schlüsselwortargument axis akzeptieren und vektorisiert sein, um die Statistik entlang der bereitgestellten axis der Stichproben-Arrays zu berechnen.- permutation_type{‘independent’, ‘samples’, ‘pairings’}, optional
Der Typ der durchzuführenden Permutationen in Übereinstimmung mit der Nullhypothese. Die ersten beiden Permutationstypen sind für gepaarte Stichprobenstatistiken, bei denen alle Stichproben die gleiche Anzahl von Beobachtungen enthalten und Beobachtungen mit entsprechenden Indizes entlang axis als gepaart betrachtet werden; der dritte ist für unabhängige Stichprobenstatistiken.
'samples': Beobachtungen werden verschiedenen Stichproben zugewiesen, bleiben aber mit denselben Beobachtungen aus anderen Stichproben gepaart. Dieser Permutationstyp ist geeignet für gepaarte Stichproben-Hypothesentests wie den Wilcoxon-Vorzeichen-Rang-Test und den gepaarten t-Test.'pairings': Beobachtungen werden mit verschiedenen Beobachtungen gepaart, bleiben aber innerhalb derselben Stichprobe. Dieser Permutationstyp ist geeignet für Assoziations-/Korrelationstests mit Statistiken wie Spearmans \(\rho\), Kendalls \(\tau\) und Pearsons \(r\).'independent'(Standard) : Beobachtungen werden verschiedenen Stichproben zugewiesen. Stichproben können unterschiedliche Anzahlen von Beobachtungen enthalten. Dieser Permutationstyp ist geeignet für unabhängige Stichproben-Hypothesentests wie den Mann-Whitney \(U\)-Test und den unabhängigen Stichproben-t-Test.Bitte lesen Sie den Abschnitt Hinweise unten für detailliertere Beschreibungen der Permutationstypen.
- vectorizedbool, optional
Wenn vectorized auf
Falsegesetzt ist, wird statistic nicht das Schlüsselwortargument axis übergeben und es wird erwartet, dass die Statistik nur für 1D-Stichproben berechnet wird. WennTrue, wird statistic das Schlüsselwortargument axis übergeben und es wird erwartet, dass die Statistik entlang axis berechnet wird, wenn ein ND-Stichproben-Array übergeben wird. WennNone(Standard), wird vectorized aufTruegesetzt, wennaxisein Parameter von statistic ist. Die Verwendung einer vektorisierten Statistik reduziert typischerweise die Rechenzeit.- n_resamplesint oder np.inf, Standard: 9999
Anzahl der zufälligen Permutationen (Resamples), die zur Annäherung der Nullverteilung verwendet werden. Wenn sie größer oder gleich der Anzahl der verschiedenen Permutationen ist, wird die exakte Nullverteilung berechnet. Beachten Sie, dass die Anzahl der verschiedenen Permutationen mit der Größe der Stichproben sehr schnell anwächst, sodass exakte Tests nur für sehr kleine Datensätze praktikabel sind.
- batchint, optional
Die Anzahl der Permutationen, die in jedem Aufruf von statistic verarbeitet werden. Der Speicherbedarf beträgt O( batch *
n), wobeindie Gesamtgröße aller Stichproben ist, unabhängig vom Wert von vectorized. Der Standardwert istNone, in diesem Fall istbatchdie Anzahl der Permutationen.- alternative{‘zweiseitig’, ‘kleiner’, ‘größer’}, optional
Die alternative Hypothese, für die der p-Wert berechnet wird. Für jede Alternative wird der p-Wert bei exakten Tests wie folgt definiert.
'greater': der Prozentsatz der Nullverteilung, der größer oder gleich dem beobachteten Wert der Teststatistik ist.'less': der Prozentsatz der Nullverteilung, der kleiner oder gleich dem beobachteten Wert der Teststatistik ist.'two-sided'(Standard) : doppelt so klein wie die p-Werte oben.
Beachten Sie, dass p-Werte für randomisierte Tests gemäß der konservativen (überschätzten) Annäherung berechnet werden, wie in [2] und [3] vorgeschlagen, anstatt des unverzerrten Schätzers, wie in [4] vorgeschlagen. Das heißt, bei der Berechnung des Anteils der randomisierten Nullverteilung, der so extrem ist wie der beobachtete Wert der Teststatistik, werden die Werte im Zähler und Nenner beide um eins erhöht. Eine Interpretation dieser Anpassung ist, dass der beobachtete Wert der Teststatistik immer als Element der randomisierten Nullverteilung enthalten ist. Die Konvention für zweiseitige p-Werte ist nicht universell; die beobachtete Teststatistik und die Nullverteilung werden zurückgegeben, falls eine andere Definition bevorzugt wird.
- axisint, Standard: 0
Die Achse der (broadcasteten) Stichproben, über die die Statistik berechnet werden soll. Wenn Stichproben eine unterschiedliche Anzahl von Dimensionen haben, werden Einzeldimensionen vor axis zu Stichproben mit weniger Dimensionen hinzugefügt.
- rng{None, int,
numpy.random.Generator}, optional Wenn rng als Schlüsselwort übergeben wird, werden andere Typen als
numpy.random.Generatorannumpy.random.default_rngübergeben, um einenGeneratorzu instanziieren. Wenn rng bereits eineGenerator-Instanz ist, dann wird die bereitgestellte Instanz verwendet. Geben Sie rng für reproduzierbares Funktionsverhalten an.Wenn dieses Argument positional übergeben wird oder random_state als Schlüsselwort übergeben wird, gilt das ältere Verhalten für das Argument random_state.
Wenn random_state None ist (oder
numpy.random), wird die Singleton-Instanznumpy.random.RandomStateverwendet.Wenn random_state eine Ganzzahl ist, wird eine neue
RandomState-Instanz verwendet, die mit random_state initialisiert wurde.Wenn random_state bereits eine
Generator- oderRandomState-Instanz ist, wird diese Instanz verwendet.
Geändert in Version 1.15.0: Im Rahmen der SPEC-007-Umstellung von der Verwendung von
numpy.random.RandomStateaufnumpy.random.Generatorwurde dieses Schlüsselwort von random_state zu rng geändert. Für eine Übergangszeit werden beide Schlüsselwörter weiterhin funktionieren, obwohl nur eines gleichzeitig angegeben werden kann. Nach der Übergangszeit werden Funktionsaufrufe mit dem Schlüsselwort random_state Warnungen ausgeben. Das Verhalten von sowohl random_state als auch rng ist oben beschrieben, aber nur das Schlüsselwort rng sollte in neuem Code verwendet werden.
- Rückgabe:
- resPermutationTestResult
Ein Objekt mit den Attributen
- statisticfloat oder ndarray
Die beobachtete Teststatistik der Daten.
- pvaluefloat oder ndarray
Der p-Wert für die gegebene Alternative.
- null_distributionndarray
Die Werte der Teststatistik, die unter der Nullhypothese generiert wurden.
Hinweise
Die drei von dieser Funktion unterstützten Arten von Permutationstests sind unten beschrieben.
Ungepaarte Statistiken (
permutation_type='independent')Die Nullhypothese, die mit diesem Permutationstyp verbunden ist, besagt, dass alle Beobachtungen aus derselben zugrundeliegenden Verteilung gezogen werden und dass sie zufällig einer der Stichproben zugewiesen wurden.
Angenommen,
dataenthält zwei Stichproben; z. B.a, b = data. Wenn1 < n_resamples < binom(n, k), wobeikdie Anzahl der Beobachtungen inaist,ndie Gesamtzahl der Beobachtungen inaundbist undbinom(n, k)der Binomialkoeffizient ist (nüberk),
werden die Daten gepoolt (konkateniert), zufällig entweder der ersten oder der zweiten Stichprobe zugewiesen und die Statistik berechnet. Dieser Vorgang wird wiederholt, permutation Mal, wodurch eine Verteilung der Statistik unter der Nullhypothese erzeugt wird. Die Statistik der ursprünglichen Daten wird mit dieser Verteilung verglichen, um den p-Wert zu ermitteln.
Wenn
n_resamples >= binom(n, k), wird ein exakter Test durchgeführt: Die Daten werden in jeder unterschiedlichen Weise zwischen den Stichproben partitioniert und die exakte Nullverteilung gebildet. Beachten Sie, dass für eine gegebene Partitionierung der Daten zwischen den Stichproben nur eine Reihenfolge/Permutation der Daten innerhalb jeder Stichprobe berücksichtigt wird. Für Statistiken, die nicht von der Reihenfolge der Daten innerhalb der Stichproben abhängen, reduziert dies die Rechenkosten drastisch, ohne die Form der Nullverteilung zu beeinflussen (da die Häufigkeit/Anzahl jedes Wertes durch denselben Faktor beeinflusst wird).Für
a = [a1, a2, a3, a4]undb = [b1, b2, b3]ist ein Beispiel für diesen Permutationstypx = [b3, a1, a2, b2]undy = [a4, b1, a3]. Da bei einem exakten Test nur eine Reihenfolge/Permutation der Daten innerhalb jeder Stichprobe berücksichtigt wird, wäre eine Resample wiex = [b3, a1, b2, a2]undy = [a4, a3, b1]nicht als vom obigen Beispiel unterscheidbar betrachtet.permutation_type='independent'unterstützt keine Ein-Stichproben-Statistiken, kann aber auf Statistiken mit mehr als zwei Stichproben angewendet werden. In diesem Fall ist, wennnein Array der Anzahl der Beobachtungen innerhalb jeder Stichprobe ist, die Anzahl der unterschiedlichen Partitionennp.prod([binom(sum(n[i:]), sum(n[i+1:])) for i in range(len(n)-1)])
Gepaarte Statistiken, Permutation von Paaren (
permutation_type='pairings')Die Nullhypothese, die mit diesem Permutationstyp verbunden ist, besagt, dass Beobachtungen innerhalb jedes Paares aus derselben zugrundeliegenden Verteilung stammen und dass die Paarungen mit Elementen anderer Stichproben zufällig zugewiesen werden.
Angenommen,
dataenthält nur eine Stichprobe; z. B.a, = data, und wir möchten alle möglichen Paarungen von Elementen vonamit Elementen einer zweiten Stichprobe,b, betrachten. Seindie Anzahl der Beobachtungen ina, die auch der Anzahl der Beobachtungen inbentsprechen muss.Wenn
1 < n_resamples < factorial(n), werden die Elemente vonazufällig permutiert. Die vom Benutzer bereitgestellte Statistik akzeptiert ein Datenargument, z. B.a_perm, und berechnet die Statistik unter Berücksichtigung vona_permundb. Dieser Vorgang wird wiederholt, permutation Mal, wodurch eine Verteilung der Statistik unter der Nullhypothese erzeugt wird. Die Statistik der ursprünglichen Daten wird mit dieser Verteilung verglichen, um den p-Wert zu ermitteln.Wenn
n_resamples >= factorial(n), wird ein exakter Test durchgeführt:awird in jeder unterschiedlichen Weise genau einmal permutiert. Daher wird die statistic für jede eindeutige Paarung von Stichproben zwischenaundbgenau einmal berechnet.Für
a = [a1, a2, a3]undb = [b1, b2, b3]ist ein Beispiel für diesen Permutationstypa_perm = [a3, a1, a2], währendbin seiner ursprünglichen Reihenfolge bleibt.permutation_type='pairings'unterstütztdata, das eine beliebige Anzahl von Stichproben enthält, von denen jede die gleiche Anzahl von Beobachtungen enthalten muss. Alle indatabereitgestellten Stichproben werden unabhängig permutiert. Daher ist, wennmdie Anzahl der Stichproben undndie Anzahl der Beobachtungen innerhalb jeder Stichprobe ist, die Anzahl der Permutationen bei einem exakten Testfactorial(n)**m
Beachten Sie, dass, wenn eine zweiseitige Statistik beispielsweise nicht inhärent von der Reihenfolge abhängt, in der Beobachtungen bereitgestellt werden - nur von den Paarungen von Beobachtungen -, dann nur eine der beiden Stichproben in
databereitgestellt werden sollte. Dies reduziert die Rechenkosten drastisch, ohne die Form der Nullverteilung zu beeinflussen (da die Häufigkeit/Anzahl jedes Wertes durch denselben Faktor beeinflusst wird).Gepaarte Statistiken, Permutation von Stichproben (
permutation_type='samples')Die Nullhypothese, die mit diesem Permutationstyp verbunden ist, besagt, dass Beobachtungen innerhalb jedes Paares aus derselben zugrundeliegenden Verteilung stammen und dass die Stichprobe, der sie zugewiesen werden, zufällig ist.
Angenommen,
dataenthält zwei Stichproben; z. B.a, b = data. Seindie Anzahl der Beobachtungen ina, die auch der Anzahl der Beobachtungen inbentsprechen muss.Wenn
1 < n_resamples < 2**n, werden die Elemente vonaundbzufällig zwischen Stichproben vertauscht (wobei ihre Paarungen beibehalten werden) und die Statistik wird berechnet. Dieser Vorgang wird wiederholt, permutation Mal, wodurch eine Verteilung der Statistik unter der Nullhypothese erzeugt wird. Die Statistik der ursprünglichen Daten wird mit dieser Verteilung verglichen, um den p-Wert zu ermitteln.Wenn
n_resamples >= 2**n, wird ein exakter Test durchgeführt: Die Beobachtungen werden jeder Stichprobe in jeder unterschiedlichen Weise (wobei Paarungen beibehalten werden) genau einmal zugewiesen.Für
a = [a1, a2, a3]undb = [b1, b2, b3]ist ein Beispiel für diesen Permutationstypx = [b1, a2, b3]undy = [a1, b2, a3].permutation_type='samples'unterstütztdata, das eine beliebige Anzahl von Stichproben enthält, von denen jede die gleiche Anzahl von Beobachtungen enthalten muss. Wenndatamehr als eine Stichprobe enthält, werden gepaarte Beobachtungen innerhalb vondataunabhängig zwischen den Stichproben ausgetauscht. Daher ist, wennmdie Anzahl der Stichproben undndie Anzahl der Beobachtungen innerhalb jeder Stichprobe ist, die Anzahl der Permutationen bei einem exakten Testfactorial(m)**n
Mehrere gepaarte Stichproben-Statistiken, wie der Wilcoxon-Vorzeichen-Rang-Test und der gepaarte Stichproben-t-Test, können unter Berücksichtigung nur der Differenz zwischen zwei gepaarten Elementen durchgeführt werden. Dementsprechend wird, wenn
datanur eine Stichprobe enthält, die Nullverteilung gebildet, indem unabhängig das Vorzeichen jeder Beobachtung geändert wird.Warnung
Der p-Wert wird berechnet, indem die Elemente der Nullverteilung gezählt werden, die so extrem oder extremer als der beobachtete Wert der Statistik sind. Aufgrund der Verwendung von endlicher Präzisionsarithmetik geben einige Statistikfunktionen numerisch unterschiedliche Werte zurück, wenn die theoretischen Werte exakt gleich wären. In einigen Fällen könnte dies zu einem großen Fehler im berechneten p-Wert führen.
permutation_testschützt davor, indem Elemente in der Nullverteilung, die "nah" (innerhalb einer relativen Toleranz von 100 mal dem Fließkomma-Epsilon von ungenauen DTypes) am beobachteten Wert der Teststatistik liegen, als gleich dem beobachteten Wert der Teststatistik betrachtet werden. Es wird jedoch dem Benutzer geraten, die Nullverteilung zu überprüfen, um zu beurteilen, ob diese Vergleichsmethode geeignet ist, und falls nicht, den p-Wert manuell zu berechnen. Siehe Beispiel unten.Referenzen
[1]Fisher. The Design of Experiments, 6th Ed (1951).
[2]B. Phipson und G. K. Smyth. „Permutation P-values Should Never Be Zero: Calculating Exact P-values When Permutations Are Randomly Drawn.“ Statistical Applications in Genetics and Molecular Biology 9.1 (2010).
[3]M. D. Ernst. „Permutation Methods: A Basis for Exact Inference“. Statistical Science (2004).
[4]B. Efron und R. J. Tibshirani. An Introduction to the Bootstrap (1993).
Beispiele
Nehmen wir an, wir möchten testen, ob zwei Stichproben aus derselben Verteilung gezogen wurden. Angenommen, die zugrundeliegenden Verteilungen sind uns unbekannt, und dass wir vor der Beobachtung der Daten die Hypothese aufgestellt haben, dass der Mittelwert der ersten Stichprobe kleiner als der der zweiten Stichprobe sein würde. Wir beschließen, die Differenz zwischen den Stichprobenmittelwerten als Teststatistik zu verwenden, und wir werden einen p-Wert von 0,05 als statistisch signifikant betrachten.
Aus Effizienzgründen schreiben wir die Funktion, die die Teststatistik definiert, in vektorisierter Form: Die Stichproben
xundykönnen ND-Arrays sein, und die Statistik wird für jede Achsenscheibe entlang von axis berechnet.>>> import numpy as np >>> def statistic(x, y, axis): ... return np.mean(x, axis=axis) - np.mean(y, axis=axis)
Nachdem wir unsere Daten gesammelt haben, berechnen wir den beobachteten Wert der Teststatistik.
>>> from scipy.stats import norm >>> rng = np.random.default_rng() >>> x = norm.rvs(size=5, random_state=rng) >>> y = norm.rvs(size=6, loc = 3, random_state=rng) >>> statistic(x, y, 0) -3.5411688580987266
Tatsächlich ist die Teststatistik negativ, was darauf hindeutet, dass der wahre Mittelwert der zugrundeliegenden Verteilung von
xkleiner ist als der der zugrundeliegenden Verteilung vony. Um die Wahrscheinlichkeit zu ermitteln, dass dies zufällig geschieht, wenn die beiden Stichproben aus derselben Verteilung gezogen wurden, führen wir einen Permutationstest durch.>>> from scipy.stats import permutation_test >>> # because our statistic is vectorized, we pass `vectorized=True` >>> # `n_resamples=np.inf` indicates that an exact test is to be performed >>> res = permutation_test((x, y), statistic, vectorized=True, ... n_resamples=np.inf, alternative='less') >>> print(res.statistic) -3.5411688580987266 >>> print(res.pvalue) 0.004329004329004329
Die Wahrscheinlichkeit, unter der Nullhypothese eine Teststatistik zu erhalten, die kleiner oder gleich dem beobachteten Wert ist, beträgt 0,4329 %. Dies ist kleiner als unser gewählter Schwellenwert von 5 %, daher betrachten wir dies als signifikanten Beweis gegen die Nullhypothese zugunsten der Alternative.
Da die Größe der obigen Stichproben klein war, konnte
permutation_testeinen exakten Test durchführen. Für größere Stichproben greifen wir auf einen randomisierten Permutationstest zurück.>>> x = norm.rvs(size=100, random_state=rng) >>> y = norm.rvs(size=120, loc=0.2, random_state=rng) >>> res = permutation_test((x, y), statistic, n_resamples=9999, ... vectorized=True, alternative='less', ... rng=rng) >>> print(res.statistic) -0.4230459671240913 >>> print(res.pvalue) 0.0015
Die ungefähre Wahrscheinlichkeit, unter der Nullhypothese eine Teststatistik zu erhalten, die kleiner oder gleich dem beobachteten Wert ist, beträgt 0,0225 %. Dies ist wiederum kleiner als unser gewählter Schwellenwert von 5 %, daher haben wir erneut signifikante Beweise, um die Nullhypothese zugunsten der Alternative zu verwerfen.
Bei großen Stichproben und einer großen Anzahl von Permutationen ist das Ergebnis vergleichbar mit dem des entsprechenden asymptotischen Tests, dem unabhängigen Stichproben-t-Test.
>>> from scipy.stats import ttest_ind >>> res_asymptotic = ttest_ind(x, y, alternative='less') >>> print(res_asymptotic.pvalue) 0.0014669545224902675
Die Permutationsverteilung der Teststatistik wird zur weiteren Untersuchung bereitgestellt.
>>> import matplotlib.pyplot as plt >>> plt.hist(res.null_distribution, bins=50) >>> plt.title("Permutation distribution of test statistic") >>> plt.xlabel("Value of Statistic") >>> plt.ylabel("Frequency") >>> plt.show()
Die Überprüfung der Nullverteilung ist unerlässlich, wenn die Statistik aufgrund begrenzter Maschinenpräzision ungenau ist. Betrachten Sie den folgenden Fall
>>> from scipy.stats import pearsonr >>> x = [1, 2, 4, 3] >>> y = [2, 4, 6, 8] >>> def statistic(x, y, axis=-1): ... return pearsonr(x, y, axis=axis).statistic >>> res = permutation_test((x, y), statistic, vectorized=True, ... permutation_type='pairings', ... alternative='greater') >>> r, pvalue, null = res.statistic, res.pvalue, res.null_distribution
In diesem Fall unterscheiden sich einige Elemente der Nullverteilung aufgrund von numerischem Rauschen vom beobachteten Wert des Korrelationskoeffizienten
r. Wir überprüfen manuell die Elemente der Nullverteilung, die nahezu gleich dem beobachteten Wert der Teststatistik sind.>>> r 0.7999999999999999 >>> unique = np.unique(null) >>> unique array([-1. , -1. , -0.8, -0.8, -0.8, -0.6, -0.4, -0.4, -0.2, -0.2, -0.2, 0. , 0.2, 0.2, 0.2, 0.4, 0.4, 0.6, 0.8, 0.8, 0.8, 1. , 1. ]) # may vary >>> unique[np.isclose(r, unique)].tolist() [0.7999999999999998, 0.7999999999999999, 0.8] # may vary
Wenn
permutation_testden Vergleich naiv durchführen würde, würden die Elemente der Nullverteilung mit dem Wert0.7999999999999998nicht als extrem oder extremer als der beobachtete Wert der Statistik betrachtet werden, sodass der berechnete p-Wert zu klein wäre.>>> incorrect_pvalue = np.count_nonzero(null >= r) / len(null) >>> incorrect_pvalue 0.14583333333333334 # may vary
Stattdessen behandelt
permutation_testElemente der Nullverteilung, die innerhalb vonmax(1e-14, abs(r)*1e-14)vom beobachteten Wert der Statistikrliegen, als gleichr.>>> correct_pvalue = np.count_nonzero(null >= r - 1e-14) / len(null) >>> correct_pvalue 0.16666666666666666 >>> res.pvalue == correct_pvalue True
Diese Vergleichsmethode wird voraussichtlich in den meisten praktischen Situationen genau sein, aber dem Benutzer wird geraten, dies zu bewerten, indem die Elemente der Nullverteilung überprüft werden, die nahe am beobachteten Wert der Statistik liegen. Erwägen Sie auch die Verwendung von Statistiken, die mit exakter Arithmetik berechnet werden können (z. B. ganzzahlige Statistiken).