{
  "chapter": {
    "id": "knn",
    "level": "premiere",
    "theme": "Algorithmique",
    "title": "k plus proches voisins (k-NN)",
    "description": "Algorithme des k plus proches voisins (k-NN) : exemple\nd'algorithme d'apprentissage supervisé. Distance entre\npoints, vote majoritaire, choix de k, applications,\nforces et limites.",
    "prerequisites": [],
    "references": []
  },
  "questions": [
    {
      "id": "q01",
      "difficulty": 1,
      "skills": [
        "definition"
      ],
      "title": "k-NN : qu'est-ce que c'est ?",
      "statement": "Que fait l'algorithme des **k plus proches voisins**\n(k-NN, *k-Nearest Neighbors*) ?",
      "options": [
        {
          "text": "Prédit la classe d'un nouvel élément en regardant les classes des k éléments les plus proches dans un jeu de données déjà étiqueté",
          "correct": true,
          "feedback": "Bonne réponse : c'est un algorithme\nd'**apprentissage supervisé** par\nmémorisation. On classe un nouveau point\nselon ses voisins.\n"
        },
        {
          "text": "Mesure la complexité d'un programme",
          "correct": false,
          "feedback": "Erreur : la mesure de\ncomplexité algorithmique\nn'a aucun rapport avec\nl'algorithme des k plus\nproches voisins.\n"
        },
        {
          "text": "Cherche un élément dans une liste triée",
          "correct": false,
          "feedback": "Erreur : c'est la recherche dichotomique.\n"
        },
        {
          "text": "Trie une liste par ordre croissant",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec le tri.\n"
        }
      ],
      "explanation": "Apprentissage supervisé : on dispose d'exemples\nétiquetés (avec leur classe connue), on\napprend à prédire la classe pour de nouveaux\nexemples."
    },
    {
      "id": "q02",
      "difficulty": 1,
      "skills": [
        "supervisé"
      ],
      "title": "Apprentissage supervisé",
      "statement": "Pourquoi parle-t-on d'apprentissage\n**supervisé** pour k-NN ?",
      "options": [
        {
          "text": "Parce qu'il est lent à l'exécution",
          "correct": false,
          "feedback": "La rapidité d'exécution n'a\naucun rapport avec le\ncaractère supervisé d'un\nalgorithme d'apprentissage.\n"
        },
        {
          "text": "Parce qu'il ne fonctionne qu'avec un professeur dans la salle",
          "correct": false,
          "feedback": "Cette interprétation est\nfantaisiste. Le mot\n« supervisé » est un terme\ntechnique précis, sans\nrapport avec une\nprésence humaine.\n"
        },
        {
          "text": "Parce qu'un humain doit surveiller le programme pendant son exécution",
          "correct": false,
          "feedback": "Cette interprétation littérale\nne correspond pas au sens\ntechnique. En apprentissage\nautomatique, « supervisé »\nrenvoie au fait que les\ndonnées portent une\nétiquette connue, et non à\nune surveillance humaine.\n"
        },
        {
          "text": "Parce que les données d'entraînement sont étiquetées : chaque exemple est associé à sa classe connue",
          "correct": true,
          "feedback": "Bonne réponse : « supervisé » = on a la\nréponse pour les exemples\nd'entraînement. L'algorithme apprend la\nrelation entrée → classe.\n"
        }
      ],
      "explanation": "Distinction : **supervisé** (avec étiquettes,\nex. classification, régression) vs **non\nsupervisé** (sans étiquettes, ex.\npartitionnement automatique). k-NN est\nsupervisé."
    },
    {
      "id": "q03",
      "difficulty": 1,
      "skills": [
        "distance"
      ],
      "title": "Distance euclidienne",
      "statement": "Comment calcule-t-on la **distance euclidienne**\nentre deux points $A=(x_A, y_A)$ et $B=(x_B,\ny_B)$ du plan ?",
      "options": [
        {
          "text": "$d = \\sqrt{(x_B - x_A)^2 + (y_B - y_A)^2}$",
          "correct": true,
          "feedback": "Bonne réponse : formule de Pythagore.\nC'est la distance « à vol d'oiseau »\nentre les deux points.\n"
        },
        {
          "text": "$d = |x_A - x_B|$",
          "correct": false,
          "feedback": "Erreur : ce serait la distance sur l'axe\nhorizontal seulement.\n"
        },
        {
          "text": "$d = x_A + y_A + x_B + y_B$",
          "correct": false,
          "feedback": "Erreur : ce serait juste une somme.\n"
        },
        {
          "text": "$d = x_A \\times y_A - x_B \\times y_B$",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec une distance.\n"
        }
      ],
      "explanation": "Cette formule se généralise en dimension n :\n$d = \\\\sqrt{\\\\sum_{i=1}^{n}(b_i - a_i)^2}$.\nPour comparer des distances, on peut omettre\nla racine carrée."
    },
    {
      "id": "q04",
      "difficulty": 1,
      "skills": [
        "vote-majoritaire"
      ],
      "title": "Vote majoritaire",
      "statement": "Une fois les k plus proches voisins\nidentifiés, comment k-NN détermine-t-il la\nclasse à attribuer ?",
      "options": [
        {
          "text": "Au hasard",
          "correct": false,
          "feedback": "Erreur : k-NN est déterministe.\n"
        },
        {
          "text": "En choisissant la classe du voisin le plus proche",
          "correct": false,
          "feedback": "C'est k-NN avec k = 1, cas particulier. En\ngénéral on utilise plusieurs voisins pour\nplus de robustesse.\n"
        },
        {
          "text": "Par vote majoritaire : la classe la plus représentée parmi les k voisins l'emporte",
          "correct": true,
          "feedback": "Bonne réponse : si parmi les 5 voisins\nles plus proches, 3 sont de la classe A et\n2 de la classe B, on prédit A.\n"
        },
        {
          "text": "En faisant la moyenne des classes",
          "correct": false,
          "feedback": "Erreur : on ne fait pas la moyenne d'une\nclasse (c'est une catégorie, pas un\nnombre).\n"
        }
      ],
      "explanation": "Variante : **vote pondéré** par la distance\n(les voisins plus proches comptent plus).\nPermet de gérer les ex æquo."
    },
    {
      "id": "q05",
      "difficulty": 1,
      "skills": [
        "choix-k"
      ],
      "title": "Choix de k",
      "statement": "Pourquoi prend-on souvent k **impair** quand\non classe en deux classes ?",
      "options": [
        {
          "text": "Pour éviter les égalités lors du vote majoritaire entre deux classes",
          "correct": true,
          "feedback": "Bonne réponse : avec k pair (par exemple\nk = 4), on peut avoir 2 votes pour chaque\nclasse → indécision. Avec k impair (k = 5),\nimpossible.\n"
        },
        {
          "text": "Aucune raison particulière",
          "correct": false,
          "feedback": "Cette parité répond au\ncontraire à un besoin\ntechnique précis : éviter\nles égalités lors du\nvote, comme expliqué dans\nla bonne réponse.\n"
        },
        {
          "text": "Parce que les nombres impairs sont plus rapides à calculer",
          "correct": false,
          "feedback": "Aucun lien n'existe entre la\nparité d'un nombre et la\nrapidité de calcul.\n"
        },
        {
          "text": "Parce que k pair ne fonctionne pas",
          "correct": false,
          "feedback": "Erreur : ça fonctionne, mais on doit gérer\nles ex æquo.\n"
        }
      ],
      "explanation": "Pour trois classes ou plus, un\n$k$ impair n'évite pas\nforcément les ex æquo : trois\nclasses peuvent par exemple\nobtenir chacune $k/3$ voix.\nOn peut alors recourir à la\nclasse du voisin le plus\nproche, ou à un vote pondéré\npar la distance."
    },
    {
      "id": "q06",
      "difficulty": 1,
      "skills": [
        "exemple-iris"
      ],
      "title": "Exemple typique",
      "statement": "Lequel de ces problèmes est un **bon candidat**\npour l'algorithme k-NN ?",
      "options": [
        {
          "text": "Compresser un fichier pour gagner de la place",
          "correct": false,
          "feedback": "La compression de fichiers\nest une tâche très\ndifférente, sans rapport\navec la classification.\n"
        },
        {
          "text": "Trier une liste de nombres",
          "correct": false,
          "feedback": "Erreur : ce n'est pas un problème de\nclassification.\n"
        },
        {
          "text": "Reconnaître si un mail est un spam ou non, à partir d'exemples étiquetés",
          "correct": true,
          "feedback": "Bonne réponse : tâche de classification\nbinaire (spam / non spam). On peut\ncomparer le mail aux exemples connus\nselon des caractéristiques (mots-clés,\nlongueur, etc.).\n"
        },
        {
          "text": "Calculer la racine carrée d'un nombre",
          "correct": false,
          "feedback": "Erreur : pas un problème d'apprentissage.\n"
        }
      ],
      "explanation": "Autres exemples : reconnaissance de\nchiffres manuscrits, classification de\nfleurs (jeu de données Iris), recommandation\nde films."
    },
    {
      "id": "q07",
      "difficulty": 1,
      "skills": [
        "absence-apprentissage"
      ],
      "title": "Pas d'entraînement explicite",
      "statement": "Quelle particularité de k-NN le distingue\nd'autres algorithmes d'apprentissage ?",
      "options": [
        {
          "text": "Il n'a quasiment pas de phase d'entraînement : il mémorise les exemples et fait tout le calcul au moment de la prédiction",
          "correct": true,
          "feedback": "Bonne réponse : k-NN est un algorithme\ndit « paresseux ». Pas de modèle interne ;\ntout le travail est fait à la prédiction.\n"
        },
        {
          "text": "Il fonctionne sans aucune donnée d'entraînement",
          "correct": false,
          "feedback": "Au contraire, l'algorithme\na besoin d'exemples\nétiquetés pour pouvoir\ncomparer le nouveau\npoint.\n"
        },
        {
          "text": "Il a une phase d'entraînement très longue",
          "correct": false,
          "feedback": "Erreur : c'est l'inverse. La phase\nd'entraînement consiste juste à\n**mémoriser** les exemples.\n"
        },
        {
          "text": "Il invente de nouveaux exemples au cours de la prédiction",
          "correct": false,
          "feedback": "Aucun exemple n'est\ninventé. L'algorithme se\ncontente de comparer le\npoint à classer aux\nexemples déjà connus.\n"
        }
      ],
      "explanation": "Conséquence : prédiction lente quand le jeu\nd'entraînement est gros (il faut calculer la\ndistance à tous les exemples). Compromis :\nstockage important, calcul à la prédiction."
    },
    {
      "id": "q08",
      "difficulty": 1,
      "skills": [
        "pseudocode"
      ],
      "title": "Squelette de l'algorithme",
      "statement": "Quelle est la **structure générale** de\nl'algorithme k-NN pour classer un nouveau\npoint `p` ?",
      "options": [
        {
          "text": "1. Calculer la distance de `p` à chaque exemple connu.\n2. Trier les exemples par distance croissante.\n3. Garder les k premiers.\n4. Retourner la classe majoritaire parmi ces k voisins.\n",
          "correct": true,
          "feedback": "Bonne réponse : algorithme en quatre\nétapes claires. Les étapes 1 et 2\ndominent le coût.\n"
        },
        {
          "text": "1. Trier les exemples par classe.\n2. Retourner la première classe.\n",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec la distance.\n"
        },
        {
          "text": "1. Choisir un exemple au hasard.\n2. Retourner sa classe.\n",
          "correct": false,
          "feedback": "Erreur : k-NN n'est pas aléatoire.\n"
        },
        {
          "text": "1. Calculer la moyenne des exemples.\n2. La retourner comme classe.\n",
          "correct": false,
          "feedback": "Erreur : on ne peut pas faire la moyenne\nd'une classe.\n"
        }
      ],
      "explanation": "En Python, on utilise typiquement :\n```python\ndistances = [(dist(p, e), c) for (e, c) in exemples]\ndistances.sort()\nvoisins = distances[:k]\n```"
    },
    {
      "id": "q09",
      "difficulty": 1,
      "skills": [
        "parametres"
      ],
      "title": "Paramètre k",
      "statement": "Que se passe-t-il si l'on prend **k = 1** ?",
      "options": [
        {
          "text": "La classe prédite est celle de l'unique voisin le plus proche, l'algorithme est très sensible aux exceptions (bruit) dans le jeu d'entraînement",
          "correct": true,
          "feedback": "Bonne réponse : un seul exemple aberrant\npeut fausser la prédiction. Augmenter k\nrend la décision plus robuste.\n"
        },
        {
          "text": "La complexité du calcul devient logarithmique",
          "correct": false,
          "feedback": "Le coût d'un calcul de\nprédiction ne dépend pas\ndu choix de $k$ : il\nreste linéaire en\n$N$ (nombre d'exemples).\n"
        },
        {
          "text": "La prédiction est plus stable",
          "correct": false,
          "feedback": "Erreur : c'est l'inverse. k = 1 est très\nsensible au bruit.\n"
        },
        {
          "text": "L'algorithme ne fonctionne pas avec $k = 1$",
          "correct": false,
          "feedback": "Le choix $k = 1$ est tout\nà fait valide d'un point\nde vue algorithmique. Il\nest simplement peu\nrobuste face au bruit\ndes données.\n"
        }
      ],
      "explanation": "Choix de k : compromis. k trop petit →\nsensibilité au bruit. k trop grand → frontières\nlissées, perte de précision locale. On choisit\nsouvent k empiriquement."
    },
    {
      "id": "q10",
      "difficulty": 1,
      "skills": [
        "exemple-trace"
      ],
      "title": "Trace simple",
      "statement": "Avec k = 3, on classe un nouveau point P. Ses\n3 plus proches voisins ont les classes : A, B,\nA. Quelle classe prédit k-NN pour P ?",
      "options": [
        {
          "text": "Aucune des deux (égalité)",
          "correct": false,
          "feedback": "Erreur : il n'y a pas d'égalité (2 vs 1).\n"
        },
        {
          "text": "B (le plus proche)",
          "correct": false,
          "feedback": "Erreur : ce serait k = 1. Avec k = 3, on\nfait un vote majoritaire.\n"
        },
        {
          "text": "A (deux votes contre un pour B)",
          "correct": true,
          "feedback": "Bonne réponse : vote majoritaire. A\nobtient 2 votes, B obtient 1. La classe\nprédite est A.\n"
        },
        {
          "text": "Les deux à la fois",
          "correct": false,
          "feedback": "Erreur : k-NN renvoie une seule classe.\n"
        }
      ],
      "explanation": "Le vote est très simple à implémenter en\nPython : `Counter([cl for (_, cl) in\nvoisins]).most_common(1)[0][0]`."
    },
    {
      "id": "q11",
      "difficulty": 2,
      "skills": [
        "code-distance"
      ],
      "title": "Code distance",
      "statement": "Quel code calcule correctement la **distance\neuclidienne** entre deux points 2D représentés\ncomme tuples `a = (xa, ya)` et `b = (xb, yb)` ?",
      "options": [
        {
          "text": "`((a[0] - b[0])  2 + (a[1] - b[1])  2)  0.5`",
          "correct": true,
          "feedback": "Bonne réponse : Pythagore en Python.\n`** 0.5` calcule la racine carrée. Variante :\n`math.sqrt(...)`.\n"
        },
        {
          "text": "`a[0] * b[0] + a[1] * b[1]`",
          "correct": false,
          "feedback": "Erreur : c'est le produit scalaire.\n"
        },
        {
          "text": "`a + b`",
          "correct": false,
          "feedback": "Erreur : on ne peut pas additionner deux\ntuples comme cela (concaténation, pas\naddition).\n"
        },
        {
          "text": "`abs(a[0] - b[0]) + abs(a[1] - b[1])`",
          "correct": false,
          "feedback": "Erreur : c'est la distance de Manhattan\n(|Δx| + |Δy|), pas l'euclidienne.\n"
        }
      ],
      "explanation": "Astuce : pour comparer des distances, on\npeut omettre la racine carrée (la fonction\nracine est croissante). Plus rapide."
    },
    {
      "id": "q12",
      "difficulty": 2,
      "skills": [
        "tri-distances"
      ],
      "title": "Sélection des voisins",
      "statement": "Pour trouver les k plus proches voisins d'un\npoint P parmi N exemples, quelle approche est\nla plus simple ?",
      "options": [
        {
          "text": "Calculer la distance à chacun des N exemples, trier, garder les k premiers",
          "correct": true,
          "feedback": "Bonne réponse : simple à implémenter.\nCoût : O(N) pour les distances + O(N log\nN) pour le tri = O(N log N).\n"
        },
        {
          "text": "Aucune solution n'existe pour ce problème",
          "correct": false,
          "feedback": "Plusieurs solutions\nexistent au contraire ;\nla plus simple est\nprécisément celle qu'on\nvient de décrire.\n"
        },
        {
          "text": "Choisir k exemples au hasard",
          "correct": false,
          "feedback": "Erreur : pas k-NN.\n"
        },
        {
          "text": "Calculer la moyenne des exemples",
          "correct": false,
          "feedback": "Erreur : ce n'est pas le rôle.\n"
        }
      ],
      "explanation": "Optimisations possibles : structures\nspatiales (kd-trees), heuristiques (pas au\nprogramme Première). Mais l'approche naïve\nsuffit pour comprendre."
    },
    {
      "id": "q13",
      "difficulty": 2,
      "skills": [
        "normalisation"
      ],
      "title": "Pourquoi normaliser ?",
      "statement": "Pourquoi est-il souvent **utile de normaliser**\nles caractéristiques des données avant\nd'appliquer k-NN ?",
      "options": [
        {
          "text": "Parce qu'une caractéristique avec une plage de valeurs très grande (ex. revenu en €) écraserait l'influence d'une caractéristique à plus petite plage (ex. âge en années) dans le calcul de distance",
          "correct": true,
          "feedback": "Bonne réponse : la distance euclidienne\nest sensible aux échelles. Normaliser\n(rescaler entre 0 et 1, ou centrer-\nréduire) garantit que toutes les\ncaractéristiques pèsent autant.\n"
        },
        {
          "text": "Pour rendre l'algorithme déterministe",
          "correct": false,
          "feedback": "L'algorithme des $k$ plus\nproches voisins est déjà\ndéterministe par\nconstruction. La\nnormalisation joue un\nautre rôle, comme\nexpliqué dans la bonne\nréponse.\n"
        },
        {
          "text": "Pour économiser de la mémoire",
          "correct": false,
          "feedback": "La normalisation n'a pas\nd'effet notable sur la\nconsommation mémoire.\nSon intérêt se situe sur\nle plan numérique.\n"
        },
        {
          "text": "Parce que c'est obligatoire en Python",
          "correct": false,
          "feedback": "Aucune obligation n'est\nimposée par le langage.\nLa normalisation est une\nbonne pratique, mais\nreste facultative.\n"
        }
      ],
      "explanation": "Exemple concret : si on classe des personnes\npar (âge en années [0-100], revenu en € [0-\n100 000]), le revenu domine totalement la\ndistance. Normaliser remet les deux sur une\néchelle comparable."
    },
    {
      "id": "q14",
      "difficulty": 2,
      "skills": [
        "k-petit-grand"
      ],
      "title": "Compromis sur k",
      "statement": "Quel **risque** y a-t-il à choisir un k **trop\ngrand** (par exemple k = nombre total\nd'exemples) ?",
      "options": [
        {
          "text": "Aucun risque ; un grand $k$ est toujours préférable",
          "correct": false,
          "feedback": "Au contraire, un $k$ trop\ngrand pose un problème\nspécifique, comme expliqué\ndans la bonne réponse.\n"
        },
        {
          "text": "Le coût d'un calcul explose en $n^3$",
          "correct": false,
          "feedback": "Le coût d'un calcul de\nprédiction reste linéaire\nen $N$ : il ne dépend pas\ndu choix de $k$.\n"
        },
        {
          "text": "L'algorithme cesse de fonctionner",
          "correct": false,
          "feedback": "L'algorithme continue de\nfonctionner, mais le\nrésultat qu'il produit\nn'est plus pertinent.\n"
        },
        {
          "text": "La prédiction tend vers la classe majoritaire globale : on perd toute spécificité locale",
          "correct": true,
          "feedback": "Bonne réponse : si k = N, tous les\nexemples votent. Le résultat est toujours\nla classe la plus représentée dans tout\nle jeu de données, indépendamment de la\nposition de P. Plus rien d'utile.\n"
        }
      ],
      "explanation": "Compromis biais-variance : k petit = haute\nvariance, faible biais ; k grand = faible\nvariance, biais élevé. À doser selon la\ntaille du jeu."
    },
    {
      "id": "q15",
      "difficulty": 2,
      "skills": [
        "donnees-entrainement"
      ],
      "title": "Rôle des données d'entraînement",
      "statement": "Que sont les **données d'entraînement**\n(training set) pour k-NN ?",
      "options": [
        {
          "text": "Les nouvelles données à classer",
          "correct": false,
          "feedback": "Erreur : ce sont les données de **test**\n(à classer).\n"
        },
        {
          "text": "Une formule mathématique",
          "correct": false,
          "feedback": "Les données d'entraînement\nne sont pas une formule,\nmais un ensemble\nd'exemples concrets,\nchacun étiqueté avec sa\nclasse.\n"
        },
        {
          "text": "L'ensemble des exemples étiquetés que k-NN utilise pour comparer un nouveau point. La taille et la qualité de ce jeu déterminent la performance.",
          "correct": true,
          "feedback": "Bonne réponse : plus le jeu\nd'entraînement est riche et représentatif,\nmeilleures sont les prédictions.\n"
        },
        {
          "text": "Le code source de l'algorithme",
          "correct": false,
          "feedback": "Le code source est une\nnotion distincte des\ndonnées d'entraînement,\nqui sont les exemples\nutilisés.\n"
        }
      ],
      "explanation": "En pratique, on divise un jeu étiqueté en\n**train** (entraînement) + **test**\n(évaluation) pour mesurer la performance\nsans tricher."
    },
    {
      "id": "q16",
      "difficulty": 2,
      "skills": [
        "code-knn"
      ],
      "title": "Code k-NN simple",
      "statement": "Quel code en Python implémente correctement\nk-NN pour classer un point `p` ?\n```python\n# exemples = [(point, classe), ...]\n# k entier, dist(a, b) renvoie la distance\n```",
      "options": [
        {
          "text": "```python\nreturn exemples[0][1]\n```\n",
          "correct": false,
          "feedback": "Erreur : on renvoie toujours la classe du\npremier exemple, sans tenir compte de la\ndistance.\n"
        },
        {
          "text": "```python\nreturn min(exemples)\n```\n",
          "correct": false,
          "feedback": "Erreur : aucun rapport avec k-NN.\n"
        },
        {
          "text": "```python\nreturn k\n```\n",
          "correct": false,
          "feedback": "Erreur : on renvoie le paramètre k au\nlieu d'une classe.\n"
        },
        {
          "text": "```python\nfrom collections import Counter\npaires = [(dist(p, x), c) for (x, c) in exemples]\npaires.sort()\nvoisins = [c for (_, c) in paires[:k]]\nreturn Counter(voisins).most_common(1)[0][0]\n```\n",
          "correct": true,
          "feedback": "Bonne réponse : on calcule les distances,\non trie, on prend les k plus proches, on\nfait le vote majoritaire avec `Counter`.\n"
        }
      ],
      "explanation": "Implementation simple, lisible. Pour de gros\nvolumes, des bibliothèques comme\nscikit-learn proposent des implémentations\noptimisées (kd-trees)."
    },
    {
      "id": "q17",
      "difficulty": 2,
      "skills": [
        "iris"
      ],
      "title": "Jeu de données Iris",
      "statement": "Le jeu de données **Iris** est célèbre pour\nillustrer la classification. Que contient-il ?",
      "options": [
        {
          "text": "Des mesures de couleurs au format rouge-vert-bleu",
          "correct": false,
          "feedback": "Le jeu de données Iris ne\ncontient pas de mesures\ncolorimétriques, mais des\nmesures morphologiques\ndes fleurs.\n"
        },
        {
          "text": "150 fleurs d'iris décrites par 4 mesures (longueur/largeur des sépales et pétales) et leur espèce (setosa, versicolor, virginica)",
          "correct": true,
          "feedback": "Bonne réponse : jeu de données\nhistorique introduit par Fisher en 1936.\nTrès utilisé pour tester les algorithmes\nde classification.\n"
        },
        {
          "text": "Des graines à planter",
          "correct": false,
          "feedback": "Cette interprétation\nlittérale du nom « Iris »\nest sans rapport avec le\ncontenu du jeu de\ndonnées.\n"
        },
        {
          "text": "Des images de fleurs au format JPEG",
          "correct": false,
          "feedback": "Erreur : ce sont des **mesures**\nnumériques, pas des images.\n"
        }
      ],
      "explanation": "Ce jeu est le « hello world » de\nl'apprentissage automatique. Idéal pour\nillustrer k-NN : 4 dimensions, 3 classes,\ntaille raisonnable."
    },
    {
      "id": "q18",
      "difficulty": 2,
      "skills": [
        "coût"
      ],
      "title": "Coût de la prédiction",
      "statement": "Si l'on a N exemples d'entraînement, quel est\nle **coût** d'une prédiction k-NN naïve ?",
      "options": [
        {
          "text": "Logarithmique en N",
          "correct": false,
          "feedback": "Erreur : il faut bien examiner tous les\nexemples.\n"
        },
        {
          "text": "Linéaire en N (proportionnel au nombre d'exemples)",
          "correct": true,
          "feedback": "Bonne réponse : on calcule N distances.\nLe tri ajoute un facteur log N (donc\nO(N log N) total), mais au plus simple\non peut prendre les k minimums en O(N k)\nou O(N) avec un tri partiel.\n"
        },
        {
          "text": "Constant, indépendant de N",
          "correct": false,
          "feedback": "Erreur : il faut bien comparer le\nnouveau point à chaque exemple.\n"
        },
        {
          "text": "Quadratique en N",
          "correct": false,
          "feedback": "Erreur : on ne fait pas de double boucle.\n"
        }
      ],
      "explanation": "Conséquence : prédiction lente sur de gros\njeux d'entraînement. Optimisations possibles\n(kd-trees) hors programme."
    },
    {
      "id": "q19",
      "difficulty": 2,
      "skills": [
        "forces-faiblesses"
      ],
      "title": "Forces et limites",
      "statement": "Quelle est une **limite importante** de k-NN ?",
      "options": [
        {
          "text": "Il ne peut pas faire de classification",
          "correct": false,
          "feedback": "Erreur : c'est précisément son rôle.\n"
        },
        {
          "text": "Il ne fonctionne qu'en dimension 2",
          "correct": false,
          "feedback": "Erreur : k-NN se généralise à toute\ndimension.\n"
        },
        {
          "text": "Il est lent à la prédiction sur de gros jeux d'entraînement (pas de modèle compact appris) et sensible aux échelles des caractéristiques",
          "correct": true,
          "feedback": "Bonne réponse : tous les calculs ont lieu\nà la prédiction. Pour 1 million d'exemples\nen haute dimension, k-NN peut être\nimpraticable.\n"
        },
        {
          "text": "Il invente de nouveaux exemples au cours de la prédiction",
          "correct": false,
          "feedback": "L'algorithme se contente\nde comparer le nouveau\npoint aux exemples déjà\nfournis. Il n'en invente\naucun.\n"
        }
      ],
      "explanation": "Forces : simple, intuitif, sans hypothèse\nsur la distribution des données.\nLimites : lent, sensible à la malédiction de\nla dimensionnalité (en très haute dimension,\nles distances perdent leur sens)."
    },
    {
      "id": "q20",
      "difficulty": 2,
      "skills": [
        "vote-pondéré"
      ],
      "title": "Vote pondéré",
      "statement": "Une variante de k-NN consiste à **pondérer le\nvote** des voisins. Pourquoi ?",
      "options": [
        {
          "text": "Pour donner plus d'influence aux voisins plus proches (typiquement avec un poids proportionnel à $1/d$)",
          "correct": true,
          "feedback": "Bonne réponse : un voisin très proche\ndevrait peser plus qu'un voisin éloigné.\nAméliore souvent la qualité des\nprédictions et résout les égalités.\n"
        },
        {
          "text": "Pour économiser la mémoire",
          "correct": false,
          "feedback": "La pondération n'a aucun\neffet sur la consommation\nmémoire.\n"
        },
        {
          "text": "Pour rendre l'algorithme aléatoire",
          "correct": false,
          "feedback": "Cette pondération reste\nparfaitement déterministe.\nElle ne fait pas\nintervenir le hasard.\n"
        },
        {
          "text": "Pour ralentir intentionnellement le programme",
          "correct": false,
          "feedback": "Aucun procédé de\npondération n'a pour but\nde ralentir le\nprogramme.\n"
        }
      ],
      "explanation": "Vote uniforme = chaque voisin compte 1.\nVote pondéré = poids dépendant de la\ndistance. Variante classique du k-NN."
    },
    {
      "id": "q21",
      "difficulty": 3,
      "skills": [
        "trace-detaillee"
      ],
      "title": "Trace détaillée",
      "statement": "Avec k = 3, on classe un point P. Les 5\nexemples les plus proches sont (par distance\ncroissante) : (1.0, classe A), (1.5, B), (2.0,\nA), (3.0, A), (4.0, B). Quelle classe prédit\nk-NN ?",
      "options": [
        {
          "text": "A",
          "correct": true,
          "feedback": "Bonne réponse : on garde les k = 3 plus\nproches : (1.0, A), (1.5, B), (2.0, A).\nVote : A = 2, B = 1 → A gagne.\n"
        },
        {
          "text": "B",
          "correct": false,
          "feedback": "Erreur : B n'a qu'un seul vote.\n"
        },
        {
          "text": "Indéterminé",
          "correct": false,
          "feedback": "Erreur : k-NN est déterministe.\n"
        },
        {
          "text": "Égalité",
          "correct": false,
          "feedback": "Erreur : pas d'égalité.\n"
        }
      ],
      "explanation": "Méthode : trier par distance, garder les k\npremiers, voter à la majorité. Les exemples\nau-delà de k (4ᵉ et 5ᵉ ici) ne comptent pas."
    },
    {
      "id": "q22",
      "difficulty": 3,
      "skills": [
        "malediction"
      ],
      "title": "Malédiction de la dimensionnalité",
      "statement": "Pourquoi k-NN devient-il **moins efficace en\nhaute dimension** (par exemple 1000 attributs) ?",
      "options": [
        {
          "text": "En haute dimension, les distances entre points deviennent presque toutes égales : la notion de « proche » perd son sens. C'est la malédiction de la dimensionnalité.",
          "correct": true,
          "feedback": "Bonne réponse : phénomène\ncontre-intuitif. Les volumes en haute\ndimension se concentrent dans les coins,\nles distances se ressemblent. k-NN\nfonctionne mal.\n"
        },
        {
          "text": "La mémoire n'est plus suffisante",
          "correct": false,
          "feedback": "Cet effet peut survenir\ndans certains cas\nextrêmes, mais ce n'est\npas la cause principale\nde la dégradation des\nperformances en haute\ndimension.\n"
        },
        {
          "text": "Aucun problème particulier en haute dimension",
          "correct": false,
          "feedback": "Au contraire, un phénomène\nréel et bien étudié\ndégrade les performances\nde l'algorithme en haute\ndimension : c'est la\nmalédiction de la\ndimensionnalité, comme\ndétaillé dans la bonne\nréponse.\n"
        },
        {
          "text": "Le programme plante systématiquement",
          "correct": false,
          "feedback": "Le programme s'exécute\nsans erreur, mais sa\nqualité de prédiction se\ndégrade fortement.\n"
        }
      ],
      "explanation": "Solutions : réduction de dimension (ACP,\nautres méthodes), sélection de\ncaractéristiques. En NSI, on reste sur des\ncas simples (2D, 3D, jeu Iris à 4D)."
    },
    {
      "id": "q23",
      "difficulty": 3,
      "skills": [
        "evaluation"
      ],
      "title": "Évaluation de la performance",
      "statement": "Pour évaluer la qualité de k-NN sur un jeu\nétiqueté, quelle est la **bonne pratique** ?",
      "options": [
        {
          "text": "Mesurer la précision sur les exemples d'entraînement eux-mêmes",
          "correct": false,
          "feedback": "Erreur : on testerait sur les données\ndéjà mémorisées (k = 1 donnerait 100 %),\nce qui est sans intérêt.\n"
        },
        {
          "text": "Aucune évaluation n'est possible",
          "correct": false,
          "feedback": "Plusieurs méthodes\nd'évaluation existent au\ncontraire ; la plus\nsimple consiste à\nséparer les données en\nun ensemble\nd'entraînement et un\nensemble de test.\n"
        },
        {
          "text": "Demander l'avis d'un expert humain",
          "correct": false,
          "feedback": "Faire intervenir un expert\npeut être utile, mais\nc'est une démarche\nsubjective et coûteuse.\nPour évaluer la\nperformance d'un\nalgorithme, on préfère\nune mesure quantitative\nsur des données de test.\n"
        },
        {
          "text": "Séparer le jeu en données d'entraînement et données de test disjointes, puis mesurer la précision sur les données de test",
          "correct": true,
          "feedback": "Bonne réponse : on évalue sur des\nexemples que l'algorithme n'a jamais\n« vus ». Pratique standard en\napprentissage automatique. Souvent 80 %\n/ 20 %.\n"
        }
      ],
      "explanation": "Variantes : validation croisée\n(cross-validation, on découpe en plusieurs\nblocs et on alterne). Pratique standard pour\ndes évaluations robustes."
    },
    {
      "id": "q24",
      "difficulty": 3,
      "skills": [
        "variantes"
      ],
      "title": "k-NN pour la régression",
      "statement": "Peut-on adapter k-NN pour **prédire un nombre**\n(régression) au lieu d'une classe ?",
      "options": [
        {
          "text": "Oui, mais à condition de doubler la valeur de $k$",
          "correct": false,
          "feedback": "Le passage à la régression\nn'a aucun rapport avec un\ndoublement de $k$. C'est\nla nature de l'agrégation\nfinale (vote majoritaire\nou moyenne) qui change.\n"
        },
        {
          "text": "Non, l'algorithme est strictement limité à la classification",
          "correct": false,
          "feedback": "L'algorithme s'adapte au\ncontraire très naturellement\nau cas de la régression,\ncomme expliqué dans la\nbonne réponse.\n"
        },
        {
          "text": "Non, il faut nécessairement un autre algorithme",
          "correct": false,
          "feedback": "L'algorithme des $k$ plus\nproches voisins s'étend\nnaturellement à la\nrégression, sans qu'il\nsoit nécessaire de le\nremplacer.\n"
        },
        {
          "text": "Oui, en remplaçant le vote majoritaire par la moyenne (ou médiane) des valeurs des k voisins",
          "correct": true,
          "feedback": "Bonne réponse : si la cible est\nnumérique (prix d'une maison, note\nattendue), la classe « majoritaire » est\nremplacée par la moyenne des cibles des\nk voisins. Idée générale identique.\n"
        }
      ],
      "explanation": "Algorithme **k-NN régresseur** : très utilisé\nen pratique pour des prédictions de prix,\ndurées, scores. Même principe que la\nclassification."
    },
    {
      "id": "q25",
      "difficulty": 3,
      "skills": [
        "synthese"
      ],
      "title": "Synthèse",
      "statement": "Parmi les affirmations suivantes sur k-NN,\nlaquelle est **fausse** ?",
      "options": [
        {
          "text": "La phase d'entraînement se résume essentiellement à mémoriser les exemples.",
          "correct": false,
          "feedback": "Vrai : algorithme paresseux.\n"
        },
        {
          "text": "La distance euclidienne est un choix courant pour la mesure de proximité.",
          "correct": false,
          "feedback": "Vrai : c'est la mesure standard, mais\nd'autres existent (Manhattan, cosinus).\n"
        },
        {
          "text": "Plus k est grand, plus l'algorithme est sensible au bruit local.",
          "correct": true,
          "feedback": "Faux (donc bonne réponse) : c'est\nl'**inverse**. Avec k grand, le vote\nintègre beaucoup de voisins, ce qui\n**lisse** la décision et la rend\n**moins** sensible aux exemples isolés\n(bruit). Avec k petit (k = 1), un seul\nexemple aberrant change la prédiction.\n"
        },
        {
          "text": "k-NN est un algorithme d'apprentissage supervisé.",
          "correct": false,
          "feedback": "Vrai : il apprend depuis des exemples\nétiquetés.\n"
        }
      ],
      "explanation": "Mnémonique : k petit = local, sensible au\nbruit ; k grand = global, lissé. Choisir k\nempiriquement par validation."
    },
    {
      "id": "q26",
      "difficulty": 2,
      "skills": [
        "choix-distance"
      ],
      "title": "Choix de la distance",
      "statement": "Outre la distance euclidienne, on rencontre\nsouvent la **distance de Manhattan**\n(|Δx| + |Δy|). Quel critère permet de choisir\nentre ces deux distances ?",
      "options": [
        {
          "text": "Aucun critère, on choisit au hasard",
          "correct": false,
          "feedback": "Erreur : le choix de la distance influence\nfortement les résultats de l'algorithme. Il\nfaut le justifier en fonction du problème,\npas le tirer au hasard.\n"
        },
        {
          "text": "La distance euclidienne est toujours préférable car elle est plus précise",
          "correct": false,
          "feedback": "Erreur : ces deux distances sont des choix\nvalides selon le contexte. Aucune n'est\nuniversellement meilleure. Le choix dépend\nde la nature des données et de la\nstructure de la proximité que l'on veut\nmodéliser.\n"
        },
        {
          "text": "Le choix dépend de la nature du problème :\nla distance euclidienne convient aux\nespaces continus avec des déplacements\ndirects ; la distance de Manhattan\nconvient aux situations où l'on se déplace\nsur une grille (par exemple un quadrillage\nurbain ou des composantes indépendantes)\n",
          "correct": true,
          "feedback": "Bonne réponse : la distance de Manhattan\nest moins sensible aux valeurs aberrantes\ndans les coordonnées car elle ne carre pas\nles écarts. Elle est aussi plus naturelle\nquand les composantes ont une signification\nindépendante. La distance euclidienne, plus\nrégulière, convient bien aux espaces\ngéométriques classiques.\n"
        },
        {
          "text": "La distance de Manhattan est plus rapide à calculer",
          "correct": false,
          "feedback": "Différence négligeable en pratique : les\ndeux distances se calculent en O(d) où d\nest la dimension. La performance n'est pas\nle critère qui motive le choix.\n"
        }
      ],
      "explanation": "Repère pratique : essayer plusieurs distances,\nmesurer la performance sur l'ensemble de test,\nretenir la meilleure. C'est ce qu'on appelle\nl'optimisation des hyperparamètres."
    },
    {
      "id": "q27",
      "difficulty": 3,
      "skills": [
        "classes-desequilibrees"
      ],
      "title": "Classes déséquilibrées",
      "statement": "On veut détecter une maladie rare avec k-NN.\nLe jeu d'entraînement contient 95 % d'exemples\n« sain » et 5 % d'exemples « malade ». Avec\nk = 7, que va prédire l'algorithme pour\npresque tous les nouveaux patients ?",
      "options": [
        {
          "text": "« malade » à 5 % des nouveaux patients, par symétrie",
          "correct": false,
          "feedback": "Erreur : ce serait le comportement attendu\nd'une distribution aléatoire. Or k-NN ne\ntire rien au hasard ; il prédit en\nfonction des voisins, et ceux-ci sont\nprincipalement « sain ».\n"
        },
        {
          "text": "Une classe au hasard, l'algorithme étant non déterministe",
          "correct": false,
          "feedback": "Erreur : k-NN est strictement\ndéterministe. Pour une même entrée et un\nmême jeu d'entraînement, il prédit\ntoujours la même classe.\n"
        },
        {
          "text": "« sain » dans la quasi-totalité des cas,\ncar les voisins les plus proches sont\npresque toujours majoritairement « sain » à\ncause du déséquilibre des classes ;\nl'algorithme passe à côté des cas\n« malade »\n",
          "correct": true,
          "feedback": "Bonne réponse : c'est le piège classique\ndes classes déséquilibrées. La précision\nglobale peut sembler élevée (95 %), mais le\nrappel sur la classe minoritaire est\nquasiment nul. Solutions : suréchantillonner\nla classe minoritaire, sous-échantillonner\nla majoritaire, ou utiliser un vote\npondéré par l'inverse de la fréquence des\nclasses.\n"
        },
        {
          "text": "« malade » dans la majorité des cas, par sécurité",
          "correct": false,
          "feedback": "Erreur : k-NN n'a aucune logique de\nprudence sanitaire. Il vote simplement à\nla majorité des voisins. Or les voisins\ntirés aléatoirement sont presque toujours\n« sain ».\n"
        }
      ],
      "explanation": "Le déséquilibre de classes est un problème\nmajeur en apprentissage. Mesurer uniquement la\nprécision globale peut être trompeur ; on\ncomplète par le rappel et la précision sur la\nclasse minoritaire, ou par la matrice de\nconfusion."
    },
    {
      "id": "q28",
      "difficulty": 2,
      "skills": [
        "calcul-concret"
      ],
      "title": "Calcul concret",
      "statement": "On classe le point `P = (3, 4)` avec k = 3 et\nla distance euclidienne. Les exemples\nétiquetés sont :\n`(0, 0, A)`, `(6, 8, A)`, `(2, 1, B)`,\n`(5, 4, B)`, `(3, 0, A)`. Quelle classe\nprédit k-NN ?",
      "options": [
        {
          "text": "A",
          "correct": false,
          "feedback": "Erreur : ce serait correct si A obtenait\nla majorité parmi les 3 plus proches.\nRefaire le calcul des distances : `(0, 0)`\n→ 5 ; `(6, 8)` → 5 ; `(2, 1)` → √10 ≈ 3,16 ;\n`(5, 4)` → 2 ; `(3, 0)` → 4. Les 3 plus\nproches sont `(5, 4, B)` (2), `(2, 1, B)`\n(3,16) et `(3, 0, A)` (4).\n"
        },
        {
          "text": "Égalité entre A et B",
          "correct": false,
          "feedback": "Erreur : avec k = 3 (impair) et deux\nclasses, il ne peut pas y avoir égalité.\nLe calcul donne B = 2 voix, A = 1 voix.\n"
        },
        {
          "text": "Indéterminé sans plus d'informations",
          "correct": false,
          "feedback": "Erreur : toutes les informations\nnécessaires sont fournies (point, k,\ndistance, exemples étiquetés). Le résultat\nest parfaitement calculable.\n"
        },
        {
          "text": "B",
          "correct": true,
          "feedback": "Bonne réponse. Distances calculées :\n`(0, 0)` → 5 ; `(6, 8)` → 5 ; `(2, 1)` →\n√10 ≈ 3,16 ; `(5, 4)` → 2 ; `(3, 0)` → 4.\nLes 3 plus proches sont `(5, 4, B)`,\n`(2, 1, B)`, `(3, 0, A)`. Vote : B = 2,\nA = 1 → B gagne.\n"
        }
      ],
      "explanation": "Méthode systématique : (1) calculer la\ndistance de P à chaque exemple ; (2) trier par\ndistance croissante ; (3) garder les k\npremiers ; (4) voter à la majorité. Sur les\npetits jeux, refaire le calcul à la main est\nle meilleur exercice de compréhension."
    }
  ]
}