informatique (MP2I/MPI) · Chapitre 26 · Exercice de TD
Problème — -moyennes : le paquet vide, le minimum local, les relances
Apprentissage automatique · niveau 3 (difficile)
Énoncé
- Le code du cours calcule
barycentre points affectation c. Que vaut ce barycentre si le paquet est vide ? Que devient l'algorithme ? - Sur les neuf points avec , exhiber deux départs qui donnent deux résultats différents, et calculer les deux inerties.
- Combien de départs, parmi tous les choix de trois points distincts, atteignent l'optimum ?
- Quelle stratégie en tirer, et comment la coder ?
Corrigé
1. Le paquet vide donne nan. Le barycentre est une somme divisée par un effectif ; sur un paquet vide, c'est , et en flottants IEEE cela vaut nan. Le cas se produit vraiment : sur les points avec et les centres initiaux , , , l'affectation est — le troisième centre ne reçoit personne — et son barycentre vaut nan.
Ce qui suit est pire que l'arrêt : nan contamine tout. Toute distance à ce centre vaut nan, et toute comparaison avec nan est fausse : est faux, et est faux aussi. Le centre vide n'est donc jamais choisi comme « plus proche », il reste vide, et le programme tourne en rendant paquets sans le dire.
(* Barycentre du paquet c. Si le paquet est vide, on RELANCE le centre sur
un point tiré au hasard plutôt que de rendre nan. *)
let barycentre points aff c defaut =
let s = ref 0.0 and n = ref 0 in
Array.iteri (fun i x -> if aff.(i) = c then (s := !s +. x; incr n)) points;
if !n = 0 then defaut else !s /. float_of_int !n
La règle : une division dont le dénominateur peut être nul se traite avant de diviser, pas après. En C, sur des entiers plante ; en flottants, il ne plante pas — et c'est plus dangereux.
2. Deux départs, deux résultats. Mesuré :
| centres de départ | paquets obtenus | inertie |
|---|---|---|
La seconde partition est stable : aucun point ne veut changer de paquet, aucun centre ne veut bouger. C'est bien un minimum local, et il est fois pire que l'optimum. Le mécanisme est visible : deux centres se sont posés dans le paquet de droite, aucun dans celui du milieu, et l'unique centre restant a dû couvrir les deux paquets de gauche à la fois. Une fois cette division faite, aucun pas local ne la défait.
3. Le compte. Sur les façons de choisir trois points distincts comme centres initiaux, atteignent et échouent — soit près d'un départ sur quatre. La pire inertie atteinte est , celle du tableau ci-dessus.
4. La stratégie : relancer, et garder le meilleur.
(* Meilleure partition sur r exécutions indépendantes.
Précondition : r >= 1. Complexité : r fois celle de k_moyennes. *)
let k_moyennes_relance points k r =
let meilleur = ref None in
for _ = 1 to r do
let (aff, centres, cout) = k_moyennes points (tirer points k) in
match !meilleur with
| Some (_, _, c) when c <= cout -> ()
| _ -> meilleur := Some (aff, centres, cout)
done;
!meilleur
Avec une probabilité d'échec de par départ et des départs indépendants, la probabilité que relances échouent toutes vaut : pour , pour , pour . Trois relances suffisent ici à ramener le risque au centième, pour trois fois le temps de calcul.
Le statut de cet algorithme. C'est un Las Vegas dégradé, au sens du chapitre chap:probabilistes : le résultat rendu est toujours valide — une partition stable —, seul son coût dépend du hasard. On ne peut pas savoir si l'on a l'optimum ; on peut seulement rendre l'échec improbable, et c'est exactement ce que fait la relance. Un raffinement classique, -moyennes++, tire les centres initiaux loin les uns des autres au lieu de les tirer uniformément, et réduit fortement les cas.
Exercices semblables
- L'unité change le voisin corrigé
- La matrice de confusion d'un dépistage corrigé
- L'erreur d'entraînement de -NN corrigé
- Le gain nul du ou exclusif corrigé
- Quand faut-il visiter l'autre côté ? corrigé