scipy.stats.

make_distribution#

scipy.stats.make_distribution(dist)[Quelle]#

Generiert eine Klasse UnivariateDistribution aus einem kompatiblen Objekt

Das Argument kann eine Instanz von rv_continuous oder eine Instanz einer anderen Klasse sein, die die unten beschriebene Schnittstelle erfüllt.

Der zurückgegebene Wert ist eine Unterklasse von ContinuousDistribution, wenn die Eingabe eine Instanz von rv_continuous ist, oder eine Unterklasse von DiscreteDistribution, wenn die Eingabe eine Instanz von rv_discrete ist. Wie jede Unterklasse von UnivariateDistribution muss sie vor der Verwendung instanziiert werden (d. h. indem alle Formparameter als Schlüsselwortargumente übergeben werden). Nach der Instanziierung hat das resultierende Objekt die gleiche Schnittstelle wie jede andere Instanz von UnivariateDistribution; z. B. scipy.stats.Normal, scipy.stats.Binomial.

Hinweis

make_distribution funktioniert nicht perfekt mit allen Instanzen von rv_continuous. Bekannte Fehler sind levy_stable, vonmises, hypergeom, ‘nchypergeom_fisher’, ‘nchypergeom_wallenius’ und poisson_binom. Einige Methoden einiger Verteilungen unterstützen keine Array-Formparameter.

Parameter:
distrv_continuous

Instanz von rv_continuous, rv_discrete oder eine Instanz einer beliebigen Klasse mit den folgenden Attributen

__make_distribution_version__str

Ein String, der die Versionsnummer von SciPy enthält, in der diese Schnittstelle definiert ist. Die bevorzugte Schnittstelle kann sich in zukünftigen SciPy-Versionen ändern, in diesem Fall kann die Unterstützung für eine alte Schnittstellenversion veraltet und schließlich entfernt werden.

parametersdict oder tuple

Wenn ein Wörterbuch, ist jeder Schlüssel der Name eines Parameters, und der entsprechende Wert ist entweder ein Wörterbuch oder ein Tupel. Wenn der Wert ein Wörterbuch ist, kann er die folgenden Elemente enthalten, wobei Standardwerte für nicht vorhandene Einträge verwendet werden.

endpointstuple, Standard: (-inf, inf)

Ein Tupel, das die unteren und oberen Endpunkte des Definitionsbereichs des Parameters definiert; zulässige Werte sind Floats, der Name (String) eines anderen Parameters oder eine aufrufbare Funktion, die Parameter als ausschließlich mit Schlüsselwörtern versehene Argumente nimmt und den numerischen Wert eines Endpunkts für gegebene Parameterwerte zurückgibt.

inclusivetuple von bool, Standard: (False, False)

Ein Tupel, das angibt, ob die Endpunkte innerhalb des Definitionsbereichs des Parameters enthalten sind.

typicaltuple, Standard: endpoints

Definiert die Endpunkte eines typischen Wertebereichs eines Parameters. Kann zur Stichprobenziehung von Parameterwerten für Tests verwendet werden. Funktioniert wie das obige endpoints-Tupel und sollte ein Intervall des durch endpoints gegebenen Definitionsbereichs definieren.

Ein Tupelwert (a, b), der einem Schlüssel im parameters-Wörterbuch zugeordnet ist, ist äquivalent zu {endpoints: (a, b)}.

Benutzerdefinierte Verteilungen mit mehreren Parametrisierungen können definiert werden, indem das Attribut parameters ein Tupel von Wörterbüchern mit der oben beschriebenen Struktur ist. In diesem Fall muss die Klasse von dist auch eine Methode process_parameters definieren, um zwischen den verschiedenen Parametrisierungen zu wechseln. Sie muss alle Parameter aus allen Parametrisierungen als optionale Schlüsselwortargumente akzeptieren und ein Wörterbuch zurückgeben, das Parameter auf Werte abbildet, wobei Werte aus anderen Parametrisierungen mithilfe von Werten aus der bereitgestellten Parametrisierung aufgefüllt werden. Siehe Beispiel.

supportdict oder tuple

Ein Wörterbuch, das den Träger der Verteilung beschreibt, oder ein Tupel, das die Endpunkte des Trägers beschreibt. Dies verhält sich identisch zu den Werten des parameters-Wörterbuchs, außer dass der Schlüssel typical ignoriert wird.

Die Klasse **muss** außerdem eine Methode pdf definieren und **kann** die Methoden logentropy, entropy, median, mode, logpdf, logcdf, cdf, logccdf, ccdf, ilogcdf, icdf, ilogccdf, iccdf, moment und sample definieren. Wenn diese Methoden definiert sind, müssen sie die Parameter der Verteilung als Schlüsselwortargumente akzeptieren und auch alle positional-only Argumente akzeptieren, die von der entsprechenden Methode von ContinuousDistribution akzeptiert werden. Wenn mehrere Parametrisierungen definiert sind, müssen diese Methoden alle Parameter aus allen Parametrisierungen akzeptieren. Die Methode moment muss die Argumente order und kind nach Position oder Schlüsselwort akzeptieren, kann aber None zurückgeben, wenn für die Argumente keine Formel verfügbar ist. In diesem Fall greift die Infrastruktur auf eine Standardimplementierung zurück. Die Methode sample muss shape nach Position oder Schlüsselwort akzeptieren, aber im Gegensatz zur öffentlichen Methode mit demselben Namen ist das Argument, das sie erhält, die *vollständige* Form des Ausgabearrays – d. h. die Form, die an die öffentliche Methode übergeben wird, vorangestellt der Broadcast-Form der Zufallsvariablenparameter.

Rückgabe:
CustomDistributionUnivariateDistribution

Eine Unterklasse von UnivariateDistribution, die dist entspricht. Der Initialisierer erfordert, dass alle Formparameter als Schlüsselwortargumente übergeben werden (mit denselben Namen wie die Instanz von rv_continuous/rv_discrete).

Hinweise

Die Dokumentation von UnivariateDistribution wird nicht gerendert. Siehe unten für ein Beispiel, wie die Klasse instanziiert wird (d. h. alle Formparameter von dist werden dem Initialisierer als Schlüsselwortargumente übergeben). Die Dokumentation aller Methoden ist identisch mit der von scipy.stats.Normal. Verwenden Sie help für die zurückgegebene Klasse oder ihre Methoden für weitere Informationen.

Beispiele

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> from scipy import stats
>>> from scipy import special

Erstellen Sie eine ContinuousDistribution aus scipy.stats.loguniform.

>>> LogUniform = stats.make_distribution(stats.loguniform)
>>> X = LogUniform(a=1.0, b=3.0)
>>> np.isclose((X + 0.25).median(), stats.loguniform.ppf(0.5, 1, 3, loc=0.25))
np.True_
>>> X.plot()
>>> sample = X.sample(10000, rng=np.random.default_rng())
>>> plt.hist(sample, density=True, bins=30)
>>> plt.legend(('pdf', 'histogram'))
>>> plt.show()
../../_images/scipy-stats-make_distribution-1_00_00.png

Erstellen Sie eine benutzerdefinierte Verteilung.

>>> class MyLogUniform:
...     @property
...     def __make_distribution_version__(self):
...         return "1.16.0"
...
...     @property
...     def parameters(self):
...         return {'a': {'endpoints': (0, np.inf),
...                       'inclusive': (False, False)},
...                 'b': {'endpoints': ('a', np.inf),
...                       'inclusive': (False, False)}}
...
...     @property
...     def support(self):
...         return {'endpoints': ('a', 'b'), 'inclusive': (True, True)}
...
...     def pdf(self, x, a, b):
...         return 1 / (x * (np.log(b)- np.log(a)))
>>>
>>> MyLogUniform = stats.make_distribution(MyLogUniform())
>>> Y = MyLogUniform(a=1.0, b=3.0)
>>> np.isclose(Y.cdf(2.), X.cdf(2.))
np.True_

Erstellen Sie eine benutzerdefinierte Verteilung mit variablem Träger.

>>> class MyUniformCube:
...     @property
...     def __make_distribution_version__(self):
...         return "1.16.0"
...
...     @property
...     def parameters(self):
...         return {"a": (-np.inf, np.inf),
...                 "b": {'endpoints':('a', np.inf), 'inclusive':(True, False)}}
...
...     @property
...     def support(self):
...         def left(*, a, b):
...             return a**3
...
...         def right(*, a, b):
...             return b**3
...         return (left, right)
...
...     def pdf(self, x, *, a, b):
...         return 1 / (3*(b - a)*np.cbrt(x)**2)
...
...     def cdf(self, x, *, a, b):
...         return (np.cbrt(x) - a) / (b - a)
>>>
>>> MyUniformCube = stats.make_distribution(MyUniformCube())
>>> X = MyUniformCube(a=-2, b=2)
>>> Y = stats.Uniform(a=-2, b=2)**3
>>> X.support()
(-8.0, 8.0)
>>> np.isclose(X.cdf(2.1), Y.cdf(2.1))
np.True_

Erstellen Sie eine benutzerdefinierte Verteilung mit mehreren Parametrisierungen. Hier erstellen wir eine benutzerdefinierte Version der Beta-Verteilung, die eine alternative Parametrisierung in Bezug auf den Mittelwert mu und einen Dispersionsparameter nu aufweist.

>>> class MyBeta:
...     @property
...     def __make_distribution_version__(self):
...         return "1.16.0"
...
...     @property
...     def parameters(self):
...         return ({"a": (0, np.inf), "b": (0, np.inf)},
...                 {"mu": (0, 1), "nu": (0, np.inf)})
...
...     def process_parameters(self, a=None, b=None, mu=None, nu=None):
...         if a is not None and b is not None:
...             nu = a + b
...             mu = a / nu
...         else:
...             a = mu * nu
...             b = nu - a
...         return dict(a=a, b=b, mu=mu, nu=nu)
...
...     @property
...     def support(self):
...         return {'endpoints': (0, 1)}
...
...     def pdf(self, x, a, b, mu, nu):
...         return special._ufuncs._beta_pdf(x, a, b)
...
...     def cdf(self, x, a, b, mu, nu):
...         return special.betainc(a, b, x)
>>>
>>> MyBeta = stats.make_distribution(MyBeta())
>>> X = MyBeta(a=2.0, b=2.0)
>>> Y = MyBeta(mu=0.5, nu=4.0)
>>> np.isclose(X.pdf(0.3), Y.pdf(0.3))
np.True_