{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dSC1HhME4imZ"
   },
   "source": [
    "# Descente de Gradient "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zZSvg_nj4imb"
   },
   "source": [
    "### Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Aa-K5Hz_4imb"
   },
   "source": [
    "Nous allons mettre en pratique nos connaissances sur la descente de gradient. Pour cela, nous utiliserons nos données d'entraînement provenant de l'ensemble de données sur le cancer du sein de l'Université du Wisconsin disponibles en ligne."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "E2jGmgIJ4imc",
    "outputId": "ca7e2fd1-96eb-46bf-8022-c80f57e498ac"
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "df = pd.read_csv('./cell_data.csv')\n",
    "df[:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "jhVd69-_4imd"
   },
   "source": [
    "Si nous examinons les données, nous constatons que nous avons 569 observations, et que chaque observation présente les caractéristiques `surface_moyenne` et `concavite_moyenne` ainsi qu'une cible, c'est-à-dire le résultat de l'observation qui a fini par être cancéreuse ou non. Pour cette leçon, nous ne nous entraînerons que sur la caractéristique `surface_moyenne`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "d0F6iVjG4imd",
    "outputId": "049b133b-80a6-44a0-c3b9-89de05e99f3c"
   },
   "outputs": [],
   "source": [
    "df.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "KTLOBrXB4imd"
   },
   "source": [
    "## Hypothèse "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "m8FgQnCB4imd"
   },
   "source": [
    "Comme nous le savons, notre objectif est de trouver une fonction d'hypothèse qui puisse utiliser les caractéristiques ci-dessus pour prédire la cible. Écrivons d'abord la forme de notre fonction d'hypothèse qui ne considère que la zone cellulaire. Notre fonction d'hypothèse prend la forme :"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ZdNjDcvm4ime"
   },
   "source": [
    "* $z(x) = w_1*cell\\_area + b$\n",
    "* $a(z) = \\frac{1}{1 + e^{-z}}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fEzFkjYT4ime"
   },
   "source": [
    "Nous voudrons trouver les paramètres `w_1` et `b` qui minimisent la fonction de coût pour nos données d'entraînement."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "zMJqc_u54ime"
   },
   "source": [
    "### Mise en oeuvre\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "x8hDmGbl4ime"
   },
   "source": [
    "Commençons par traduire le composant linéaire de notre fonction d'hypothèse en code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Compléter le code suivant"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "nkZQkO2K4ime"
   },
   "outputs": [],
   "source": [
    "def linear_component(w1, b, cell_area):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_80N2m3N4ime"
   },
   "source": [
    "Dans notre fonction, nous aurons nos paramètres, $w_1$ ​ et $b$ comme arguments. Cela nous permettra de tester plus facilement différents paramètres pour notre fonction d'hypothèse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Tlf2Cdyk4ime"
   },
   "source": [
    "Vérifions notre travail avec différents paramètres."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "EpDIHsI_4ime",
    "outputId": "6cf86ce6-4b58-4bd7-b58e-0586a28c2670"
   },
   "outputs": [],
   "source": [
    "w1 = .03\n",
    "b = -1\n",
    "linear_component(w1, b, 1.001)\n",
    "# -0.96997"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Qy2uK8i04imf",
    "outputId": "e2ef9e4a-c77b-4d99-a2a9-b9b3ed02eac2"
   },
   "outputs": [],
   "source": [
    "w1 = .04\n",
    "b = -.5\n",
    "linear_component(w1, b, 1.001)\n",
    "# 2.039"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "mBnmAGrB4imf"
   },
   "source": [
    "Ainsi, nous pouvons constater qu'en ajustant nos paramètres, nous obtenons différentes valeurs de sortie pour la même observation. L'objectif est d'ajuster les paramètres de manière à ce que, lorsque nous alimentons la valeur de retour de notre composant linéaire à la couche d'activation, elle se rapproche des valeurs observées dans les données d'entraînement."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xDd1huy94imf"
   },
   "source": [
    "**Question** :  Compléter l'implémentation de la fonction `sigmoid` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3P-M0HjH4imf"
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "def sigmoid(z):\n",
    "    return 1/(1 + np.exp(-z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "P4G9MsMy4imf",
    "outputId": "fe1617f7-9a2b-425b-bce8-3ac6c9a7eac8"
   },
   "outputs": [],
   "source": [
    "first_area = 1001.0\n",
    "z = linear_component(.03, -2, 1.001)\n",
    "sigmoid(z)\n",
    "# 0.12239"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "OXJrkSBx4imf",
    "outputId": "b3670d5a-db92-4033-e45c-59a07311183c"
   },
   "outputs": [],
   "source": [
    "df[:1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "RR4D0O954imf"
   },
   "source": [
    "Si nous examinons la première observation, nous constatons que notre prédiction de 0,88 n'est pas très performante pour prédire une valeur observée de 0. Mais ce n'est pas grave, nous n'avons pas encore entraîné notre fonction d'hypothèse.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UrZUHPN-4imf"
   },
   "source": [
    "### La fonction coût"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "smBrDRdz4imf"
   },
   "source": [
    "En fait, nous n'avons même pas encore évalué nos paramètres sur l'ensemble des données d'entraînement. Écrivons notre fonction de coût afin de pouvoir le faire."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "JaNGuHEI4imf"
   },
   "source": [
    "$J(\\theta) = SSE(w, b) = \\sum_{i = 1}^n (y_i - h(x_i))^2 = \\sum_{i = 1}^n (y_i - \\sigma(z(w, b, x_i)))^2$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LxFhFpkK4imf"
   },
   "source": [
    "On décompose la fonction ci dessus en bloc :"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "qIxxEMuE4imf"
   },
   "source": [
    "Commençons par la gauche, nous avons une fonction de coût $J$, dont la sortie change lorsque nous modifions les valeurs de nos paramètres, $\\theta$. Le coût est la somme des erreurs quadratiques, $SSE$, dont la sortie dépend des deux paramètres $w$ et $b$.\n",
    "\n",
    "Ensuite, nous voyons $\\sum_{i = 0}^n (y_i - h(x_i))^2$ qui est la formule pour SSE. Le terme $\\sum$ signifie qu'il faut parcourir chaque observation, de la première à la dernière (i = 1 à $n$ observations), et additionner la différence entre ce qui a été observé avec l'observation et ce que la fonction d'hypothèse a prédit, au carré."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-3mDUM9I4imf"
   },
   "source": [
    "### Mise en oeuvre"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rrNQ6EuM4imf"
   },
   "source": [
    "Avant de poursuivre, combinons les appels de notre composant linéaire et de notre fonction sigmoïde en une fonction appelée `h(w, b, x)`. C'est la fonction d'hypothèse qui dépend de nos paramètres w et b, ainsi que de la valeur de la caractéristique x."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : compléter la fonction $h$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "B7ta2kK84imf"
   },
   "outputs": [],
   "source": [
    "def h(w, b, x):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "XvbZGM4b4imf",
    "outputId": "cf5aea52-6b05-4a08-b238-bd5bdaee3279"
   },
   "outputs": [],
   "source": [
    "h(.03, -2, 1.001)\n",
    "# 0.12239"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "um8lHaOv4img"
   },
   "source": [
    "**Question** : Passons maintenant à l'écriture du code pour la somme des erreurs quadratiques. Nous le ferons en écrivant d'abord une fonction qui calcule simplement l'erreur quadratique, puis nous nous inquiéterons d'additionner toutes les erreurs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "yGpRWTJz4img"
   },
   "outputs": [],
   "source": [
    "def squared_error(w, b, x1, y):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oMpkxg4Y4img"
   },
   "source": [
    "**Question** : Utilisez les fonctions `linear_component` et `sigmoid` ci-dessous pour calculer l'erreur quadratique."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7TqwI6ge4img"
   },
   "source": [
    "```python\n",
    "def linear_component(w1, b, cell_area):\n",
    "    return w1*cell_area + b\n",
    "\n",
    "def sigmoid(z):\n",
    "    return 1/(1 + np.exp(-z))\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "GEsVuvBI4img"
   },
   "source": [
    "Vérifions les résultats"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "J8Gcfl8K4img",
    "outputId": "bb34e214-ed69-4338-e591-efe086f364d3"
   },
   "outputs": [],
   "source": [
    "w = .3\n",
    "b = -.5\n",
    "cell_area = 1.001\n",
    "y = 0\n",
    "squared_error(w, b, cell_area, y)\n",
    "# 0.2027"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OMQhmXwL4img"
   },
   "source": [
    "\n",
    "Maintenant, nous allons utiliser la fonction `squared_error` ci-dessus pour calculer la somme des erreurs quadratiques.\n",
    "\n",
    "> Ici, nous l'avons fait pour vous. Elle utilise la fonction d'erreur quadratique que vous avez écrite précédemment.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "YPXJB5x94imk"
   },
   "outputs": [],
   "source": [
    "def sum_of_squared_errors(paired_data, w, b):\n",
    "    return sum([squared_error(w, b, feature, target) for (feature, target) in paired_data])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "jZrt4ujb4imk"
   },
   "outputs": [],
   "source": [
    "paired_data = df[['surface_moyenne', 'est_cancereux']].to_numpy()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "BxQrD2Y34imk"
   },
   "source": [
    "Les données appariées sont une liste d'observations, où chaque élément est une liste avec une caractéristique et une cible"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "GSIczleC4imk",
    "outputId": "85e4c91d-8ff4-4477-883b-a09ee817239e"
   },
   "outputs": [],
   "source": [
    "paired_data[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_eMvd9Pa4imk"
   },
   "source": [
    "\n",
    "Par exemple, ci-dessus, on voit que notre première observation a une caractéristique de zone cellulaire de 1001 et une cible de 0. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "XmfJONMC4imk"
   },
   "source": [
    "Notre somme des erreurs quadratiques parcourt toutes les observations, calcule les erreurs quadratiques et les additionne ensuite."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ymyA2gyP4imk",
    "outputId": "65fac96d-be40-44fd-8f26-9a46bd57e319"
   },
   "outputs": [],
   "source": [
    "sum_of_squared_errors(paired_data, .04, -.5)\n",
    "# 168.10946204835383"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wmGTWXGu4iml"
   },
   "source": [
    "\n",
    "Si nous remplaçons nos paramètres $w$ et $b$ par différentes valeurs, nous obtiendrons différentes erreurs quadratiques. Notre objectif est de trouver les paramètres $w$ et $b$ qui minimisent notre SSE. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "yBVqNrqA4iml"
   },
   "source": [
    "### Descending Along a Cost Curve"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "9yGaJ7Ic4iml"
   },
   "source": [
    "Maintenant, si nous devions tracer chacune des valeurs potentielles de $w$ et $b$ dans une plage, nous trouverions un coût différent pour chaque combinaison de nos paramètres. Traçons ci-dessous les valeurs de nos paramètres et le coût correspondant."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "bJJ1dLV24iml",
    "outputId": "c7407cbc-4526-4951-c449-272a18c16623"
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import plotly.graph_objects as go\n",
    "url = \"https://storage.googleapis.com/curriculum-assets/nn-from-scratch/cost_curve_three_d.json\"\n",
    "\n",
    "fig_dict = dict(pd.read_json(url, typ = 'dict', convert_dates=False))\n",
    "go.Figure(fig_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "pghl_ToA4iml"
   },
   "source": [
    "Maintenant, l'objectif de la descente de gradient est de descendre le long de la courbe de coût sans avoir à la tracer. La raison en est que, lorsque l'on ajoute plus de paramètres, il devient impossible de tracer une courbe de coût entière. Au lieu de cela, nous descendons le long de la courbe de coût en utilisant la descente de gradient, en prenant des pas dans la direction de la pente la plus forte. Et nous trouvons cette direction en calculant le gradient, c'est-à-dire la dérivée partielle par rapport à chaque paramètre. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "HQ3V2QFq4iml"
   },
   "source": [
    "Les dérivées partielles s'écrivent :\n",
    "$$\n",
    "  \\frac{\\partial J}{\\partial w} \\  \\frac{\\partial J}{\\partial b}\n",
    "  \n",
    "$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ZPPgLXX04iml"
   },
   "source": [
    "C'est-à-dire, le changement de notre courbe de coût par rapport à un changement de notre paramètre w et de notre terme de biais $b$, où notre courbe de coût est la suivante"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "T4pUml1D4iml"
   },
   "source": [
    "$J(w, b) = \\sum_{i = 1}^n (y_i - \\sigma(z(w, b, x_i)))^2$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "dpTY1zH34iml"
   },
   "source": [
    "Le calcul des dérivées partielles pour notre courbe de coût ci-dessus est assez compliqué et implique ce qu'on appelle la règle de la chaîne. Nous aborderons la règle de la chaîne dans de futures leçons, donc pour l'instant, nous allons simplement vous donner les dérivées partielles."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "cJ53mUrQ4iml"
   },
   "source": [
    "$\\frac{\\partial J}{\\partial w} = \\frac{\\partial J}{\\partial a} \\frac{\\partial a}{\\partial z} \\frac{\\partial z}{\\partial w} = 2(h(x_i) - y_i)*\\sigma(z(x))(1 - \\sigma(z(x))) * x_i$\n",
    "\n",
    "$\\frac{\\partial J}{\\partial b} = \\frac{\\partial J}{\\partial a} \\frac{\\partial a}{\\partial z} \\frac{\\partial z}{\\partial b} = 2(h(x_i) - y_i)*\\sigma(z(x))(1 - \\sigma(z(x))) * 1$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "CRzQZ3Ry4iml"
   },
   "source": [
    "Et nous pouvons transformer ce qui précède en code avec ce qui suit :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "S89a0LM-4iml"
   },
   "outputs": [],
   "source": [
    "def dj_dw(w, b, x, y):\n",
    "    return 2*(h(w, b, x) - y)*h(w, b, x)*(1 - h(w, b, x))*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "HltFFuB44iml"
   },
   "outputs": [],
   "source": [
    "def dj_db(w, b, x, y):\n",
    "    return 2*(h(w, b, x) - y)*h(w, b, x)*(1 - h(w, b, x))*1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "0Q3-Cv0f4iml"
   },
   "source": [
    "\"Les deux fonctions ci-dessus nous permettent de déterminer le taux de variation instantané dans chaque direction sur notre courbe de coût. Par exemple, lorsque nous sommes à l'emplacement de notre courbe de coût de $w = .04$ et $b = -.5$, notre taux de variation instantané dans la direction de $w$ est de .18.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "yhLS_Bvz4iml",
    "outputId": "c48ac86f-3efc-4096-e7b2-45e858217d5d"
   },
   "outputs": [],
   "source": [
    "w = .04\n",
    "b = -.5\n",
    "y = 0\n",
    "x = 1.001\n",
    "dj_dw(w, b, x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TUa96giX4iml"
   },
   "source": [
    "\n",
    "En d'autres termes, si nous modifions légèrement notre paramètre $w$, nous nous attendons à ce que notre coût, calculé par notre fonction $J$, change de $.18$.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "bHaqQRDg4imm"
   },
   "source": [
    "\n",
    "Donc, comme nous le savons, notre procédure de descente de gradient consiste à mettre à jour nos paramètres de manière répétée en fonction de notre \"bang for our buck\" (rapport coût-efficacité). C'est-à-dire que nous modifions chaque paramètre en proportion de la quantité dont le changement nous déplacerait vers le minimum de la courbe de coût. Et nous avons calculé ce changement de la courbe de coût par changement du paramètre à travers $\\frac{\\partial J}{\\partial w}$ et $\\frac{\\partial J}{\\partial w}$ ci-dessus. Ok, donc ci-dessous, nous appliquons la descente de gradient en mettant à jour de manière répétée chaque paramètre par sa dérivée partielle respective.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "y8VouyHv4imm"
   },
   "source": [
    "\n",
    "> Choisissez des paramètres initiaux $\\theta$ et un taux d'apprentissage $\\eta$, puis\n",
    ">\n",
    "> Répétez\n",
    ">\n",
    "> $\\theta =  \\theta - \\eta *\\frac{\\partial J}{\\partial \\theta}$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "c5ys6BbB4imm"
   },
   "source": [
    "Le programme correspondant s'écrit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "nQZfgS3z4imm"
   },
   "outputs": [],
   "source": [
    "w = .5\n",
    "b = .5\n",
    "eta = .01\n",
    "\n",
    "for i in range(0, 150):\n",
    "    for (x, y) in paired_data:\n",
    "        dj_dw_calc = dj_dw(w, b, x, y)\n",
    "        dj_db_calc = dj_db(w, b, x, y)\n",
    "        w += -eta*dj_dw_calc\n",
    "        b += -eta*dj_db_calc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "REclzDhV4imm",
    "outputId": "1c5f958f-db3d-48d8-84f7-8cc29c0b52c7"
   },
   "outputs": [],
   "source": [
    "w"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "E4TQSkzd4imm",
    "outputId": "27440cf5-ab01-4021-a60c-245d4e31ea81"
   },
   "outputs": [],
   "source": [
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Zudwvexc4imm"
   },
   "source": [
    "Ainsi, en mettant à jour de manière répétée nos paramètres de manière à trouver des valeurs qui se rapprochent du minimum de la courbe de coût, nous finissons par obtenir des valeurs de $w = -6.57$ et $b = 4.75$.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "NgO2Ib4b4imm"
   },
   "source": [
    "> Voyons comment nous avons réussi par rapport à ce que `sklearn`trouve pour nos paramètres"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "Cf9b8ybW4imm",
    "outputId": "09f52027-82e8-45d2-c17d-afa50c551af8"
   },
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "log_model = LogisticRegression(fit_intercept=True)\n",
    "\n",
    "areas = df[['surface_moyenne']]\n",
    "targets = df['est_cancereux']\n",
    "\n",
    "log_model.fit(areas, targets)\n",
    "log_model.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "V_piR2Nt4imm",
    "outputId": "41223912-8c15-4d98-bce4-eff7ba7b670d"
   },
   "outputs": [],
   "source": [
    "log_model.intercept_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "78XkQsjI4imm"
   },
   "source": [
    "### Predicting Going Forward"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "LczGU6J24imm"
   },
   "source": [
    "Une fois que nous avons trouvé ces paramètres, nous pouvons les utiliser dans notre fonction d'hypothèse à l'avenir."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wMaLMssI4imm"
   },
   "source": [
    "Nous avons fait l'hypothèse suivante :\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "_lybcXqT4imm"
   },
   "outputs": [],
   "source": [
    "def h(w, b, x):\n",
    "    return sigmoid(linear_component(w, b, x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TTcdAPeK4imm"
   },
   "source": [
    "Une fois que nous avons entraîné notre modèle et déterminé les valeurs optimales des paramètres $w$ et $b$, nous pouvons utiliser ce modèle pour faire des prédictions sur de nouvelles observations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "5E41tjjc4imm",
    "outputId": "886ff243-92d8-4920-996f-b3474b417909"
   },
   "outputs": [],
   "source": [
    "selected_obs = df[['surface_moyenne', 'est_cancereux']][17:21]\n",
    "selected_obs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lWDbHxhJ4imm"
   },
   "source": [
    "Nous avons choisi une sélection qui contient à la fois des observations bénignes et cancéreuses."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "zjy8n5Ii4imn",
    "outputId": "f318e834-0878-4b9d-8e15-e7b3af484d7c"
   },
   "outputs": [],
   "source": [
    "observations = selected_obs.to_numpy()\n",
    "observations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ll6cJSRf4imn",
    "outputId": "6c89cb37-e186-441f-d944-19d6e3f260d9"
   },
   "outputs": [],
   "source": [
    "w = -6.57\n",
    "b = 4.754\n",
    "[h(w, b, observation[0]) for observation in observations]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 141
    },
    "id": "lM3VLR5p4imn",
    "outputId": "407f9519-1192-46a9-ca70-b13a5c8fb7a8"
   },
   "outputs": [],
   "source": [
    "selected_obs['est_cancereux']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5zc3Pwqy4imn"
   },
   "source": [
    "<center>\n",
    "<a href=\"https://www.jigsawlabs.io/free\" style=\"position: center\"><img src=\"https://storage.cloud.google.com/curriculum-assets/curriculum-assets.nosync/mom-files/jigsaw-labs.png\" width=\"15%\" style=\"text-align: center\"></a>\n",
    "</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "k6Lv9gxF4imn"
   },
   "source": [
    "### Answers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "x4BDsyjb4imn"
   },
   "outputs": [],
   "source": [
    "def linear_component(w1, b, cell_area):\n",
    "    return w1*cell_area + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ni9IvDTp4imn"
   },
   "outputs": [],
   "source": [
    "def h(w, b, x):\n",
    "    return sigmoid(linear_component(w, b, x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "9vCWId6f4imn"
   },
   "outputs": [],
   "source": [
    "def squared_error(w, b, x1, y):\n",
    "    return (y - h(w, b, x1))**2"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "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.11.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
