Découvrez les chaînes de Markov
À Rennes, on dit volontiers qu’il fait beau plusieurs fois par jour. Plus sérieusement, le temps qu’il fera demain n’est pas prévisible avec certitude, mais il n’est pas non plus tiré au hasard sans règle : après une journée de pluie, une autre journée de pluie est plus probable qu’après une journée de grand soleil. Comment décrire un système qui évolue au hasard, mais avec une mémoire de son état présent ?
C’est exactement ce que fait une chaîne de Markov. Dans ce chapitre, vous allez poser le vocabulaire, écrire votre première matrice de transition et calculer la probabilité qu’il pleuve dans trois jours. Nous suivrons la météo rennaise tout au long du chapitre, et nous la retrouverons au chapitre 3.
Un processus stochastique, c’est une suite de variables aléatoires
Section intitulée « Un processus stochastique, c’est une suite de variables aléatoires »Observons le ciel chaque matin à 8 h. Le jour , on note la météo observée, qui prend une valeur parmi trois : soleil, nuages ou pluie. Avant d’observer, est une variable aléatoire. La suite est ce qu’on appelle un processus stochastique (stochastic process).
Plus précisément, un processus stochastique est une famille de variables aléatoires , où :
- est l’ensemble des temps. Si (on observe à des instants ), on parle de processus à temps discret, ou de chaîne. Si (on observe à tout instant), le processus est à temps continu ; ce sera l’objet de la partie 2.
- est l’espace d’états, l’ensemble des valeurs que peut prendre chaque . Dans tout ce cours, est discret : fini (trois météos) ou infini dénombrable (le nombre de clients dans une file d’attente, qui peut valoir ).
Pour simplifier l’écriture, on numérote les états. Ici : 0 pour soleil, 1 pour nuages, 2 pour pluie. Une trajectoire est une suite de valeurs effectivement prises, par exemple « soleil, soleil, nuages, pluie ».
La propriété de Markov : seul le présent compte
Section intitulée « La propriété de Markov : seul le présent compte »Pour prévoir la météo de demain, faut-il connaître celle de toute la semaine passée ? Dans un modèle de Markov, non : le futur ne dépend du passé qu’à travers l’état présent. Mathématiquement, pour tous états :
La barre verticale se lit « sachant ». À gauche, on conditionne par tout l’historique ; à droite, seulement par le dernier état. La propriété de Markov dit que ces deux probabilités sont égales : une fois l’état présent connu, l’historique n’apporte plus aucune information sur le futur.
On ajoute presque toujours une deuxième hypothèse, l’homogénéité : la probabilité de passer de l’état à l’état ne dépend pas de l’instant . On la note simplement
Pour notre météo, cela revient à dire que la règle « après un jour de pluie, il pleut encore avec probabilité 0,5 » vaut en janvier comme en juillet. C’est évidemment une simplification (les saisons existent, même en Bretagne), mais elle rend le modèle calculable. Tout ce cours travaille avec des chaînes homogènes.
La matrice de transition et son graphe
Section intitulée « La matrice de transition et son graphe »Supposons qu’une longue série d’observations donne les fréquences suivantes (elles sont inventées pour l’exemple) :
| Aujourd’hui \ Demain | Soleil | Nuages | Pluie |
|---|---|---|---|
| Soleil | 0,6 | 0,3 | 0,1 |
| Nuages | 0,3 | 0,4 | 0,3 |
| Pluie | 0,1 | 0,4 | 0,5 |
On range ces probabilités dans la matrice de transition :
La ligne correspond à l’état de départ, la colonne à l’état d’arrivée. Ainsi est la probabilité qu’il fasse soleil demain sachant qu’il pleut aujourd’hui.
Une matrice de transition est toujours stochastique :
- tous ses coefficients sont positifs ou nuls, ;
- chaque ligne somme à 1, , car depuis l’état , la chaîne va forcément quelque part (éventuellement elle reste en ).
On représente aussi la chaîne par son graphe de transition : un sommet par état, un arc de vers chaque fois que , étiqueté par . Les boucles représentent le fait de rester dans le même état.
Le graphe n’apporte aucune information de plus que la matrice, mais il se lit beaucoup mieux. Au chapitre suivant, c’est sur lui que vous classerez les états.
Prévoir la loi à l’instant n
Section intitulée « Prévoir la loi à l’instant n »Supposons qu’il fasse soleil ce matin. Quelle est la probabilité de chaque météo dans trois jours ? On range les probabilités d’état à l’instant dans un vecteur ligne
C’est lui aussi un vecteur stochastique : ses coefficients sont positifs et somment à 1. La loi initiale est ici .
Pour passer d’un jour au suivant, on applique la formule des probabilités totales en conditionnant sur l’état de la veille :
C’est exactement un produit vecteur ligne par matrice : . En répétant, on obtient la formule centrale du régime transitoire :
où est la puissance -ième de la matrice. Le régime transitoire, c’est justement l’étude de pour un donné.
On peut aussi calculer la probabilité d’une trajectoire précise. Par la définition des probabilités conditionnelles puis la propriété de Markov, la probabilité d’observer la suite d’états est un simple produit :
La probabilité de la loi initiale, puis celle de chaque transition. Sachant qu’il fait soleil aujourd’hui, la trajectoire « soleil, soleil, nuages, pluie » a pour probabilité .
La relation de Chapman-Kolmogorov
Section intitulée « La relation de Chapman-Kolmogorov »On note la probabilité de passer de à en exactement pas (grâce à l’homogénéité, elle ne dépend pas de ). Comment la calculer ? En se demandant par où la chaîne passe à mi-parcours. Pour aller de à en pas, elle est forcément dans un certain état après pas :
C’est la relation de Chapman-Kolmogorov : on somme, sur tous les états intermédiaires , la probabilité d’aller de à en pas puis de à en pas. Sous forme matricielle, si désigne la matrice des , elle s’écrit , et on en déduit par récurrence que
Autrement dit, la matrice de transition en pas est la puissance -ième de la matrice de transition en un pas. Le coefficient de est la probabilité d’aller de à en deux jours. Pour notre météo :
S’il pleut aujourd’hui, il pleuvra encore après-demain avec probabilité 0,38.
Calculer et simuler en Python
Section intitulée « Calculer et simuler en Python »Avec NumPy, les calculs précédents tiennent en quelques lignes. La simulation, elle, tire au hasard une trajectoire : à chaque pas, on choisit l’état suivant selon la ligne de correspondant à l’état présent.
import numpy as np
etats = ["soleil", "nuages", "pluie"]P = np.array([[0.6, 0.3, 0.1], [0.3, 0.4, 0.3], [0.1, 0.4, 0.5]])assert np.allclose(P.sum(axis=1), 1) # chaque ligne somme à 1
p0 = np.array([1.0, 0.0, 0.0]) # soleil aujourd'huip3 = p0 @ np.linalg.matrix_power(P, 3) # vecteur ligne à gaucheprint(p3) # [0.398 0.354 0.248]
# Simulation de 100 000 trajectoires de 3 joursrng = np.random.default_rng(0)n_traj, pluie_j3 = 100_000, 0for _ in range(n_traj): x = 0 for _ in range(3): x = rng.choice(3, p=P[x]) # tirage selon la ligne de l'état courant pluie_j3 += (x == 2)print(pluie_j3 / n_traj) # proche de 0.248La simulation ne sert à rien ici, puisque le calcul exact est immédiat. Mais elle devient précieuse dès que le modèle se complique (un espace d’états énorme, des règles difficiles à écrire en matrice). Vérifier un calcul par simulation, et l’inverse, est un bon réflexe que nous garderons tout au long du cours.
En résumé
Section intitulée « En résumé »- Un processus stochastique est une famille de variables aléatoires ; à temps discret, on parle de chaîne.
- Propriété de Markov : sachant l’état présent, le futur est indépendant du passé. Si elle n’est pas vérifiée, on peut enrichir l’état.
- Une chaîne homogène est décrite par sa matrice de transition : ligne = départ, colonne = arrivée, lignes de somme 1. Le graphe associé a un arc quand .
- La loi à l’instant est le vecteur ligne (régime transitoire).
- La probabilité d’une trajectoire est le produit de la probabilité initiale et des probabilités de transition successives.
- Chapman-Kolmogorov : , soit .
Exercices
Section intitulée « Exercices »Exercice · Un pas de météo
facileOn reprend la matrice de la météo rennaise. Ce matin, les prévisionnistes hésitent : soleil ou pluie, une chance sur deux chacun, .
- Vérifiez que est bien une matrice stochastique.
- Calculez .
Voir la solution
-
Tous les coefficients sont positifs, et chaque ligne somme à 1 : , , .
-
:
- soleil : ;
- nuages : ;
- pluie : .
Donc , qui somme bien à 1.
En code
import numpy as np
# Météo rennaise : soleil, nuages, pluieP = np.array([[0.6, 0.3, 0.1], [0.3, 0.4, 0.3], [0.1, 0.4, 0.5]])print((P >= 0).all(), P.sum(axis=1)) # True [1. 1. 1.]
p0 = np.array([0.5, 0.0, 0.5]) # soleil ou pluie, une chance sur deuxp1 = p0 @ P # vecteur ligne à gaucheprint(p1, p1.sum()) # [0.35 0.35 0.3 ] 1.0# Météo rennaise : soleil, nuages, pluieP <- matrix(c(0.6, 0.3, 0.1, 0.3, 0.4, 0.3, 0.1, 0.4, 0.5), nrow = 3, byrow = TRUE)all(P >= 0); rowSums(P) # TRUE ; 1 1 1
p0 <- c(0.5, 0, 0.5) # soleil ou pluie, une chance sur deuxp1 <- p0 %*% P # vecteur ligne à gauchep1; sum(p1) # 0.35 0.35 0.3 ; 1Exercice · Trajectoires et transitions en deux pas
moyenIl pleut aujourd’hui.
- Quelle est la probabilité d’observer exactement « pluie, nuages, soleil » aujourd’hui, demain et après-demain ?
- Calculez, à l’aide de Chapman-Kolmogorov, la probabilité qu’il fasse soleil après-demain. Retrouvez-la dans la matrice .
- Pourquoi la réponse à la question 2 est-elle plus grande que celle de la question 1 ?
Voir la solution
- La loi initiale met toute la masse sur « pluie ». La probabilité est .
- On somme sur la météo de demain : . C’est bien le coefficient (ligne pluie, colonne soleil) de .
- La question 2 regroupe toutes les trajectoires qui finissent au soleil après-demain (en passant par le soleil, les nuages ou la pluie demain), alors que la question 1 n’en compte qu’une. La trajectoire par les nuages représente sur les .
En code
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]])SOLEIL, NUAGES, PLUIE = 0, 1, 2
# 1) Trajectoire pluie -> nuages -> soleil (il pleut aujourd'hui avec certitude)print(P[PLUIE, NUAGES] * P[NUAGES, SOLEIL]) # 0.12
# 2) Chapman-Kolmogorov : somme sur la météo de demain ktermes = P[PLUIE, :] * P[:, SOLEIL]print(termes, termes.sum()) # [0.06 0.12 0.05] 0.23print(np.linalg.matrix_power(P, 2)[PLUIE, SOLEIL]) # 0.23, coefficient de P^2P <- matrix(c(0.6, 0.3, 0.1, 0.3, 0.4, 0.3, 0.1, 0.4, 0.5), nrow = 3, byrow = TRUE)soleil <- 1; nuages <- 2; pluie <- 3
# 1) Trajectoire pluie -> nuages -> soleilP[pluie, nuages] * P[nuages, soleil] # 0.12
# 2) Chapman-Kolmogorov : somme sur la météo de demaintermes <- P[pluie, ] * P[, soleil]termes; sum(termes) # 0.06 0.12 0.05 ; 0.23(P %*% P)[pluie, soleil] # 0.23, coefficient de P^2Exercice · Rendre markovien un processus à mémoire
difficileUn modèle plus fin de la météo ne distingue que deux états, sec (S) et pluvieux (P), mais tient compte des deux derniers jours : s’il a plu hier et aujourd’hui, il pleut demain avec probabilité 0,7 ; s’il a plu un seul des deux jours, avec probabilité 0,5 ; s’il a fait sec les deux jours, avec probabilité 0,2.
- La suite des météos quotidiennes est-elle une chaîne de Markov ?
- Construisez une chaîne de Markov en prenant pour état le couple . Combien a-t-elle d’états ? Écrivez sa matrice de transition.
Voir la solution
- Non : la loi de dépend de et de . Savoir qu’il pleut aujourd’hui ne suffit pas, il faut savoir s’il a plu hier.
- L’état prend 4 valeurs : SS, SP, PS, PP. Depuis l’état , la chaîne ne peut aller que vers : le second élément du couple devient le premier. Avec l’ordre SS, SP, PS, PP :
Par exemple, depuis SP (sec hier, pluie aujourd’hui), il a plu un seul des deux jours, donc demain il pleut avec probabilité 0,5 (on va en PP) ou il fait sec (on va en PS). Chaque ligne somme à 1, et la loi du futur ne dépend que du couple présent : est markovienne. C’est la technique générale pour traiter une mémoire d’ordre 2, au prix d’un espace d’états plus grand.
En code
import numpy as np
# Probabilité de pluie demain selon le nombre de jours de pluie parmi (hier, aujourd'hui)p_pluie = {0: 0.2, 1: 0.5, 2: 0.7}couples = ["SS", "SP", "PS", "PP"] # (hier, aujourd'hui)
Q = np.zeros((4, 4))for i, (hier, auj) in enumerate(couples): p = p_pluie[(hier == "P") + (auj == "P")] Q[i, couples.index(auj + "P")] = p # le couple glisse : (auj, demain) Q[i, couples.index(auj + "S")] = 1 - pprint(Q)# [[0.8 0.2 0. 0. ]# [0. 0. 0.5 0.5]# [0.5 0.5 0. 0. ]# [0. 0. 0.3 0.7]]print(Q.sum(axis=1)) # [1. 1. 1. 1.]# Probabilité de pluie demain selon le nombre de jours de pluie parmi (hier, aujourd'hui)p_pluie <- c(0.2, 0.5, 0.7) # 0, 1 ou 2 jours de pluiecouples <- c("SS", "SP", "PS", "PP") # (hier, aujourd'hui)
Q <- matrix(0, 4, 4, dimnames = list(couples, couples))for (co in couples) { hier <- substr(co, 1, 1); auj <- substr(co, 2, 2) p <- p_pluie[(hier == "P") + (auj == "P") + 1] Q[co, paste0(auj, "P")] <- p # le couple glisse : (auj, demain) Q[co, paste0(auj, "S")] <- 1 - p}Q## SS SP PS PP## SS 0.8 0.2 0.0 0.0## SP 0.0 0.0 0.5 0.5## PS 0.5 0.5 0.0 0.0## PP 0.0 0.0 0.3 0.7rowSums(Q) # 1 1 1 1