Support de cours semaine 8

Variables aléatoires discrètes

Distribution uniforme

On a déjà vu randint et randrange pour tirer de manière uniforme des entiers dans un intervalle.

Remarque : le randint de sagemath ne fonctionne pas comme le randint de la bibliothèque random de python...

In [1]:
[ randint(0, 2) for i in range(20) ]
Out[1]:
[0, 1, 0, 0, 2, 1, 1, 2, 0, 0, 0, 0, 2, 0, 2, 1, 0, 0, 1, 2]
In [2]:
[ randrange(2) for i in range(20) ]
Out[2]:
[1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1]
In [3]:
[ randrange(-12, 7, 4) for i in range(20) ]
Out[3]:
[-12,
 4,
 -12,
 -4,
 -12,
 -12,
 4,
 -4,
 4,
 -12,
 0,
 -8,
 -4,
 -8,
 -4,
 -4,
 -12,
 -12,
 -8,
 4]

Remarque : Dans beaucoup de structures finies (comme les listes, les ensembles finis, les graphes, etc.), il existe des fonctions de tirage uniforme déjà codées.

In [4]:
A = Zmod(17)
print(A)
print(A.random_element())
Ring of integers modulo 17
5
In [5]:
G = graphs.CompleteGraph(5)
show(G)
print(G.random_vertex())
0

Distribution finie quelconque

Si l'on souhaite définir une variable aléatoire de distribution non-uniforme, on peut utiliser l'objet GeneralDiscreteDistribution(P)P est la liste des probabilités de la distribution.

In [6]:
P = [0.2, 0.1, 0.7]
D = GeneralDiscreteDistribution(P)
[ D.get_random_element() for i in range(20) ]
Out[6]:
[2, 2, 2, 0, 2, 2, 0, 0, 2, 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2]

Variables aléatoires continues

Distribution uniforme

La fonction uniform(a, b) permet de tirer uniformément dans l'intevalle $[a, b[$.

In [7]:
uniform(1, 7)
Out[7]:
3.7947960116176267

Autres distributions

La fonction RealDistribution permet de définir quelques autres distributions. Par exemple, pour la distribution gaussienne centrée de variance sigma :

In [8]:
sigma = 1
G = RealDistribution("gaussian", sigma)

La fonction de densité de probabilité est distribution_function(), et la fonction de répartition est cum_distribution_function().

In [9]:
print(G.distribution_function(0), G.cum_distribution_function(0))
0.3989422804014327 0.5

Pour la loi exponentielle, c'est un peu pénible, il faut passer par une loi plus générale appelée loi de Weibull, et fixer le second paramètre à $1$. Ainsi, pour la loi exponentielle de paramètre $\lambda = 0.5$ :

In [10]:
P = RealDistribution('weibull', [0.5, 1])
plot(P, xmin=0, xmax=4)
Out[10]:

Pour aller plus loin : la bibliothèque scipy.stats

Sagemath contient relativement peu de fonctions de probabilités/statistiques. Si l'on souhaite une utilisation plus avancée, il est conseillé d'utiliser le logiciel R (qui est inclus dans Sagemath) ou le module stats de la bibliothèque scipy.

Le logiciel R est assez complexe que vous aurez l'occasion de découvrir si vous poursuivez dans l'analyse de données, les statistiques, etc.

Voyons rapidement ce que l'on peut effectuer avec scipy.stats.

Il faut d'abord importer la bibliothèque : import scipy.stats as sc. Puis, s'offre à nous une quantité importante de fonctions (voyez en tapant sc.<tab>). Par exemple pou r la loi binomiale avec $n = 12$ et $p = 0.2$ :

In [11]:
import scipy.stats as sc

b = sc.binom(12, 0.2)
bar_chart([b.pmf(k) for k in range(13)])
Out[11]:

On voit que la fonction .pmf() permet d'obtenir la distribution de la loi. On peut également obtenir la fonction de répartition par .cdf() :

In [12]:
bar_chart([b.cdf(k) for k in range(13)])
Out[12]:

Beaucoup d'autres valeurs sont disponibles : l'espérance par .mean() ou .expect(), la variance par .var(), la mediane par .median(), et les moments d'ordres quelconques par .moment(k).

Attention : les valeurs sont souvent arrondies et peut précises :

In [13]:
print(b.moment(2) - b.moment(1)**2, b.var())
1.92000000000000 1.9200000000000004

Pour la loi normale centrée réduite :

In [14]:
c = sc.norm(0, 1)
plot(c.pdf, xmin=-4, xmax=4)
Out[14]: