Calculez des probabilités d'absorption
Vous jouez à pile ou face contre un ami, un euro par lancer. Vous avez 3 €, lui 2 €, et la partie s’arrête quand l’un de vous deux est ruiné. Quelle est votre probabilité de gagner ? Combien de lancers faudra-t-il en moyenne ? La partie finira forcément (les états « ruiné » sont absorbants), mais où et quand ?
Au chapitre 2, vous avez appris à repérer les classes transitoires et les classes fermées. Ici, vous allez calculer ce qui se passe entre les deux : la probabilité d’être absorbé par chaque classe fermée, et le temps moyen pour y arriver. Nous suivrons la ruine du joueur, un exemple classique du cours, puis nous reviendrons au visiteur du site de presse.
Le fil rouge : la ruine du joueur
Section intitulée « Le fil rouge : la ruine du joueur »Notons votre fortune après lancers et la fortune totale en jeu (ici ). À chaque lancer, vous gagnez un euro avec probabilité et en perdez un avec probabilité . Les états sont :
- depuis : et ;
- (vous êtes ruiné) et (votre ami est ruiné) sont absorbants : .
q q q q 0 ◄──── 1 ◄───► 2 ◄───► 3 ◄───► 4 ────► 5 p p p p
(0 et 5 bouclent sur eux-mêmes avec probabilité 1)Les états 1 à 4 forment une classe ouverte, donc transitoire ; et sont deux classes fermées. La chaîne sera absorbée en 0 ou en 5 avec probabilité 1. Reste à savoir avec quelle probabilité chacun.
Conditionner sur le premier pas
Section intitulée « Conditionner sur le premier pas »L’idée clé du chapitre tient en une phrase : pour calculer une grandeur depuis l’état , regardez où va la chaîne au premier pas, puis utilisez la propriété de Markov.
Notons la probabilité de finir en (vous gagnez) en partant de . Depuis , au premier lancer, on va en avec probabilité , en avec probabilité , et ensuite tout recommence depuis ce nouvel état. D’où le système :
Plus généralement, pour une chaîne quelconque et un ensemble d’états cible , la probabilité d’atteindre depuis vérifie
avec pour les états d’où est inaccessible (les autres classes fermées). C’est exactement ce que vous avez fait au chapitre 2 pour calculer une probabilité de retour.
On calcule de la même façon le temps moyen d’absorption , c’est-à-dire le nombre moyen de pas avant d’atteindre un état absorbant. Le premier pas coûte 1, puis tout recommence :
Pour la ruine du joueur équitable, la solution est . Partant de 3 € sur 5, la partie dure en moyenne lancers.
La forme matricielle : la matrice fondamentale
Section intitulée « La forme matricielle : la matrice fondamentale »Pour une grande chaîne, on écrit ces systèmes sous forme matricielle. On range les états transitoires en premier, les états absorbants ensuite. La matrice de transition prend alors la forme canonique :
- contient les transitions entre états transitoires ;
- contient les transitions des états transitoires vers les états absorbants ;
- et traduisent le fait qu’un état absorbant ne mène qu’à lui-même.
On définit alors la matrice fondamentale
Son coefficient est le nombre moyen de passages par l’état transitoire quand on part de : chaque terme compte la probabilité d’être en au pas , et la somme compte les passages. On en déduit tout le reste :
- temps moyens d’absorption : , où est le vecteur colonne de 1 (on somme les passages dans tous les états transitoires) ;
- probabilités d’absorption : , où est la probabilité d’être absorbé en en partant de (on passe un certain nombre de fois par chaque état transitoire, puis on sort vers ).
Et si la pièce est défavorable ? Avec , le calcul matriciel donne une probabilité de gagner de 0,360 seulement depuis 3 €, pour une durée moyenne d’environ 6,0 lancers. Un faible désavantage à chaque lancer se transforme en un net désavantage sur la partie. L’exercice 3 pousse ce constat jusqu’au casino.
Retour au site : qui s’abonne ?
Section intitulée « Retour au site : qui s’abonne ? »Au chapitre 2, nous avions établi que tout visiteur finit abonné ou parti. Calculons maintenant les probabilités. La classe fermée « Abonné, Vidéo » se traite comme un seul état absorbant (une fois entré, on n’en sort plus), de même que Départ. Avec les états transitoires dans l’ordre Accueil, Recherche, Article :
(la première colonne de mène à l’abonnement, la seconde au départ). Le calcul donne :
| Point d’entrée | Probabilité de s’abonner | Probabilité de partir | Clics moyens avant absorption |
|---|---|---|---|
| Accueil | 0,112 | 0,888 | 3,03 |
| Recherche | 0,150 | 0,850 | 3,58 |
| Article | 0,167 | 0,833 | 2,39 |
Un visiteur qui arrive directement sur un article (depuis un moteur de recherche, par exemple) s’abonne plus souvent que celui qui arrive par l’accueil. Et le coefficient est bien le nombre moyen de pages « Article » calculé à l’exercice 3 du chapitre 2.
import numpy as np
# États transitoires : Accueil, Recherche, Article ; absorbants : Abonné, DépartQ = np.array([[0.0, 0.3, 0.4], [0.3, 0.0, 0.7], [0.3, 0.0, 0.2]])R = np.array([[0.0, 0.3], [0.0, 0.0], [0.1, 0.4]])
N = np.linalg.inv(np.eye(3) - Q) # matrice fondamentalek = N @ np.ones(3) # clics moyens avant absorptionB = N @ R # probabilités d'absorptionprint(np.round(k, 2)) # [3.03 3.58 2.39]print(np.round(B, 3)) # ligne Accueil : [0.112 0.888]assert np.allclose(B.sum(axis=1), 1)Le lien avec les processus de décision markoviens
Section intitulée « Le lien avec les processus de décision markoviens »Regardez à nouveau l’équation des temps moyens : . Remplacez « 1 » par une récompense reçue dans l’état et ajoutez un facteur d’actualisation : vous obtenez
l’équation de Bellman qui donne la valeur d’un état sous une politique fixée. Un processus de décision markovien, c’est une chaîne de Markov dont un agent choisit les transitions par ses actions, et l’évaluation d’une politique se résout exactement comme nos probabilités d’absorption : par conditionnement sur le premier pas, soit en résolvant un système linéaire, soit en itérant. Le cours d’Apprentissage par renforcement part de là.
En résumé
Section intitulée « En résumé »- Dans une chaîne finie, on finit toujours par quitter les classes transitoires ; la question est dans quelle classe fermée et en combien de temps.
- Conditionnement sur le premier pas : (probabilité d’atteindre une cible), (temps moyen), avec les conditions aux bords.
- Forme canonique ; matrice fondamentale , dont le coefficient est le nombre moyen de passages en depuis .
- Temps moyens d’absorption ; probabilités d’absorption .
- Ruine du joueur équitable : gain avec probabilité , durée moyenne . Un léger désavantage par partie devient un fort désavantage global.
- L’équation des temps moyens a la même forme que l’équation de Bellman des processus de décision markoviens.
Exercices
Section intitulée « Exercices »Exercice · Petit contre gros
facileVous jouez à pile ou face équilibré, un euro par lancer, avec 2 € contre un adversaire qui en a 8. Quelle est votre probabilité de ruiner votre adversaire ? Combien de lancers dure la partie en moyenne ?
Voir la solution
Ici et . Dans le cas équitable, : vous gagnez une fois sur cinq. La durée moyenne vaut lancers. Le jeu est équitable (votre gain moyen est nul), mais le joueur le plus riche gagne le plus souvent.
En code
import numpy as np
K, p = 10, 0.5 # 10 € en jeu, pièce équilibréen = K - 1 # états transitoires 1, ..., 9Q = np.diag([p] * (n - 1), 1) + np.diag([1 - p] * (n - 1), -1)R = np.zeros((n, 2))R[0, 0] = 1 - p # de 1 € vers la ruine (0)R[-1, 1] = p # de 9 € vers la victoire (K)
N = np.linalg.inv(np.eye(n) - Q) # matrice fondamentalei = 2 # vous partez avec 2 €print((N @ R)[i - 1, 1]) # 0.2 : probabilité de ruiner l'adversaireprint(N.sum(axis=1)[i - 1]) # 16.0 lancers en moyenneK <- 10; p <- 0.5 # 10 € en jeu, pièce équilibréen <- K - 1 # états transitoires 1, ..., 9Q <- matrix(0, n, n)Q[cbind(1:(n - 1), 2:n)] <- p # gagner un euroQ[cbind(2:n, 1:(n - 1))] <- 1 - p # perdre un euroR <- matrix(0, n, 2)R[1, 1] <- 1 - p # de 1 € vers la ruineR[n, 2] <- p # de 9 € vers la victoire
N <- solve(diag(n) - Q) # matrice fondamentalei <- 2 # vous partez avec 2 €(N %*% R)[i, 2] # 0.2 : probabilité de ruiner l'adversairerowSums(N)[i] # 16 lancers en moyenneExercice · Une souris dans un labyrinthe
moyenUne souris se déplace entre deux salles, 1 et 2. Depuis la salle 1, elle y reste avec probabilité 0,2, passe en salle 2 avec probabilité 0,4 et tombe dans un piège (T) avec probabilité 0,4. Depuis la salle 2, elle passe en salle 1 avec probabilité 0,3, reste avec probabilité 0,2 et trouve le fromage (C) avec probabilité 0,5. Le piège et le fromage sont absorbants.
Calculez, depuis chaque salle, la probabilité de trouver le fromage et le nombre moyen de pas avant absorption.
Voir la solution
Notons les probabilités de trouver le fromage :
- , soit , donc ;
- , soit .
En substituant, , d’où et .
Pour les temps moyens :
- ;
- , donc .
En substituant dans la première : , d’où pas, puis pas.
On peut vérifier avec la matrice fondamentale : , a pour sommes de lignes et .
En code
import numpy as np
# États transitoires : salles 1 et 2 ; absorbants : piège T, fromage CQ = np.array([[0.2, 0.4], [0.3, 0.2]])R = np.array([[0.4, 0.0], [0.0, 0.5]])
N = np.linalg.inv(np.eye(2) - Q)B = N @ Rk = N.sum(axis=1)print(B[:, 1]) # [0.3846 0.7692] : trouver le fromageprint(k) # [2.3077 2.1154] : pas avant absorptionprint(5/13, 10/13, 30/13, 55/26) # 0.3846 0.7692 2.3077 2.1154# États transitoires : salles 1 et 2 ; absorbants : piège T, fromage CQ <- matrix(c(0.2, 0.4, 0.3, 0.2), nrow = 2, byrow = TRUE)R <- matrix(c(0.4, 0, 0, 0.5), nrow = 2, byrow = TRUE)
N <- solve(diag(2) - Q)(N %*% R)[, 2] # 0.3846 0.7692 : trouver le fromagerowSums(N) # 2.3077 2.1154 : pas avant absorptionc(5/13, 10/13, 30/13, 55/26) # 0.3846 0.7692 2.3077 2.1154Exercice · La ruine au casino
difficileOn joue avec une probabilité de gain à chaque partie, et on note .
- Vérifiez que satisfait les équations et les conditions , .
- Retrouvez la probabilité 0,360 donnée dans le chapitre pour , , .
- À la roulette, en misant sur une couleur, on gagne avec une probabilité légèrement inférieure à 1/2. Prenons . Vous arrivez avec 50 € et comptez partir dès que vous aurez doublé votre mise (ou tout perdu). Quelle est votre probabilité de réussir ?
Voir la solution
- Les conditions aux bords sont immédiates : et . Pour l’équation, il suffit de vérifier que la satisfait (une constante la satisfait aussi, et l’équation est linéaire) : . Or , donc , et on obtient bien .
- , donc .
- , , . Comme , on a . Or , donc . Avec un désavantage de seulement 1 point par partie, vous n’avez qu’environ 12 % de chances de doubler votre mise, contre 50 % dans un jeu équitable. C’est le principe du casino.
En code
import numpy as np
def h_formule(i, K, p): r = (1 - p) / p return (1 - r**i) / (1 - r**K)
def h_systeme(i, K, p): """Résout h_j = p h_{j+1} + q h_{j-1} avec h_0 = 0 et h_K = 1.""" n = K - 1 Q = np.diag([p] * (n - 1), 1) + np.diag([1 - p] * (n - 1), -1) b = np.zeros(n); b[-1] = p return np.linalg.solve(np.eye(n) - Q, b)[i - 1]
print(h_formule(3, 5, 0.4), h_systeme(3, 5, 0.4)) # 0.3602 0.3602print(h_formule(50, 100, 0.49), h_systeme(50, 100, 0.49)) # 0.1192 0.1192print((0.51 / 0.49) ** 50) # 7.391 = r^50h_formule <- function(i, K, p) { r <- (1 - p) / p (1 - r^i) / (1 - r^K)}h_systeme <- function(i, K, p) { # h_j = p h_{j+1} + q h_{j-1}, h_0 = 0, h_K = 1 n <- K - 1 Q <- matrix(0, n, n) Q[cbind(1:(n - 1), 2:n)] <- p Q[cbind(2:n, 1:(n - 1))] <- 1 - p b <- c(rep(0, n - 1), p) solve(diag(n) - Q, b)[i]}c(h_formule(3, 5, 0.4), h_systeme(3, 5, 0.4)) # 0.3602 0.3602c(h_formule(50, 100, 0.49), h_systeme(50, 100, 0.49)) # 0.1192 0.1192(0.51 / 0.49)^50 # 7.391 = r^50