5.3. TP analyse de données avec numpy#
Marc BUFFAT, dpt mécanique, Université Lyon 1

Pour indiquer que vous avez compris les consignes (la charte du cours) sur les IA Génératives, veuillez recopier le texte ci-dessus dans la variable acceptation dans la cellule suivante.
acceptation=""
## BEGIN SOLUTION
## END SOLUTION
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
# police des titres
plt.rc('font', family='serif', size='18')
from IPython.display import display, Markdown, clear_output
from validation.valide_markdown import test_markdown, test_code, test_algorithme
from validation.validation import info_etudiant
def printmd(string):
display(Markdown(string))
# test si numero étudiant spécifier
try: NUMERO_ETUDIANT
except NameError: NUMERO_ETUDIANT = None
if type(NUMERO_ETUDIANT) is not int :
NOM, PRENOM, NUMERO_ETUDIANT = info_etudiant()
# parametres spécifiques
_uid_ = NUMERO_ETUDIANT
np.random.seed(_uid_)
printmd("**Etudiant** {} {} id={}".format(NOM,PRENOM,NUMERO_ETUDIANT))
# parametres
_i1 = 5 + np.random.randint(10)
_i2 = 146 - np.random.randint(10)
_an = 2030 + np.random.randint(10)
# generation du fichier de donnees
cde="'1,{}d;{},$d'".format(_i1,_i2)
#print("cde:",cde)
!sed $cde ./data/land_global_temperature_anomaly.csv > ./data/anomalie_temperature.csv
printmd("**Estimation de la hausse des température en {}**".format(_an))
Etudiant Marc BUFFAT id=137764122
Estimation de la hausse des température en 2036
5.3.1. Objectifs#
Apprendre à lire des données dans un fichier, les analyser et les traiter pour en déduire des prédictions.
La démarche consiste en
lecture des données
analyse des données
détermination d’une loi simple
prédiction à partir de cette loi
analyse des résultats
application
problème du réchauffement climatique.
5.3.2. Étape 1: lecture des données#
Dans le répertoire data, le fichier anomalie_temperature.csv contient des mesures annuelles du réchauffement climatique, i.e. l’écart de température annuelle du globe par rapport à une moyenne climatique. Dans la suite on appelle anomalie climatique cet écart.
En utilisant la commande unix/linux head mon_fichier, on affiche les 10 premières lignes du fichier ./data/anomalie_temperature.csv dans la cellule ci-dessous
Attention vous n’avez pas tous les mêmes données, donc ne vous contentez pas de comparer les résultats bruts, mais essayer de comprendre la méthode.
!head "./data/anomalie_temperature.csv"
1883,-0.28
1884,-0.24
1885,-0.45
1886,-0.18
1887,-0.52
1888,-0.33
1889,-0.03
1890,-0.34
1891,-0.40
1892,-0.24
5.3.2.1. lecture du fichier#
Pour charger les données à partir du fichier, nous utiliserons la fonction numpy.loadtxt(), qui nous permet de charger directement les données lues dans des tableaux NumPy en spécifiant comme paramètre le nom du fichier
en tant que chaîne de caractères.
Les données sont séparées par des , et on veut enregistrer directement les données dans les deux tableaux annee et anomalie_temp. On va donc fournir des arguments à la fonction np.loadtxt pour l’utiliser (voir la documentation de loadtxt)
annee, anomalie_temp = np.loadtxt("nom du fichier", delimiter=',', unpack=True)
Dans la cellule suivante,
importer la bibliothèque numpy.
écrire le code python pour lire les données dans les deux tableaux
anneeetanomalie_tempvérifier le type et la taille des tableaux et afficher les 10 premières valeurs des tableaux pour comparer avec head
import numpy as np
annee = 0
anomalie_temp = 0
### BEGIN SOLUTION
### END SOLUTION
5.3.3. Étape 2: tracer des données#
Utiliser ensuite la fonction
plot()pour tracer l’anomalie de température en fonction de l’année,Ajouter un titre,
Ajouter des labels pour les axes.
%matplotlib inline
import matplotlib.pyplot as plt
# police des titres
plt.rc('font', family='serif', size='18')
### BEGIN SOLUTION
### END SOLUTION
5.3.4. Etape 3: régression linéaire par moindres carrés#
Les données brutes étant très fluctuantes, on va lisser les données d’anomalie de température par une droite, pour en déduire l’évolution de la température terrestre. Nous utiliserons la régression linéaire par moindres carrés pour calculer la pente \(a_1\) et la constante \(a_0\)
avec pour expression des coefficients \(a_1\) et \(a_0\):
La notation \(\bar{x}\) signifie la moyenne des valeurs de x. Dans notre cas, les données x sont dans le tableau annee, et les données y sont dans le tableau anomalie_temp. Pour calculer nos coefficients avec la formule ci-dessus, nous avons besoin des valeurs moyennes des données. Comme nous devons calculer la moyenne à la fois pour x ety, il est utile d’écrire une fonction Python personnalisée valeur_moyenne qui calcule la moyenne pour n’importe quel tableau, que l’on peut ensuite réutiliser.
5.3.4.1. Question 1: écriture de la fonction valeur_moyenne#
On veut définir une fonction valeur_moyenne qui calcule la valeur moyenne de n’importe quel tableau TAB passé en argument. On devra utiliser une boucle sur les valeurs du tableau et ne pas utiliser la méthode .mean() de numpy qui calcule la moyenne arithmétique d’un tableau.
Dans la première cellule ci-dessous
Écrire la fonction Python
valeur_moyenne(TAB)(sans utilisermean) qui calcule la moyenne du tableau TAB passé en argument et renvoie la valeur moyenne de ce tableau.
Dans la deuxième cellule ci-dessous
Créer un tableau X contenant 11 nombres équi-répartis entre 1 et 3.
Calculer et affecter dans Xm la valeur moyenne du tableau X avec la fonction
valeur_moyenne.Faire afficher la valeur de Xm.
Mettre une phrase de commentaire (en utilisant le symbole #) pour dire si la valeur de Xm vous semble cohérente.
# fonction valeur_moyenne(TAB)
### BEGIN SOLUTION
### END SOLUTION
# utilisation de la fonction valeur_moyenne en l'appelant avec son argument
X = None
Xm = 0
### BEGIN SOLUTION
### END SOLUTION
# ne pas modifier la cellule
### BEGIN HIDDEN TESTS
assert(np.isclose(valeur_moyenne(np.linspace(1,3,11)),2.0))
assert(test_code("TP_regression_lineaire.ipynb","cell-verif0","valeur_moyenne"))
### END HIDDEN TESTS
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[8], line 3
1 # ne pas modifier la cellule
2 ### BEGIN HIDDEN TESTS
----> 3 assert(np.isclose(valeur_moyenne(np.linspace(1,3,11)),2.0))
4 assert(test_code("TP_regression_lineaire.ipynb","cell-verif0","valeur_moyenne"))
NameError: name 'valeur_moyenne' is not defined
5.3.4.2. question 2: utilisation de la fonction valeur_moyenne#
Calculer et affecter dans
moyenne_anneela valeur moyenne du tableauanneeavec la fonctionvaleur_moyenne.Calculer et affecter dans
moyenne_anomaliela valeur moyenne du tableauanomalie_tempavec la fonctionvaleur_moyenne.
moyenne_annee = 0
moyenne_anomalie = 0
### BEGIN SOLUTION
### END SOLUTION
5.3.4.3. question 3: écriture de la fonction Lissage()#
On cherche maintenant à écrire une fonction pour trouver la droite de régression par les moindres carrés \( Y = A0 + A1*X \). Les coefficients \( A1 \) et \( A0 \) sont donnés par les relations:
. Indication 1 : Il faut d’abord calculer \( A1 \) puis d’utiliser cette valeur pour calculer \( A0\).
. Indication 2 : Pour calculer \(A1\), on se sert plusieurs fois de la fonction valeur_moyenne() pour déterminer \(\bar{X}\), \(\bar{Y}\), \(\overline{X*Y}\) et \(\overline{X*X}\), qui sont respectivement les valeurs moyennes des tableaux \(X\), \(Y\), \((X*Y)\) et \((X*X)\).
Ecrire une fonction python
Lissage(X,Y)qui prend en arguments les tableaux X,Y, calcule et renvoie la valeur des 2 coefficients A0 et A1 dans cet ordre.A l’aide de
Lissage, calculer et affecter dans \(a_1\) et \(a_0\) les coefficients de la droite de régression linéaire pour les tableauxanneeetanomalie_temp.Afficher les valeurs de \(a_1\) et \(a_0\)
# fonction de Lissage Lissage(X,Y)
### BEGIN SOLUTION
### END SOLUTION
5.3.4.4. question 5: prédiction#
On va utiliser les données précédentes pour obtenir une prédiction prediction de la hausse des températures (si la tendance actuelle se confirme) dans l’année qui est donnée au bas de cette cellule.
A la question précédente, nous avons calculé les coefficients \(a_0\), \(a_1\) d’une fonction linéaire qui lisse les données. Nous pouvons maintenant calculer des valeurs d’anomalie de température \( f (t) \) avec $\( f(t) = a_0 + a_1 t\)$
Appelons reg le tableau obtenu en évaluant \( f (t) \) pour toutes les valeurs du tableau annee.
Dans la première cellule suivante
Calculer le tableau
regà partir des valeurs de \(a_0\), \(a_1\) et annee.Affecter à
anla valeur de l’année de prédiction qui vous a été attribuée.Calculer la valeur de la hausse de température prédite dans la variable
predictionà partir des valeurs de \(a_0\), \(a_1\) etan. On utilisera la fonction numpynp.round(val,2)qui arrondit une valeurvalà 2 chiffres.
Dans la deuxième cellule suivante
Tracer les données d’origine
anomalie_tempen fonction deannee(idem étape 2) avec un titre, des labels et des légendesTracer la régression linéaire correspondant à ces données
Rajouter sur la figure le point de prédiction.
Indication :
Pour agrandir la figure, on pourra utiliser l’instruction
plt.figure(figsize=(12, 6))
Pour rajouter le point de prédiction, on pourra utiliser l’instruction
plt.plot([an],[prediction],'*',markersize=15)
Dans la troisième cellule suivante (format markdown)
Commenter sur quelques lignes la figure et le résultat obtenu.
printmd("**Estimation** de la hausse des température en {}".format(_an))
# calcul de la prediction
prediction = 0
an = 0
reg = None
### BEGIN SOLUTION
### END SOLUTION
# tracer la figure avec les donnees, le lissage et le point de prédiction
### BEGIN SOLUTION
### END SOLUTION
# ne pas modifier la cellule
### BEGIN HIDDEN TESTS
assert(a1>0)
assert(np.abs(prediction*100 - np.round(prediction*100) < 1.0))
### END HIDDEN TESTS
5.3.5. Amélioration du modèle de prédiction#
Si vous regardez le graphique ci-dessus, vous remarquerez peut-être que vers 1970, la température commence à augmenter plus rapidement que la tendance précédente. Peut-être qu’une seule droite ne nous donne pas un bonne prédiction.
On propose de diviser les données en deux (avant et après 1970) et de faire une régression linéaire sur chaque partie. Nous avons besoin de créer deux sous-tableaux à partir des tableaux annee et anomalie_temp.
Pour ce faire, nous devons d’abord trouver la position dans notre tableau annee où se trouve l’année 1970. Heureusement, NumPy a une fonction pour cela appelée np.where() qui peut nous aider. Nous passons en argument une condition et np.where() nous indique où dans le tableau la condition est vrai (True). On rappelle que le test d’égalité en Python est noté ==. La fonction np.where() renvoie un tableau qui contient l’indice recherché. Pour trouver l’indice de l’année 1970, on utilisera donc l’instruction suivante pour sélectionner cet indice dans le tableau renvoyé par np.where:
i_1970 = np.where(annee==1970)[0][0]
Ensuite pour diviser les données, nous utilisons la notation de slicing avec : . N’oubliez pas qu’un deux-points entre deux indices indique une plage de valeurs d’un début à une fin. La règle est que [début:fin] inclut l’élément au début de l’index mais exclut celui à la fin de l’index.
Nous savons maintenant comment diviser nos données en deux partie, pour obtenir les deux droites de régression. Nous avons besoin de deux tranches des tableaux annee et anomalie_temp, que nous mettons dans de nouvelles variables. Puis, nous effectuons deux régressions linéaires à l’aide des fonctions NumPy apprises ci-dessus.
Déterminer l’indice de l’année 1970 et la mettre dans la variable
i_1970.Vérifier le résultat.
Calculer les 2 tranches des tableaux
anneeetanomalie_tempdansannee_1 , anomalie_temp_1pour les années avant 1970 exclue etannee_2 , anomalie_temp_2pour les années après 1970 inclue.
i_1970 = 0
annee_1 = 0
anomalie_temp_1 = 0
annee_2 = 0
anomalie_temp_2 = 0
### BEGIN SOLUTION
### END SOLUTION
5.3.5.1. Nouveau modèle#
en utilisant la fonction de Lissage sur les données précédentes, calculer les 2 courbes de lissage des données
pour t < 1970
\[ f1(t) = b0 + b1 * t \]sinon
\[ f2(t) = c0 + c1 * t \]
Calculer et afficher les valeurs des coefficients \(b0\), \(b1\) et \(c0\) \(c1\)
En déduire une nouvelle estimation de la hausse des températures dans la variable
prediction_2avec une précision de 2 chiffres et comparer à la prédiction précédente.Dans la cellule suivante, tracer sur une figure les données d’origine, les 2 régressions linéaires, ainsi que le point de prédiction en mettant des légendes, un titre et un label pour les axes.
Enfin dans la cellule Markdown en dessous de la courbe, commenter le résultat et donner votre analyse et conclusion sur quelques lignes.
# calcul de la prediction
prediction_2 = 0
### BEGIN SOLUTION
### END SOLUTION
# tracer du résultat avec les données, le lissage et le point de prédiction
### BEGIN SOLUTION
### END SOLUTION
# ne pas modifier la cellule
### BEGIN HIDDEN TESTS
# test validation du code de la cellule précédente
_X = annee_1
_Y = anomalie_temp_1
assert (np.abs(b1 - np.sum(_X*(_Y-np.ndarray.mean(_Y)))/np.sum(_X*(_X-np.ndarray.mean(_X)))) < 1.e-8)
assert (np.abs(_Y.mean() - b0 - b1*_X.mean())<1.e-8)
_X = annee_2
_Y = anomalie_temp_2
assert (np.abs(c1 - np.sum(_X*(_Y-np.ndarray.mean(_Y)))/np.sum(_X*(_X-np.ndarray.mean(_X)))) < 1.e-8)
assert (np.abs(_Y.mean() - c0 - c1*_X.mean())<1.e-8)
print("prédiction de la hausse de temperature: {} degré en {}".format(prediction_2,an))
assert (np.abs(prediction_2*100 - np.trunc(prediction_2*100))<1.)
### END HIDDEN TESTS
5.4. FIN du TP#
# version
from platform import python_version,uname,platform
print("Systeme :",uname())
print("OS :",platform())
print("version python:",python_version())
print("version numpy :",np.__version__)