{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TP 2 : chapitres 3 et 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chapitre 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Considérons les données $\\{(1,1),(20,400),(30,800),(40,1300)\\}$.\n",
    "\n",
    "- Calculer la droite d'équation $y=\\alpha_0+\\alpha_1x$ de meilleur approximation de ces données. \n",
    "- Calculer la parabole d'équation $y=\\alpha_0+\\alpha_1x+\\alpha_2x^2$ de meilleur approximation de ces données. \n",
    "- Calculer la fonction $f(x)=\\alpha_0 \\cos(0x)+\\alpha_1 \\cos(1x)$ de meilleur approximation de ces données."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Méthode 1 : minimisation de la fonction erreur quadratique"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 377,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sympy as sp\n",
    "\n",
    "from IPython.display import Math, Markdown # Affichage de formules mathématiques amelioré"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 378,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Définition des données\n",
    "data = [ (1, 1), (20, 400), (30, 800), (40, 1300) ]\n",
    "x_data, y_data = zip(*data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 379,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Coefficients (inconnus) de la fonction de meilleure ajustement\n",
    "\n",
    "deg = 1 # Degré du polynôme = (dimension-1) de l'espace des fonctions de base \n",
    "alpha = sp.symbols(f'\\\\alpha_0:{deg+1}')\n",
    "\n",
    "f = lambda x : sum(alpha[i] * x**i for i in range(deg+1))\n",
    "# f = lambda x : sum( alpha[i] * sp.cos(i*x) for i in range(deg+1) ) # base de cosinus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 380,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Fonction d'erreur (somme des carrés des écarts)\n",
    "error = sum(  (y - f(x))**2  for x, y in zip(x_data, y_data))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 381,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calcul des dérivées partielles\n",
    "grad = [ sp.diff(error, a) for a in alpha ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 382,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Résolution du système d'équations\n",
    "solution = sp.solve(  grad, alpha )\n",
    "# solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 383,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_0 = - \\frac{388690}{3323} \\approx -116.969605777912$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_1 = \\frac{108413}{3323} \\approx 32.6250376166115$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for key, value in solution.items():\n",
    "    display(Math(f'{key} = {sp.latex(value)} \\\\approx {value.evalf()}'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Méthode 2 : construction de la matrice et résolution du système linéaire"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 384,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle M1 = \\left[\\begin{matrix}4 & 91\\\\91 & 2901\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle M2 = \\left[\\begin{matrix}4 & 91 & 2901\\\\91 & 2901 & 99001\\\\2901 & 99001 & 3530001\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Matrices des coefficients\n",
    "\n",
    "A0 = sum([x**0 for x in x_data])\n",
    "A1 = sum([x**1 for x in x_data])\n",
    "A2 = sum([x**2 for x in x_data])\n",
    "A3 = sum([x**3 for x in x_data])\n",
    "A4 = sum([x**4 for x in x_data])\n",
    "\n",
    "# Pour la droite\n",
    "M1 = sp.Matrix([\n",
    "    [A0, A1],\n",
    "    [A1, A2]\n",
    "])\n",
    "display(Math(r'M1 = ' + sp.latex(M1)))\n",
    "\n",
    "# Pour la parabole\n",
    "M2 = sp.Matrix([\n",
    "    [A0, A1, A2],\n",
    "    [A1, A2, A3],\n",
    "    [A2, A3, A4]\n",
    "])\n",
    "display(Math(r'M2 = ' + sp.latex(M2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 385,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle s1 = \\left[\\begin{matrix}2501\\\\84001\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle s2 = \\left[\\begin{matrix}2501\\\\84001\\\\2960001\\end{matrix}\\right]$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Termes source\n",
    "\n",
    "b0 = sum([y for y in y_data])\n",
    "b1 = sum([x*y for x, y in zip(x_data, y_data)])\n",
    "b2 = sum([x**2*y for x, y in zip(x_data, y_data)])\n",
    "\n",
    "# Pour la droite\n",
    "s1 = sp.Matrix([b0,b1])\n",
    "display(Math(r's1 = ' + sp.latex(s1)))\n",
    "\n",
    "# Pour la parabole\n",
    "s2 = sp.Matrix([b0,b1,b2])\n",
    "display(Math(r's2 = ' + sp.latex(s2)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 386,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Résolution des systèmes linéaires \n",
    "\n",
    "# Coefficients (inconnus) de la fonction de meilleure ajustement, degré max\n",
    "deg = 2\n",
    "alpha = sp.symbols(f'\\\\alpha_0:{deg+1}')\n",
    "\n",
    "solution1 = list(sp.linsolve((M1, s1), alpha[:2]))[0]\n",
    "solution2 = list(sp.linsolve((M2, s2), alpha))[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 387,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_0 = - \\frac{388690}{3323} \\approx -116.969605777912$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_1 = \\frac{108413}{3323} \\approx 32.6250376166115$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_0 = - \\frac{17432050}{1909543} \\approx -9.12891199622108$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_1 = \\frac{16478205}{1909543} \\approx 8.62939719084619$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\alpha_2 = \\frac{1153388}{1909543} \\approx 0.604012583115436$"
      ],
      "text/plain": [
       "<IPython.core.display.Math object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for i, value in enumerate(solution1):\n",
    "    display(Math(f'{alpha[i]} = {sp.latex(value)} \\\\approx {value.evalf()}'))\n",
    "\n",
    "for i, value in enumerate(solution2):\n",
    "    display(Math(f'{alpha[i]} = {sp.latex(value)} \\\\approx {value.evalf()}'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Chapitre 4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Statistiques uni-variées"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "36 personnes sont interrogées sur le nombre de pièces dans leur logement. Les 36 réponses obtenues sont résumé dans la série statistique suivante:\n",
    "$$\n",
    "[1, 3, 4, 2, 2, 4, 5, 5, 1, 1, 2, 3, 4, 3, 2, 6, 6, 1, 2, 2, 3, 2, 1, 3, 4, 2, 3, 3, 3, 5, 6, 4, 2, 2, 4, 2]\n",
    "$$\n",
    "\n",
    "- Donner la distribution statistique associée à cette série (effectifs $n_i$ et fréquences $f_i$).  \n",
    "- Déterminer la moyenne, le mode, la médiane, la variance et l'écart type.  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 388,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import sympy as sp\n",
    "\n",
    "import pandas as pd "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 389,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,\n",
       "       3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6])"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "36"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "xx = np.array(sorted([1, 3, 4, 2, 2, 4, 5, 5, 1, 1, 2, 3, 4, 3, 2, 6, 6, 1, 2, 2, 3, 2, 1, 3, 4, 2, 3, 3, 3, 5, 6, 4, 2, 2, 4, 2]))\n",
    "\n",
    "# xx = np.array(sorted([1]*5 + [2]*11 + [3]*8 + [4]*6 + [5]*3 + [6]*3))\n",
    "\n",
    "n = len(xx)\n",
    "\n",
    "display(xx)\n",
    "display(n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 390,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Valeurs</th>\n",
       "      <th>Effectifs</th>\n",
       "      <th>Fréquences</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>5</td>\n",
       "      <td>5/36</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>11</td>\n",
       "      <td>11/36</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>8</td>\n",
       "      <td>2/9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>6</td>\n",
       "      <td>1/6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>3</td>\n",
       "      <td>1/12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>3</td>\n",
       "      <td>1/12</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Valeurs  Effectifs Fréquences\n",
       "0        1          5       5/36\n",
       "1        2         11      11/36\n",
       "2        3          8        2/9\n",
       "3        4          6        1/6\n",
       "4        5          3       1/12\n",
       "5        6          3       1/12"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "aa, nn = np.unique(xx, return_counts=True)\n",
    "ff = nn/sp.S(n)\n",
    "\n",
    "# display(Markdown(f\"Les valeurs uniques sont {aa}, leur effectif est {nn} et leur fréquence est {ff}\"))\n",
    " \n",
    "df = pd.DataFrame({'Valeurs': aa, 'Effectifs': nn, 'Fréquences': ff})\n",
    "display(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 391,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Le mode est 2 (numpy) et [2] (pandas)"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Mode\n",
    "\n",
    "mode_np = aa[np.argmax(nn)]\n",
    " \n",
    "series = pd.Series(xx)\n",
    "mode_pd = list(series.mode())\n",
    "\n",
    "display(Markdown(f\"Le mode est {mode_np} (numpy) et {mode_pd} (pandas)\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 392,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "La moyenne avec sympy est 3, avec numpy 3.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Moyenne arithmétique\n",
    "mu_sp = sp.Rational( sum(xx) , n )\n",
    "mu_np = np.mean(xx)\n",
    "display(Markdown(f\"La moyenne avec sympy est {mu_sp}, avec numpy {mu_np}\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 393,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "La médiane avec sympy est 3, avec numpy 3.0"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Médiane\n",
    "xx_sorted = np.sort(xx)\n",
    "if n%2==0:\n",
    "    median = (xx_sorted[n//2-1] + xx_sorted[n//2])/sp.S(2)\n",
    "else:\n",
    "    median = xx_sorted[n//2]\n",
    "\n",
    "median_np = np.median(xx)\n",
    "\n",
    "display(Markdown(f\"La médiane avec sympy est {median}, avec numpy {median_np}\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 394,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "La variance avec sympy est $\\frac{19}{9} \\approx 2.11111111111111$, avec numpy 2.111111111111111"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Variance\n",
    "\n",
    "V_sp = sum([(x-mu)**2 for x in xx])/sp.S(n)\n",
    "V_sp2 = sum([x**2 for x in xx])/sp.S(n)-mu**2\n",
    "if V_sp != V_sp2 : display(\"ERROR\")\n",
    "\n",
    "V_np = np.var(xx) # avec numpy\n",
    "# v_np = np.var(xx,ddof=1) # division par n-1\n",
    "\n",
    "display(Markdown(f\"La variance avec sympy est ${sp.latex(V_sp)} \\\\approx {V_sp.evalf()}$, avec numpy {V_np}\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 395,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "L'écart-type avec sympy est $\\frac{\\sqrt{19}}{3} \\approx 1.45296631451356$, avec numpy 1.4529663145135578"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Écart-type\n",
    "s_sp = sp.sqrt(V_sp)\n",
    "s_np = np.std(xx)\n",
    "display(Markdown(f\"L'écart-type avec sympy est ${sp.latex(s_sp)} \\\\approx {s_sp.evalf()}$, avec numpy {s_np}\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Statistiques bi-variées"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Exemple 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Considérons l'échantillon bivarié $((1,1),(2,3),(3,5), (1,2))$. \n",
    "\n",
    "Calculer la covariance et la corrélation entre les deux variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 396,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = [1, 2, 3, 1]\n",
    "y = [1, 3, 5, 2]\n",
    "points = list(zip(x, y))\n",
    "\n",
    "n = len(x)\n",
    "if len(y) != n:\n",
    "    raise ValueError(\"Les listes x et y doivent avoir la même longueur\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 397,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "La covariance avec sympy est $\\frac{19}{16} \\approx 1.18750000000000$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "La covariance avec numpy est 1.1875"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mean_x = sum(x) / sp.S(n)\n",
    "mean_y = sum(y) / sp.S(n)\n",
    "covariance_sp = sum( (x[i]-mean_x) * (y[i]-mean_y) for i in range(n)) / sp.S(n)    \n",
    "\n",
    "covariance_np = np.cov(x, y, ddof=0)[0, 1] \n",
    "\n",
    "display(Markdown(f\"La covariance avec sympy est ${sp.latex(covariance_sp)} \\\\approx {covariance_sp.evalf()}$\"))\n",
    "display(Markdown(f\"La covariance avec numpy est {covariance_np}\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 398,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Le coefficient de corrélation avec sympy est $\\frac{19 \\sqrt{385}}{385} \\approx 0.968329663731489$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "Le coefficient de corrélation avec numpy est 0.9683296637314884"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "variance_x_sp = sum( (x[i]-mean_x)**2 for i in range(n) ) / sp.S(n)\n",
    "variance_y_sp = sum( (y[i]-mean_y)**2 for i in range(n) ) / sp.S(n)\n",
    "correl_sp = covariance_sp / (sp.sqrt(variance_x_sp) * sp.sqrt(variance_y_sp))\n",
    "\n",
    "correl_np = np.corrcoef(x, y)[0, 1]\n",
    "\n",
    "display(Markdown(f\"Le coefficient de corrélation avec sympy est ${sp.latex(correl_sp)} \\\\approx {correl_sp.evalf()}$\"))\n",
    "display(Markdown(f\"Le coefficient de corrélation avec numpy est {correl_np}\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 399,
   "metadata": {},
   "outputs": [],
   "source": [
    "gamma_1 = covariance_sp / variance_x_sp\n",
    "gamma_0 = mean_y - gamma_1 * mean_x\n",
    "\n",
    "droite = lambda x : gamma_0 + gamma_1 * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 400,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAfkElEQVR4nO3deZRU9Zn/8fcjdKQFTEfpIHSzuBCMigj2IIZEUZOwGSEMM8EYNSYnHD0mozMJGUlmNMaT0dEcJ4tRgssoKlHzY1ERRRSJGEWm2UFsxC1AY2iJDaKtsjy/P77Vqeqmm67qrqpby+d1Th/r+723q55Urh+rn7r3fs3dERGR/HdY1AWIiEh6KNBFRAqEAl1EpEAo0EVECoQCXUSkQHSO6oV79Ojh/fv3j+rlRUTy0ooVK9519/KWtkUW6P3796e6ujqqlxcRyUtm9nZr29RyEREpEAp0EZECoUAXESkQCnQRkQKhQBcRKRBJneViZm8B7wP7gX3uXtVsuwG/BsYCHwLfdveV6S1VRCS/zVu1jVsW1lBb30DvslKmjhrIhCEVaXv+VE5bPMfd321l2xhgQOznDOCO2D9FRIQQ5tPmrKNh734AttU3MG3OOoC0hXq6Wi7jgZkeLAPKzKxXmp5bRCTv3bKw5u9h3qhh735uWViTttdINtAdeNrMVpjZlBa2VwBbEsZbY3NNmNkUM6s2s+q6urrUqxURyVO19Q0pzbdHsoE+wt2HElorV5rZWc22Wwu/c9DKGe4+w92r3L2qvLzFK1dFRApS77LSlObbI6lAd/fa2D93AHOBYc122Qr0SRhXArXpKFBEpBBMHTWQ0pJOTeZKSzoxddTAtL1Gm4FuZl3NrHvjY+CrwPpmuz0GXGLBcGCXu29PW5UiInluwpAKbpw4iIqyUgyoKCvlxomDsn6WS09gbjgzkc7ALHd/yswuB3D36cACwimLmwmnLV6WtgpFRArBRx8x4bJxTFizBmbNggvHpf0l2gx0d38DGNzC/PSExw5cmd7SREQKgDv8y7/AbbfF54Y171qnh64UFRHJlFmz4LDD4mF+6aVw4AAcf3xGXi6y+6GLiBSs1athyJD4+NhjYd066No1oy+rQBcRSZedO6GyEj76KD732mtwwglZeXm1XEREOmr/fhg9Gnr0iIf5ggWhf56lMAcFuohIx/ziF9C5MyxcGMY33BCCfMyYrJeilouISHs89VTT0B41Cp54Ajp1av13MkyBLiKSitdfb9pG6dIFtm6Fo4+OrqYYtVxERJLxwQdw3HFNw3zlSmhoyIkwBwW6iMihucO3vw3dusGbb4a5Bx4I84mnJuYABbqISGvuvDNcGHTffWH8/e+HC4MuuijaulqhHrqISHMvvwzDh8fHp54a5rp0ia6mJCjQRUQavfMO9Gq22Npf/gJ9+rS8f45Ry0VEZO9e+MIXmob5c8+FPnmehDko0EWk2E2bBp/6FLz0Uhj/z/+EIB85MtKy2kMtFxEpTnPnwsSJ8fGkSfDww+FL0DylQBeR4rJxI5x0UnxcXh5uoPXpT0dXU5ok/Z8iM+tkZqvMbH4L20aa2S4zWx37uTa9ZYqIdNCuXSG8E8P8lVdgx46CCHNIrYd+FbDxENuXuvtpsZ+fd7AuEZH0OHAA/vEfoawM3n03zM2ZE/rkn/98pKWlW1KBbmaVwDjgrsyWIyKSRr/6VbhZ1pw5YXzNNSHIv/71SMvKlGR76L8Cfgx0P8Q+Z5rZGqAW+JG7b2i+g5lNAaYA9O3bN7VKRUSStWQJnHNOfDxiRDgNsaQkspKyoc1AN7PzgR3uvsLMRray20qgn7vvMbOxwDxgQPOd3H0GMAOgqqrK21mziEjLtmyB5h8W33kHevaMpp4sS6blMgK4wMzeAh4CzjWzBxJ3cPfd7r4n9ngBUGJmPdJdrIhIiz76CAYNahrmL70U2itFEuaQRKC7+zR3r3T3/sBkYLG7fytxHzM7xsws9nhY7Hl3ZqBeEZE493DDrNJSWL8+zM2YEeYT78VSJNp9HrqZXQ7g7tOBScAVZrYPaAAmu7taKiKSOQ88ABdfHB9fdhncfTeEz5ZFyaLK3aqqKq+uro7ktUUkj61aBUOHxsfHHQdr10LXrtHVlEVmtsLdq1rapitFRSQ/7NwJFRXw8cfxuc2b4fjjo6spx+TvTQtEpDjs2wdf/Sr06BEP8yefDH1yhXkTCnQRyV033BDOHV+0KIx/8YsQ5KNHR1tXjlLLRURyz5NPwtix8fHo0TB/frjqU1qlQBeR3PH663DCCfHxEUeEFYOOPjq6mvKIWi4iEr0PPoD+/ZuG+apVYV5hnjQFuohExx0uvRS6dYO33w5zDz4Y5k87LdLS8pECXUSiMWNGWB1o5sww/sEPwq1uv/nNaOvKY+qhi0h2vfRSWJC50eDBsGwZdOkSXU0FQoEuItnxzjvQq1fTuS1boLIymnoKkFouIpJZn3wSPpEnhvmSJaFPrjBPKwW6iGTOv/87HH54aLNAWEHIHc4+O9KyCpVaLiKSfrNnw6RJ8fGkSfDww+FLUMkYBbqIpM8rr8DJJ8fHPXvCpk1w5JHR1VREFOgi0nG7doXb2P7tb/G5jRvhxBOjq6kI6e8fEWm/Awdg4kQoK4uH+dy5oU+uMM+6pAPdzDqZ2Sozm9/CNjOz35jZZjNba2ZDW3oOESkgt94abpY1d24Y/+QnIcgnTIi0rGKWSsvlKmAj0FIzbAwwIPZzBnBH7J8iUmieew7OPTc+/uIXYfHicJtbiVRSn9DNrBIYB9zVyi7jgZkeLAPKzKxXK/uKSD76y1/Cep2JYf7OO7B0qcI8RyTbcvkV8GPgQCvbK4AtCeOtsbkmzGyKmVWbWXVdXV0qdYpIVD76CE45Bfr1i88tWxbaKz17RleXHKTNQDez84Ed7r7iULu1MHfQ6tPuPsPdq9y9qry8PIUyRSTr3OHKK6G0FDZsCHN33hnmz1BHNRcl00MfAVxgZmOBLsCRZvaAu38rYZ+tQJ+EcSVQm74yRSSr7r8fLrkkPv7Od+Cuu0LLRXJWm4Hu7tOAaQBmNhL4UbMwB3gM+L6ZPUT4MnSXu29Pb6kiknGrVsHQhJPUjj8e1qyBrl2jq0mS1u4Li8zscgB3nw4sAMYCm4EPgcvSUp2IZMe770Lv3rB3b3zu9dfDxUKSN1IKdHdfAiyJPZ6eMO/AleksTESyYN++sADzs8/G5556CkaNiq4maTddKSpSrG64IZxu2Bjm//Vf4QtPhXne0r1cRIrNggUwblx8PGYMPP54uOpT8poCXaRYbN4MAwbEx127houFjjoqupokrdRyESl0e/aEi4ISw3z16jCvMC8oCnSRQuUeziXv3j18EgeYNSvMDx4cbW2SEQp0kUL0+9+H1YHuvz+Mr7oqBPmFF0Zbl2SUeugiheTFF2HEiPj4tNPCfVcOPzyykiR7FOgihWD79nBhUKItW6CyMpp6JBJquYjks08+CTfKSgzzP/0ptFcU5kVHgS6Sr37849BKWb48jH/96xDkZ50VbV0SGbVcRPLN7NkwaVJ8/I1vhLNXDtPns2KnQBfJFxs2hIUmGh1zDNTUwJEtrQopxUiBLpLr6uvDXQ/fey8+t3EjnHhiZCVJbtLfaCK56sABmDABPvOZeJjPmxf65ApzaYECXSQX3XpruFnWo4+G8U9/GoJ8/Pho65Kc1mbLxcy6AM8Dh8f2/3/ufl2zfUYCjwJvxqbmuPvP01qpSDFYvBjOOy8+PusseOaZcJtbkTYk00P/GDjX3feYWQnwgpk96e7Lmu231N3PT3+JIkXg7behf/+mc3/9K3z2s5GUI/mpzZaLB3tiw5LYj2e0KpFi0dAAJ5/cNMxffjm0VxTmkqKkeuhm1snMVgM7gEXu/nILu51pZmvM7EkzO7mV55liZtVmVl1XV9f+qkXynTtccQUccQS88kqYu/vuMD9sWLS1Sd5KKtDdfb+7nwZUAsPM7JRmu6wE+rn7YOC3wLxWnmeGu1e5e1V5eXn7qxbJZzNnhouApseW5f3ud8MZLd/5TrR1Sd5LdZHoejNbAowG1ifM7054vMDMbjezHu7+btoqFcl3K1fC6afHxwMGhIUmjjgispKksLT5Cd3Mys2sLPa4FPgy8GqzfY4xM4s9HhZ73p1pr1YkH9XVhbNUEsP8jTdg0yaFuaRVMi2XXsBzZrYW+D9CD32+mV1uZpfH9pkErDezNcBvgMnuri9Opbjt2wdf/nL4cnPfvjC3cGHokx97bLS1SUFqs+Xi7muBIS3MT094fBtwW3pLE8lj118PP/tZfHzjjXDNNZGVI8VB93IRSacnnoDzEy7HGDcuXO3ZqVN0NUnRUKCLpMPmzeFLzkbdu4eLhT7zmehqkqKje7mIdMSePdC3b9MwX7MGdu9WmEvWKdBF2sMdvvWt8El8y5Yw94c/hPlTT422NilaCnSRVN1xR7gw6MEHw/jqq0OQT54caVki6qGLJOvFF2HEiPh46NAwd/jh0dUkkkCBLtKW7duhd++mc1u3QkVFNPWItEItF5HWfPIJnHFG0zB//vnQXlGYSw5SoIu0ZOrU0EpZvjyMf/vbEORf+lK0dYkcglouIon++Ef453+OjydPhlmzINyqSCSnKdBFANavh0GD4uNeveDVV+HII6OrSSRFCnQpbvX14UZZ9fXxuVdfhYEDo6pIpN3UQ5fidOAAjB8fruZsDPNHHw19coW55CkFuhSfX/4y3CzrscfC+D/+IwT5BRdEW5dIB6nlIsXj2WfD/ckbnX02LFoUFp8QKQAKdCl8b78N/fvHx2bwzjth4QmRApLMEnRdzGy5ma0xsw1mdn0L+5iZ/cbMNpvZWjMbmplyRVLQ0AAnndQ0zJcvD/3zVsJ83qptjLhpMcde8wQjblrMvFXbslOrSBok00P/GDjX3QcDpwGjzWx4s33GAANiP1OAO9JZpEhK3OHyy8N6nRs3hrl77gnz//APrf7avFXbmDZnHdvqG3BgW30D0+asU6hL3mgz0D3YExuWxH6arxc6HpgZ23cZUGZmvdJbqkgS7rsv3Anx978P4+99L3wiv+yyNn/1loU1NOzd32SuYe9+bllYk4lKRdIuqR66mXUCVgAnAL9z95eb7VIBbEkYb43NbW/2PFMIn+Dp27dvO0sWacGKFVBVFR9/7nOwalX4lJ6k2vqGlOZFck1Spy26+353Pw2oBIaZ2SnNdmnpuujmn+Jx9xnuXuXuVeXl5SkXK3KQujro3LlpmL/xBtTUpBTmAL3LSlOaF8k1KZ2H7u71wBJgdLNNW4E+CeNKoLYjhYkc0r59cO654cvN/bE2yaJFoU9+7LHtesqpowZSWtJ0MefSkk5MHaULjSQ/JHOWS7mZlcUelwJfBl5ttttjwCWxs12GA7vcfTsimXDddeHc8eeeC+P//u8Q5InnmLfDhCEV3DhxEBVlpRhQUVbKjRMHMWGIbpUr+SGZHnov4L5YH/0w4BF3n29mlwO4+3RgATAW2Ax8CLT9DZRIqubPh699LT7+2tdg7txw1WeaTBhSoQCXvNVmoLv7WmBIC/PTEx47cGV6SxOJ2bSp6f1VjjwS3nor3IdFRP5O93KR3PX++1BZ2TTM166FXbsU5iItUKBL7nGHiy4Kn8S3xS7qeeihMJ94z3IRaUKBLrnl9tvDhUGzZoXxv/5rCPJvfCPaukTygG7OJbnhz3+GL34xPq6qghdeCOt6ikhSFOgSrdpaqGh2VsnWrQfPiUib1HKRaHz8cbhRVmJwL10a2isKc5F2UaBL9v3oR9ClC1RXh/HvfheCPLHlIiIpU8tFsueRR5p+ufnNb8IDD4QFJ0SkwxToknnr1sGpp8bHFRXhPuXdu0dXk0gBUqBL5rz3XlgtaPfu+FxNTbi1rYiknXrokn4HDsAFF8BRR8XD/PHHQ59cYS6SMQp0Sa+bbw43y3r88TC+9toQ5OefH21dIkVALRdJj2eega98JT4+5xx4+umw+ISIZIX+bZOOeeutpgtKdOoE27eDVqQSyTq1XKR9GhrgxBObhnl1dVhJSGEuEgkFuqTGHaZMCet11tSEuXvvDfOnnx5paSLFLpkl6PqY2XNmttHMNpjZVS3sM9LMdpnZ6tjPtZkpVyJ1773hToh33hnGU6aEM1ouvTTSskQkSKaHvg/4obuvNLPuwAozW+TurzTbb6m761SGQlRdHe670ujzn4cVK6C0NLqaROQgySxBtx3YHnv8vpltBCqA5oEuhaauDnr2DO2URm++GS4WEpGck1IP3cz6E9YXfbmFzWea2Roze9LMTm7l96eYWbWZVdfV1aVerWTHvn3htMPPfjYe5s88Ex4rzEVyVtKBbmbdgNnA1e6+u9nmlUA/dx8M/BaY19JzuPsMd69y96pynQmRm667DkpKYMmSML755hDk550XaVki0rakzkM3sxJCmD/o7nOab08MeHdfYGa3m1kPd383faVKRj3+eLhcv9EFF8DcueFLUBHJC20GupkZcDew0d1vbWWfY4C/urub2TDCJ/+daa1UMmPTJhg4MD4uKwt98rKyqCoSkXZK5hP6COBiYJ2ZrY7N/QToC+Du04FJwBVmtg9oACa7J36TJjnn/ffDhUG1tfG5devglFOiq0lEOiSZs1xeAA65AoG73wbclq6iJIPcw8ISDz0Un3vkEfinf4quJhFJCzVIi8nvfhd64o1h/sMfhoBXmIsUBN2cqxi88AJ86Uvx8bBhYUHmT30quppEJO0U6IVs2zaorDx4rnfvaOoRkYxSy6UQffwxVFU1DfMXXgjtFYW5SMFSoBeaf/s36NIl3GsF4PbbQ5CPGBFtXSKScWq5FIqHH4bJk+Pjiy6C++8HO+QJSiJSQBTo+W7dOjj11Pi4Tx945RXo1i26mkQkEgr0fPXee9CvX7hAqNGmTTBgQHQ1iUik1EPPN/v3w/nnw1FHxcN8/vzQJ1eYixQ1BXo+uflm6NwZnngijH/2sxDk48ZFWpaI5Aa1XPLBokXw1a/Gx+edB089FcJdRCRGiZDL3nwTjjsuPi4pCTfT6tEjuppEJGep5ZKLPvwQPve5pmFeXQ2ffKIwF5FWKdBziTt873vQtSu89lqYu+++MH/66dHWJiI5T4GeK/73f8OdEO+6K4yvuAIOHIBLLom2LhHJG8msWNQHmAkcAxwAZrj7r5vtY8CvgbHAh8C33X1luoudt2obtyysoba+gd5lpUwdNZAJQyrS/TLZ9X//F+5+2Ojkk8NcaWl0NYlIXkrmS9F9wA/dfaWZdQdWmNkid38lYZ8xwIDYzxnAHbF/ps28VduYNmcdDXv3A7CtvoFpc9YB5Geo79gBPXs2nXvrrXCxkIhIO7TZcnH37Y2ftt39fWAj0DxBxwMzPVgGlJlZr3QWesvCmr+HeaOGvfu5ZWFNOl8m8/buhbPPbhrmzz4b+uQKcxHpgJR66GbWHxgCvNxsUwWwJWG8lYNDHzObYmbVZlZdV1eXUqG19Q0pzeek//zPsKjE88+H8S9/GYL83HOjrUtECkLS56GbWTdgNnC1u+9uvrmFXzlokWh3nwHMAKiqqkppEeneZaVsayG8e5flQa/5scdg/Pj4eMIEmD07fAkqIpImSSWKmZUQwvxBd5/Twi5bgT4J40qgtoX92m3qqIGUlnRqMlda0ompowam82XSq6Ym3L62McyPOircVGvuXIW5iKRdm6kSO4PlbmCju9/aym6PAZdYMBzY5e7b01gnE4ZUcOPEQVSUlWJARVkpN04clJtfiO7eDb16wYknxufWr4edO6GsLLKyRKSwJdNyGQFcDKwzs9WxuZ8AfQHcfTqwgHDK4mbCaYuXpb1SQqjnZIA3cocLLwyLTTT64x9h0qToahKRotFmoLv7C7TcI0/cx4Er01VUXrrtNvjBD+LjqVPD3RFFRLJEN+fqqKVL4ayz4uPhw+FPfwpns4iIZJECvb22bYPKyqZztbWhdy4iEgGdapGqjz+GoUObhvmLL4b+ucJcRCKkQE/F1VdDly6walUYT58egvzMMyMtS0QE1HJJzkMPhbNXGl1yCdx7bzjHXEQkRyjQD2XtWhg8OD7u1y+cT96tW3Q1iYi0QoHekr/9Dfr2hQ8+iM+99hqccEJ0NYmItEE99ET798O4cXD00fEwf+KJ0CdXmItIjlOgN7rpJujcGRYsCOPrrw9BPnZstHWJiCRJLZenn4ZRo+Ljr3wlhHpnvTUikl+KN7XefBOOOy4+Pvxw2LoVevSIriYRkQ4ovpbLhx/CgAFNw3zFCvjoI4W5iOS14gl0d/jud6FrV9i8OczNnBnmhw6NtjYRkTQojkC/++6woMQ994TxlVfCgQNw8cXR1iUikkaF3UNfvhzOOCM+PuWUMFeaB8vWiYikqDAD/a9/hWOOaTr39tvhYiERkQKVzBJ095jZDjNb38r2kWa2y8xWx36uTX+ZSdq7N9ybPDHMFy8OfXKFuYgUuGR66PcCo9vYZ6m7nxb7+XnHy2qHn/40LCqxdGkY33prCPJzzomkHBGRbEtmCbrnzax/Fmppn0cfhQkT4uOJE8M6nocVx/e9IiKN0tVDP9PM1gC1wI/cfUNLO5nZFGAKQN+OtkBqauDEE+PjHj3C6Yif/nTHnldEJE+l42PsSqCfuw8GfgvMa21Hd5/h7lXuXlVeXt6+V9u9O/TIE8N8wwaoq1OYi0hR63Cgu/tud98Te7wAKDGzzF1yOWZMOIsFYPbs0Cc/6aSMvZyISL7ocKCb2TFmYekeMxsWe86dHX3eVj3zTPxOiBMnZuxlRETyTZs9dDP7AzAS6GFmW4HrgBIAd58OTAKuMLN9QAMw2d09YxWXlsK10Z0ZKSKSq5I5y+XCNrbfBtyWtopERKRddG6fiEiBUKCLiBQIBbqISIFQoIuIFAgFuohIgVCgi4gUCAW6iEiBUKCLiBQIBbqISIFQoIuIFAgFuohIgVCgi4gUCAW6iEiBUKCLiBQIBbqISIFQoIuIFIg2A93M7jGzHWa2vpXtZma/MbPNZrbWzIamv8xg3qptjLhpMcde8wQjblrMvFXbMvVSIiJ5J5lP6PcCow+xfQwwIPYzBbij42UdbN6qbUybs45t9Q04sK2+gWlz1inURURi2gx0d38e+NshdhkPzPRgGVBmZr3SVWCjWxbW0LB3f5O5hr37uWVhTbpfSkQkL6Wjh14BbEkYb43NHcTMpphZtZlV19XVpfQitfUNKc2LiBSbdAS6tTDnLe3o7jPcvcrdq8rLy1N6kd5lpSnNi4gUm3QE+lagT8K4EqhNw/M2MXXUQEpLOjWZKy3pxNRRA9P9UiIieSkdgf4YcEnsbJfhwC53356G521iwpAKbpw4iIqyUgyoKCvlxomDmDCkxe6OiEjR6dzWDmb2B2Ak0MPMtgLXASUA7j4dWACMBTYDHwKXZarYCUMqFOAiIq1oM9Dd/cI2tjtwZdoqEhGRdtGVoiIiBUKBLiJSIBToIiIFQoEuIlIgLHynGcELm9UBb7fz13sA76axnHTJ1bogd2tTXalRXakpxLr6uXuLV2ZGFugdYWbV7l4VdR3N5WpdkLu1qa7UqK7UFFtdarmIiBQIBbqISIHI10CfEXUBrcjVuiB3a1NdqVFdqSmquvKyhy4iIgfL10/oIiLSjAJdRKRA5FSgd2RBajMbbWY1sW3XZLmui2L1rDWzF81scMK2t8xsnZmtNrPqLNc10sx2xV57tZldm7AtyvdrakJN681sv5kdFduWyferj5k9Z2YbzWyDmV3Vwj5ZP8aSrCvrx1iSdWX9GEuyrqwfY2bWxcyWm9maWF3Xt7BPZo8vd8+ZH+AsYCiwvpXtY4EnCaskDQdejs13Al4HjgM+BawBTspiXV8APhN7PKaxrtj4LaBHRO/XSGB+C/ORvl/N9v0asDhL71cvYGjscXdgU/P/3VEcY0nWlfVjLMm6sn6MJVNXFMdY7JjpFntcArwMDM/m8ZVTn9C9/QtSDwM2u/sb7v4J8FBs36zU5e4vuvt7seEywqpNGZfE+9WaSN+vZi4E/pCu1z4Ud9/u7itjj98HNnLw+rdZP8aSqSuKYyzJ96s1kb5fzWTlGIsdM3tiw5LYT/OzTjJ6fOVUoCehtQWpk16oOgu+S/gvcCMHnjazFWY2JYJ6zoz9CfikmZ0cm8uJ98vMjgBGA7MTprPyfplZf2AI4VNUokiPsUPUlSjrx1gbdUV2jLX1fmX7GDOzTma2GtgBLHL3rB5fbS5wkWNaW5A66YWqM8nMziH8y/bFhOkR7l5rZp8FFpnZq7FPsNmwknDfhz1mNhaYBwwgR94vwp/Cf3b3xE/zGX+/zKwb4V/wq919d/PNLfxKVo6xNupq3Cfrx1gbdUV2jCXzfpHlY8zd9wOnmVkZMNfMTnH3xO+SMnp85dsn9NYWpM7KQtWHYmanAncB4919Z+O8u9fG/rkDmEv40yor3H1345+A7r4AKDGzHuTA+xUzmWZ/Cmf6/TKzEkIIPOjuc1rYJZJjLIm6IjnG2qorqmMsmfcrJuvHWOy564ElhL8OEmX2+ErHlwHp/AH60/qXfONo+oXC8th8Z+AN4FjiXyicnMW6+hLWVP1Cs/muQPeExy8Co7NY1zHELx4bBvwl9t5F+n7Ftn+a0Gfvmq33K/a/fSbwq0Psk/VjLMm6sn6MJVlX1o+xZOqK4hgDyoGy2ONSYClwfjaPr5xquVg7F6R2931m9n1gIeHb4nvcfUMW67oWOBq43cwA9nm4k1pPwp9dEP4Pm+XuT2WxrknAFWa2D2gAJns4eqJ+vwC+Djzt7h8k/GpG3y9gBHAxsC7W5wT4CSEsozzGkqkrimMsmbqiOMaSqQuyf4z1Au4zs06E7scj7j7fzC5PqCujx5cu/RcRKRD51kMXEZFWKNBFRAqEAl1EpEAo0EVECoQCXUSkQCjQRUQKhAJdRKRA/H84RCk4f6IbRAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.scatter(x, y)\n",
    "plt.plot(x, droite(np.array(x)), color='red');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Exemple 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Calculer les droites de meilleur approximation de l'ensemble de points suivant:\n",
    "\n",
    "\\begin{array}{c|cccccccc}\n",
    "x&1&3&4&6&8&9&11&14\\\\\n",
    "\\hline\n",
    "y&1&2&4&4&5&7&8&9\n",
    "\\end{array}\n",
    "ainsi que leurs coefficients de corrélation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 401,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Nous avons 8 points"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import sympy as sp\n",
    "x = sp.Symbol('x', real=True)\n",
    "y = sp.Symbol('y', real=True)\n",
    "\n",
    "xx = sp.Matrix([1,3,4,6,8,9,11,14])\n",
    "yy = sp.Matrix([1,2,4,4,5,7,8,9])\n",
    "n = len(xx)\n",
    "display(Markdown(f\"Nous avons {n} points\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 402,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "n = $8$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "moy(x) = 7$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "moy(y) = $5$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "var(x) = $\\frac{33}{2}$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "var(y) = $7$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "cov(x,y) = $\\frac{21}{2}$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "moy_x = sum(xx)/n\n",
    "moy_y = sum(yy)/n\n",
    "var_x = sum((xi-moy_x)**2 for xi in xx) / n\n",
    "var_y = sum((yi-moy_y)**2 for yi in yy) / n\n",
    "cov_xy = sum((xx[i]-moy_x)*(yy[i]-moy_y) for i in range(n)) / n\n",
    "\n",
    "display(Markdown(f\"n = ${sp.latex(n)}$\"))\n",
    "display(Markdown(f\"moy(x) = {sp.latex(moy_x)}$\"))\n",
    "display(Markdown(f\"moy(y) = ${sp.latex(moy_y)}$\"))\n",
    "display(Markdown(f\"var(x) = ${sp.latex(var_x)}$\"))\n",
    "display(Markdown(f\"var(y) = ${sp.latex(var_y)}$\"))\n",
    "display(Markdown(f\"cov(x,y) = ${sp.latex(cov_xy)}$\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 403,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Coefficient de corrélation $r=\\frac{\\sqrt{462}}{22} \\approx 0.977008420918394$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "r_xy = cov_xy / sp.sqrt(var_x * var_y)\n",
    "display(Markdown(f\"Coefficient de corrélation $r={sp.latex(r_xy)} \\\\approx {r_xy.evalf()}$\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 404,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "$y=\\frac{7 x}{11} + \\frac{6}{11}$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Droite de régression de y en fonction de x\n",
    "\n",
    "gamma_1_xy = cov_xy / var_x\n",
    "gamma_0_xy = moy_y - gamma_1_xy * moy_x\n",
    "\n",
    "line_y = gamma_0_xy + gamma_1_xy * x\n",
    "\n",
    "# display(Markdown(r\"$y=q+mx$\"))\n",
    "# display(Markdown(f\"$m={sp.latex(gamma_1_xy)}$\"))\n",
    "# display(Markdown(f\"$q={sp.latex(gamma_0_xy)}$\"))\n",
    "display(Markdown(f\"$y={sp.latex(line_y)}$\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 405,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "$x=\\frac{3 y}{2} - \\frac{1}{2}$"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Droite de régression de x en fonction de y\n",
    "\n",
    "gamma_1_yx = cov_xy / var_y\n",
    "gamma_0_yx = moy_x - gamma_1_yx * moy_y\n",
    "\n",
    "line_x = gamma_0_yx + gamma_1_yx * y\n",
    "\n",
    "# display(Markdown(r\"$x=q+my$\"))\n",
    "# display(Markdown(f\"$m={sp.latex(gamma_1_yx)}$\"))\n",
    "# display(Markdown(f\"$q={sp.latex(gamma_0_yx)}$\"))\n",
    "display(Markdown(f\"$x={sp.latex(line_x)}$\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 406,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/markdown": [
       "Le produit des pentes est gamma_1_xy * gamma_1_yx = 21/22 et r_xy**2 = 21/22"
      ],
      "text/plain": [
       "<IPython.core.display.Markdown object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "display(Markdown(f\"Le produit des pentes est {gamma_1_xy * gamma_1_yx = } et {r_xy**2 = }\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 407,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "plt.scatter(xx, yy)\n",
    "plt.plot(xx, [line_y.subs(x, xi) for xi in xx], color='red');\n",
    "plt.plot([line_x.subs(y, yi) for yi in yy], yy, color='green')\n",
    "plt.legend([points,'y en fonction de x', 'x en fonction de y'], bbox_to_anchor=(1.05, 1), loc='upper left');"
   ]
  },
  {
   "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
