Aller au contenu

Trouvez la loi stationnaire

Au chapitre 1, vous avez calculé la météo dans trois jours. Mais quelle est la proportion de jours de pluie sur une année entière ? Et cette proportion dépend-elle du temps qu’il faisait le 1er janvier ? L’intuition dit que non : au bout d’un moment, la chaîne « oublie » son point de départ.

Ce chapitre donne un sens précis à cette intuition. Vous allez calculer la loi stationnaire d’une chaîne, apprendre dans quels cas la chaîne converge vers elle, et à quelle vitesse. Nous reprenons la météo rennaise du chapitre 1, et nous finirons par l’algorithme qui a fait la fortune de Google.

Rappelons la matrice de la météo (soleil, nuages, pluie) :

P=(0,60,30,10,30,40,30,10,40,5)P = \begin{pmatrix} 0{,}6 & 0{,}3 & 0{,}1 \\ 0{,}3 & 0{,}4 & 0{,}3 \\ 0{,}1 & 0{,}4 & 0{,}5 \end{pmatrix}

Calculons p(n)=p(0) Pnp(n) = p(0)\,P^n pour deux points de départ opposés : un jour de soleil et un jour de pluie.

nnDépart au soleilDépart sous la pluie
1(0,600 ; 0,300 ; 0,100)(0,100 ; 0,400 ; 0,500)
5(0,357 ; 0,363 ; 0,280)(0,335 ; 0,368 ; 0,297)
10(0,346 ; 0,365 ; 0,288)(0,346 ; 0,365 ; 0,289)
20(0,346 ; 0,365 ; 0,288)(0,346 ; 0,365 ; 0,288)

Au bout d’une dizaine de jours, les deux colonnes sont identiques à trois décimales : la loi de XnX_n ne dépend plus de X0X_0. Elle s’est stabilisée sur un vecteur, qu’on appelle la loi stationnaire. Pourquoi « stationnaire » ? Parce que si p(n)p(n) ne bouge plus, alors p(n+1)=p(n) P=p(n)p(n+1) = p(n)\,P = p(n).

051015jour n0,00,20,40,60,81,0probabilitéΠ = 0,346P(Xₙ = soleil)départ au soleildépart sous la pluie051015jour nΠ = 0,365P(Xₙ = nuages)051015jour nΠ = 0,288P(Xₙ = pluie)
Quel que soit le temps du premier jour, les deux courbes se confondent en une dizaine de jours sur la même ligne pointillée : la loi stationnaire Π.

Une loi stationnaire (ou invariante) est un vecteur ligne Π=(Πi)i∈E\Pi = (\Pi_i)_{i \in E} qui vérifie

Π P=Π,∑i∈EΠi=1,Πi≥0.\Pi\, P = \Pi, \qquad \sum_{i \in E} \Pi_i = 1, \qquad \Pi_i \geq 0.

La première équation dit que si la chaîne suit la loi Π\Pi à un instant, elle la suit encore à l’instant suivant, et donc pour toujours. La deuxième en fait une loi de probabilité. En langage d’algèbre linéaire, Π\Pi est un vecteur propre à gauche de PP pour la valeur propre 1, normalisé pour sommer à 1.

Le système ΠP=Π\Pi P = \Pi contient une équation redondante (les lignes de PP sommant à 1, l’une se déduit des autres). On en supprime donc une, et on la remplace par la normalisation.

Pour une chaîne à deux états, le calcul se fait de tête. Reprenons la machine du chapitre 2, qui tombe en panne avec probabilité aa et est réparée avec probabilité bb :

P=(1−aab1−b)⟹Π=(ba+b, aa+b).P = \begin{pmatrix} 1-a & a \\ b & 1-b \end{pmatrix} \quad\Longrightarrow\quad \Pi = \left(\frac{b}{a+b},\ \frac{a}{a+b}\right).

En effet, la première équation donne a Π0=b Π1a\,\Pi_0 = b\,\Pi_1 : le « flux » de la marche vers la panne égale le flux de la panne vers la marche. Avec a=0,1a = 0{,}1 et b=0,4b = 0{,}4, la machine fonctionne 80 % du temps.

Une loi stationnaire existe-t-elle toujours ? Est-elle unique ? Et surtout, p(n)p(n) converge-t-elle vers elle ? Le résultat central du chapitre répond à tout.

Chaque hypothèse compte. Voyons ce qui se passe quand l’une manque.

Sans apériodicité. Le robot du chapitre 2 fait la navette entre deux entrepôts : P=(0110)P = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}. La loi Π=(12,12)\Pi = (\tfrac12, \tfrac12) est bien stationnaire et unique. Mais partant de l’entrepôt 0, p(n)p(n) vaut (1,0)(1, 0) aux instants pairs et (0,1)(0, 1) aux instants impairs : elle oscille et ne converge pas. En revanche, Π\Pi garde un sens : c’est la proportion du temps passée dans chaque état sur une longue période (le robot est la moitié du temps dans chaque entrepôt).

02468101214161820instant n0,00,51,0Π₀ = 1/2p₀(n) : probabilité d’être en 0 à l’instant nproportion du temps passé en 0 jusqu’à n
Chaîne périodique : p₀(n) saute sans fin de 1 à 0 et ne converge pas, mais la proportion du temps passé en 0 converge bien vers Π₀ = 1/2.

Sans irréductibilité. Dans la chaîne du site du chapitre 2, deux classes sont fermées. La loi qui met toute la masse sur Départ est stationnaire, celle qui se répartit sur Abonné et Vidéo en proportions (611,511)(\tfrac{6}{11}, \tfrac{5}{11}) aussi, et tout mélange des deux également. Il y a une infinité de lois stationnaires, et la limite dépend du point de départ. C’est l’objet du chapitre 4.

Sans récurrence positive (espace infini seulement). Dans une file d’attente où les clients arrivent plus vite qu’ils ne sont servis, la file grandit sans fin : aucune loi stationnaire n’existe. Nous le verrons au chapitre 8.

À quelle vitesse la chaîne oublie-t-elle son départ ? Pour la machine, on peut calculer p(n)p(n) exactement. Partant de l’état « marche » :

p0(n)=ba+b+aa+b (1−a−b)np_0(n) = \frac{b}{a+b} + \frac{a}{a+b}\,(1 - a - b)^n

Le premier terme est Π0\Pi_0 ; le second est l’écart à la limite, qui décroît géométriquement avec la raison 1−a−b1 - a - b. Avec a=0,1a = 0{,}1 et b=0,4b = 0{,}4, on a p0(n)=0,8+0,2×0,5np_0(n) = 0{,}8 + 0{,}2 \times 0{,}5^n : l’écart est divisé par deux chaque heure (1 ; 0,9 ; 0,85 ; 0,825…).

Ce nombre 1−a−b1 - a - b n’est pas un hasard : c’est la seconde valeur propre de PP (la première vaut toujours 1). En général, la vitesse de convergence est gouvernée par la plus grande valeur propre de PP en module après 1. Pour la météo, elle vaut environ 0,456 : l’écart à la loi stationnaire est divisé par un peu plus de 2 chaque jour, ce qui explique la stabilisation en une dizaine de jours. Une valeur proche de 1 signale une chaîne qui « se mélange » lentement.

02468heure n0,800,850,900,951,00Π₀ = 0,810,90,850,825machine : p₀(n) = 0,8 + 0,2 × 0,5ⁿ051015pas n10,0110⁻⁴10⁻⁶écart à la loi stationnairemachine (raison 0,5)météo (raison ≈ 0,456)
L'écart à la limite est divisé par deux à chaque pas pour la machine, et par environ 2,2 pour la météo. En échelle logarithmique, une décroissance géométrique devient une droite, dont la pente est fixée par la seconde valeur propre.

La loi stationnaire a une autre interprétation, très parlante. Pour une chaîne irréductible et récurrente positive, la probabilité stationnaire d’un état est l’inverse de son temps moyen de retour :

Πi=1μi\Pi_i = \frac{1}{\mu_i}

où μi\mu_i est le nombre moyen de pas pour revenir en ii en partant de ii. Plus on revient vite, plus on passe de temps dans l’état. Pour la machine, μ0=1,25\mu_0 = 1{,}25 heure (calculé au chapitre 2), et on retrouve bien Π0=1/1,25=0,8\Pi_0 = 1/1{,}25 = 0{,}8. Pour la météo, le temps moyen entre deux jours de pluie vaut 52/15≈3,552/15 \approx 3{,}5 jours.

PageRank : la loi stationnaire d’un surfeur aléatoire

Section intitulée « PageRank : la loi stationnaire d’un surfeur aléatoire »

Comment classer des pages web par importance ? L’idée de PageRank est de lâcher un surfeur aléatoire sur le web : sur chaque page, il clique au hasard sur l’un des liens sortants. Une page importante est une page où il passe souvent, c’est-à-dire une page de forte probabilité stationnaire.

Problème : le graphe du web n’est ni irréductible (des pages sans lien entrant, des culs-de-sac) ni forcément apériodique. On corrige avec la téléportation : à chaque pas, avec probabilité 1−α1 - \alpha, le surfeur saute sur une page tirée uniformément. La matrice devient

G=α M+(1−α) 1N JG = \alpha\, M + (1 - \alpha)\,\frac{1}{N}\,J

où MM est la matrice de la marche sur les liens, NN le nombre de pages, JJ la matrice remplie de 1, et α\alpha le facteur d’amortissement, classiquement 0,85. Tous les coefficients de GG sont strictement positifs : la chaîne est irréductible et apériodique, et le théorème ergodique s’applique.

taille du disque ∝ PageRank12340,00,10,20,30,40,5probabilité stationnairepage 1page 2page 3page 40,3730,1960,3940,037part de la téléportation : 0,15/4
La page 3 reçoit trois liens et arrive en tête ; la page 1, qui n'en reçoit qu'un mais depuis la page 3, la suit de près. La page 4, sans lien entrant, n'a que la part de la téléportation (pointillés).

Pour calculer Π\Pi sur des milliards de pages, on ne résout pas de système linéaire : on itère simplement π←π G\pi \leftarrow \pi\, G à partir d’une loi quelconque. C’est la méthode de la puissance, qui converge d’autant plus vite que la seconde valeur propre est petite (pour PageRank, elle est au plus α\alpha).

import numpy as np
P = np.array([[0.6, 0.3, 0.1],
[0.3, 0.4, 0.3],
[0.1, 0.4, 0.5]])
n = len(P)
# 1) Système linéaire : (P^T - I) Pi^T = 0, une équation remplacée par sum(Pi) = 1
A = P.T - np.eye(n)
A[-1, :] = 1
b = np.zeros(n); b[-1] = 1
pi = np.linalg.solve(A, b)
print(pi) # [0.3462 0.3654 0.2885]
# 2) Méthode de la puissance
pi_it = np.ones(n) / n
for _ in range(100):
pi_it = pi_it @ P
print(np.allclose(pi, pi_it)) # True
# 3) Valeurs propres : 1, puis la seconde qui fixe la vitesse de convergence
print(np.sort(np.abs(np.linalg.eigvals(P)))[::-1]) # [1. 0.456 0.044]
# 4) Proportion du temps sur une longue trajectoire simulée
rng = np.random.default_rng(1)
x, compte = 0, np.zeros(n)
for _ in range(100_000):
x = rng.choice(n, p=P[x])
compte[x] += 1
print(compte / compte.sum()) # proche de pi

Le quatrième calcul illustre une autre face du théorème ergodique : la proportion du temps passée dans chaque état le long d’une seule trajectoire converge elle aussi vers Π\Pi. C’est ce résultat qui fonde les méthodes MCMC en statistique bayésienne : on construit une chaîne dont la loi stationnaire est la loi qu’on veut échantillonner, on la laisse tourner un moment (la « chauffe », qui correspond au régime transitoire), puis on utilise ses états comme des tirages.

101001 00010 000100 000nombre de jours simulés (une seule trajectoire)0,00,10,20,30,40,50,60,70,8proportion du temps0,3460,3650,288soleilnuagespluie
Une seule trajectoire suffit : au fil des jours, la fraction du temps passée dans chaque état se cale sur la loi stationnaire (pointillés). Les premières centaines de jours, encore marqués par le départ, jouent le rôle de la chauffe en MCMC.
  • Une loi stationnaire vérifie ΠP=Π\Pi P = \Pi, ∑iΠi=1\sum_i \Pi_i = 1 : c’est un vecteur propre à gauche de PP pour la valeur propre 1.
  • On la calcule en remplaçant une équation de ΠP=Π\Pi P = \Pi par la normalisation, ou par la méthode de la puissance.
  • Théorème ergodique : irréductible + récurrente positive (automatique si finie) + apériodique implique une unique Π\Pi et p(n)→Πp(n) \to \Pi quelle que soit la loi initiale.
  • Périodique : Π\Pi existe mais p(n)p(n) oscille ; Π\Pi reste la proportion du temps passée dans chaque état. Non irréductible : plusieurs lois stationnaires possibles.
  • La convergence est géométrique, à la vitesse de la seconde plus grande valeur propre en module.
  • Πi=1/μi\Pi_i = 1/\mu_i : probabilité stationnaire et temps moyen de retour sont inverses. PageRank est la loi stationnaire d’une marche aléatoire avec téléportation.

Exercice · Disponibilité d'une machine

facile

Une imprimante 3D tombe en panne en cours d’heure avec probabilité 0,2 et, quand elle est en panne, est réparée dans l’heure avec probabilité 0,3. Quelle proportion du temps fonctionne-t-elle à long terme ? En moyenne, combien d’heures s’écoulent entre deux heures de panne ?

Voir la solution

Avec a=0,2a = 0{,}2 et b=0,3b = 0{,}3, la chaîne est irréductible, finie et apériodique (boucles), donc ergodique. La loi stationnaire vaut

Π=(ba+b, aa+b)=(0,6 ; 0,4).\Pi = \left(\frac{b}{a+b},\ \frac{a}{a+b}\right) = (0{,}6 \,;\, 0{,}4).

L’imprimante fonctionne 60 % du temps. Le temps moyen de retour dans l’état « panne » vaut μ1=1/Π1=2,5\mu_1 = 1/\Pi_1 = 2{,}5 heures.

En code

import numpy as np
a, b = 0.2, 0.3 # panne, réparation (par heure)
P = np.array([[1 - a, a],
[b, 1 - b]])
# Pi P = Pi : une équation remplacée par la normalisation
A = P.T - np.eye(2)
A[-1, :] = 1
pi = np.linalg.solve(A, [0, 1])
print(pi) # [0.6 0.4] : en marche 60 % du temps
print(1 / pi[1]) # 2.5 heures entre deux heures de panne

Exercice · Une chaîne à trois états

moyen

Un livreur travaille dans trois quartiers alignés A, B, C. Depuis A, il reste en A ou passe en B avec probabilité 1/2 chacun ; depuis B, il va en A ou en C avec probabilité 1/4 chacun et reste en B avec probabilité 1/2 ; depuis C, il reste en C ou passe en B avec probabilité 1/2 chacun.

  1. Justifiez que la chaîne converge vers une loi stationnaire unique.
  2. Calculez-la, puis le temps moyen entre deux passages en A.
Voir la solution
  1. Tous les quartiers communiquent (A ⇄ B ⇄ C) : la chaîne est irréductible. Elle est finie, donc récurrente positive, et chaque état a une boucle, donc elle est apériodique. Le théorème ergodique s’applique.
  2. L’équation de la colonne A donne ΠA=12ΠA+14ΠB\Pi_A = \tfrac12 \Pi_A + \tfrac14 \Pi_B, soit ΠB=2 ΠA\Pi_B = 2\,\Pi_A. Par symétrie entre A et C, ΠC=ΠA\Pi_C = \Pi_A. La normalisation donne ΠA(1+2+1)=1\Pi_A (1 + 2 + 1) = 1, donc
Π=(14, 12, 14).\Pi = \left(\tfrac14,\ \tfrac12,\ \tfrac14\right).

Le temps moyen de retour en A vaut μA=1/ΠA=4\mu_A = 1/\Pi_A = 4 pas.

En code

import numpy as np
P = np.array([[1/2, 1/2, 0], # quartiers A, B, C
[1/4, 1/2, 1/4],
[0, 1/2, 1/2]])
# Vecteur propre à gauche pour la valeur propre 1, normalisé
valeurs, vecteurs = np.linalg.eig(P.T)
pi = np.real(vecteurs[:, np.argmin(abs(valeurs - 1))])
pi = pi / pi.sum()
print(pi) # [0.25 0.5 0.25]
print(1 / pi[0]) # 4.0 pas entre deux passages en A
print(np.linalg.matrix_power(P, 50)[2]) # [0.25 0.5 0.25] : partant de C, on converge

Exercice · Stationnaire mais pas limite

difficile

Une balle rebondit entre trois positions alignées : depuis une extrémité (0 ou 2), elle va toujours au centre (1) ; depuis le centre, elle va à chaque extrémité avec probabilité 1/2.

  1. Quelle est la période de la chaîne ? Calculez sa loi stationnaire.
  2. La balle part de la position 0. Calculez p(1)p(1), p(2)p(2), p(3)p(3). La suite p(n)p(n) converge-t-elle ?
  3. Montrez que la moyenne de p(n)p(n) sur deux pas consécutifs est égale à la loi stationnaire. Interprétez.
Voir la solution
  1. Tout chemin alterne entre le centre et une extrémité, donc un retour n’est possible qu’en un nombre pair de pas : la période vaut 2. La colonne 0 de ΠP=Π\Pi P = \Pi donne Π0=12Π1\Pi_0 = \tfrac12 \Pi_1, de même Π2=12Π1\Pi_2 = \tfrac12 \Pi_1, et la normalisation conduit à Π=(14,12,14)\Pi = (\tfrac14, \tfrac12, \tfrac14).
  2. p(0)=(1,0,0)p(0) = (1, 0, 0), p(1)=(0,1,0)p(1) = (0, 1, 0), p(2)=(12,0,12)p(2) = (\tfrac12, 0, \tfrac12), p(3)=(0,1,0)p(3) = (0, 1, 0), puis la suite alterne entre (12,0,12)(\tfrac12, 0, \tfrac12) et (0,1,0)(0, 1, 0). Elle ne converge pas : la chaîne est irréductible et récurrente positive, mais périodique.
  3. 12[(12,0,12)+(0,1,0)]=(14,12,14)=Π\tfrac12\big[(\tfrac12, 0, \tfrac12) + (0, 1, 0)\big] = (\tfrac14, \tfrac12, \tfrac14) = \Pi. La loi stationnaire ne décrit pas la position à un instant donné, mais la proportion du temps passée à chaque position : la balle est au centre un pas sur deux, et à chaque extrémité un pas sur quatre.

En code

import numpy as np
P = np.array([[0, 1, 0], # extrémité 0 -> centre
[0.5, 0, 0.5], # centre -> une extrémité
[0, 1, 0]])
p = np.array([1.0, 0, 0]) # départ en 0
lois = [p]
for n in range(5):
p = p @ P
lois.append(p)
for n, loi in enumerate(lois):
print(n, loi)
# 0 [1. 0. 0.]
# 1 [0. 1. 0.]
# 2 [0.5 0. 0.5]
# 3 [0. 1. 0.] et ainsi de suite : la suite oscille
print((lois[4] + lois[5]) / 2) # [0.25 0.5 0.25] = Pi