Last active
March 15, 2018 12:23
-
-
Save nicofarr/3cb15c558d9f7241cf832d9c76ba16f1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Projet [Br.A.In.](www.brain.bzh) \n", | |
| "--\n", | |
| "Exercices - candidature de Wassim Barhi\n", | |
| "\n", | |
| "Merci de télécharger ce fichier .ipynb et de le renvoyer complété au plus tard le *Mardi 21 Mars 2018 à 23h59* à l'email [email protected]\n", | |
| "\n", | |
| "La partie 1 est composée de questions portant sur [cet article](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5623038/) à propos des modèles d'encodage et de décodage. \n", | |
| "\n", | |
| "La partie 2 porte sur l'utilisation de numpy, scipy, librosa et matplotlib.\n", | |
| "\n", | |
| "**Ressources : **\n", | |
| "\n", | |
| "Afin de pouvoir compléter ce notebook, il vous faudra un environnement python ainsi que les paquets suivants : \n", | |
| "\n", | |
| "- jupyter\n", | |
| "- matlplotlib\n", | |
| "- numpy\n", | |
| "- scipy\n", | |
| "- [librosa](http://librosa.github.io/librosa/index.html)\n", | |
| "\n", | |
| "\n", | |
| "Nous conseillons l'installer d'un environnement virtuel avec miniconda, puis d'installer les paquets avec pip. \n", | |
| "\n", | |
| "Un bon tutorial de Jupyter Notebook se trouve [ici](https://nbviewer.jupyter.org/github/jupyter/notebook/blob/master/docs/source/examples/Notebook/Running%20Code.ipynb) et [ici](https://nbviewer.jupyter.org/github/ipython/ipython/blob/master/examples/IPython%20Kernel/Index.ipynb). \n", | |
| "\n", | |
| "Pour approfondir les jupyter notebook : une collection de [ressources](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks#introductory-tutorials)\n", | |
| "\n", | |
| "\n", | |
| "Concernant Matplotlib, numpy et scipy, voir les [scipy lectures](https://www.scipy-lectures.org/index.html)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Partie 1 \n", | |
| "--\n", | |
| "Question 1\n", | |
| "--\n", | |
| "On réalise une expérience d'Electroencéphalographie (EEG) pendant laquelle des sujets humains écoutent des extraits de musique de genre différents (rock, pop, jazz, classique). Chaque extrait dure 30 secondes, n'est présenté qu'une seule fois, et on dispose de 10 extraits par genre. 20 sujets participent à cette expérience. \n", | |
| "\n", | |
| "La question de recherche posée est de tester la reconnaissance du genre musical à partir de l'activité cérébrale. \n", | |
| "\n", | |
| "1. Faut-il estimer un modèle d'encodage (encoding model) ou de décodage (decoding model) ? \n", | |
| "2. En supposant que la méthode de prétraitement des données à déjà été définie, et en faisant l'hypothèse que l'on peut utiliser indifférement les données des différents sujets (on ignore la variabilité inter sujets), proposer un paradigme d'apprentissage supervisé permettant de valider un tel modèle. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Réponse à la question 1 : " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Question 2\n", | |
| "--\n", | |
| "On mesure l'activité cérébrale (EEG, 256 électrodes échantillonnées à 1024 Hz) pendant l'écoute continue de longs extraits de musique. Pour chacun de ces extraits, un vecteur de caractéristiques musicales a été estimé, pour chaque pas temporel $t$ (ex : clarté de la tonalité, clarté de la pulsation, \"brightness\", \"fullness\", ... cf MIR Toolbox et Alluri et al. 2013). On considère avoir sous-échantilloné l'EEG pour que chaque échantillon corresponde à (et soit synchronisé avec) le vecteur de caractéristiques musicales. On note alors $X_e(t)$ le vecteur de l'activité EEG à l'instant $t$, et $M(t)$ le vecteur de caractéristiques musicales. \n", | |
| "\n", | |
| "Décrire les étapes principales à mettre en oeuvre pour estimer un modèle d'encodage (par sujet) permettant de prédire l'activité cérébrale à partir des caractéristiques musicales. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Réponse à la question 2 :" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Partie 2 \n", | |
| "--" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "En utilisant numpy et le module random, définir deux vecteurs $X_1$ et $X_2$ de taille $N$ (paramétrable) ayant une distribution normale standard." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "import numpy as np \n", | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Utiliser matplotlib et le module pyplot pour représenter les histogrammes des distributions de ces deux vecteurs. \n", | |
| "De manière préférable, utiliser des subplots, des noms pour les plots et leurs axes. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 116, | |
| "metadata": { | |
| "collapsed": false, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "import matplotlib.pyplot as plt \n", | |
| "%matplotlib inline\n", | |
| "\n", | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Utiliser scipy pour lire le fichier audio \"1.wav\" inclus dans le répertoire. \n", | |
| "\n", | |
| "Quelle est la fréquence d'échantillonnage ainsi que la durée (en secondes) de ce fichier ? \n", | |
| "\n", | |
| "Il s'agit d'un échantillon stéréo. Utiliser numpy pour calculer la moyenne des canaux gauche et droite, et représenter la forme d'onde mono résultante par un graphe du signal en fonction du temps" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 115, | |
| "metadata": { | |
| "collapsed": false, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from scipy.io.wavfile import read\n", | |
| "\n", | |
| "### A COMPLETER\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Utiliser la fonction beat_track de librosa afin d'estimer conjointement le tempo de cet échantillon, ainsi que la position des \"beats\". " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 40, | |
| "metadata": { | |
| "collapsed": false, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from librosa.beat import beat_track\n", | |
| "\n", | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Superposer la visualisation du signal mono avec les positions des beats. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": false, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Utiliser l'algorithme Harmonic-Percussive Source Separation (HPSS) de librosa afin de séparer les composantes percussives et harmoniques du signal mono. \n", | |
| "\n", | |
| "Représenter les deux composantes obtenues en les superposant avec les beats détectés précédemment. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 56, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from librosa.effects import hpss\n", | |
| "\n", | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Nous allons tenter de vérifier si la composante percussive correspond bien à la détection des \"beats\" effectuée précedemment. Pour cela, une méthode simple consisterait à étudier la corrélation entre chacune des composantes et un signal représentant la position des beats. \n", | |
| "\n", | |
| "Utiliser scipy pour calculer les coefficients de corrélations de Pearson $r$ et leurs p-value $p$ entre chaque composante, et la série temporelle comportant des 1 aux positions des beats, et des 0 aux autres positions. \n", | |
| "\n", | |
| "Pour créer cette dernière, vous pouvez utiliser la fonction zeros_like de numpy afin de créer un signal de la bonne taille, puis utiliser le vecteur de positions des beats pour mettre à 1 les éléments correspondants. Le signal obtenu est un *modèle* de la position des beats. \n", | |
| "\n", | |
| "Que remarquez-vous concernant les valeurs obtenues de r et p? " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 66, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from scipy.stats import pearsonr\n", | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Les valeurs obtenues correspondent au coefficient de corrélation estimé sur le signal entier. Qu'en est-il si l'on étudie uniquement des portions du signal total ? Refaire l'étape précédente en ne considérant par exemple que la deuxième moitié du signal. " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "\n", | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Maintenant, au lieu d'estimer un seul coefficient de corrélation et p-value, utiliser une fenêtre glissante de largeur $L$ échantillons, se déplaçant avec un pas de $P$ échantillons, et estimer un couple (r,p) pour chaque pas temporel correspondant à chaque pas de la fenêtre glissante. \n", | |
| "\n", | |
| "Une implementation de fenêtre glissante en numpy peut être trouvée [ici](https://gist.github.com/nils-werner/9d321441006b112a4b116a8387c2280c) et est recopiée ci-dessous : " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 82, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "def sliding_window(data, size, stepsize=1, padded=False, axis=-1, copy=False):\n", | |
| " \"\"\"\n", | |
| " Calculate a sliding window over a signal\n", | |
| " Parameters\n", | |
| " ----------\n", | |
| " data : numpy array\n", | |
| " The array to be slided over.\n", | |
| " size : int\n", | |
| " The sliding window size\n", | |
| " stepsize : int\n", | |
| " The sliding window stepsize. Defaults to 1.\n", | |
| " axis : int\n", | |
| " The axis to slide over. Defaults to the last axis.\n", | |
| " copy : bool\n", | |
| " Return strided array as copy to avoid sideffects when manipulating the\n", | |
| " output array.\n", | |
| " Returns\n", | |
| " -------\n", | |
| " data : numpy array\n", | |
| " A matrix where row in last dimension consists of one instance\n", | |
| " of the sliding window.\n", | |
| " Notes\n", | |
| " -----\n", | |
| " - Be wary of setting `copy` to `False` as undesired sideffects with the\n", | |
| " output values may occurr.\n", | |
| " Examples\n", | |
| " --------\n", | |
| " >>> a = numpy.array([1, 2, 3, 4, 5])\n", | |
| " >>> sliding_window(a, size=3)\n", | |
| " array([[1, 2, 3],\n", | |
| " [2, 3, 4],\n", | |
| " [3, 4, 5]])\n", | |
| " >>> sliding_window(a, size=3, stepsize=2)\n", | |
| " array([[1, 2, 3],\n", | |
| " [3, 4, 5]])\n", | |
| " See Also\n", | |
| " --------\n", | |
| " pieces : Calculate number of pieces available by sliding\n", | |
| " \"\"\"\n", | |
| " if axis >= data.ndim:\n", | |
| " raise ValueError(\n", | |
| " \"Axis value out of range\"\n", | |
| " )\n", | |
| "\n", | |
| " if stepsize < 1:\n", | |
| " raise ValueError(\n", | |
| " \"Stepsize may not be zero or negative\"\n", | |
| " )\n", | |
| "\n", | |
| " if size > data.shape[axis]:\n", | |
| " raise ValueError(\n", | |
| " \"Sliding window size may not exceed size of selected axis\"\n", | |
| " )\n", | |
| "\n", | |
| " shape = list(data.shape)\n", | |
| " shape[axis] = np.floor(data.shape[axis] / stepsize - size / stepsize + 1).astype(int)\n", | |
| " shape.append(size)\n", | |
| "\n", | |
| " strides = list(data.strides)\n", | |
| " strides[axis] *= stepsize\n", | |
| " strides.append(data.strides[axis])\n", | |
| "\n", | |
| " strided = np.lib.stride_tricks.as_strided(\n", | |
| " data, shape=shape, strides=strides\n", | |
| " )\n", | |
| "\n", | |
| " if copy:\n", | |
| " return strided.copy()\n", | |
| " else:\n", | |
| " return strided" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "source": [ | |
| "Utiliser cette fonction pour étudier comment varie en fonction du temps la corrélation entre la composante percussive et le signal modélisant la position des beats. \n", | |
| "\n", | |
| "Il sera nécessaire de rajouter une petite quantité de bruit sur le signal des beats, afin d'éviter que certaines portions ne soient composées que de 0 (auquel cas il est impossible de calculer la corrélation). \n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true, | |
| "deletable": true, | |
| "editable": true | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "### A COMPLETER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Ouvertures: \n", | |
| "\n", | |
| "1. Comment serait-il possible de \"lisser\" le signal modélisant les beats ? \n", | |
| "2. Quels autres types d'analyses permettraient de confirmer le lien entre le signal modélisant les beats et la composante percussive ? " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "collapsed": true | |
| }, | |
| "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.1" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 2 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment