{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ## Avant de commencer...\n",
    "\n",
    "Cet environnement de travail s'appelle un **notebook Jupyter** : à l'intérieur d'un navigateur Web, alternent\n",
    "- des cellules de média (comme celle-ci) avec du texte, des images, des liens;\n",
    "- des cellules de code (destinées à contenir du Python).\n",
    "\n",
    "Pour exécuter une cellule de code, il faut :\n",
    "- cliquer sur la cellule pour qu'elle soit encadrée en vert (selectionnée);\n",
    "- le curseur de texte clignote à l'intérieur : on peut modifier le contenu de la cellule;\n",
    "- pour exécuter la cellule, il y a le bouton « Exécuter » du menu du haut, ou mieux, le raccourci <code>MAJ + Entrée</code>.\n",
    "\n",
    "Quand une cellule **n'a pas encore exécutée**, dans sa marge gauche on peut lire `IN [ ]` (ou `Entrée [ ]`).\n",
    "\n",
    "Une fois exécutée, on pourra lire `IN [n]`, où `n` représente le nombre de fois qu'on a exécuté n'importe laquelle des cellules de code.\n",
    "\n",
    "### En théorie\n",
    "\n",
    "Le notebook est écrit pour que les cellules soient exécutées les unes après les autres, dans l'ordre de la lecture : en effet, toutes les exécutions sont « gardées en mémoire ».\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "**À FAIRE :** Exécuter les deux cellules suivantes.</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = 3\n",
    "\n",
    "\n",
    "b= 14"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "**À FAIRE :** Modifier la première cellule : affecter une valeur autre que 3, puis exécuter de nouveau les deux cellules et constater le résultat.</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Apprentissage automatique - reconnaissance de caractères manuscrits\n",
    "\n",
    "On s’intéresse à la problématique de la reconnaissance de chiffres manuscrits. Cette application de l’intelligence artificielle est déjà assez ancienne - sa percée est intervenue en 1989 avec la réalisation d’une analyse syntaxique fiable et automatisée des codes postaux pour les courriers.\n",
    "\n",
    "Depuis, de nombreuses institutions financières ont adopté la technique d’analyse automatique des numéros de compte\n",
    "sur les bordereaux de versement pour les virements électroniques ou les chèques bancaires.\n",
    "\n",
    "Cette technique s’est maintenant généralisée dans d’autres domaines. Il s’agit, par exemple, du même type d’algorithme\n",
    "pour la reconnaissance faciale.\n",
    "\n",
    "Une base de données contenant des données labellisées de chiffres manuscrits est disponible directement sur Python\n",
    "dans la bibliothèque <code>scikit learn</code>. On y retrouve :\n",
    "* Des images de chiffres manuscrits (entrées de l’algorithme) ;\n",
    "* L’entier associé au chiffre écrit de manière manuscrite (sorties de l’algorithme)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 1.</strong> De quel type de problème d’intelligence artificielle s’agit-il ?</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 2.</strong> Selon vous, comment sont obtenues de telles données ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets ## module datasets contenant des bases de données\n",
    "digits = datasets.load_digits () ## digits contient les entrées et les sorties\n",
    "\n",
    "\n",
    "## digits.images est la liste de toutes les images --- entrées\n",
    "## digits.target est la liste des chiffres associés à la liste des images --- sorties\n",
    "\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "i = 89\n",
    "plt.imshow(digits.images[i], cmap ='binary')\n",
    "## permet d’afficher l’image indicée i\n",
    "print(digits.target[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 3.</strong> Exécuter plusieurs fois ces premières lignes en changeant l’indice de l’image associée et observer le résultat.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour travailler sur les données, il est nécessaire d’obtenir, en entrée, des vecteurs (et non pas un tableau numpy à deux\n",
    "dimensions) contenant l’intensité associée à chaque pixel. Ici, l’image est en niveau de gris ce qui signifie qu’il n’y a\n",
    "donc qu’une seule couche \"de couleur\". Plus la valeur est grande, plus le pixel est foncé. Une valeur nulle est associée\n",
    "à un pixel blanc.\n",
    "\n",
    "Pour pallier ce problème, on pourra écrire :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y = digits.target\n",
    "x = digits.images.reshape((len(digits.images),-1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On fournit l’extrait de documentation suivant :"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 0px;\">\n",
    "\n",
    "<strong>- Documentation -</strong> <code>A = B.reshape((len(B), -1))</code> permet de modifier la taille de l’image <code>B</code> sans en altérer le contenu. Le résultat\n",
    "de la fonction <code>reshape</code> est affecté à <code>A</code>.\n",
    "Compte-tenu des arguments fournis ici <code>((len(B), -1))</code>, l’image de $n_l$ lignes et de $n_c$ colonnes est modifiée en\n",
    "une image d’une seule colonne et de $n_l \\times n_c$ lignes. Le pixel d’indice $i$ (pour la colonne) et $j$ (pour la ligne)\n",
    "devient alors le pixel d’indice 0 pour la colonne et $j \\times n_c + i$ pour la ligne. \n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Poour connaitre la taille (nombre de lignes et de colonnes) d'un tableau, noté <code>tableau</code>, on pourra utiliser la fonctions <code>shape</code> de la bibliothèque <code>numpy</code>."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 0px;\">\n",
    "\n",
    "<strong>- Documentation -</strong> <code>tableau.shape</code> renvoie un tuple contenant les longueurs du tableau <code>tableau</code>\n",
    "\n",
    "Voir exemple ci-dessous.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "tableau = np.array([[1,2,3],[4,5,6]])\n",
    "print('tableau =')\n",
    "print(tableau)\n",
    "tableau.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 4.</strong> Décrire les éléments suivants et afficher leur taille en utilisant la fonction shape :\n",
    "* <code>digits.images</code>\n",
    "* <code>digits.images[25]</code>\n",
    "* <code>x</code>\n",
    "* <code>x[25]</code>\n",
    "* <code>y</code>\n",
    "* <code>y[25]</code>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y.shape\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Utilisation d'un réseau de neurone\n",
    "\n",
    "\n",
    "On envisage d’abord d’utiliser un réseau de neurones pour la reconnaitre ces chiffres manuscrits."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 5.</strong> Rappeler le fonctionnement d'un neurone et d'un réseau.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 6.</strong> Compte-tenu des images utilisées, combien faudra-t-il de neurones dans la couche d’entrée du réseau ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 7.</strong> Combien faudra-t-il de sorties ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On fixe la structure du réseau à 1 seule couche cachée avec  $N$ neurones. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 8.</strong> Représenter ce réseau de neurones.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 9.</strong> Compter le nombre de biais et de poids qui seront à optimiser ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 10.</strong> Quelle est la méthode qui permet de déterminer la valeur ces paramètres ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 11.</strong> Quelle fonction d’activation peut-on utiliser pour résoudre ce problème ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour sélectionner les données d’apprentissage et les données de test, on utilise les lignes ci-dessous. Cela permet de\n",
    "préparer une portion des données pour la phase d’apprentissage (entrées <code>x_train</code> et sortie <code>y_train</code>) et une portion\n",
    "pour la phase de test (entrées <code>x_test</code> et sortie <code>y_test</code>) (ici 33% des données seront utilisées pour le test et 67% pour\n",
    "l’apprentissage). L’instruction <code>shuffle = True</code> permet de mélanger les données avant la séparation pour éviter d’utiliser\n",
    "une base de données déjà triée."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "x_train , x_test , y_train , y_test = train_test_split (x, y, shuffle = True , test_size = 0.33)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 12.</strong> Quel phénomène risque d’apparaitre si $N$ est trop grand ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On choisit finalement $N = 10$ et on s’impose d’avoir deux fois plus de données d’apprentissage que de paramètres internes (poids et biais)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 14.</strong> Quels sont les pourcentages (<code>test_size</code>) que l’on peut choisir pour valider le fait d’avoir deux fois plus\n",
    "de données d’apprentissage que de paramètres internes ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Préparation des données"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 15. a.</strong> Modifier le <code>test_size</code>dans le code ci-dessous.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "x_train , x_test , y_train , y_test = train_test_split (x, y, shuffle = True , test_size = )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Création du modèle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 15. b.</strong> Chercher la documentaion de <code>MLPClassifier</code> sur https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html et régler les paramètres pour :\n",
    "* qu'il y ait une seule couche cachée contenant 10 neurones ;\n",
    "* que la fonction d'activation soit la fonction sigmoïde (logistic en anglais) ;\n",
    "* que le maximum d'itération autorisée pour la convergence lors de la descente de gradient soit de 1000.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neural_network import MLPClassifier ## réseau de neurone pour la classification\n",
    "mlp = MLPClassifier(   !!! zone à compléter !!!   )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Entrainement du modèle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 15. c.</strong> Chercher la documentaion de <code>MLPClassifier.fit</code> sur https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPClassifier.html#sklearn.neural_network.MLPClassifier.fit et renseigner les arguments de la fonction ci-dessous pour entraîner le modèle.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mlp.fit( !!! zone à compléter !!! )\n",
    "### le modèle mlp est prêt à être utilisé !"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Affichage des résultats à partir des données tests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = mlp . predict ( x_test )\n",
    "\n",
    "from sklearn.metrics import confusion_matrix\n",
    "cm = confusion_matrix (y_test , y_pred )\n",
    "print ('score = ',mlp. score (x_test , y_test )) ## Score obtenu\n",
    "print ('matrice de confusion =',cm) ## Affichage de la matrice de confusion"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 16.</strong> Que contient <code>y_pred</code> ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 17.</strong> Calculer la justesse de votre algorithme à partir de la matrice de confusion affichée.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On définit le taux de bonnes prédictions d’images représentant le chiffre $i$ :\n",
    "\n",
    "$$t_i = \\frac{\\text{nb. de bonnes prédictions du chiffre } i}{\\text{nb. d'images du chiffre } i} \\hspace{1cm} \\text{avec $i \\in [0,9]$}$$\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 18.</strong> Compléter le scipt ci-dessous pour calculer les taux $t_i$. Y-a-t-il un chiffre qui est moins bien et/ou mieux préduit que les autres (relancer éventuellement plusieurs fois le modèle) ?\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "T = []\n",
    "for i in range(0,10):\n",
    "    ni = 0\n",
    "    for j in range(0,10):\n",
    "        ni = cm[i][j] + ni \n",
    "        if i==j:\n",
    "            bon = cm[i][j]\n",
    "    T.append( !!! zone à compléter !!! )\n",
    "print(T)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut également évaluer l’intérêt du réglage du taux d’apprentissage (<code>learning rate</code>) en rajoutant dans le modèle :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neural_network import MLPClassifier ## réseau de neurone pour la classification\n",
    "mlp = MLPClassifier( !!! zone à compléter de la question 15.b !!! ,learning_rate_init=0.001)\n",
    "## (10) signifie qu ’il y a une couche cachée avec 10 neurones\n",
    "## et ’logistic ’ signifie qu ’on utilise une fonction sigmoide comme fonction d’activation\n",
    "## et max_iter permet de régler le nombre d'itération maximale lors de la descente de gradient\n",
    "## et on impose un learning rate de 0.001"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On peut également afficher le temps d’apprentissage des paramètres en utilisant dans le code ci-dessous :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from time import time\n",
    "start = time ()\n",
    "mlp.fit( !!! zone à compléter de la question 15.c !!! )\n",
    "t_app = time () - start\n",
    "print(\"temps d'apprentissage =\",t_app)\n",
    "print ('score = ',mlp.score(x_test , y_test ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 19.</strong> Faire quelques simulations à partir des instructions ci-dessus et modifier éventuellement le <code>learning rate</code>. Compléter ensuite le script ci-dessous pour analyser l'évolution du temps d'apprentissage et de la justesse en fonction du <code>learning rate</code>.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from time import time\n",
    "liste_des_learning_rate = [0.001,0.01,0.1,0.5]\n",
    "tableau_resultat = [['Learning rate'],['Temps apprentissage (en s)'],['Justesse']]\n",
    "for lr in liste_des_learning_rate:\n",
    "    start = time ()\n",
    "    mlp = MLPClassifier( !!! zone à compléter de la question 15.b !!! ,learning_rate_init=lr)\n",
    "    mlp.fit( !!! zone à compléter de la question 15.c !!! )\n",
    "    t_app = time () - start\n",
    "    tableau_resultat[0].append(lr)\n",
    "    tableau_resultat[1].append(t_app)\n",
    "    tableau_resultat[2].append(mlp.score(x_test , y_test ))\n",
    "\n",
    "print(tableau_resultat[0][0],tableau_resultat[0][1:])\n",
    "print(tableau_resultat[1][0],tableau_resultat[1][1:])\n",
    "print(tableau_resultat[2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Utilisation des algorithme des $k$-plus proches voisins"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 20.</strong> Reprendre le problème en le traitant avec l’algorithme des $k$-plus proches voisins. Celui-ci est disponible\n",
    "dans la bibliothèque <code>scikit learn</code> dont vous trouverez la documentation ici : https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html . Modifier le script ci-dessous pour créer un modèle avec 3 plus proches voisins (seul paramètre du modèle).\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn . neighbors import KNeighborsClassifier\n",
    "mlp = KNeighborsClassifier ( !!! zone à compléter !!! )\n",
    "## Création d’un modèle k-NN avec 3 voisins"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div style=\"padding:10px ;border:solid 2px black; border-radius: 10px; background-color:Beige;\">\n",
    "\n",
    "<strong>Question 21.</strong> Faire quelques tests en variant le nombre de voisins. Discuter du résultat obtenu.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Il vous reste du temps ?\n",
    "\n",
    "Vous pouvez traiter le problème de la classification des iris (vu en cours) en important les données avec l’instruction :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
