Aller au contenu

Découvrez ce que signifie « apprendre » pour une machine

Imaginez un cabinet médical rennais qui perd chaque semaine une dizaine de créneaux parce que des patients ne viennent pas à leur rendez-vous. Personne n’a écrit de règle du type « si le rendez-vous est pris trois semaines à l’avance, le patient risque d’oublier », et pourtant l’historique du cabinet contient peut-être déjà cette règle, cachée dans des milliers de lignes. L’apprentissage automatique, c’est précisément l’art de faire émerger ce genre de règle à partir d’exemples, plutôt que de la programmer à la main.

Dans ce chapitre, vous allez poser le vocabulaire et les grandes familles de problèmes. Nous suivrons ce cabinet médical tout au long du chapitre (et nous le retrouverons, avec de vraies données, au dernier chapitre du cours).

En programmation classique, vous écrivez la règle et la machine l’applique : des données entrent, une réponse sort. En apprentissage automatique (machine learning), vous fournissez des données et les réponses attendues, et c’est la machine qui produit la règle. Cette règle apprise s’appelle un modèle. Une fois construit, le modèle s’applique à de nouveaux cas, exactement comme un programme ordinaire.

Programmation classiqueApprentissage automatiquepuis il s’applique à de nouveaux cas,comme un programmedonnéesrègle écritepar vousprogrammeréponsesdonnéesréponsesattenduesapprentissagemodèle(la règle apprise)
Les rôles s'inversent : en apprentissage automatique, les réponses font partie des entrées et la règle (le modèle) devient la sortie.

Une définition classique, due à Tom Mitchell, le dit de façon plus précise : un programme apprend d’une expérience E, pour une tâche T et une mesure de performance P, si sa performance sur T, mesurée par P, s’améliore avec E.

Pour notre cabinet :

  • la tâche T consiste à prédire, pour chaque rendez-vous à venir, si le patient viendra ;
  • l’expérience E est l’historique des rendez-vous passés, dont on sait s’ils ont été honorés ;
  • la performance P pourrait être la proportion d’absences correctement anticipées.

Cette définition a un mérite : elle vous oblige à dire ce que vous mesurez. Vous verrez au chapitre 3 que ce choix de P n’a rien d’anodin.

Le vocabulaire de base : exemples, caractéristiques, étiquettes

Section intitulée « Le vocabulaire de base : exemples, caractéristiques, étiquettes »

Avant d’aller plus loin, fixons les mots. Voici un extrait (inventé) de l’historique du cabinet :

PatientÂgeDélai de prise (jours)SMS de rappelVenu ?
A342ouioui
B7125nonnon
C80nonoui
D4540ouinon
  • Chaque ligne est un exemple (on dit aussi instance, individu ou observation). Ici, un exemple est un rendez-vous.
  • Chaque colonne décrivant l’exemple est une caractéristique (feature), aussi appelée variable ou attribut : l’âge, le délai, le SMS. On note souvent xx le vecteur des caractéristiques d’un exemple, et dd leur nombre.
  • La colonne à prédire est l’étiquette (label) ou variable cible, notée yy. Ici, « Venu ? ».
  • L’ensemble des exemples dont on connaît l’étiquette forme le jeu d’apprentissage (training set), noté D={(x1,y1),…,(xm,ym)}D = \lbrace (x_1, y_1), \dots, (x_m, y_m) \rbrace, où mm est le nombre d’exemples.

Les caractéristiques n’ont pas toutes la même nature. L’âge est numérique (on peut calculer une moyenne), le SMS est binaire, et une variable comme le quartier du patient serait nominale (des catégories sans ordre). Cette nature compte : certains modèles ne savent manipuler que des nombres, d’autres acceptent directement des catégories. Nous y reviendrons à chaque modèle.

Toutes les situations ne se ressemblent pas. Ce qui les distingue, c’est surtout ce que vous savez sur vos exemples.

Vous disposez d’exemples étiquetés : pour chaque rendez-vous passé, vous savez si le patient est venu. Le modèle apprend la relation entre xx et yy, puis prédit yy pour de nouveaux xx. C’est le cas le plus courant en entreprise, et celui qui occupe l’essentiel de ce cours.

Vous n’avez que les xx, sans étiquette. Le but n’est plus de prédire, mais de découvrir une structure : regrouper les patients en profils semblables (partitionnement ou clustering), réduire le nombre de dimensions pour visualiser les données, détecter des cas atypiques. Le cabinet pourrait ainsi découvrir, sans rien lui dire, qu’il existe un groupe de jeunes actifs qui prennent rendez-vous au dernier moment.

020406080âge (ans)−1001020304050délai de prise (jours)Supervisé : x et y connusvenuabsent020406080âge (ans)jeunes actifs,dernier momentseniors,longtemps à l’avanceenfantsNon supervisé : x seuls
Mêmes patients, deux questions. En supervisé, on connaît l'étiquette et l'on apprend à la prédire ; en non supervisé, on ne voit que les x et l'on découvre des profils (données inventées).

L’apprentissage semi-supervisé et faiblement supervisé

Section intitulée « L’apprentissage semi-supervisé et faiblement supervisé »

Entre les deux, vous avez quelques exemples étiquetés et beaucoup qui ne le sont pas. Étiqueter coûte cher (il faut parfois un médecin pour annoter une radiographie), alors on essaie de tirer parti des exemples non annotés. On parle d’apprentissage faiblement supervisé quand les étiquettes existent mais sont partielles, bruitées ou approximatives (par exemple, produites par des règles automatiques).

Ici, pas de jeu d’exemples tout prêt. Un agent agit dans un environnement et reçoit une récompense (reward) après ses actions. Il apprend, par essais et erreurs, une stratégie qui maximise la récompense cumulée. Pour le cabinet, on pourrait imaginer un agent qui décide chaque jour combien de rendez-vous surréserver, et qui est récompensé quand la salle d’attente est pleine sans être débordée. C’est l’approche des jeux (échecs, go) et d’une partie de la robotique.

agent(le planning)environnement(le cabinet)action : surréserver 2 créneauxnouvel état + récompense(salle pleine sans débordement)
En renforcement, pas d'étiquettes : l'agent agit, observe la récompense, et ajuste sa stratégie au fil des tours.
FamilleCe que vous avezCe que vous cherchezExemple au cabinet
Supervisédes couples (x,y)(x, y)prédire yyle patient viendra-t-il ?
Non supervisédes xx seulsune structuredes profils de patients
Semi-supervisépeu de (x,y)(x, y), beaucoup de xxprédire yy à moindre coûtquelques dossiers annotés à la main
Par renforcementun environnement et des récompensesune stratégie d’actionune politique de surréservation

Dans l’apprentissage supervisé, la nature de l’étiquette yy décide du type de problème.

  • Si yy est une catégorie, on parle de classification. « Viendra / ne viendra pas » est une classification binaire. Reconnaître l’espèce d’une fleur d’iris parmi trois est une classification multiclasse : une seule classe par exemple, parmi KK possibles. Si un exemple peut recevoir plusieurs étiquettes à la fois (un article de presse à la fois « santé » et « économie »), on parle de classification multi-étiquette (multi-label).
  • Si yy est un nombre réel, on parle de régression : prédire le retard du patient en minutes, ou le prix d’un appartement.

Mais alors, prédire une probabilité d’absence, c’est de la régression ? Bonne question ! Non : le modèle produit bien un nombre entre 0 et 1, mais ce nombre sert à choisir une classe. On reste en classification, avec un modèle qui fournit un score en plus de sa décision.

010203040délai de prise (jours)venu0,5absentseuil 0,5score = P(absent)Classification : y est une classe255075100125surface (m²)100200300400500prix (k€)Régression : y est un nombre réel
À gauche, le modèle produit un score entre 0 et 1, mais la sortie utile est une classe (au-dessus ou en dessous du seuil) : c'est une classification. À droite, la sortie est le nombre lui-même : c'est une régression.

Vous rencontrerez beaucoup de modèles dans ce cours. Pour ne pas vous perdre, il est utile de les ranger selon deux axes.

Un modèle paramétrique a un nombre de paramètres fixé à l’avance, quelle que soit la quantité de données. Une régression linéaire sur trois caractéristiques a toujours quatre paramètres (trois poids et une constante), que vous ayez cent ou un million de rendez-vous. Le modèle résume les données dans ces paramètres, puis on peut oublier les données.

Un modèle non paramétrique voit sa taille croître avec les données. Le cas extrême est celui des k plus proches voisins, qui garde tous les exemples en mémoire et s’en sert au moment de prédire (on le dit aussi paresseux, lazy). Un arbre de décision qu’on laisse pousser sans limite est aussi non paramétrique : plus il y a de données, plus il a de nœuds.

Un modèle discriminant apprend directement ce qui sert à décider : la probabilité P(y∣x)P(y \mid x) (lisez « probabilité de yy sachant xx »), ou simplement une frontière entre les classes. La régression logistique, les SVM et les arbres sont discriminants.

Un modèle génératif apprend comment les données sont produites dans chaque classe, c’est-à-dire P(x∣y)P(x \mid y), ainsi que la fréquence de chaque classe P(y)P(y). Il obtient ensuite P(y∣x)P(y \mid x) grâce à la formule de Bayes (chapitre 5). Comme il modélise la distribution des xx, il pourrait en principe générer de nouveaux exemples plausibles, d’où son nom. Le classifieur bayésien naïf est génératif.

020406080âge (ans)−1001020304050délai de prise (jours)P(absent | x) = 0,5Discriminant : P(y | x) directement0,20,8020406080âge (ans)P(x | venu)P(x | absent)Génératif : P(x | y) et P(y), puis Bayes
Le modèle discriminant apprend directement la frontière (ou P(y | x)) ; le génératif décrit comment chaque classe produit ses x, puis retrouve la même frontière par la formule de Bayes (données inventées).
ModèleParamétrique ?Discriminant ou génératif
Régression logistiqueouidiscriminant
Bayes naïfouigénératif
k plus proches voisinsnonni l’un ni l’autre au sens strict (vote local)
Arbre de décision non bornénondiscriminant

Pour finir, voyons la forme que prend tout cela en pratique. La bibliothèque scikit-learn impose la même interface à tous ses modèles : on crée le modèle, on l’entraîne avec fit, on prédit avec predict. Voici le tableau du cabinet, traduit en code :

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
# Historique (inventé) : une ligne par rendez-vous
historique = pd.DataFrame({
"age": [34, 71, 8, 45, 52, 23],
"delai": [2, 25, 0, 40, 3, 30],
"sms": [1, 0, 0, 1, 1, 0],
"venu": [1, 0, 1, 0, 1, 0],
})
X = historique[["age", "delai", "sms"]] # caractéristiques
y = historique["venu"] # étiquette
modele = DecisionTreeClassifier(max_depth=2)
modele.fit(X, y) # apprentissage
nouveau = pd.DataFrame({"age": [60], "delai": [35], "sms": [0]})
print(modele.predict(nouveau)) # prédiction pour un rendez-vous à venir

Six exemples, c’est évidemment beaucoup trop peu pour apprendre quoi que ce soit de fiable. Ce code montre seulement la mécanique. Toute la difficulté, que vous découvrirez au chapitre suivant, est de savoir si le modèle obtenu fonctionnera sur des rendez-vous qu’il n’a jamais vus.

  • L’apprentissage automatique produit une règle (le modèle) à partir d’exemples, au lieu de la programmer à la main.
  • Un jeu de données se compose d’exemples (lignes) décrits par des caractéristiques (colonnes) ; en supervisé, chaque exemple porte une étiquette yy.
  • Supervisé : on connaît yy ; non supervisé : on cherche une structure dans les xx seuls ; semi-supervisé : peu d’étiquettes ; par renforcement : un agent apprend par récompenses.
  • Classification si yy est une catégorie (binaire, multiclasse, multi-étiquette), régression si yy est un nombre réel.
  • Un modèle paramétrique a une taille fixe ; un modèle non paramétrique grandit avec les données.
  • Un modèle discriminant apprend P(y∣x)P(y \mid x) ou une frontière ; un modèle génératif apprend P(x∣y)P(x \mid y) et P(y)P(y).

Exercice · Nommer le type de problème

facile

Pour chaque situation, dites s’il s’agit d’apprentissage supervisé, non supervisé ou par renforcement et, s’il est supervisé, s’il s’agit de classification ou de régression.

  1. Prédire la durée (en minutes) d’une consultation à partir du motif et de l’âge du patient.
  2. Regrouper les 3 000 patients du cabinet en profils, sans idée préalable des groupes.
  3. Décider si un courriel est un spam, à partir de 10 000 courriels déjà triés.
  4. Apprendre à un robot à marcher en le récompensant quand il avance sans tomber.
Voir la solution
  1. Supervisé, régression : l’étiquette (une durée) est un nombre réel, et on dispose de consultations passées dont on connaît la durée.
  2. Non supervisé : aucune étiquette n’est fournie, on cherche une structure (c’est du partitionnement).
  3. Supervisé, classification binaire : spam ou non, avec des exemples déjà triés.
  4. Par renforcement : pas d’exemples étiquetés, mais un agent qui agit et reçoit une récompense.

Exercice · Paramétrique et génératif

moyen

Le cabinet hésite entre deux modèles pour prédire les absences : un classifieur bayésien naïf et un classifieur des k plus proches voisins.

  1. Lequel est paramétrique ? Que se passe-t-il pour la taille de chaque modèle si le cabinet passe de 10 000 à 100 000 rendez-vous d’historique ?
  2. Lequel est génératif ? Qu’est-ce que cela signifie concrètement ?
Voir la solution
  1. Le Bayes naïf est paramétrique : il résume chaque classe par un nombre fixe de probabilités (une par valeur de chaque caractéristique et par classe). Passer à 100 000 rendez-vous change la valeur de ces probabilités, pas leur nombre. Les k plus proches voisins sont non paramétriques : le modèle, c’est l’historique lui-même, donc sa taille est multipliée par dix, tout comme le temps de calcul d’une prédiction (il faut comparer le nouveau rendez-vous à tous les anciens).
  2. Le Bayes naïf est génératif : il apprend, pour chaque classe (« venu », « absent »), comment se répartissent les caractéristiques, P(x∣y)P(x \mid y), ainsi que la proportion de chaque classe, P(y)P(y). Il en déduit ensuite P(y∣x)P(y \mid x) par la formule de Bayes. Les k plus proches voisins, eux, ne modélisent pas la distribution des données : ils décident directement par un vote local.

En code

import numpy as np
from sklearn.naive_bayes import CategoricalNB
from sklearn.neighbors import KNeighborsClassifier
rng = np.random.default_rng(0)
for m in [10_000, 100_000]:
# m rendez-vous inventés : 3 caractéristiques à 4 modalités, étiquette venu/absent
X = rng.integers(0, 4, size=(m, 3))
y = rng.integers(0, 2, size=m)
nb = CategoricalNB().fit(X, y)
# Bayes naïf : une probabilité par (classe, caractéristique, valeur), plus les priors
n_nb = sum(t.size for t in nb.feature_log_prob_) + nb.class_count_.size
knn = KNeighborsClassifier().fit(X, y)
# k-NN : le modèle garde toutes les valeurs de l'historique
n_knn = knn.n_samples_fit_ * X.shape[1]
print(f"{m} rendez-vous : Bayes naïf {n_nb} nombres, k-NN {n_knn} nombres")
# 10000 rendez-vous : Bayes naïf 26 nombres, k-NN 30000 nombres
# 100000 rendez-vous : Bayes naïf 26 nombres, k-NN 300000 nombres

Exercice · Repérer une fausse variable numérique

moyen

Dans l’historique du cabinet, le quartier du patient est codé par un entier de 0 à 80 (0 pour « Centre », 1 pour « Beaulieu », etc.). Un collègue propose de donner cette colonne telle quelle à un modèle qui calcule des distances entre patients. Qu’en pensez-vous ?

Voir la solution

C’est une mauvaise idée. Le quartier est une variable nominale : les entiers ne sont que des codes, sans ordre ni écart significatif. Pour un modèle à base de distance, les quartiers 1 et 2 seraient « proches » et les quartiers 1 et 80 « éloignés », ce qui n’a aucun sens géographique ni médical. Il vaut mieux utiliser un encodage one-hot (une colonne binaire par quartier), ou regrouper les quartiers selon une information pertinente (distance au cabinet, par exemple). Nous rencontrerons exactement ce défaut dans l’étude de cas du chapitre 10.

En code

import numpy as np
# Trois patients : quartiers codés 1 (Beaulieu), 2 et 80
codes = np.array([1, 2, 80])
# Codes utilisés comme un nombre : 1 et 2 paraissent voisins, 1 et 80 très éloignés
print(abs(codes[0] - codes[1]), abs(codes[0] - codes[2])) # 1 79
# Encodage one-hot : une colonne binaire par quartier (81 quartiers)
onehot = np.eye(81)[codes]
d = lambda a, b: np.linalg.norm(a - b)
print(round(d(onehot[0], onehot[1]), 3), round(d(onehot[0], onehot[2]), 3)) # 1.414 1.414 : tous à égale distance