scipy.stats.sampling.

DiscreteAliasUrn#

class scipy.stats.sampling.DiscreteAliasUrn(dist, *, domain=None, urn_factor=1, random_state=None)#

Discrete Alias-Urn Methode.

Diese Methode wird verwendet, um aus univariaten diskreten Verteilungen mit endlichem Definitionsbereich zu stichproben. Sie verwendet den Wahrscheinlichkeitsvektor der Größe \(N\) oder eine Wahrscheinlichkeitsmassenfunktion mit endlichem Träger, um Zufallszahlen aus der Verteilung zu generieren.

Parameter:
distarray_like oder Objekt, optional

Wahrscheinlichkeitsvektor (PV) der Verteilung. Wenn kein PV verfügbar ist, wird eine Instanz einer Klasse mit einer pmf Methode erwartet. Die Signatur der PMF wird erwartet als: def pmf(self, k: int) -> float. D.h., sie sollte einen Python-Integer akzeptieren und einen Python-Float zurückgeben.

domainint, optional

Träger der PMF. Wenn kein Wahrscheinlichkeitsvektor (pv) verfügbar ist, muss ein endlicher Definitionsbereich angegeben werden. D.h., die PMF muss einen endlichen Träger haben. Standard ist None. Wenn None

  • Wenn eine support-Methode vom Verteilungsobjekt dist bereitgestellt wird, wird sie verwendet, um den Definitionsbereich der Verteilung festzulegen.

  • Andernfalls wird angenommen, dass der Träger (0, len(pv)) ist. Wenn dieser Parameter in Kombination mit einem Wahrscheinlichkeitsvektor übergeben wird, wird domain[0] verwendet, um die Verteilung von (0, len(pv)) nach (domain[0], domain[0]+len(pv)) zu verschieben, und domain[1] wird ignoriert. Siehe Hinweise und Tutorial für eine detailliertere Erklärung.

urn_factorfloat, optional

Größe der Urnentabelle *relativ* zur Größe des Wahrscheinlichkeitsvektors. Sie darf nicht kleiner als 1 sein. Größere Tabellen führen zu schnelleren Generierungszeiten, erfordern aber eine aufwendigere Einrichtung. Standard ist 1.

random_state{None, int, numpy.random.Generator,

Ein NumPy-Zufallszahlengenerator oder ein Seed für den zugrunde liegenden NumPy-Zufallszahlengenerator, der zur Erzeugung des Stroms von gleichverteilten Zufallszahlen verwendet wird. Wenn random_state None ist (oder np.random), wird die Singleton-Instanz numpy.random.RandomState verwendet. Wenn random_state ein Integer ist, wird eine neue RandomState-Instanz verwendet, die mit random_state initialisiert wurde. Wenn random_state bereits eine Generator- oder RandomState-Instanz ist, wird diese Instanz verwendet.

Methoden

rvs([size, random_state])

Stichprobe aus der Verteilung.

set_random_state([random_state])

Setzt den zugrunde liegenden gleichmäßigen Zufallszahlengenerator.

Hinweise

Diese Methode funktioniert, wenn entweder ein endlicher Wahrscheinlichkeitsvektor verfügbar ist oder die PMF der Verteilung verfügbar ist. Falls nur eine PMF verfügbar ist, muss auch der *endliche* Träger (Definitionsbereich) der PMF angegeben werden. Es wird empfohlen, zunächst den Wahrscheinlichkeitsvektor zu erhalten, indem die PMF für jeden Punkt im Träger ausgewertet wird, und diesen dann zu verwenden.

Wenn ein Wahrscheinlichkeitsvektor angegeben wird, muss es sich um ein eindimensionales Array von nicht-negativen Gleitkommazahlen ohne inf oder nan Werte handeln. Außerdem muss mindestens ein Nicht-Null-Eintrag vorhanden sein, sonst wird eine Ausnahme ausgelöst.

Standardmäßig wird der Wahrscheinlichkeitsvektor ab Index 0 indiziert. Dies kann jedoch durch Angabe eines domain-Parameters geändert werden. Wenn domain in Kombination mit dem PV angegeben wird, hat dies den Effekt, die Verteilung von (0, len(pv)) nach (domain[0], domain[0] + len(pv)) zu verschieben. domain[1] wird in diesem Fall ignoriert.

Der Parameter urn_factor kann für eine schnellere Generierung auf Kosten einer erhöhten Einrichtungszeit erhöht werden. Diese Methode verwendet eine Tabelle zur Generierung von Zufallsvariablen. urn_factor steuert die Größe dieser Tabelle relativ zur Größe des Wahrscheinlichkeitsvektors (oder der Breite des Trägers, falls kein PV verfügbar ist). Da diese Tabelle während der Einrichtung berechnet wird, erhöht die Erhöhung dieses Parameters linear die benötigte Einrichtungszeit. Es wird empfohlen, diesen Parameter unter 2 zu halten.

Referenzen

[1]

UNU.RAN Referenzhandbuch, Abschnitt 5.8.2, „DAU - (Discrete) Alias-Urn Method“, http://statmath.wu.ac.at/software/unuran/doc/unuran.html#DAU

[2]

A.J. Walker (1977). An efficient method for generating discrete random variables with general distributions, ACM Trans. Math. Software 3, S. 253-256.

Beispiele

>>> from scipy.stats.sampling import DiscreteAliasUrn
>>> import numpy as np

Um einen Zufallszahlengenerator mit einem Wahrscheinlichkeitsvektor zu erstellen, verwenden Sie

>>> pv = [0.1, 0.3, 0.6]
>>> urng = np.random.default_rng()
>>> rng = DiscreteAliasUrn(pv, random_state=urng)

Der RNG wurde eingerichtet. Nun können wir die rvs Methode verwenden, um Stichproben aus der Verteilung zu generieren.

>>> rvs = rng.rvs(size=1000)

Um zu überprüfen, ob die Zufallsvariablen der gegebenen Verteilung folgen, können wir den Chi-Quadrat-Test (als Maß für die Anpassungsgüte) verwenden.

>>> from scipy.stats import chisquare
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> freqs
array([0.092, 0.292, 0.616])
>>> chisquare(freqs, pv).pvalue
0.9993602047563164

Da der p-Wert sehr hoch ist, verwerfen wir die Nullhypothese nicht, dass die beobachteten Häufigkeiten mit den erwarteten Häufigkeiten übereinstimmen. Daher können wir sicher davon ausgehen, dass die Variablen aus der gegebenen Verteilung generiert wurden. Beachten Sie, dass dies nur die Korrektheit des Algorithmus und nicht die Qualität der Stichproben angibt.

Wenn kein PV verfügbar ist, kann auch eine Instanz einer Klasse mit einer PMF-Methode und einem endlichen Definitionsbereich übergeben werden.

>>> urng = np.random.default_rng()
>>> class Binomial:
...     def __init__(self, n, p):
...         self.n = n
...         self.p = p
...     def pmf(self, x):
...         # note that the pmf doesn't need to be normalized.
...         return self.p**x * (1-self.p)**(self.n-x)
...     def support(self):
...         return (0, self.n)
...
>>> n, p = 10, 0.2
>>> dist = Binomial(n, p)
>>> rng = DiscreteAliasUrn(dist, random_state=urng)

Nun können wir mit der rvs Methode aus der Verteilung stichproben und auch die Anpassungsgüte der Stichproben messen.

>>> rvs = rng.rvs(1000)
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> obs_freqs = np.zeros(11)  # some frequencies may be zero.
>>> obs_freqs[:freqs.size] = freqs
>>> pv = [dist.pmf(i) for i in range(0, 11)]
>>> pv = np.asarray(pv) / np.sum(pv)
>>> chisquare(obs_freqs, pv).pvalue
0.9999999999999999

Um zu überprüfen, ob die Stichproben aus der richtigen Verteilung gezogen wurden, können wir das Histogramm der Stichproben visualisieren.

>>> import matplotlib.pyplot as plt
>>> rvs = rng.rvs(1000)
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> x = np.arange(0, n+1)
>>> fx = dist.pmf(x)
>>> fx = fx / fx.sum()
>>> ax.plot(x, fx, 'bo', label='true distribution')
>>> ax.vlines(x, 0, fx, lw=2)
>>> ax.hist(rvs, bins=np.r_[x, n+1]-0.5, density=True, alpha=0.5,
...         color='r', label='samples')
>>> ax.set_xlabel('x')
>>> ax.set_ylabel('PMF(x)')
>>> ax.set_title('Discrete Alias Urn Samples')
>>> plt.legend()
>>> plt.show()
../../_images/scipy-stats-sampling-DiscreteAliasUrn-1_00_00.png

Um den urn_factor einzustellen, verwenden Sie

>>> rng = DiscreteAliasUrn(pv, urn_factor=2, random_state=urng)

Dies verwendet eine Tabelle, die doppelt so groß ist wie der Wahrscheinlichkeitsvektor, um Zufallsvariablen aus der Verteilung zu generieren.