Un algorithme qui apprend quelle décision prendre dans chaque situation en essayant, en observant le gain obtenu et en corrigeant son estimation. Il remplit un tableau situation par action : la valeur Q. On l'utilise quand chaque décision change la situation suivante, comme un prix fixé jour après jour sur un stock qui s'écoule.
Un nouveau vendeur au marché teste des prix différents chaque jour. Au fil des semaines, il note dans un carnet ce que chaque prix a rapporté selon le jour et le stock restant, en comptant aussi ce qu'il pourra encore vendre ensuite.
Ici, la situation est le jour et le stock restant ; les actions sont trois niveaux de prix. La table Q contient une case par couple situation et action, à zéro au départ.
La plupart du temps, l'algorithme choisit l'action qui a la meilleure valeur dans la table. Dans 10 % des cas, il en tire une au hasard pour découvrir des options encore mal connues.
Après chaque action, la case est rapprochée de « gain du jour + meilleure valeur de la situation suivante ». Ce second terme est la clé : il fait remonter vers les premiers jours les conséquences des choix.
Trois prix possibles : plein tarif, -20 %, -50 %. Chaque prix entraîne une demande moyenne différente. Un simulateur tire la demande de chaque jour et l'algorithme joue 50 000 semaines fictives.
Le résultat est une règle lisible par le magasin : garder le plein tarif quand il reste peu d'unités, baisser le prix quand il en reste beaucoup et que les jours passent.
Dans l'exemple Python, sur 5 000 semaines simulées, la politique apprise rapporte 122 € en moyenne, contre 112 € avec un prix fixe à -20 %, le meilleur prix unique. On compare toujours à la règle actuelle, jamais à zéro.
Le Q-learning se programme en quelques lignes, sans package dédié. Les réglages portent sur la façon d'apprendre.
Poids donné à chaque nouvelle expérience. Trop haut, la table suit le hasard du dernier essai ; trop bas, l'apprentissage traîne. 0,1 est un point de départ courant.
Part des décisions prises au hasard. Sans exploration, l'algorithme se fige sur la première stratégie correcte trouvée. On le fait souvent décroître au fil des essais.
Poids du futur face au gain immédiat, entre 0 et 1. La semaine ayant une fin, l'exemple utilise 1 ; sur un horizon sans fin, une valeur comme 0,95 évite que les gains s'additionnent à l'infini.
Le réglage le plus important. L'algorithme maximise exactement ce qu'on lui donne : s'il ignore le coût des invendus ou l'image prix, sa politique l'ignorera aussi.
# Déstockage de produits frais : Q-learning en R
set.seed(42)
prix <- c(10, 8, 5) # plein tarif, -20 %, -50 %
demande_moy <- c(1, 2, 5) # ventes moyennes par jour selon le prix
JOURS <- 7
STOCK <- 20
Q <- array(0, dim = c(JOURS + 1, STOCK + 1, 3)) # jour, stock restant + 1, prix
jouer <- function(choix, apprendre = FALSE) {
stock <- STOCK
recette <- 0
for (jour in 1:JOURS) {
a <- choix(jour, stock)
vendus <- min(stock, rpois(1, demande_moy[a]))
if (apprendre) { # mise à jour de Q : gain du jour + meilleure valeur du lendemain
cible <- prix[a] * vendus + max(Q[jour + 1, stock - vendus + 1, ])
Q[jour, stock + 1, a] <<- Q[jour, stock + 1, a] + 0.1 * (cible - Q[jour, stock + 1, a]) # taux d'apprentissage 0,1
}
recette <- recette + prix[a] * vendus
stock <- stock - vendus
}
recette
}
# Apprentissage : on explore 10 % du temps, sinon on prend le meilleur prix connu
explorer <- function(j, s) if (runif(1) < 0.1) sample(3, 1) else which.max(Q[j, s + 1, ])
for (episode in 1:50000) jouer(explorer, apprendre = TRUE)
meilleur <- function(j, s) which.max(Q[j, s + 1, ])
cat("Recette moyenne, politique apprise :", round(mean(replicate(5000, jouer(meilleur))), 1), "€\n")
cat("Recette moyenne, prix fixe -20 % :", round(mean(replicate(5000, jouer(function(j, s) 2))), 1), "€\n")
cat("Prix conseillé le jour 5 pour un stock de 2, 6, 10 :", prix[apply(Q[5, c(2, 6, 10) + 1, ], 1, which.max)], "\n")
# Déstockage de produits frais : Q-learning en Python
import numpy as np
rng = np.random.default_rng(42)
prix = np.array([10.0, 8.0, 5.0]) # plein tarif, -20 %, -50 %
demande_moy = np.array([1.0, 2.0, 5.0]) # ventes moyennes par jour selon le prix
JOURS, STOCK = 7, 20
Q = np.zeros((JOURS + 1, STOCK + 1, 3)) # valeur de chaque prix, par jour et stock restant
alpha, epsilon = 0.1, 0.1
def jouer(choix, apprendre=False):
stock, recette = STOCK, 0.0
for jour in range(JOURS):
a = choix(jour, stock)
vendus = min(stock, rng.poisson(demande_moy[a]))
if apprendre: # mise à jour de Q : gain du jour + meilleure valeur du lendemain
cible = prix[a] * vendus + Q[jour + 1, stock - vendus].max()
Q[jour, stock, a] += alpha * (cible - Q[jour, stock, a])
recette += prix[a] * vendus
stock -= vendus
return recette
# Apprentissage : on explore 10 % du temps, sinon on prend le meilleur prix connu
explorer = lambda j, s: rng.integers(3) if rng.random() < epsilon else Q[j, s].argmax()
for episode in range(50000):
jouer(explorer, apprendre=True)
print("Recette moyenne, politique apprise :", round(np.mean([jouer(lambda j, s: Q[j, s].argmax()) for _ in range(5000)]), 1), "€")
print("Recette moyenne, prix fixe -20 % :", round(np.mean([jouer(lambda j, s: 1) for _ in range(5000)]), 1), "€")
print("Prix conseillé le jour 5 pour un stock de 2, 6, 10 :", prix[Q[4, [2, 6, 10]].argmax(axis=1)])
En supervisé, on fournit la bonne réponse pour chaque exemple. En Q-learning, personne ne connaît la bonne décision : l'algorithme reçoit seulement un gain après coup, parfois bien plus tard, et doit découvrir quelles actions l'ont produit.
Oui, c'est l'apprentissage hors ligne (offline). Mais l'historique ne contient que les décisions déjà prises par l'entreprise : si un prix n'a jamais été pratiqué, l'algorithme ne peut pas deviner son effet. D'où l'intérêt d'un simulateur ou de tests contrôlés.
Parce qu'une action jugée mauvaise après deux essais malchanceux ne serait plus jamais retentée. L'exploration, réglée par epsilon, garantit que chaque action continue d'être testée de temps en temps.
Remplace la table par un réseau de neurones quand les situations sont trop nombreuses pour être listées.
Voir la fiche → l'autre approcheApprend directement la stratégie au lieu de la valeur des actions. Plus naturel quand les actions sont continues.
Voir la fiche → la version sans lendemainQuand chaque décision est indépendante des suivantes, un bandit apprend plus vite et plus simplement.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus