Après avoir étudié la [théorie des probabilités](https://ja.wikipedia.org/wiki/probability théorie) et les statistiques, diverses [distribution de probabilité](https://ja.wikipedia.org/wiki/probability distribution) s'affiche, et il y en a tellement que vous ne pouvez pas décider quel type de distribution utiliser dans quelle situation.
Quelle distribution de probabilité peut expliquer la valeur de [variable de probabilité](https://ja.wikipedia.org/wiki/probability variable) dans un phénomène naturel varie en fonction du phénomène.
Dans cet article, je vais essayer de dessiner la distribution en simulant le phénomène selon lequel diverses distributions de probabilité se produisent avec python.
En fait, même si vous ne connaissez pas l'origine de la distribution, vous pouvez facilement implémenter diverses distributions de probabilités en utilisant le module scipy.stats de scipy, mais tout d'abord, je pense qu'il est significatif de savoir dans quelles circonstances et comment faire une telle distribution.
Nous allons donc l'implémenter ici uniquement avec le module random de python et numpy.
Utilisez le module aléatoire pour randomiser un par un, et numpy pour randomiser beaucoup à la fois. (Le graphique est matplotlib)
Utilisez ensuite scipy.stats pour comparer les résultats. Si vous comprenez la signification de la distribution, les résultats doivent être cohérents.
Comment utiliser scipy.stats n'est pas expliqué en détail car il est écrit dans divers articles tels que cet article https://qiita.com/supersaiakujin/items/71540d1ecd60ced65add.
Fondamentalement, la distribution de probabilité est [distribution de probabilité discrète](https://ja.wikipedia.org/wiki/discrete distribution de probabilité) et distribution de probabilité continue. Il est divisé en deux types (distribution de probabilité) et la méthode de mise en œuvre est légèrement différente.
La principale différence est que, par exemple, la distribution de probabilité discrète montre la distribution de probabilité dans la [Probability Mass Function](https://ja.wikipedia.org/wiki/Probability Mass Function) (PMF), alors que la distribution de probabilité continue. Affiche la distribution de probabilité dans la [Fonction de densité de probabilité](https://ja.wikipedia.org/wiki/Probability Density Function) (PDF).
La distribution de probabilité expliquée ici est
** Distribution de probabilité discrète **
** Distribution de probabilité continue **
Lorsque vous effectuez une expérience qui aboutit à un succès ou à un échec, la distribution de probabilité du nombre de succès est ** [distribution binaire](https://ja.wikipedia.org/wiki/binary distribution) ** Il est.
La fonction de masse stochastique est
P(x) = C(n,x)p^x(1-p)^{n-x}
p = probabilité de succès n = nombre de fois $ C (n, x) $ sélectionne x sur n fonction Combination
Par exemple, dans un jeu, si vous battez un certain monstre, vous laisserez tomber un objet avec une probabilité de p, et si vous battez n, combien d'objets seront abandonnés, le nombre de gouttes devrait être une distribution binaire.
Voyons en fait le résultat au hasard. Ici, n = 2000, p = 0,01 et le nombre d'échantillons est de 10000.
import random
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats
#Tout d'abord, importez tous les modules que vous souhaitez utiliser.
n_sampl = 10000 #Nombre d'échantillons
n = 2000 #Nombre de monstres à vaincre
p = 0.01 #Probabilité de laisser tomber un objet
n_drop = [] #Nombre de chaque goutte
for _ in range(n_sampl):
#N morceaux aléatoires pour déterminer s'il est inférieur ou égal à p
drop = np.random.random(n)<=p
n_drop.append(drop.sum()) #Stocker le nombre de gouttes
y = np.bincount(n_drop) #Comptez le nombre de chaque goutte
x = np.arange(len(y))
#Dessinez un graphique à barres
plt.title('Distribution binaire',family='Arial Unicode MS')
plt.bar(x,y,color='#f9a7a0',ec='k')
plt.grid(ls='--')
plt.savefig('binom.png',dpi=100)
plt.close()
Vient ensuite l'implémentation dans scipy.stats. Utilisez maintenant .rvs () pour randomiser et .pmf () pour dessiner le graphique.
f = scipy.stats.binom(n,p)
plt.title('Distribution binaire',family='Arial Unicode MS')
h = np.bincount(f.rvs(10000))
x = np.arange(len(h))
plt.bar(x,h/n_sampl,color='#a477e2',ec='k')
plt.plot(x,f.pmf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('binom2.png',dpi=100)
plt.close()
La distribution dessinée avec .rvs () correspond approximativement au graphique dans .pmf (), et correspond également à la figure ci-dessus. Cependant, ici, divisez par le nombre d'échantillons pour que le total soit de 1.
Si n = 1 dans la distribution binomiale, on l'appelle ** [distribution Bernouy](https://ja.wikipedia.org/wiki/Bernouy distribution) **.
Si n = 1 est défini pour la fonction de masse de probabilité de la distribution binomiale
P(x) = p^x(1-p)^{1-x}
Ce sera. Puisqu'il est exécuté une fois, le résultat est seulement 0 (succès) et 1 (échec).
Le code est plus simple que la distribution binomiale.
n_sampl = 10000
p = 0.2 #Probabilité de laisser tomber un objet
n_drop = [] #Numéro de chaque goutte (0 ou 1)
for _ in range(n_sampl):
n_drop.append(random.random()<=p) #Si la valeur aléatoire est inférieure ou égale à p
y = np.bincount(n_drop)
x = np.arange(len(y))
plt.title('Distribution de Bernoulli',family='Arial Unicode MS')
plt.bar(x,y,color='#f9a7a0',ec='k')
plt.grid(ls='--')
plt.savefig('bernulli.png',dpi=100)
plt.close()
Comme la distribution binomiale, ** [Geometric Distribution](https://ja.wikipedia.org/wiki/Geometric Distribution) ** est une distribution qui se produit lors de l'exécution d'expériences réussies et infructueuses, mais une distribution géométrique. La considération dans est la distribution du nombre de fois pour réussir.
La distribution du nombre d'exécutions réussies, réussies ou échouées, est une distribution géométrique.
Si la probabilité de succès est p, alors la fonction de masse de probabilité du nombre de fois pour réussir est
P(x) = p(1-p)^{x-1}
Par exemple, la distribution de probabilité du nombre de monstres qui lâchent des objets avec une probabilité p dans le jeu doit être abandonnée est la distribution géométrique.
Les choses aléatoires sont les mêmes que dans le cas de la distribution binomiale, mais cette fois le nombre de monstres à vaincre n'est pas fixe, il sera répété jusqu'à ce qu'il réussisse une fois.
n_sampl = 10000 #Nombre d'échantillons
p = 0.2 #Probabilité de chute
kaime_drop = [] #Une liste qui stocke le résultat du nombre de fois à supprimer
for _ in range(n_sampl):
n_kai = 1 #Nombre de monstres vaincus
#Répétez jusqu'à ce que vous réussissiez
while(random.random()>p):
n_kai += 1
#Stocke le nombre de monstres tués après le succès
kaime_drop.append(n_kai)
y = np.bincount(kaime_drop) #Comptez le nombre de monstres que vous avez vaincus
x = np.arange(len(y))
#Dessinez un graphique à barres
plt.title('Distribution géométrique',family='Arial Unicode MS')
plt.bar(x,y,color='#f9a7a0',ec='k')
plt.grid(ls='--')
plt.savefig('geom.png',dpi=100)
plt.close()
Implémenté avec scipy
f = scipy.stats.geom(p)
plt.title('Distribution géométrique',family='Arial Unicode MS')
h = np.bincount(f.rvs(10000))
x = np.arange(1,len(h))
h = h[1:]
plt.bar(x,h/n_sampl,color='#a477e2',ec='k')
plt.plot(x,f.pmf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('geom2.png',dpi=100)
plt.close()
Similaire à la distribution géométrique, ** [Distribution binomiale négative](https://ja.wikipedia.org/wiki/Negative binomial distribution) ** est également une distribution du nombre d'exécutions, mais seulement une fois réussie Au lieu de vous contenter, vous pensez au nombre de fois où vous courrez vers un certain nombre de succès.
La fonction de masse stochastique est
P(x) = C(k+r-1,k)(1-p)^rp^k
p = probabilité de succès r = nombre de fois que vous souhaitez atteindre
Si r vaut 1, ce sera une distribution géométrique.
Par exemple, si vous voulez r objets d'un monstre qui lâche des objets avec une probabilité de p, combien devez-vous vaincre?
La méthode est un peu plus compliquée que la distribution géométrique, mais c'est presque la même chose.
n_sampl = 10000
p = 0.2 #Probabilité de chute
r = 4 #Nombre de succès que vous souhaitez
kaime_drop = []
for _ in range(n_sampl):
n_kai = 0 #Nombre de monstres vaincus
n_drop = 0 #Nombre de gouttes
#Battez les monstres encore et encore
while(n_drop<r):
#Que ce soit une goutte
if(random.random()<=p):
n_drop += 1
n_kai += 1
#Stocke le nombre de monstres vaincus après avoir chuté r fois
kaime_drop.append(n_kai)
y = np.bincount(kaime_drop)
x = np.arange(len(y))
plt.title('Distribution binomiale négative',family='Arial Unicode MS')
plt.bar(x,y,color='#f9a7a0',ec='k')
plt.grid(ls='--')
plt.savefig('nbinom.png',dpi=100)
plt.close()
Implémenté avec scipy
f = scipy.stats.nbinom(r,p)
plt.title('Distribution binomiale négative',family='Arial Unicode MS')
y = np.bincount(f.rvs(10000))
x = np.arange(len(h))
plt.bar(x+r,y/n_sampl,color='#a477e2',ec='k')
plt.plot(x+r,f.pmf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('nbinom2.png',dpi=100)
plt.close()
Si un événement se produit avec la même probabilité à tout moment, le nombre de fois où il se produit dans un intervalle particulier est ** [distribution de Poisson](https://ja.wikipedia.org/wiki/Poisson distribution) **.
La fonction de masse stochastique est
P(x) = \frac{λ^x e^{-λ}}{x!}
λ = nombre moyen de fois qui se produisent dans un intervalle particulier
Par exemple, si un monstre apparaît λ fois en une heure dans un jeu, le nombre de fois qu'il apparaît réellement dans chaque heure.
n = 10000 #Nombre d'intervalles de temps à diviser
λ = 8 #Nombre moyen de fois dans un certain temps
#Heure aléatoire pour se réveiller
jikan = np.random.uniform(0,n,n*λ)
#Divisez en unités d'une heure et comptez le nombre de fois dans chaque section
kaisuu = np.bincount(jikan.astype(int))
#Comptez combien de fois il y a pour voir la distribution des temps
y = np.bincount(kaisuu)
x = np.arange(len(y))
plt.title('Distribution de Poisson',family='Arial Unicode MS')
plt.bar(x,y,color='#f9a7a0',ec='k')
plt.grid(ls='--')
plt.savefig('poisson.png',dpi=100)
plt.close()
C'est un peu compliqué, mais le but est de randomiser le moment où cela se produit. Puisqu'il se produit environ λ fois dans une certaine section, la plage aléatoire doit être la même que le nombre de sections divisées (n), et le nombre de fois aléatoires doit être nλ.
Ensuite, utilisez np.bincount () pour compter le nombre de fois où chaque intervalle se produit.
Ensuite, utilisez à nouveau np.bincount () pour compter la distribution du nombre d'occurrences de tous les intervalles.
Implémentation dans scipy
f = scipy.stats.poisson(λ)
plt.title('Distribution de Poisson',family='Arial Unicode MS')
h = np.bincount(f.rvs(10000))
x = np.arange(len(h))
plt.bar(x,h/n,color='#a477e2',ec='k')
plt.plot(x,f.pmf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('poisson2.png',dpi=100)
plt.close()
Contrairement à la distribution de probabilité discrète, qui a la probabilité d'un nombre spécifique seulement, dans le cas d'une distribution de probabilité de type valeur continue, la probabilité de devenir un nombre spécifique devient 0 et la probabilité que la valeur se trouve dans chaque plage est obtenue. Par conséquent, la distribution de probabilité sera affichée par la fonction de densité de probabilité.
** [Distribution uniforme continue](https://ja.wikipedia.org/wiki/Distribution uniforme continue) ** est une distribution simple qui a une distribution de probabilité similaire uniquement dans une certaine plage.
Si la plage de distribution va de a à b, alors la fonction de densité de probabilité de x ∈ [a, b] est
f(x) = \frac{1}{b-a}
En dehors de la plage, $ f (x) = 0 $.
Il peut être facilement implémenté avec np.random.uniform ou random.uniform.
Par exemple, l'histoire d'une roulette sans section. Si vous lancez la balle à cette roulette, vous devriez penser normalement qu'elle s'arrêtera à la même probabilité de 0 degrés à 360 degrés.
n_sampl = 10000
a = 0 #le minimum
b = 360 #Maximum
x = np.random.uniform(a,b,n_sampl) #Aléatoire
#Rédiger un histogramme
plt.title('Distribution uniforme continue',family='Arial Unicode MS')
plt.hist(x,50,color='#92bee1',ec='k')
plt.grid(ls='--')
plt.savefig('uniform.png',dpi=100)
plt.close()
Pour une distribution uniforme continue, au lieu de compter les nombres avec np.bincount () et de dessiner un graphique à barres, plt.hist () crée un histogramme montrant la densité.
scipy a scipy.stats.uniform, mais lorsque vous utilisez .rvs (), il ne semble pas être très différent de np.random.uniform.
Dans scipy.stats, la méthode de la fonction de distribution est différente du type discret, le type continu est .pdf () au lieu de .pmf ().
Lors du dessin de la distribution de .rvs () avec plt.hist (), si la densité = True, elle sera divisée par le nombre total d'échantillons et correspondra à la valeur de .pdf ().
f = scipy.stats.uniform(a,b)
plt.title('Distribution uniforme continue',family='Arial Unicode MS')
_,h,_ = plt.hist(f.rvs(10000),50,color='#ffb3d3',ec='k',density=True)
x = np.linspace(h.min(),h.max(),101)
plt.plot(x,f.pdf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('uniform2.png',dpi=100)
plt.close()
** [Distribution exponentielle](https://ja.wikipedia.org/wiki/ Distribution exponentielle) ** est une distribution qui se produit en même temps que la distribution de Poisson.
Si un événement peut se produire à tout moment pendant un temps donné, la distribution temporelle entre chaque occurrence est une distribution exponentielle.
La fonction de densité de probabilité est
f(x) = λe^{-λx}
Comme pour la distribution de Poisson, λ est le nombre moyen de fois qui se produit dans un intervalle particulier.
Par exemple, si un monstre apparaît λ fois en une heure, combien de temps doit-il attendre après l'apparition de l'un avant le suivant?
La méthode est similaire à la distribution de Poisson, mais la distribution exponentielle semble plus facile.
n = 10000 #Une longueur de temps
λ = 10 #Nombre moyen de fois par heure
t = np.random.uniform(0,n*λ,n) #Heure aléatoire pour se réveiller
t = np.sort(t) #Tri
x = t[1:]-t[:-1] #Différence de temps
#Dessinez un histogramme
plt.title('Distribution exponentielle',family='Arial Unicode MS')
plt.hist(x,50,color='#92bee1',ec='k')
plt.grid(ls='--')
plt.savefig('expon.png',dpi=100)
plt.close()
Implémenté avec scipy
f = scipy.stats.expon(0,λ)
plt.title('Distribution exponentielle',family='Arial Unicode MS')
_,h,_ = plt.hist(f.rvs(10000),50,color='#ffb3d3',ec='k',density=True)
x = np.linspace(h.min(),h.max(),101)
plt.plot(x,f.pdf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('expon2.png',dpi=100)
plt.close()
** [Distribution normale](https://ja.wikipedia.org/wiki/Distribution normale) ** ou ** [distribution gaussienne](https://ja.wikipedia.org/wiki/ distribution gaussienne) ** C'est la distribution la plus courante, c'est donc la distribution la plus courante au monde.
La distribution normale peut se produire dans diverses situations, mais cette fois nous allons essayer la distribution normale générée par la [Central Pole Limitation](https://ja.wikipedia.org/wiki/Central Pole Limitation).
Selon la théorie de la limite du pôle central, si vous prenez la moyenne de nombreuses variables stochastiques, la distribution de probabilité de cette moyenne (quelle que soit la distribution d'origine) devient une distribution normale.
La fonction de densité de probabilité de la distribution normale est
f(x) = \frac{1}{\sqrt{2πσ^2}}e^{\left(-\frac{(x-μ)^2}{2σ^2}\right)}
Je vais l'essayer avec une roulette infinie comme dans l'exemple de la distribution uniforme continue, mais cette fois je vais regarder la distribution de la valeur moyenne des résultats de 100 fois.
n_sampl = 10000
n = 100
a,b = 0,360
x = np.random.uniform(a,b,[n_sampl,n]).mean(1)
plt.title('distribution normale',family='Arial Unicode MS')
plt.hist(x,50,color='#92bee1',ec='k')
plt.grid(ls='--')
plt.savefig('norm.png',dpi=100)
plt.close()
Ensuite, nous allons implémenter une distribution normale dans scipy.stats, mais nous devons d'abord calculer pour faire correspondre la moyenne et les écarts-types.
La valeur moyenne de la distribution uniforme continue est $ \ frac {b + a} {2} $, et l'écart type est $ \ frac {(ba) ^ 2} {12} $, mais la loi de la majorité Selon $ n $, l'écart type du résultat de l'essai est $ \ frac {1} {\ sqrt {n}} $.
μ = (a+b)/2 #Calculer la valeur moyenne μ
σ = np.sqrt((b-a)**2/12/n) #Calculer l'écart type σ
f = scipy.stats.norm(μ,σ)
plt.title('distribution normale',family='Arial Unicode MS')
_,h,_ = plt.hist(f.rvs(10000),50,color='#ffb3d3',ec='k',density=True)
x = np.linspace(h.min(),h.max(),101)
plt.plot(x,f.pdf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('norm2.png',dpi=100)
plt.close()
Si vous exécutez une variable de probabilité qui suit une distribution normale k fois, la somme des carrés
\sum_{i=1}^{k}x_i^2
La distribution de est [distribution Kai-square](https://ja.wikipedia.org/wiki/Kai-square distribution). Cela n'a rien à voir avec [Kai Ni](https://dic.pixiv.net/a/ Kaiji) </ s>
La fonction de densité de probabilité est
f(x) = \frac{x^{k/2-1}e^{-x/2}}{\,2^{k/2} \Gamma(k/2)}
Implémentation aléatoire de la distribution normale
n_sampl = 10000
k = 5
randn = np.random.randn(n_sampl,k)
x = (randn**2).sum(1)
plt.title('Distribution du chi carré',family='Arial Unicode MS')
plt.hist(x,50,color='#92bee1',ec='k')
plt.grid(ls='--')
plt.savefig('chi2.png',dpi=100)
plt.close()
Implémenté avec scipy
f = scipy.stats.chi2(k)
plt.title('Distribution du chi carré',family='Arial Unicode MS')
_,h,_ = plt.hist(f.rvs(10000),50,color='#ffb3d3',ec='k',density=True)
x = np.linspace(h.min(),h.max(),101)
plt.plot(x,f.pdf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('chi22.png',dpi=100)
plt.close()
** [Distribution Beta](https://ja.wikipedia.org/wiki/Beta distribution) ** se produit lorsque l'on considère la [Probabilité Bayes](https://ja.wikipedia.org/wiki/Bayes probabilité) Il s'agit d'une distribution de probabilité, qui est considérablement plus compliquée que les autres distributions.
Si vous ne connaissez pas la probabilité qu'un événement se produise et que vous souhaitez l'estimer à partir du nombre de succès, la distribution de probabilité pour cette probabilité est bêta.
La fonction de densité de probabilité est
f(x) = \frac{x^{α-1}(1-x)^{β-1}}{B(α,β)}
α-1 = nombre de succès β-1 = nombre de pannes B est [Fonction Beta](https://ja.wikipedia.org/wiki/Beta Function)
Pour plus de détails, reportez-vous au livre "Auto-étude complète: Introduction aux statistiques bayésiennes".
Il devrait y avoir différentes manières d'exprimer cette distribution, mais ici nous considérerons l'intervalle de probabilité de 0 à 1 divisé en 50.
Considérez le cas où vous réussissez 3 fois sur 4.
n_sampl = 10000 #Nombre d'échantillons
n_bin = 50 #Nombre de sections à diviser
n = 4 #Chaque fois
k = 3 #Nombre de succès
p = [] #Liste pour stocker les numéros de section
x = (np.arange(n_bin)+0.5)/n_bin #Centre de probabilité pour chaque section(0.01, 0.03, 0.05, ..., 0.99)
i_shikou = 0 #Nombre de Tentatives
while(i_shikou<n_sampl):
rand = np.random.random(n) #Des nombres aléatoires qui déterminent le succès ou l'échec
for i in range(n_bin):
#Nombre de succès dans le cas de la probabilité de cette section
if((rand<=x[i]).sum()==k):
#Stockez le numéro de section s'il est identique à un numéro spécifique
p.append(i)
i_shikou += 1
y = np.bincount(p)
plt.title('Distribution bêta',family='Arial Unicode MS')
plt.bar(x,y,width=1/n_bin,color='#92bee1',ec='k')
plt.grid(ls='--')
plt.savefig('beta.png',dpi=100)
plt.close()
J'utilise np.bincount et plt.bar au lieu de plt.hist, mais comme la distribution bêta est également une distribution continue, j'ai en fait dessiné un histogramme.
Implémenté dans scipy.stats
α = k+1 # 4
β = n-k+1 # 2
f = scipy.stats.beta(α,β)
plt.title('Distribution bêta',family='Arial Unicode MS')
plt.hist(f.rvs(10000),50,color='#ffb3d3',ec='k',density=True)
x = np.linspace(0,1,101)
plt.plot(x,f.pdf(x),'#4aec96')
plt.grid(ls='--')
plt.savefig('beta2.png',dpi=100)
plt.close()
Lorsque vous regardez les résultats au hasard, vous pouvez vous rendre compte que ce type de distribution se produit de cette manière, et vous pouvez approfondir votre compréhension et vous convaincre.
La distribution expliquée ci-dessus est résumée ici.
Nom | une fonction | Gamme de x | scipy.stats | Paramètres |
---|---|---|---|---|
Distribution binaire | 0,1,2,...,n | scipy.stats.binom(n,p) | ||
Distribution de Bernoulli | 0,1 | scipy.stats.bernoulli(p) | ||
Distribution géométrique | 1,2,... | scipy.stats.geom(p) | ||
Distribution binomiale négative | 0,1,2,... | scipy.stats.nbinom(r,p) | ||
Distribution de Poisson | 0,1,2,... | scipy.stats.poisson(λ) | ||
Distribution uniforme continue | [a,b] | scipy.stats.uniform(a,b) | ||
Distribution exponentielle | [0,∞) | scipy.stats.expon(0,λ) | ||
distribution normale | (-∞,∞) | scipy.stats.norm(μ,σ) | ||
Distribution du chi carré | [0,∞) | scipy.stats.chi2(k) | ||
Distribution bêta | [0,1] | scipy.stats.beta(α,β) |
Reportez-vous également à cet article https://qiita.com/qiita_kuru/items/d9782185652351c78aac https://qiita.com/hamage/items/738b65668b1093dd9660
Recommended Posts