{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Coder une variable aléatoire\n",
    "\n",
    "Marc Lorenzi - 9 juin 2018"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "from fractions import Fraction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Dans ce notebook nous allons mettre en place quelques fonctions permettant de coder simplement et élégamment la loi d'une variable aléatoire. Nous verrons que notre codage s'adapte immédiatement à la représentation d'un couple de variables aléatoires et permet de calculer facilement espérance, variance, covariance et tout un tas d'autres choses.\n",
    "\n",
    "Un autre titre pour ce notebook pourrait être : __dictionnaires__."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Coder la loi d'une variable aléatoire"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour coder la loi d'une variable aléatoire $X$ (prenant un nombre fini de valeurs, cela va de soi), nous allons utiliser un __dictionnaire__ que nous noterons comme la variable aléatoire, $X$. Bref, nous oublierons l'ensemble de départ de $X$ pour ne garder que sa loi. Les clés du dictionnaire sont les valeurs prises par $X$ et pour toute clé $x$, $X[x]=P[X=x]$.\n",
    "\n",
    "Nous allons coder les lois usuelles dans la suite de cette section."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 Loi de Bernoulli"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Commençons par la loi de Bernoulli de paramètre $p\\in[0,1]$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Bernoulli(p):\n",
    "    return {0:1-p, 1:p}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Bernoulli(Fraction(1,3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.2 Les dictionnaires en Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La structure de dictionnaire permet d'associer des __valeurs__ à des objets, les __clés__ du dictionnaire. Les clés peuvent être à peu près n'importe quoi (ce n'est pas tout à fait vrai mais n'entrons pas dans les détails), les valeurs aussi.\n",
    "\n",
    "Quelques fonctions permettent de travailler avec les dictionnaires. Nous venons de voir comment en initialiser un dans la fonction `Bernoulli`. Si $d$ est un dictionnaire, voici quelques méthodes associées :\n",
    "\n",
    "- Obtenir la valeur associée à une clé $k$ : `d[k]`\n",
    "- Associer à la clé $k$ la valeur $v$ : `d[k]=v`\n",
    "- Le dictionnaire $d$ a-t-il la clé $k$ ? `k in d`\n",
    "- Supprimer la clé $k$ : `del d[k]`\n",
    "- Itérer sur l'ensemble des clés : `for k in d ...`\n",
    "\n",
    "Les trois méthodes ci-dessous renvoient des objets de type `view`. Je ne précise pas plus avant.\n",
    "\n",
    "- Obtenir toutes les clés : `d.keys()`. Une instruction du type `list(d.keys())` renvoie la liste des clés.\n",
    "- Obtenir toutes les valeurs : `d.values()`\n",
    "- Obtenir tous les couples (clé, valeur) : `d.items()`\n",
    "\n",
    "et encore bien d'autres méthodes. Consultez la documentation de Python.\n",
    "\n",
    "En exemple, voici en une ligne l'ensemble des valeurs prises par une variable aléatoire codée avec notre modèle :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def valeurs_prises(X):\n",
    "    return list(X.keys())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "valeurs_prises(Bernoulli(Fraction(1, 3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et voici une fonction qui vérifie si une variable aléatoire en est bien une."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def est_va(X):\n",
    "    s = 0\n",
    "    for x in X:\n",
    "        if X[x] < 0 or X[x] > 1: return False\n",
    "        s = s + X[x]\n",
    "    return s == 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "est_va(Bernoulli(Fraction(1,3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.3 Fonctions utiles"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Avant de passer aux lois binomiale et hypergéométrique, définissons quelques fonctions bien utiles."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction `power_dn` prend en paramètres deux entiers $n$ et $k$ et renvoie $(n)_k=n(n-1)\\ldots(n-k+1)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def power_dn(n, k):\n",
    "    p = 1\n",
    "    for i in range(k):\n",
    "        p = p * (n - i)\n",
    "    return p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "power_dn(6, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction `factorial` calcule ... la factorielle de l'entier $n$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def factorial(n):\n",
    "    return power_dn(n, n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "factorial(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et enfin, la fonction `binom` prend deux entiers $n$ et $k$ en paramètres et renvoie le coefficient binomial $\\binom n k$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def binom(n, k):\n",
    "    return power_dn(n, k) // factorial(k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "binom(6, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquons que cette fonction marché très bien même si $k > n$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "binom(5, 12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.4 La loi binomiale"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La fonction `Binomial` prend en paramètres un entier $n$ et un réel $p\\in[0,1]$  et renvoie (la loi d') une variable aléatoire suivant la loi binomiale $\\mathcal B(n, p)$. Dans la suite j'abuserai et j'identifierai la variable aléatoire et sa loi."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Binomial(n, p):\n",
    "    X = {}\n",
    "    for k in range(n + 1):\n",
    "        X[k] = binom(n, k) * p ** k * (1 - p) ** (n - k)\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Binomial(5, Fraction(1, 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "est_va(_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.5 La loi hypergéométrique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soient $r,n,N$ trois entiers tels que $r,n\\le N$. La loi hypergéométrique de paramètres $r, n, N$ est définie ainsi :   pour $0\\le k\\le n$,\n",
    "$$P(X=k)=\\frac{\\binom r k \\binom {N-r}{n-k}}{\\binom N n}$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def Hypergeom(r, n, N):\n",
    "    X = {}\n",
    "    for k in range(n + 1):\n",
    "        X[k] = Fraction(binom(r, k) * binom(N - r, n - k), binom(N, n))\n",
    "    return X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Exemple__ : une urne contient $N=20$ boules. Parmi celles-ci, $r=8$ boules sont rouges. On tire $n=10$ boules dans l'urne __sans remise__. Soit $X$ le nombre de boules rouges tirées. Alors $X$ suit une loi hypergéométrique $\\mathcal H(r,n,N)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Hypergeom(8, 10, 20)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Remarquez que les événements $\\{X=9\\}$ et $\\{X=10\\}$ sont de probabilité nulle, ce qui est heureux puisqu'ils sont vides."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "est_va(_)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Espérance, variance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1 Formule de transfert"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Au lieu de réécrire plusieurs fois la même chose, codons une fonction très générale `gen_esp`. Cette fonction prend en paramètres une fonction $f:\\mathbb R\\to\\mathbb R$ et une variable aléatoire réelle $X$. Elle renvoie $E(f(X))$, l'espérance de la variable aléatoire $f(X)$.\n",
    "\n",
    "Comment ? Eh bien mettons que $X:\\Omega\\to\\mathbb R$. Le théorème de transfert nous dit que\n",
    "\n",
    "$$E(f(X))=\\sum_{x\\in X(\\Omega)}f(x)P(X=x)$$\n",
    "\n",
    "La fonction `gen_esp` est donc facile à écrire."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def gen_esp(f, X):\n",
    "    s = 0\n",
    "    for x in X:\n",
    "        s = s + f(x) * X[x]\n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gen_esp(lambda x:  x ** 2, Binomial(5, Fraction(1, 3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2 Moments d'une variable aléatoire réelle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Définition__ : Pour tout entier $n\\in\\mathbb N$, le moment d'ordre $n$ de la variable aléatoire $X$ est l'espérance de $X^n$ :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def moment(X, n):\n",
    "    return gen_esp(lambda x: x ** n, X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "moment(Binomial(5, Fraction(1, 3)), 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 Espérance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L'espérance est donc le moment d'ordre 1 !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def esperance(X):\n",
    "    return moment(X, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "esperance(Binomial(5, Fraction(1, 3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On retrouve le résultat bien connu. Si $X$ suit une loi binomiale $\\mathcal B(n,p)$, alors $E(X)=np$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "esperance(Hypergeom(8, 10, 20))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On retrouve le résultat moins bien connu. Si $X$ suit une loi hypergéométrique $\\mathcal H(r, n, N)$, alors $E(X)=\\frac {nr} N$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.4 Variance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et voici en une ligne la variance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def variance(X):\n",
    "    return moment(X, 2) - esperance(X) ** 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "variance(Binomial(5, Fraction(1, 3)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Le résultat général pour la loi binomiale $\\mathcal B(n,p)$ est $V(X)=np(1-p)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "variance(Hypergeom(8, 10, 20))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Le résultat général pour la loi hypergéométrique $\\mathcal H(r,n,H)$ est $V(X)=np(1-p)\\frac{N-n}{N-1}$ où $p=\\frac r N$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "p = Fraction(8, 20)\n",
    "10 * p * (1 - p) * Fraction(20 - 10, 20 - 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On a bien sûr pour pas cher l'écart-type d'une variable aléatoire."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ecart_type(X):\n",
    "    return sqrt(variance(X))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Exercice__ : Le __moment centré__ d'ordre $n$ d'une variable aléatoire réelle est $M_n(X)=E(X-E(X))^n$. Écrire une fonction `moment_centré(X, n)`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Couples de variables aléatoires"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Comment coder un couple de variables aléatoires ? Mais dans un dictionnaire bien entendu ! Sauf que cette fois-ci, les clés du dictionnaire sont des couples."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.1 L'exemple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous allons travailler sur l'exemple de la loi du couple $(X,Y)$ où $X$ est l'ordre d'une permutation de $\\mathfrak S_6$ et $Y$ est le nombre d'orbites non triviales de la permutation. Il nous faut d'abord trouver la loi conjointe. Pour cela, listons toutes les permutations de $\\mathfrak S_6$ (il y en a $6!=720$) par la nature de leur décomposition en produit de cycles de supports disjoints. Dans l'ordre ci-dessous : le type de permutation, entre parenthèses le nombre de telles permutations, puis leur ordre et leur nombre d'orbites.\n",
    "\n",
    "- $id$ : $(1)\\ 1, 0$\n",
    "- $(ij)$ : $(15)\\ 2, 1$\n",
    "- $(ijk)$ : $(40)\\ 3, 1$\n",
    "- $(ijkl)$ : $(90)\\ 4, 1$\n",
    "- $(ijklm)$ : $(144)\\ 5, 1$\n",
    "- $(ijklmn)$ : $(120)\\ 6, 1$\n",
    "- $(ij)(kl)$ : $(45)\\ 2, 2$\n",
    "- $(ij)(kl)(mn)$ : $(15)\\ 2, 3$\n",
    "- $(ijk)(lm)$ : $(120)\\ 6, 2$\n",
    "- $(ijk)(lmn)$ : $(40)\\ 3, 2$\n",
    "- $(ijkl)(mn)$ : $(90)\\ 4, 2$\n",
    "\n",
    "Au lecteur le soin de vérifier tous ces chiffres. C'est un excellent exercice."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "XY = {\n",
    "    (1,0): Fraction(1, 720),\n",
    "    (2,1): Fraction(15, 720),\n",
    "    (3,1): Fraction(40, 720),\n",
    "    (4,1): Fraction(90, 720),\n",
    "    (5,1): Fraction(144, 720),\n",
    "    (6,1): Fraction(120, 720),\n",
    "    (2,2): Fraction(45, 720),\n",
    "    (2,3): Fraction(15, 720),\n",
    "    (6,2): Fraction(120, 720),\n",
    "    (3,2): Fraction(40, 720),\n",
    "    (4,2): Fraction(90, 720)\n",
    "    \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 Lois marginales"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Soit $Z=(X, Y)$ un couple de variables aléatoires réelles. Connaissant la loi de $Z$, commet calculer la loi de $X$ ? \n",
    "\n",
    "Il suffit de sommer sur les valeurs prises par $Y$ : \n",
    "\n",
    "$$P(X=x)=\\sum_y P(X=x, Y=y)$$\n",
    "\n",
    "où $y$ varie dans l'ensemble des valeurs prises par $Y$. On obtient évidemment, en sommant sur $x$, la loi de $Y$. La fonction `loi_marginale` fait le travail. Elle prend un paramètre $Z$ (représentant un couple $(X, Y)$ de variables aléatoires) et un entier $j$ qui vaut 0 ou 1. Si $j=0$ la fonction renvoie la loi de $X$. Si $j=1$ elle renvoie la loi de $Y$. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loi_marginale(Z, j):\n",
    "    X = {}\n",
    "    for t in Z:\n",
    "        x = t[j]\n",
    "        if x in X: X[x] = X[x] + Z[t]\n",
    "        else: X[x] = Z[t]\n",
    "    return X"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reprenons notre exemple fétiche."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = loi_marginale(XY, 0)\n",
    "print(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Y = loi_marginale(XY, 1)\n",
    "print(Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Petite vérification ?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "est_va(X), est_va(Y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tout va bien. Au passage :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(esperance(X), variance(X))\n",
    "print(esperance(Y), variance(Y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 Covariance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Étant données deux variables aléatoires $X$ et $Y$, leur covariance est $Cov(X, Y)=E(XY)-E(X)E(Y)$. Avec un peu de réflexion on se rend compte que pour calculer $E(XY)$ il suffit d'utiliser la fonction `gen_esp` que nous avons déjà vue, sauf que maintenant la fonction $f$ est une \"fonction de deux variables\" ! Bref, tout est déjà écrit, il suffit de recoller les morceaux."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def covariance(Z):\n",
    "    EX = esperance(loi_marginale(Z, 0))\n",
    "    EY = esperance(loi_marginale(Z, 1))\n",
    "    EXY = gen_esp(lambda z: z[0] * z[1], Z)\n",
    "    return EXY - EX * EY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "covariance(XY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "float(_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(ecart_type(X) * ecart_type(Y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pourquoi ce dernier calcul ? Rappelons-nous : étant données deux variables aléatoires $X$ et $Y$ on a $|Cov(X,Y)|\\le\\sigma(X)\\sigma(Y)$, le produit de leurs écarts-types. Si $X$ et $Y$ ont des écarts-types non nuls, on pose\n",
    "$$\\rho(X,Y)=\\frac{Cov(X,Y)}{\\sigma(X)\\sigma(Y)}$$\n",
    "\n",
    "__Proposition__ : \n",
    "\n",
    "- $-1\\le\\rho(X,Y)\\le 1$\n",
    "- $\\rho(X,Y)=\\pm 1$ si et seulement si il existe trois réels $a, b, c$, $(a,b)\\ne(0,0)$ tels que $aX+bY+c=0$ presque sûrement.\n",
    "- Si $X$ et $Y$ sont indépendantes, $\\rho(X,Y)=0$.\n",
    "\n",
    "__Démonstration__ : faite en cours.\n",
    "\n",
    "__Définition__ $\\rho(X, Y)$ est le coefficient de corrélation des variables $X$ et $Y$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def correlation(Z):\n",
    "    X = loi_marginale(Z, 0)\n",
    "    Y = loi_marginale(Z, 1)\n",
    "    return covariance(Z) / (ecart_type(X) * ecart_type(Y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et pour finir, le coefficient de corrélation de la signature et de l'ordre dans $\\mathfrak S_5$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "correlation(XY)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Que signifie cette valeur ? Traçons les couples $(x,y)$ des valeurs prises par le couple $(X,Y)$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sx = [x for (x,y) in XY]\n",
    "sy = [y for (x,y) in XY]\n",
    "plt.plot(sx, sy, 'o')\n",
    "plt.grid()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "si notre coefficient de corrélation était $\\pm 1$, les points seraient alignés. Un coefficient de 0 indiquerait des points \"un peu n'importe comment\". Ici, je n'ose rien dire :-)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "__Mini projet__ : automatiser tout cela dans $\\mathfrak S_n$ (avec $n$ quelconque mais raisonnable, cela va de soi). Voici un plan possible :\n",
    "\n",
    "- Écrire une fonction qui calcule toutes les permutations de $\\mathfrak S_n$.\n",
    "- Utiliser pour le reste des étapes les fonctions qui ont été écrites dans le notebook dédié aux permutations."
   ]
  },
  {
   "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.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
