Notebook originel: exam22.ipynb
Examen Science des données🔗
Date: 08 décembre 2022
Durée: 2 h
[1]:
import numpy as np
import matplotlib.pyplot as plt
[2]:
%matplotlib notebook
Consignes🔗
Créez un répertoire Exam22_NOM_Prenom dans lequel vous travaillerez, et où seront stockés
le notebook jupyter d’analyse (
nom_prenom.ipynb, copié à partir de ce notebook énoncé sans l’extension.orig), que vous complèterez progressivement en ajoutant une ou plusieurs cellules en dessous de chaque question;le package python en développement, selon les instructions ci-dessous.
Vous devez alors mettre ce répertoire sous contrôle git sur un projet dédié sur le serveur https://gitlab.in2p3.fr, et en transmettre l’adresse à y.copin@ipnl.in2p3.fr.
Si, par manque de temps ou de connaissance, vous ne pouvez pas créer un dépôt git, envoyez par mail le notebook et/ou le package (sous forme d’un fichier tar ou zip) à y.copin@ipnl.in2p3.fr (cette solution sera pénalisée dans la notation).
Tests🔗
Ce notebook inclut des tests unitaires vous permettant de tester a minima le code du notebook. Utilisez ces tests pour guider votre développement et vérifier vos résultats. Ne modifiez pas (a fortiori, n’effacez pas) ces tests.
Régression linéaire🔗
Soit un jeu de données de \(N\) points \(\{(x_i, y_i)\}\). La régression linéaire
est définie par
où
Le coefficient de corrélation linéaire est défini par:
Sans détailler les calculs, quelles équations ont conduit à ces estimateurs?
Dans le notebook, écrire une fonction
linregress_1D(x, y)qui, en utilisant uniquement la fonctionnp.mean, retourne \(\hat{a}\), \(\hat{b}\) et \(r\) pour des vecteurs (1D) d’entrée \(x\) et \(y\).
Tester explicitement sur le cas
>>> x = np.arange(10)
>>> y = 3. + 2. * x + np.round(np.sin(x * 10), 3)
et vérifier le résultat avec scipy.stats.linregress.
Faire une figure illustrant les points de données \(\{(x, y)\}\) (
scatter) et la régression linéaire (plot). Ajouter un label sur chacun des axes, un titre à la figure et une légende.
Detrending🔗
Le detrending permet de retirer une composant linéaire d’un jeu de données \(\{y_i\}\):
Écrire une fonction
detrend_1D(y)retournant \(\tilde{y}\) (càd \(y\) duquel a été soustrait sa composante linéaire) et \(r\).
Tester et faire une figure sur le vecteur
yprécédent.
Généralisation multi-dimensionnelle🔗
Écrire la function de régression linéaire
linregress(x, y, axis)pour retourner le résultat de la régression sur les tableauxxetyde rang arbitraire, le long de la dimensionaxis. La fonction doit retourner 3 tableauxa,betrde même rang que les tableaux d’entrée.Par example:
>>> x = np.arange(3*4).reshape((3, 4)) >>> y = 3 + 2 * x >>> linregress(x, y, axis=0) (array([[3., 3., 3., 3.]]), array([[2., 2., 2., 2.]]), array([[1., 1., 1., 1.]])) >>> linregress(x, y, axis=1) (array([[3.], [3.], [3.]]), array([[2.], [2.], [2.]]), array([[1.], [1.], [1.]])) >>> linregress(x, y, axis=2) Traceback (most recent call last): ... AxisError: axis 2 is out of bounds for array of dimension 2
De même, écrire la fonction
detrend(y, axis). Vous pouvez utiliser les lignes suivantes pour générer un indice courant le long de la dimensionaxis:shape = np.ones_like(np.shape(y)) shape[axis] = -1 i = np.arange(np.shape(y)[axis]).reshape(shape)
Ajouter des options suivantes à la fonction
detrend(voir scipy.signal.detrend pour un modèle):type='linear'pour soustraire la composante linéaire \(a + b\,i\) (type='linear'), la composante affine \(b\,i\) (type='affine'), ou uniquement la composante constante \(a\) (type='constant');overwrite=Falsepour réaliser la soustraction sur un nouveau tableau (overwrite=False) ou sur place (overwrite=True)
Si vous n’avez pas réussi à stocker votre package sous
git, envoyer le notebook à y.copin@ipnl.in2p3.fr.
Packaging🔗
Extraire les 4 fonctions précédentes (
linregress_1D,detrend_1D,linregressetdetrend) et les inclure dans un fichierdetrend.py. Il constituera le module de votre package.Documenter (succinctement) le module et les fonctions par des docstrings.
Créer un package
Exam22_Nom_Prenomconstitué du seul moduledetrend.py, avec l’arborescence suivante:Exam22_Nom_Prenom/ ├── detrend_nom_prenom │ ├── detrend.py │ └── __init__.py ├── LICENSE ├── README ├── setup.cfg └── setup.py
avec les fichiers suivants (à adapter à votre contexte):
Ajouter un répertoire
doc/pour configurer et générer la documentation Sphinx du package (voir documentation pyyc). Y inclure votre notebook (sousdoc/notebooks/) dans une section dédiée.Si vous n’avez pas réussi à stocker votre package sous
git, générer un tarball des sources de votre package (duquel vous aurez effacé les répertoires_build/,dist/s’ils existent),$ tar cvzf Exam22_NOM_Prenom.tgz Exam22_NOM_Prenom/
et envoyer le tarball résultant à nouveau à y.copin@ipnl.in2p3.fr.
Tests🔗
Tests unitaires🔗
[3]:
import unittest
import numpy as np
class TestNotebook(unittest.TestCase):
def test_linregress_1D(self):
x = np.arange(10)
self.assertEqual(linregress_1D(x, 3 + 2 * x), (3.0, 2.0, 1.0))
self.assertAlmostEqual(linregress_1D(x, 3 + 2 * x + np.round(np.sin(x * 10), 3)),
(2.8803090909090923, 2.0317757575757573, 0.9925669351010524))
def test_detrend_1D(self):
x = np.arange(5)
np.testing.assert_allclose(detrend_1D(1 + 2 * x), [0., 0., 0., 0., 0.])
np.testing.assert_allclose(
detrend_1D(x**0.5),
[-0.28284271, 0.24395221, 0.18496069, 0.02959285, -0.17566304])
def test_linregress(self):
x = np.arange(3*4).reshape((3, 4))
y = 3 + 2 * x
np.testing.assert_allclose(
linregress(x, y, axis=0),
([[3., 3., 3., 3.]],
[[2., 2., 2., 2.]],
[[1., 1., 1., 1.]]))
np.testing.assert_allclose(
linregress(x, y, axis=0),
([[3., 3., 3., 3.]],
[[2., 2., 2., 2.]],
[[1., 1., 1., 1.]]))
np.testing.assert_allclose(
linregress(x, y, axis=1),
([[3.], [3.], [3.]],
[[2.], [2.], [2.]],
[[1.], [1.], [1.]]))
with self.assertRaises(np.AxisError):
linregress(x, y, axis=2)
def test_detrend(self):
x = np.arange(3*4).reshape((3, 4))
y = 3 + 2 * x
np.testing.assert_allclose(detrend(y, axis=0), 0.)
np.testing.assert_allclose(detrend(y, axis=1), 0.)
with self.assertRaises(IndexError):
detrend(y, axis=2)
unittest.main(argv=[''], verbosity=2, exit=False)
test_detrend (__main__.TestNotebook) ... ERROR
test_detrend_1D (__main__.TestNotebook) ... ERROR
test_linregress (__main__.TestNotebook) ... ERROR
test_linregress_1D (__main__.TestNotebook) ... ERROR
======================================================================
ERROR: test_detrend (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/ipykernel_364400/4254163955.py", line 43, in test_detrend
np.testing.assert_allclose(detrend(y, axis=0), 0.)
NameError: name 'detrend' is not defined
======================================================================
ERROR: test_detrend_1D (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/ipykernel_364400/4254163955.py", line 14, in test_detrend_1D
np.testing.assert_allclose(detrend_1D(1 + 2 * x), [0., 0., 0., 0., 0.])
NameError: name 'detrend_1D' is not defined
======================================================================
ERROR: test_linregress (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/ipykernel_364400/4254163955.py", line 23, in test_linregress
linregress(x, y, axis=0),
NameError: name 'linregress' is not defined
======================================================================
ERROR: test_linregress_1D (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/ipykernel_364400/4254163955.py", line 8, in test_linregress_1D
self.assertEqual(linregress_1D(x, 3 + 2 * x), (3.0, 2.0, 1.0))
NameError: name 'linregress_1D' is not defined
----------------------------------------------------------------------
Ran 4 tests in 0.004s
FAILED (errors=4)
[3]:
<unittest.main.TestProgram at 0x7efbd41636d0>
[ ]:
Cette page a été générée à partir de
exam22.ipynb.