{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bc2d6497",
   "metadata": {},
   "source": [
    "# TP LoL — Pronostiquer une victoire après dix minutes — correction\n",
    "\n",
    "**Mission.** Prédire `blueWins` à partir des seules statistiques disponibles à dix minutes. Toutes les cellules marquées `TODO` sont à compléter. \n",
    "\n",
    "Source : [Kaggle — League of Legends Diamond Ranked Games (10 min)](https://www.kaggle.com/datasets/bobbyscience/league-of-legends-diamond-ranked-games-10-min)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "020766b7",
   "metadata": {},
   "source": [
    "## 1. Charger, comprendre et réserver le test\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee1f3a83",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "from tempfile import TemporaryDirectory\n",
    "from joblib import dump, load\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "from IPython.display import display\n",
    "from sklearn.dummy import DummyClassifier\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import ConfusionMatrixDisplay, accuracy_score, confusion_matrix, roc_auc_score\n",
    "from sklearn.model_selection import GridSearchCV, StratifiedKFold, cross_validate, train_test_split\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "\n",
    "DATA_NAME = \"high_diamond_ranked_10min.csv\"\n",
    "data_path = next((candidate for candidate in [Path(\"data\") / DATA_NAME, Path(\"../data\") / DATA_NAME] if candidate.exists()), None)\n",
    "assert data_path is not None, \"CSV absent : placer le dossier data à la racine du projet\"\n",
    "df = pd.read_csv(data_path)\n",
    "print(\"Dimensions :\", df.shape)\n",
    "display(df.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d705cc15",
   "metadata": {},
   "source": [
    "**À faire.** Vérifier les classes, les valeurs manquantes et la présence d'un identifiant. Quelle serait l'accuracy d'une prédiction systématique de la classe majoritaire ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "53407902",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfe1a3c7",
   "metadata": {},
   "source": [
    "**À faire.** Séparer `X` et `y`, retirer `gameId`, puis créer un jeu de développement et un test stratifié à 20 % (`random_state=42`). Ne plus regarder le test avant la section 7."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98cc6a5b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6834ce65",
   "metadata": {},
   "source": [
    "## 2. Première erreur : juger sur l'entraînement"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "54ef93d7",
   "metadata": {},
   "source": [
    "**À faire.** Entraîner un arbre non contraint sur le développement. Comparer accuracy sur entraînement et sur une validation interne à 20 %. Ne pas utiliser `X_test`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ccd31a2e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b46192b",
   "metadata": {},
   "source": [
    "**Discussion.** Pourquoi le premier score ne mesure-t-il pas la capacité à prédire une nouvelle partie ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74d18bdd",
   "metadata": {},
   "source": [
    "## 3. Deuxième erreur : croire un seul découpage"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a8819db",
   "metadata": {},
   "source": [
    "**À faire.** Comparer baseline, régression logistique, k-NN et arbre avec les **mêmes** cinq plis stratifiés. Utiliser `Pipeline` pour que la normalisation soit recalculée dans chaque pli. Relever accuracy moyenne et écart-type, puis AUC ROC."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ec31394b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf2c2e84",
   "metadata": {},
   "source": [
    "**À faire.** Comparer la régression logistique sur trois découpages simples (faire varier la graine du random_state). Leur dispersion explique-t-elle l'intérêt de la validation croisée ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1bddca0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "639fadd5",
   "metadata": {},
   "source": [
    "## 4. Régulariser au lieu de mémoriser"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e7bc3d4",
   "metadata": {},
   "source": [
    "**À faire.** Faire varier `max_depth` de l'arbre. Comparer scores d'entraînement et de validation croisée ; tracer les deux courbes. La meilleure profondeur est-elle forcément la plus grande ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "108efd51",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad732305",
   "metadata": {},
   "source": [
    "**À faire.** Rechercher `C` parmi `0.01, 0.1, 1, 10` dans une régression logistique standardisée. \n",
    "Rappel : plus le `C` est petit, plus la régularisation est forte**. \n",
    "La recherche ne doit voir que le dataset de développement."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76753d30",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO : écrire votre solution ici"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8881efc2",
   "metadata": {},
   "source": [
    "## Fin du jour 1\n",
    "\n",
    "Conserver vos observations. Le notebook du jour 2 recrée le même découpage et un modèle de référence sans dépendre de l'état Jupyter actuel."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
