Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Enseignant : M. EBOA Michel Anicet
Enseignant – Chercheur, LGIA - ENSET DOUALA
[email protected]Tel / WhatsApp : +237 693 759 733
Pour valider le module :
• CC : Présence, TP et TPE
• Un examen de fin de semestre
Code B3014
Volume Horaire 42 h
Crédits 2
Niveau 3
Semestre 1
Pré-requis Bases du C
Plan du cours :
1 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
2 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 1 : Variables et fonctions
Introduction
Pour faire du machine Learning avec python, il faut bien sur installer python. Pour cela nous pouvons :
- Installer Visual studio code et y installer le distribuable python
- Installer Anaconda python
a) Installer Python Anaconda : le meilleur outil de Machine Learning
Il existe deux façons d’installer les outils de Machine Learning sur votre ordinateur : La bonne et la
mauvaise. En installant Anaconda, vous vous épargnez des heures de souffrance à taper des commandes
en mode ‘geek’ à installer les packages, librairies et éditeur de texte indispensables pour faire du Machine
Learning. Pourquoi faire simple quand on peut faire compliquer ?
Anaconda contient tous les outils et librairies dont vous avez besoin pour faire du Machine Learning :
Numpy, Matplotlib, Sklearn, etc. Commencez par télécharger puis installer Anaconda depuis le site
officiel : https://www.anaconda.com/distribution/#download-section
Note: Téléchargez toujours la version la plus récente de Python
Une fois Anaconda installé, vous pouvez lancer l’application Jupyter Notebook depuis votre barre de
recherche Windows/Mac/Linux.
b) Utilisation de Jupyter Notebook
Pour vos projets Jupyter Notebook est une application Web qui permet de créer et de partager des codes
Python.
Note : C’est une application Web, mais il n’est pas nécessaire d’avoir une connexion Internet pour vous
servir de Jupyter. Aussi, vos données/codes ne sont à aucun moment stockés sur Internet (ce n’est pas du
Cloud).
Lorsque vous démarrez Jupyter, il est possible que 2 fenêtres s’ouvrent, auquel cas ne vous occupez pas
de la fenêtre noire (la console) et surtout ne la fermez pas (ceci déconnecterait Jupyter de votre disque
dur).
3 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
La fenêtre principale de Jupyter n’est ni plus ni moins qu’un explorateur de fichier relié à votre disque
dur, vous pouvez ouvrir tous vos fichiers, Dataset, codes, etc. depuis cette fenêtre. Cliquez sur le bouton
‘New’ situé en haut à droite de cette fenêtre pour commencer à écrire un nouveau programme (puis
cliquez sur Python 3). La fenêtre suivante s’affiche alors : Vous êtes prêts à coder !
I.1. La programmation : une nouvelle vision du monde
En programmation, on choisit d’adopter une certaine vision du monde dans lequel nous vivons. On peut
considérer que le monde peut être modélisé à partir de 2 concepts :
• Des objets
• Des actions, qui modifient l’état des objets. Regardez autour de vous. Vous êtes entourés d’objets.
En réalisant une action, des objets peuvent apparaitre, disparaitre, se combiner, se transformer, etc.
D’ailleurs, quand nous nous exprimons, il est nécessaire et suffisant de dire un nom (objet) et un verbe
(action) pour faire une phrase. Exemple : « Le chien boit. » ou bien « Le chien boit de l’eau. »
Chien : Objet
Boit : Action
Eau : Objet, qui diminue avec l’action boire.
En programmation, ces deux notions prennent le nom de variable et de fonction, les fonctions
transformant la valeur des variables.
4 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Le plus souvent, il n’est pas nécessaire de développer ses propres fonctions car celles-ci sont déjà
développées dans des librairies open source. Par exemple, la librairie Sklearn contient toutes les
fonctions mathématiques et l’algorithme de Gradient Descent que nous verrons plus tard !
En pratique, il est donc inutile d’écrire la moindre équation mathématique. Génial, non ?! Au fil des
exemples dans ce cours, vous allez naturellement apprendre comment programmer en Python
spécialement pour le Machine Learning. Mon but est de vous épargner une avalanche de détails inutiles,
pour vous montrer les fonctions essentielles et utiles qui vous aideront réellement à résoudre des
problèmes dans votre travail après la lecture de ce cours.
I.2. Les commentaires
Dans tout langage de programmation, il est possible d’écrire des commentaires. Un commentaire n’est
pas lu par la machine et vous pouvez donc y écrire ce que vous voulez pour documenter votre code. Dans
Python, il suffit de précéder votre code du symbole « # » pour le transformer en commentaire.
# Ceci est un commentaire
Il est parfois nécessaire de faire un bloc de code en commentaire, le plus simple c’est de créer une zone de
commentaire sur plusieurs lignes. Pour le faire, il suffit d’encadrer votre code des triples guillemets
«"""» ou sectionner le bloc de code et taper la commande shift + Alt + a pour le transformer en
commentaire.
"""Ceci
Est
Un
Commentaire
Sur plusieurs lignes"""
I.3. Les variables
Pour définir une variable dans Jupyter, il suffit de lui donner un nom et de lui assigner une valeur. Par
exemple, vous pouvez choisir de créer la variable « vitesse » et de lui assigner la valeur 90.
Note : les accents et chiffres sont à bannir pour le nom d’une variable ! Vous pouvez effectuer des
opérations mathématiques entre les
variables numériques. Une fois le code
écrit, appuyez sur CTRL + Entrée pour
exécuter votre code. Le résultat est affiché
et une nouvelle cellule s’ouvre en bas
pour continuer à écrire du code.
Il existe de nombreux types de variables : les variables numériques, les listes, les matrices, les chaines de
caractères… on peut les regrouper en 4 grands types de variables
- int (nombre entier)
- float (nombre décimal)
- string (chaine de caractères)
5 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
- bool (booléen)
x = 3# type int
y = 2.5# type float
prenom = 'Pierre'# type string
z = True # type Bool
On peut également déclarer et affecter les valeurs à plusieurs variables sur la même ligne :
x, y = 3, 2.5
Résultats :
x = 3
y = 2.5
a.1) Opérations arithmétiques
print('x + y =', x + y)
print('x - y =', x - y)
print('x / y =', x / y)
print('x // y =', x // y) # division entière (très utile pour les tableaux Numpy)
print('x * y =', x * y)
print('x ^ y =', x ** y) # x puissance y
Résultats :
x + y = 5.5
x - y = 0.5
x / y = 1.2
x // y = 1.0
x * y = 7.5
x ^ y = 15.588457268119896
Note : dans Spyder ou sur Visual studio code l’instruction print est obligatoire pour afficher le résultat
des opérations, par contre sur jupyter il suffit d’écrire le code et exécuter.
a.2) Opérations de comparaison
print('égalité :', x == y)
print('inégalité :', x != y)
print('inférieur ou égal :', x <= y)
print('supérieur ou égal :', x >= y)
Résultats :
égalité : False
inégalité : True
inférieur ou égal : False
supérieur ou égal : True
a.3) Opérations Logiques
print('ET :', False and True)
print('OU :', False or True)
print('OU exclusif :', False ^ True)
Résultats :
ET : False
OU : True
OU exclusif : True
Note: - Les opérations de comparaison et de logique utilisées ensemble permettent de construire des
structures algorithmiques de bases (if/esle, while, ...)
-Les operateurs logiques répondent aux structures des tables de vérité : ET, OU, Non, Ou-
Exclusif.
6 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
I.4. Les fonctions
Comme énoncé plus haut, Python contient déjà de nombreuses librairies remplies de fonctions très utiles
et il n’est pas nécessaire de coder ses propres fonctions pour faire du Machine Learning. Cependant, je
vais tout de même vous montrer la structure d’une fonction dans Python, pour votre connaissance
personnelle.
a.1) Fonction lambda
Une fonction anonyme est une fonction créée avec lambda. Ce type de fonction est basique et est utile
pour être intégrée au milieu de structures de contrôles ou bien d'autres fonctions mais principalement pour
des opérations mathématiques. On l'utilise rarement.
# Exemple d'une fonction f(x) = x^2
f = lambda x : x**2
print(f(5))
# Exemple d'une fonction g(x, y) = x^2 - y^2
g = lambda x, y : x**2 - y**2
print(g(4, 2))
a.2) Fonction def
Rappelez-vous qu’une fonction transforme le
plus souvent une entrée en sortie :
Pour créer une fonction dans Python, il faut commencer par écrire « def » en début de ligne, puis donner
un nom à la fonction, écrire les inputs entre parenthèse, et finir la ligne par un « : ». Les lignes suivantes
font partie de la fonction, vous pouvez y écrire des commentaires, créés de nouvelles variables, faire des
opérations mathématiques etc. La fonction s’arrête à la ligne « return » qui indique quelle sortie la
fonction doit produire. Une fois la fonction créée, il est possible de l’utiliser à l’infini !
# une fonction à un nom, prend des entrées (arguments) et les transforme pour retourner un résultat
def nom_de_la_fonction(argument_1, argument_2):
restultat = argument_1 + argument_2
return restultat
nom_de_la_fonction(3, 2) #appel de la fonction
Exemples :
7 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# Exemple concret : fonction qui calcul l'énergie potentielle d'un corps
def e_potentielle(masse, hauteur, g=9.81):
energie = masse * hauteur * g
return energie
# Ici g a une valeur par défaut donc nous ne sommes pas oblige de lui donner une autre valeur
e_potentielle(masse=10, hauteur=10)
Note : rappeler les noms des keywords de nos paramètres avant de passer les valeurs n’est pas
obligatoire, mais nécessaire pour modifier par exemple la valeur par de défaut d’un paramètre.
# Exemple concret : fonction qui calcul l'énergie potentielle d'un corps
def e_potentielle(masse, hauteur, g=9.81):
energie = masse * hauteur * g
return energie
# Ici g a une valeur par défaut, mais nous pouvons modifier la valeur pour cette appel
e_potentielle(masse=10, hauteur=10, g=5)
a.3) Exercice : fonction e_potentielle
Modifiez la fonction e_potentielle définie plus haut pour retourner une valeur indiquant si l'énergie
calculée est supérieure ou inférieur a une energie_limite passée en tant que 4eme argument !
I.5. Les 4 librairies à maîtriser pour le Machine Learning
Pour importer une librairie dans Python, rien de plus simple. Il suffit d’écrire le nom de la librairie
précédé de « import » en tête de votre programme. Il est également possible d’importer certaines
fonctions de la librairie en écrivant from « librairie » import « alias ». Exemple :
Numpy est la librairie qui permet de créer et manipuler des
matrices simplement et avec efficacité. En Machine Learning, on
insère le plus souvent notre Dataset dans des matrices. Ainsi le
calcul matriciel représente l’essentiel du Machine Learning. Il est
important de le comprendre, mais les fonctions présentes dans Numpy font les calculs matriciels à notre
place… Magique !
Matplotlib est la librairie qui permet de visualiser nos
Datasets, nos fonctions, nos résultats sous forme de graphes,
courbes et nuages de points.
Pandas est une excellente librairie pour
importer vos tableaux Excel (et autres
formats) dans Python dans le but de tirer
8 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
des statistiques et de charger votre Dataset dans Sklearn.
Sklearn est la librairie qui contient toutes les fonctions de l’état de l’art
du Machine Learning. On y trouve les algorithmes les plus importants
ainsi que diverses fonctions de pré-processing.
9 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 2 : Structures de contrôle
Dans le monde de la programmation, il existe 3 principales structures de contrôle pour créer des
algorithmes.
- Les alternatives If / Else
- Les boucles For
- Les boucles While
II.1) Comparaisons
Avant de passer aux structures, nous abordons tout de suite les comparaisons. Python est capable
d’effectuer toute une série de comparaisons entre le contenu de différentes variables, telles que :
Syntaxe Python signification
== égal à
!= différent de
> Supérieur à
>= supérieur ou égal à
< Inférieur à
<= inférieur ou égal à
II.2) Alternatives If / Else :
Cette structure permet de tester une séquence d'alternatives. Si une condition est respectée, alors les
instructions qui la suivent sont exécutées et la structure de contrôle est stoppée, sinon la condition
suivante est testée. Exemple :
Def test_du_signe(valeur):
if valeur <0:
print('négatif')
elif valeur == 0:
print('nul')
else:
print('positif')
test_du_signe(-2) # appel de la fonction
Une condition est respectée si et seulement si elle correspond au résultat booléen True.
valeur = -2
print(valeur <0) # le résultat de cette comparaison est True
if valeur <0:
print('négatif')
Résultat :
True
Négatif
Cela permet de développer des algorithmes avec des mélanges d'opérations Logiques et d'opérations de
comparaisons. Par exemple : s’il fait beau et qu'il faut chaud, alors j'irai me baigner
x = 3
y = -1
10 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
if (x>0) and (y>0):
print('x et y sont positifs')
else:
print('x et y ne sont pas tous les 2 positifs')
II.3) Boucle For
Une boucle for permet de créer des algorithmes itératifs (qui effectuent une certaine tache plusieurs fois
de suite). Pour ça, la boucle parcourt tous les éléments d'un objet dit itérable. Il peut s'agir d'une liste, d'un
dictionnaire, d'un range, d'un tableau Numpy, ou de bien d'autres objets...
a.1) La fonction range
# range(début, fin, pas) est une built-in fonction très utile de python qui retourne un itérable.
for i in range(0, 10):
print(i)
L’instruction range() fonctionne sur le modèle range([début,] fin[, pas]). Les arguments entre crochets
sont optionnels.
# On peut s'amuser à combiner cette boucle avec notre fonction de tout à l'heure.
for i in range(-10, 10, 2):
print(i)
test_du_signe(i)
a.2) La fonction len
L’instruction len() vous permet d e connaître la longueur d’une liste, ce qui parfois est bien pratique
lorsqu’on lit un fichier par exemple, et que l’on ne connaît pas a priori la longueur des lignes. Voici un
exemple d’utilisation :
animaux = ['girafe', 'tigre', 'singe', 'souris']
print (len(animaux)) #résultat : 4
print (len(range(10))) #résultat : 10
a.3) Parcours d’un liste
Imaginez que vous ayez une liste de quatre éléments dont vous voulez afficher les éléments les uns après
les autres. Dans l’état actuel de vos connaissances, il faudrait taper quelque chose du style :
animaux = ['girafe','tigre','singe','souris']
print(animaux[0])
print(animaux[1])
print(animaux[2])
print(animaux[3])
Si votre liste ne contient que quatre éléments, ceci est encore faisable mais imaginez qu’elle en contienne
100 voire 1000 ! Pour remédier à cela, il faut utiliser les boucles. Regardez l’exemple suivant :
animaux = ['girafe','tigre','singe','souris']
for animal in animaux:
print (animal)
En fait, la variable animale va prendre successivement les différentes valeurs de la liste desanimaux à
chaque itération de la boucle. Notez bien les types de variable : animaux est une liste sur laquelle on itère,
et animal est une chaîne de caractère qui à chaque itération de la boucle prendra les valeurs successives de
la liste animaux (car les éléments de la liste sont des chaînes de caractère, mais on verra plus loin que cela
est valable pour n’importe quel type de variable).
Il est aussi possible d’utiliser une tranche d’une liste :
11 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
animaux = ['girafe','tigre','singe','souris']
for animal in animaux[1:3]:
print (animal) #on va afficher le 1 et le 2e element de la liste
Nous allons maintenant parcourir cette liste, mais cette fois par une itération sur ses indices :
animaux = ['girafe','tigre','singe','souris']
for i in range(4): La valeur de départ par défaut est 0 et le pas par défaut est 1
print(animaux[i])
La variable i prendra successivement les valeurs 0, 1, 2 et 3 et on accèdera à chaque élément de la liste
animaux par son indice (i.e. animaux[i]). Sur ces différentes méthodes de parcours de liste, quelle est la
plus efficace ? La méthode à utiliser pour parcourir avec une boucle for les éléments d’une liste est celle
qui réalise les itérations directement sur les éléments.
a.4) La fonction enumerate
Enfin, si vous avez besoin de l’indice d’un élément d’une liste et de l’élément lui-même, la fonction
enumerate() est pratique.
animaux = ['girafe','tigre','singe','souris']
for i, ani in enumerate(animaux):
print (i, ani)# ou i contient l'indice et ani l’élément
II.4) Boucle While
Une autre alternative à l’instruction for couramment utilisée en informatique est la boucle while. Le
principe est simple. Une série d’instructions est exécutée tant qu’une condition d'exécution est valide,
vraie (tant que la condition est True).
x = 0
while x <10:
print(x)
x += 1# incrémente x de 1 (équivalent de x = x+1)
Une boucle while nécessite trois éléments pour fonctionner correctement :
- L’initialisation de la variable de test avant la boucle ;
- Le test de la variable associé à l’instruction while ;
- L’incrémentation de la variable de test dans le corps de la boucle.
Faites bien attention aux tests et à l’incrémentation que vous utilisez car une erreur mène souvent à des
boucles infinies qui ne s’arrêtent pas. Vous pouvez néanmoins toujours stopper l’exécution d’un script
Python à l’aide de la combinaison de touches Ctrl-C.
II.5) Instructions break et continue
Ces deux instructions permettent de modifier le comportement d’une boucle (for ou while) avec un test.
L’instruction break stoppe la boucle.
For i in range(5):
if i>2:
break
print(i) # 0 1 2
L’instruction continue saute à l’itération suivante.
For i in range(5):
if i == 2:
12 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
continue
print(i) # 0 1 3 4
II.6) Exercice : Suite de Fibonacci.
La suite de Fibonacci est une suite mathématique qui porte le nom de Leonardo Fibonacci, un
mathématicien italien du XIIIe siècle. Initialement, cette suite a été utilisée pour décrire la croissance
d’une population de lapins mais elle est peut également être utilisée pour décrire certains motifs
géométriques retrouvés dans la nature (coquillages, fleurs de tournesol...).
Par définition, les deux premiers termes de la suite de Fibonacci sont 0 et 1. Ensuite, le terme au rang n
est la somme des nombres aux rangs n - 1 et n - 2. Par exemple, les 10 premiers termes de la suite de
Fibonacci sont 0, 1, 1, 2, 3, 5, 8, 13, 21, 34.
1. Écrivez un script qui construit la suite de Fibonacci puis l’affiche pour des nombre compris entre
0 et n.
Indice :
- Pour cet exercice vous aurez besoin d'une boucle While
- Vous pouvez imprimer cette suite jusqu'a atteindre un nombre n que vous aurez choisi
- dans python il est possible de mettre à jour 2 variables simultanément sur les mêmes lignes : a, b = b,
a+b
2. Refaire la fonction en utilisant les listes. Cette fois on aura une fonction qui retourne une liste qui
contient tous les éléments de la suite de Fibonacci.
3. Écrivez un script qui construit la liste des n premiers termes de la suite de Fibonacci puis
l’affiche.
13 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 3 : Structures de donnes : Listes, Tuples et Dictionnaire
Une structure de données est une variable capable de contenir plusieurs valeurs à la fois. Une structure de
données peut former une séquence si les valeurs qui la composent sont rangées dans un certain ordre.
C'est le cas des listes et des Tuples. A l'inverse un Dictionnaire ne forme pas une séquence.
Un tuple est un tableau qu'on Un dictionnaire a une clé et une valeur
III.1. Listes peut lire mais dont on ne
peut modifier le contenu
Une liste est une structure de données qui contient une série de valeurs. Python autorise la construction de
liste contenant des valeurs de type différent (par exemple entier et chaîne de caractères), ce qui leur
confère une grande flexibilité. Une liste est déclarée par une série de valeurs (ne pas oublier les
guillemets, simples ou doubles, s’il s’agit de chaînes de caractères) séparées par des virgules, et le tout
encadré par des crochets. En voici quelques exemples :
animaux = ['girafe','tigre','singe','souris']
tailles = [5, 2.5, 1.75, 0.15]
mixte = ['girafe', 5, 'souris', 0.15]
print(animaux)
print(tailles)
print(mixte)
a.1) Utilisation
Un des gros avantages d’une liste est que vous pouvez appeler ses éléments par leur position. Ce numéro
est appelé indice (ou index) de la liste.
Liste : ['girafe', 'tigre', 'singe', 'souris']
Indice : 0 1 2 3
Soyez très attentifs au fait que les indices d’une liste de n éléments commence à 0 et se termine à n-1.
Voyez l’exemple suivant :
animaux = ['girafe','tigre','singe','souris']
print(animaux[0])
print(animaux[1])
print(animaux[2])
print(animaux[3])
print(animaux[4]) #Par conséquent, si on appelle l’élément d’indice 4 de notre liste, Python renverra un message
d’erreur :
a.2) Opération sur les listes
Tout comme les chaînes de caractères, les listes supportent l’opérateur + de concaténation, ainsi que
l’opérateur * pour la duplication :
ani1 = ['girafe','tigre']
ani2 = ['singe','souris']
ani3 = ani1 + ani2
print(ani3)
ani4 = ani1 * 3
print(ani4)
a.3) Indexing et Slicing : Indiçage négatif et tranches
Dans une séquence, chaque élément est rangé selon un index (le premier index étant l'index 0)
Pour accéder à un élément d'une liste ou d'un Tuple, on utilise une technique appelée Indexing
Pour accéder à plusieurs éléments d'une liste ou d'un Tuple, on utilise une technique appelée Slicing
14 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
villes = ['Paris', 'Berlin', 'Londres', 'Bruxelles']
# INDEXING
print('séquence complète:', villes)
print('index 0:', villes[0])
print('index 1:', villes[1])
print('dernier index (-1):', villes[-1])
# SLICING [début (inclus) : fin (exclus) : pas]
print('séquence complète:', villes)
print('index 0-2:', villes[0:3])
print('index 1-2:', villes[1:3])
print('ordre inverse:', villes[::-1])
La liste peut également être indexée avec des nombres négatifs selon le modèle suivant :
Liste : ['girafe', 'tigre', 'singe', 'souris']
Indice positif : 0 1 2 3
Indice négatif : -4 -3 -2 -1
Ou encore :
Liste : ['A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L']
Indice positif : 0 1 2 3 4 5 6 7 8 9
Indice négatif : -10 -9 -8 -7 -6 -5 -4 -3 - 2 -1
Les indices négatifs reviennent à compter à partir de la fin. Leur principal avantage est que vous pouvez
appeler le dernier élément d’une liste à l’aide de l’indice -1 sans pour autant connaître la longueur de la
liste.
animaux = ['girafe','tigre','singe','souris']
print(animaux[-1])
Un autre avantage des listes est la possibilité de sélectionner une partie en utilisant un Slicing construit
sur le modèle [m:n+1] pour récupérer tous les éléments, du émième au énième (de l’élément m inclus à
l’élément nexclus). On dit alors qu’on récupère une tranche de la liste, par exemple :
animaux = ['girafe','tigre','singe','souris']
print(animaux[0:2])
print(animaux[0:3])
print(animaux[0:])
print(animaux[:])
print(animaux[1:])
print(animaux[1:-1])
print(animaux[1:-1])
On peut aussi préciser le pas en ajoutant un« : » supplémentaire et en indiquant le pas par un entier.
animaux = ['girafe','tigre','singe','souris']
print(animaux[::2])
Finalement, on voit que l’accès au contenu d’une liste avec des crochets fonctionne sur le modèle
liste[début : fin : pas].
a.4) Listes de listes
Pour finir, sachez qu’il est tout-à-fait possible de construire des listes de listes. Cette fonctionnalité peut
être parfois très pratique. Par exemple :
enclos1 = ['girafe', 4]
enclos2 = ['tigre', 2]
enclos3 = ['singe', 5]
zoo = [enclos1, enclos2, enclos3]
15 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
print(zoo) # [['girafe', 4], ['tigre', 2], ['singe', 5]]
Dans cet exemple, chaque sous-liste contient une catégorie d’animal et le nombre d’animaux pour chaque
catégorie. Pour accéder à un élément de la sous-liste, on utilise un double indiçage.
print(zoo[1]) #['tigre', 2]
print(zoo[1][0]) #'tigre'
print(zoo[1][1]) #2
On verra un peu plus loin qu’il existe en Python les dictionnaires qui sont très pratiques pour faire ce
genre de choses. On verra aussi qu’il existe un module nommé Numpy permettant de gérer des listes ou
tableaux de nombres (vecteurs et matrices), ainsi que de faire des opérations dessus.
a.5) Actions utiles sur les listes
villes = ['Paris', 'Berlin', 'Londres', 'Bruxelles'] # liste initiale
print(villes)
villes.append('Dublin') # Rajoute un élément à la fin de la liste
print(villes)
villes.insert(2, 'Madrid') # Rajoute un élément a l'index indiqué
print(villes)
villes.extend(['Amsterdam', 'Rome']) # Rajoute une liste à la fin de notre liste
print(villes)
print('longueur de la liste:', len(villes)) #affiche la longueur de la liste
villes.sort(reverse=False) # trie la liste par ordre alphabétique / numérique
print(villes)
print(villes.count('Paris')) # compte le nombre de fois qu'un élément apparait dans la liste
Les listes et les Tuples fonctionnent en harmonies avec les structures de contrôle if/else et For
If 'Paris' in villes:
print('oui')
else:
print('non')
for element in villes:
print(element)
La fonction enumerate est très utile pour sortir à la fois les éléments d'une liste et leurs index. C'est une
fonction très utilisée en data-science :
for index, element in enumerate(villes):
print(index, element)
La fonction zip est aussi très utile pour itérée à travers 2 listes en parallèles. Si une liste est plus courte
que l'autre, la boucle for s'arrête a la liste la plus courte :
villes = ['Paris', 'Berlin', 'Londres', 'Bruxelles'] # liste initiale
liste_2 = [312, 52, 654, 23, 65, 12, 678]
for element_1, element_2 inzip(villes, liste_2):
print(element_1, element_2)
III.2. Tuples
Une liste ou un Tuple peuvent contenir tous types de valeurs (int, float, bool, string). On dit que ce sont
des structures hétérogenèses. La différence entre les 2 est qu'une liste est mutable alors qu'un Tuple ne
l'est pas (on ne peut pas le changer après qu'il soit crée)
16 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
#Tuples
tuple_1 = (1, 2, 6, 2)
print(tuple_1)
tuple_villes = ('Paris', 'Berlin', 'Londres', 'Bruxelles') # Tuple initiale
print(tuple_ villes)
Note : toutes les opérations, l’indexing, le Slicing et les actions possibles sur les listes sont également
possible sur les Tuples avec les mêmes syntaxes à l’exception de celles qui pourraient modifier le Tuple.
Car il ne faut pas oublier qu’un Tuple ne peux pas être modifié âpres sa déclaration, toutefois il est plus
raide en temps d’exécution qu’une liste pour de grande quantité de données.
III.3. Dictionnaires
Les dictionnaires sont des structures de contrôle non-ordonnées, c'est-a-dire que les valeurs qu'ils
contiennent ne sont pas rangées selon un index, mais suivant une clef unique.
Une utilisation parfaite des dictionnaires est pour regrouper ensemble des "variables" dans un même
conteneur (Ces variables ne sont pas de vraies variables, mais des keys).
On peut par exemple crée un dictionnaire inventaire qui regroupe plusieurs produits (les clefs) et leur
quantités (les valeurs)
inventaire = {'pommes': 100,
'bananes': 80,
'poires': 120}
print(inventaire.values())
print(inventaire.keys())
print(len(inventaire)) #nombre d'enregistrement dans le dictionnaire
Voici comment ajouter une association key/value dans notre dictionnaire (attention si la clef existe déjà
elle est remplacée)
inventaire['abricots'] = 30
print(inventaire)
Attention : si vous cherchez une clef qui n'existe pas dans un dictionnaire, python vous retourne une
erreur. Pour éviter cela, vous pouvez utiliser la méthode get()
print(inventaire.get('peches') ) # n'existe pas
print(inventaire.get('pommes')) # pomme existe
On peut définir une valeur par défaut si la clef n’existe pas
print(inventaire.get('peches', 0) ) # n'existe pas et retourne 0 comme valeur par défaut
La méthode pop() permet de retirer une clef d'un dictionnaire tout en retournant la valeur associée a la
clef.
abricots = inventaire.pop("abricots")
print(inventaire) # ne contient plus de clef abricots
print(abricots) # abricots contient la valeur du dictionnaire
Pour utiliser une boucle for avec un dictionnaire, il est utile d'utiliser la méthode items() qui retourne à la
fois les clefs et les valeurs
for key, value in inventaire.items():
print(key, value)
On peut également avoir des dictionnaires contenant d’autres dictionnaires :
traduction = {
17 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
'chien' : 'dog',
'chat' : "cat",
'souris' : 'mouse',
'oiseau' :'birth'
}
fruit = {
'banane' : 2000,
'pommes' : 2500,
'poires' : 1500
}
dictionnaire = {
'dict_1' : traduction,
'dict_2' : fruit
}
print(dictionnaire)
print(dictionnaire.items())
print(dictionnaire.keys())
print(dictionnaire.values())
Les dictionnaires peuvent être utilisés pour stocker les paramètres des réseaux de neurone au fur et à
mesure qu’on entraine les modèles.
Exercice : fonction trier
1. Implémentez une fonction trier(classeur, valeur) qui place une valeur dans un dictionnaire en
fonction de son signe. La fonction prend en paramètre un classeur (dictionnaire) et une valeur et
va donc range les valeurs dans le dictionnaire selon leurs signes. Puis on affichera le classeur.
classeur = {'négatifs':[],
'positifs':[]
}
Def trier(classeur, valeur):
return classeur
2. Modifier le programme de la question 1 pour donner nom pas une valeur, mais plutôt une liste de
valeur en paramètre. La fonction prendra donc en paramètre un classeur (dictionnaire) et une liste
de valeurs qui seront rangées selon leurs signes. Puis on affichera le classeur.
III.4. List Comprehension
Les listes compréhension sont une façon habile de créer des listes sur une seule ligne de code, ce qui rend
le code beaucoup plus rapide (car python est un langage assez lent). Les deux codes ci-dessous effectuent
chacun la même opération. On peut voir (grâce au module time) que le temps d'exécution avec liste
compréhension est bien inférieur au temps d'exécution avec la méthode append()
import time
#Liste compréhension: permet de mettre des boucles for dans la liste
#plus rapide dans l'exécution et en une ligne
#code normal
start = time.time()
liste_1 = []
for i in range(10000000):
liste_1.append(i**2)
end = time.time()
print(end-start) #durée : 5.985000133514404 secondes
#équivalent en List compréhension
start = time.time()
liste_2 = [i**2 for i in range(10000000)]
end = time.time()
print(end-start) #durée : 3.934999942779541 secondes
18 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
On peut rajouter des conditions if dans les listes compréhensions, par exemple :
liste = [i**2 for i in range(100000) if (i % 2) == 0] # calcule i**2 seulement pour les nombres pairs.
print(liste[:10]) #affiche les 10 premiers éléments de la liste
On peut aussi créer des Nested List ou listes dans une liste :
liste = [[i for i in range(3)] for j in range(4) ] #permet de répéter la liste générée par i, en fonction du range
de j
print(liste)
Dans ce cas, nous aurons une liste répétée 4 fois. On peut également s’amuser avec i et j
liste = [[i+j for i in range(3)] for j in range(4) ] #n peut s’amuser a modifier la valeur de i
print(liste)
III.5. Dictionnaire compréhension
Le même principe s'applique aux dictionnaires :
#code normale pour le dictionnaire
dictionnaire = {'0' : 'Pierre',
'1' : 'Jean',
'2' : 'Julie',
'3' : 'Sophie'}
On peut utiliser la fonction enumarate() pour parcourir la liste et range les données dans le dictionnaire
prenoms = ['Pierre', 'Jean', 'Julie','Sophie']
dico = {key : value for key, value in enumerate(prenoms)}
print(dico)
Si on veut convertir les clefs en string
dico = {str(key) : value for key, value in enumerate(prenoms)}
print(dico)
print(dico.keys())
print(dico.values())
Si nous avons deux listes qui contiennent nos données on peut utiliser la fonction zip
ages = [10, 21, 32, 53]
dico_2 = {prenom : age for prenom, age in zip(prenoms, ages)}
print(dico_2)
On peut ajouter des conditions dans notre dictionnaire compréhension
dico_2 = {prenom : age for prenom, age in zip(prenoms, ages) if age>25} #le dictionnaire ne va contenir les données
que pour age > à 20 ans
print(dico_2)
III.6. Tuple compréhension
Bien qu’on ne puisse modifier un Tuple après son initialisation, le même principe s'applique aux Tuples :
tuple_1 = tuple(i**2 for i in range(10))
print(tuple_1)
Exercice : dictionnaire
Essayez-donc de créer un dictionnaire qui contienne des clefs de 1 à 20, avec comme valeur le carré de
chaque clef.
# SOLUTION
dictionnaire = {k : k**2 for k in range(1, 21)}
print(dictionnaire)
19 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 4 : Built-in functions
Python contient un grand nombre de
fonctions intégrées très utiles à connaitre.
Cela vous permet de construire des codes
plus rapidement, sans avoir à développer
vos propres fonctions pour les taches les
plus basiques.
Dans cette section, je vous montre les plus
importantes :
- Fonctions de bases : abs(), round(),
max(), min(), len(), sum(), any(),
all()
- Conversions de types de variables : int(), str(), float(), type()
- Conversions de structures de données : list(), tuple()
- Conversions binaires (moins utile en machine Learning): bin(), oct(), hex()
- Fonction input()
- Fonction format(), (f-string)
- Fonction open()
IV.1. Fonctions de base
Utiles en toute circonstance :
x = -3.14
print(abs(x)) # valeur absolue
print(round(x)) # arrondi
liste = [-2, 3, 1, 0, -4]
print(min(liste)) # minimum
print(max(liste)) # maximum
print(len(liste)) # longueur
print(sum(liste)) # somme des éléments
liste = [False, False, True]
print(any(liste)) # y-a-t'il au moins un élément True ?
print(all(liste)) # est-ce-que tous les éléments sont True ?
IV.2. Fonctions de conversion
Il peut être très utile de convertir une variable d'un type à un autre (par exemple pour faire des calculs).
Pour cela, on dispose des fonctions int(), str() et float().
La fonction type() est très utile pour inspecter les types de nos variables
age = '32'
print(type(age))
age = int(age)
print(type(age))
age + 10
On peut également convertir des listes en Tuples, ou des tableaux Numpy (que l'on verra par la suite) en
liste...
20 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
tuple_1 = (1, 2, 3, 4)
liste_1 = list(tuple_1) # convertir un Tuple en liste
print(type(liste_1))
IV.3. La fonction input()
Cette fonction est très utile pour demander à l'utilisateur du programme d'entrer une valeur dans votre
programme :
age = input('quel age avez-vous ?')
print(type(age)) # age est de type string. il faut penser a le convertir si on désire faire un calcul avec
age = int(age)
print(type(age))
new_age = int(input('quel age avez-vous ?')) + age
print(new_age)
IV.4. La fonction format()
Cette fonction permet d'insérer la valeur d'une variable au sein d'une chaine de caractères (string). Une
méthode plus rapide pour utiliser cette fonction est de faire appel au f-string :
x = 25
ville = 'Paris'
message = 'il fait {} degrés a {}'.format(x, ville)
print(message)
#autre méthode
message = f'il fait {x} degrées a {ville}'
print(message)
Cette fonction est très pratique parce qu‘elle peut par exemple permettre a des développeurs d’accéder à
certaines clefs de leurs dictionnaires contenant les paramètres de leurs réseaux de neurones.
import numpy as np
parametres = {"W1" : np.random.randn(2, 4),
"b1" : np.zeros((2, 1)),
"W2" : np.random.randn(2, 2),
"b2" : np.zeros((2, 1)),}
For i in range(1, 3):
print("couche", i)
print(parametres["W{}".format(i)])
#print(parametres["W"+str(i)])#autre méthode
IV.5. La fonction open()
Cette fonction est l'une des plus utiles de Python. Elle permet d'ouvrir n'importe quel fichier de votre
ordinateur et de l'utiliser dans Python. Différents modes existent :
- Le mode 'r' : ouvrir un fichier de votre ordinateur en lecture
- Le mode 'w' : ouvrir un fichier de votre ordinateur en écriture
- Le mode 'a' : (append) ajouter du contenu dans un fichier existant (en écriture à la fin)
#écriture dans un fichier
f = open('text.txt', 'w') # ouverture d'un objet fichier f
f.write('hello')
f.close() # il faut fermer notre fichier une fois le travail terminé
#lecture d’un fichier
f = open('text.txt', 'r')
print(f.read())
f.close()
21 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Dans la pratique, on écrit plus souvent with open() as f pour ne pas avoir a fermer le fichier une fois le
travail effectué :
With open('text.txt', 'r') as f:
print(f.read())
Pour écrire plusieurs données dans un fichier avec cette méthode pose des problèmes de même que le fait
d’écrire les entiers. Pour résoudre le problème on peut donc utiliser la fonction format()
With open ("fichier.txt", "w") as f:
for i in range(1, 13):
f.write("{}^2 = {}\n".format(i, i**2)) #pour rentrer à la ligne après chaque opération on utilise le retour
chariot : \n
Exercice : fichier
Le code ci-dessous permet de créer un fichier qui contient les carrée des nombres allant de 0 jusqu'a 19.
L'exercice consiste à implémenter un code qui permet de lire ce fichier et d'écrire chaque ligne dans une
liste.
Note_1 : la fonction read().splitlines() sera très utile
Note_2 : Pour un meilleur résultat, essayer d'utiliser une liste compréhension !
# Ce bout de code permet d'écrire le fichier
with open('fichier.txt', 'w') as f:
for i in range(0, 20):
f.write(f'{i}: {i**2}\n')
f.close()
Chapitre 5 : Modules
Python contient un certain nombre de modules (fichier contenant du code) intégrés, qui offrent de
nombreuses fonctions mathématiques, statistiques, aléatoires et os très utiles. Pour importer un module, il
faut procéder comme-ci dessous :
- import module (importe tout le module)
- import module as md (donne un surnom au module)
- from module import fonction (importe une fonction du module)
import math
import statistics
import random
import os
import glob
Vous pouvez également créer vos propres modules et les importer dans d'autres projets. Un module n'est
en fait qu'un simple fichier.py qui contient les fonctions, les classes, bref du code.
import test1 #où test1 est notre fichier python (test1.py) qui contient nos fonction, listes, dictionnaires, ...
res = test1.fibonacci(1000) #o appel la fonction fibonacci contenu dans test1.py
print(res)
Utiliser simplement import charge tout le contenu du module dans le module encours, on peut éviter cette
opération en précisant la fonction, la classe, … qu’on veut importer :
from test1 import fibonacci as fib
res = fib(1000)
print(res)
22 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
On peut accéder à la documentation python pour avoir accès à nombreux outils et modules disponible
pour faire du développement sur python
Dans l’environnement anaconda on a accès à plein de packages et de modules émettant de faire
différentes opérations : du html, de lire des images, …
V.1. Modules math et statistics
Les modules math et statistics sont en apparence très utiles, mais en data science, nous utiliserons leurs
équivalents dans le package (ensemble de module regroupe dans un même répertoire) NUMPY. Il peut
néanmoins être intéressant de voir les fonctions de bases.
print(math.pi)
print(math.cos(2*math.pi))
liste = [1, 4, 6, 2, 5]
print(statistics.mean(liste)) # moyenne de la liste
print(statistics.variance(liste)) # variance de la liste
V.2. Module Random
Le module random est l'un des plus utiles de Python. En data-science, nous utiliserons surtout sont
équivalent NUMPY.
random.seed(0) # fixe le générateur aléatoire pour produire toujours le même résultat
print(random.choice(liste)) # choisit un élément au hasard dans la liste
print(random.random()) # génère un nombre aléatoire entre 0 et 1
print(random.randint(5, 10)) # génère un nombre entier aléatoire entre 5 et 10
print(random.randrange(100)) # retourne un nombre aléatoire compris entre 0 et 100
random.sample(range(100), 10) # retourne une liste de 10 nombres aléatoires entre 0 et 100
23 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
print(random.sample(range(100), random.randrange(10))) # retourne une liste de taille (entre 0 et 10 élément)
aléatoire comprenant des nombres aléatoire compris entre 0 et 100
print('liste de départ', liste)
random.shuffle(liste) #mélange les éléments d'une liste
print('liste mélangée', liste)
V.3. Modules OS et Glob
Les modules OS et GLob sont essentiels pour effectuer des opérations sur votre disque dur, comme ouvrir
un fichier situé dans un certain répertoire de travail.
os.getcwd() # affiche le répertoire de travail actuel
print(glob.glob('*')) # contenu du répertoire de travail actuel
print(os.getcwd()) # affiche le répertoire de travail actuel
print(glob.glob('*')) # affiche le contenu du répertoire de travail actuel
print(glob.glob('*.txt')) # affiche les fichiers du répertoire de travail actuel dont l'extension est txt
Imaginons que nous avons plusieurs fichiers texte (un qui contient des noms de ville, un autre les noms de
pays, un fichier qui contient les fruits et leurs prix et un dernier qui contient des tables de multiplications)
que nous voulons analyser dans notre répertoire de travail courant. Nous pouvons donc utiliser toutes ces
données à la chaine à l’aide de la fonction glob() et de la fonction open()
import glob
filenames = glob.glob('*.txt')
for file in filenames:
with open(file, 'r' ) as f:
print(f.read())
Ici on va afficher le contenu de chaque fichier successivement.
Exercice : fichier et Liste
Enregistrer le contenu de chaque fichier dans une liste qui porte un nom spécifique associé à chaque
fichier. Utiliser les dictionnaires pour traiter cet exercice.
24 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 6 : POO
La programmation orientée objet est un paradigme, c'est à dire une façon de procéder pour écrire des
programmes clairs et simples. Le principe est de modéliser les éléments de notre programmes (comme les
tableaux et les listes) comme étant des objets caractérisés par des attributs et capables d'effectuer des
actions. Ces objets sont construits à partir de classes qui contiennent leur plan de fabrication. Dans le
langage Python, presque tout est construit pour être un objet : les listes, les dictionnaires, les tableaux
numpy, etc. Par exemple quand on écrit : list.append(), on utilise en fait la méthode append() sur un objet
liste. La documentation Python, Numpy, Pandas, Matplotlib, Sklearn, est donc en vaste majorité
constituée de classes qu'il est important de savoir déchiffrer pour pouvoir apprendre soi-même de
nouvelles choses grâce aux documentations. Voici donc comment créer simplement et efficacement des
classes :
Class vehicule:
"""
Voici un exemple de classe "vehicule" qui contient le plan de conception
d'objets "véhicules"
"""
# Une classe commence par une fonction initialisation qui contient les différents attributs
Def __init__(self, couleur='noir', vitesse=0, roues=4):
self.couleur = couleur
self.vitesse = vitesse
self.roues = roues
# voici une méthode "accélérer" qui modifie un attribut de l'objet
Def accelerer(self, vitesse):
self.vitesse += vitesse
# voici une autre méthode
Def stop(self):
self.vitesse = 0
# voici une dernière méthode, très souvent utilisée
Def afficher(self):
print(f'couleur: {self.couleur}\n roues: {self.roues}\n vitesse: {self.vitesse}')
# création d'un objet de la classe voiture
voiture_1 = vehicule(couleur='rouge')
voiture_1.afficher() #utilisation de la méthode affiche pour afficher les propriétés de la voiture
voiture_1.accelerer(100) #utilisation de la méthode accélérer pour modifier la vitesse de la voiture
voiture_1.afficher()
- class est un mot clé, vehicule le nom de la classe. Cette ligne alerte l'interpréteur : je veux créer un
objet Python de type class, une nouvelle classe (et non pas un objet de type vehicule qui, lui, sera
créé plus loin). La classe vehicule hérite de la classe object, c'est à dire que tous les attributs de la
classe object peuvent être utilisés par notre nouvelle classe.
- un docstring (""" ente """) pour expliquer le fonctionnement
- la première méthode est un constructeur (méthode spéciale) : __init__ ses quatre arguments sont :
o self : désigne l'objet non encore instancié, de type vehicule, qui appellera cette méthode.
Autrement dit, self est un vehicule, qui n'existe pas encore. De manière analogue, au moment
de la définition d'une fonction (par exemple def f(x) : return x*x) ;x ne désigne aucune variable,
25 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
mais prendra corps seulement lorsque la fonction sera appelée par exemple
a=3; f(a).
o couleur, vitesse et roues sont les attributs de la voiture, (par défaut noir, 0 et 4) Il y a création
de trois et couleur, vitesse et roues, dans self. Ces attributs prendront corps en même temps que
self, lorsqu’un vehicule sera instancié.
- accelerer() est une méthode qui modifie la vitesse. L'argument self prendra la valeur
vehicule v lorsque sera exécutée l'instruction v. accelerer()
- Instanciation. L’instruction : voiture_1 =vehicule (couleur='rouge') déclenche les actions suivantes
: appel à vehicule.__init__( couleur='rouge') , =⇒voiture_1 est instancié. Les attributs
voiture_1.couleur, voiture_1.vitesse et voiture_1.roues deviennent effectif, à l'intérieur de
voiture_1.
Créer des sous-classes : Héritage
Class voiture_electrique(vehicule):
"""
La classe moto hérite des méthodes et des attributs de la classe véhicule
"""
def __init__(self, couleur='black', vitesse=0, roues=4, autonomie=100):
super().__init__(couleur, vitesse, roues) # super() permet d'utiliser la fonction de la classe "parent"
self.autonomie = autonomie
# Ré-écriture de certaines méthodes
def accelerer(self, vitesse):
super().accelerer(vitesse)
self.autonomie -= 0.1 *self.vitesse
def afficher(self):
super().afficher()
print(f'autonomie: {self.autonomie}')
voiture_2 = voiture_electrique() # création d'un objet de la classe voiture de type voiture électrique
voiture_2.afficher() #utilisation de la méthode affiche pour afficher les propriétés de la voiture électrique
voiture_2.accelerer(10) #utilisation de la méthode accélérer pour modifier la vitesse de la voiture électrique ce
qui va aussi modifier l'autonomie
voiture_2.afficher()
class voiture_electrique(vehicule): signifie que la classe voiture_electrique hérite de la classe vehicule.
Donc voiture_electrique est un objet de vehicule. Grâce à cet héritage, tous les attributs et les méthodes de
la classe vehicule peuvent être utilisés et/ou surchargés par les instances de la classe voiture_electrique.
26 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 7 : Numpy : Tableau ndarray
Nous avons suffisamment posé les bases pour passer aux choses sérieuses. Pour ce faire nous
commençons par le package NUMPY.
Il faut rappeler que Numpy est l’un des package les plus important pour faire l’intelligence artificielle, la
data-science, le Deep et le machine Learning, Au cœur du package Numpy on trouve un objet
extrêmement puissant : le tableau à N dimensions (Tableau ndarray)
Un tableau a une dimension ressemble à une liste, mais est beaucoup plus puissant, plus rapide, prend
moins d’espace en mémoire et gère beaucoup plus de méthodes pur faire des calcules scientifiques. Nous
utiliserons principalement les tableaux à
deux dimensions où les lignes peuvent
représenter les exemples du Dataset et les
colonnes les variables.
Si on prend le cas du traitement d’une
image, on peut stocker les pixels de celle-
ci dans un tableau à deux dimensions.
Dans chaque case on peut stocker la
valeur du pixel correspond, sachant que les valeurs partent de 0 à 255 où 0 représente le noir et 255 le
blanc.
L’image suivante peut être représentée sur environs 800 lignes et 1050 colonnes.
Par contre si cette image est prise en couleur on pourra donc la décomposer en 3 couleurs vert, bleu et
rouge, chacune étant sur deux dimensions. On aura donc un tableau sur 3 dimensions (chaque dimension
27 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
représentant une couleur). Sur chaque couche on aura une valeur de pixel différente et c’est l’assemblage
des trois couches qui va donner la couleur finale pour chaque pixel.
Pour accéder à la liste complète des méthodes, routines, fonctions, … utilisables dans Numpy :
https://numpy.org/doc/stable/reference/
I.1. Générateurs de tableaux ndarray (les plus utiles) :
- générateur par défaut : ndarray()
- générateur 1D : np.linspace et np.arange()
- générateur ND : np.zeros(), np.ones(),
np.random.randn()
import numpy as np
A = np.array([1, 2, 3]) # générateur par défaut, qui
permet de convertir des listes (ou autres objets) en
tableau ndarray
A = np.zeros((2, 3)) # tableau de 0 aux dimensions 2x3
B = np.ones((2, 3)) # tableau de 1 aux dimensions 2x3
C = np.random.randn(2, 3) # tableau aléatoire
(distribution normale) aux dimensions 2x3
D = np.random.rand(2, 3) # tableau aléatoire
(distribution uniforme)
E = np.random.randint(0, 10, [2, 3]) # tableau d'entiers aléatoires de 0 a 10 et de dimension 2x3
A = np.ones((2, 3), dtype=np.float16) # définit le type et la place a occuper sur la mémoire
D = np.full((2,3), 9) #permet de créer un tableau de 2 dimensions (2 ligne et 3 colonnes) rempli de 9
print(D)
B = np.eye(4, dtype=np.bool) # créer une matrice identité et convertit les éléments en type bool.
A = np.linspace(1,10, 100) # tableau d'entiers en distribution égale de 100 valeurs allant de 1 a 10
B = np.arange(0, 10, 1)# tableau d'entiers de valeurs comprises entre 0 et 10 avec un pas, ici 1
I.2. Attributs importants
- Size : c’est un attribut qui permet de retourner le nombre d'éléments dans le tableau ndarray
(ndarray.size)
- shape
L’un des attributs les plus utiles de ndarray est l’attribut shape
(ndarray.shape) qui permet de connaitre la forme de notre tableau. C'est-à-
28 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
dire combien il ya de ligne, de colonne, quelle est la profondeur pour les tableaux à plus de 2 dimensions,
…
Pour un tableau à une dimension, on à un premier attribut ndim (ndarray.ndim) qui sera égale a un étant
donné que le tableau a une dimension. L’attribut shape de cette dimension sera égale a 2 étant donné qu’il
y’a deux éléments dans cette dimension.
shape renvoie un tuple (pas modifiable), donc pour accéder au nombre de ligne, il
faudra écrire l’index 0 : shape[0] et pour accéder au nombre de colonne, il faudra
écrire l’index 1 : shape[1].
A = np.zeros((2, 3)) # création d'un tableau de shape (2, 3)
print(A.ndim) # le nombre de dimension du tableau A
print(A.size) # le nombre d'éléments dans le tableau A
print(A.shape) # les dimensions du tableau A (sous forme de Tuple)
print(type(A.shape)) # voici la preuve que la shape est un tuple
print(A.shape[0]) # le nombre d'éléments dans la premiere dimension de A
I.3. Méthodes importantes
- reshape() : pour redimensionner un tableau
- ravel() : pour aplatir un tableau (qu'il ne fasse plus qu'une dimension)
- squeeze() : quand une dimension est égale a 1, cette dimension disparait
- concatenate() : assemble 2 tableaux ensemble selon un axes (existe aussi en hstack et vstack)
A = np.zeros((2, 3)) # création d'un tableau de shape (2, 3)
A = A.reshape((3, 2)) # redimensionne le tableau A (3 lignes, 2 colonnes)
A.ravel() # Aplatit le tableau A (une seule dimension)
A = A.reshape((A.shape[0], 1)) # si n a besoin de faire apparaitre la dimension 1 du tableau
A.squeeze() # élimine les dimensions "1" de A.
A = np.zeros((2, 3)) # création d'un tableau de shape (2, 3)
B = np.ones((2, 3)) # création d'un tableau de shape (2, 3)
On assemble deux tableaux de nombre de colonne identique : on superpose les lignes et le nombre de
colonne reste identique
C =np.concatenate((A, B), axis=0) # axe 0 : équivalent de np.vstack((A, B))
D = np.vstack((A, B))
print("tab1 :", C, "\n","tab2 :", D)
Onassemble deux tableaux de nombre de ligne identique : on superpose les colonnes et le nombre de ligne
reste identique
E = np.concatenate((A, B), axis=1) # axe 1 : équivalent de np.hstack((A, B))
F = np.hstack((A, B))
print("tab3 :", E, "\n","tab4 :", F)
Exercice : fonction initialisation
Créer une fonction initialisation qui prend deux arguments m (nombre de ligne) et n (nombre de colonne)
pour créer une matrice aléatoire de dimension (m, n+1). Où on a une matrice remplie de 1 tout à droite de
la matrice.
def initialisation(m, n):
# m : nombre de lignes
# n : nombre de colonnes
# retourne une matrice aléatoire (m, n+1)
29 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# avec une colonne biais (remplie de "1") tout a droite
return X
I.4. Numpy : Slicing et Indexing
En machine Learning et en data science on travail généralement sur les tableaux a
deux démentions où nous avons un axe 0 qui correspond aux lignes et un axe 1 qui
correspond aux colonnes. Pour éviter de faire les erreurs, il est préférable de se
déplacer sur un axe à la fois.
Le fonctionnement est le même que pour les listes :
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]])
print(A)
# Indexing
# Pour accéder a la ligne 0, colonne 1
A[0, 1]
# Pour accéder a tous les éléments de la ligne 0
A[0] #équivalent à A[0, :]
# Pour accéder a tous les éléments de la ligne 1
A[1] #équivalent à A[1, :]
# Pour accéder a tous les éléments de la colonne 0
A[ :,0]
# Pour accéder a tous les éléments de la colonne 1
A[ :,1]
# slicing
# Pour sélectionner les blocs de la ligne (0-1) colonne (0-1)
A[0:2, 0:2]
# Pour modifier les valeurs d'un les blocs de la ligne (0-1) colonne (0-1) sélectionner
A[0:2, 0:2] = 10
print(A)
I.5. Boolean Indexing
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]])
print(A<5) # masque booléen
print(A[A <5]) # sous-ensemble filtré par le masque booléen
A[A<5] = 4# convertit les valeurs sélectionnées en leur attribuant une nouvelle valeur, ici 4
print(A)
A[(A<5) & (A>2)] = 10# convertit les valeurs sélectionnées en leur attribuant une nouvelle valeur, ici 10
print(A)
A[A<5] # retourne le tableau A pour lequel les valeur sont inferieur à 5, changeant ainsi la forme du tableau
print(A)
print(A.shape)
B = np.ramdom.randn(2,3) # matrice de même dimension que A
B[A<5] #B obtient des valeur qui sont obtenue a partir du masque de A
print(B)
Exercices et Solutions
Exercice 1 : matrice
Remplir les 4 blocs du milieu de la matrice suivante par des "1" :
30 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
B = np.zeros((4, 4))
Exercice 2 : tableau
Remplir le tableau de "1" (une ligne sur deux, une colonne sur deux)
C = np.zeros((5, 5))
Exercice 3 : slicing
Sur l'image ci dessous, effectuer un slicing pour reduire l’image d’un
quart de chaque coté (ne garder que le centre) et remplacer tous les
pixels > 150 par des pixels = 255
import numpy as np
from scipy import misc# le package qui contient l’image
import matplotlib.pyplot as plt# le package qui permet l’affichage de l’image
face = misc.face() # on charge l’image en couleur (juste pour voir)
plt.imshow(face) #on affiche l’image
plt.show()#on lance la fenêtre qui contient l’image
print(face.shape) #(768, 1024, 3)
face = misc.face(gray=True)# on charge l’image en noir sur blanc (pour avoir 1
dim)
plt.imshow(face, cmap=plt.cm.gray)# on affiche l’image en définissant la couleur
plt.show()# on lance la fenêtre qui contient l’image
print(face.shape) #(768, 1024)
I.6. Numpy : Mathématiques
a.1) 1. Méthodes de bases (les plus utiles) de la classe ndarray
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]])
print(A.sum()) # effectue la somme de tous les éléments du tableau
print(A.sum(axis=0)) # effectue la somme des colonnes (somme sur éléments des lignes)
print(A.sum(axis=1)) # effectue la somme des lignes (somme sur les éléments des colonnes)
print(A.cumsum(axis=0)) # effectue la somme cumulée des colonnes (somme sur éléments des lignes)
print(A.prod()) # effectue le produit
print(A.cumprod()) # effectue le produit cumulé
print(A.min()) # trouve le minimum du tableau
print(A.max()) # trouve le maximum du tableau
print(A.min(axis=0))#trouve le minimum de chaque colonne du tableau
print(A.min(axis=1))#trouve le minimum de chaque ligne du tableau
print(A.argmin(axis=0))#trouve la position du minimum de chaque colonne
du tableau
Une méthode très importante : la méthode argsort()
A = np.random.randint(0, 10, [5, 5]) # tableau aléatoire
print(A)
print(A.argsort()) # retourne les index pour trier chaque ligne du tableau
print(A[:,0].argsort()) # retourne les index pour trier la colonne 0 de A
A = A[A[:,0].argsort(), :] # trie les colonnes du tableau selon la colonne 0.
print(A)
Pour faire la trigonométrie et autres
print(np.exp(A)) # calcul l’exponentiel de chaque nombre de a ; on peut faire de même avec toutes les fonction cos,
sin, sinh, log, …
31 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
a.2) Numpy Statistics
Toutes les routines y relatives sont documentées à l’adresse :
https://numpy.org/doc/stable/reference/routines.statistics.html
print(A.mean()) # calcule la moyenne, on peut aussi calculer selon les axes
print(A.std()) # calcule l'écart type,
print(A.var()) # calcule la variance
Corrélation de Pearson :
B = np.random.randn(3, 3) # nombres aléatoires 3x3
# retourne la matrice de corrélationde B ; corrcoef : corrélation coefficient
print(np.corrcoef(B))
# retourne la matrice de corrélation entre les lignes 0 et 1 de B
print(np.corrcoef(B[:,0], B[:, 1]))
#np.unique() :
np.random.seed(0)
A = np.random.randint(0, 10, [5,5])
print(A)
Il est parfois utile de connaitre le nombre de fois qu’un élément apparait dans un tableau. On peut donc
utiliser la fonction np. unique pour compter ces éléments. La fonction nous retourne deux variables, une
qui contient les valeurs comprises dans le tableau et une qui correspond au nombre de fois que chacune
des valeurs apparait. Il est possible de classer ses éléments en fonction de leurs nombre d’appariations
dans le tableau avec la fonction argsort()
print(np.unique(A)) #retourne chaque élément qui apparait dans la matrice
values, counts = np.unique(A, return_counts=True)
for i, j inzip(values[counts.argsort()], counts[counts.argsort()]):
print(f'valeur {i} apparait {j}')
Calculs statistiques en présence de données manquantes (NaN : Not a Number)
A = np.random.randn(5, 5)
A[0, 2] = np.nan # insère un NaN (Not a Number) dans la matrice A
print('Nombre de NaN:', np.isnan(A).sum()) # calcule e nombre de NaN dans A
print('ratio NaN/zise:', (np.isnan(A).sum()/A.size)) # calcule la proportion de NaN dans A
print('moyenne sans NaN:', np.nanmean(A)) # calcule la moyenne de A en ignorant les NaN
print('variance sans NaN:', np.nanvar(A)) # calcule la variance de A en ignorant les NaN
print('ecart type sans NaN:', np.stdmean(A)) # calcule l’écart type de A en ignorant les NaN
print('Nombre de NaN:', np.isnan(A).sum()) # calcule e nombre de NaN dans A
A[np.isnan(A)] = 0 # remplace les NaN dans A par de 0
print(A)
a.3) Algèbre Linéaire
A = np.ones((2,3))
B = np.ones((3,3))
print(A.T) # transposé de la matrice A (c'est un attribut de ndarray)
print(A.dot(B)) # produit matriciel A.B
A = np.random.randint(0, 10, [3, 3])
print('det=', np.linalg.det(A)) # calcule le déterminant de A
print('inv A:\n', np.linalg.inv(A)) # calcul l'inverse de A
print('inv A:\n', np.linalg.pinv(A)) # calcul la pseudo l'inverse de A
val, vec = np.linalg.eig(A)
print('valeur propre:\n', val) # valeur propre
print('vecteur propre:\n', vec) # vecteur propre
32 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Exercice
Exercice 1 : Standardisation
Standardisez la matrice suivante, c'est à dire effectuez le calcul suivant :
np.random.seed(0)
A = np.random.randint(0, 100, [10, 5])
print(A)
Chaque colonne doit avoir une moyenne = 0 et un écart type = 1
# SOLUTION
D = (A - A.mean(axis=0)) / A.std(axis=0)
print(D)
print(D.mean(axis=0)) # les moyennes sont toutes = 0
print(D.std(axis=0)) # les std sont tous = 1
Exercice 2 : image
Soit la solution de l’exercice 3 précédent (sur l’image), calculer le nombre de fois qu’apparait chaque
pixel. On veillera à mettre le résultat sous la forme :
La valeur 3 apparait 17 fois
La valeur 6 apparait 17 fois
La valeur 5 apparait 18 fois
La valeur 0 apparait 20 fois
import numpy as np
from scipy import misc # le package qui contient l’image
import matplotlib.pyplot as plt # le package qui permet l’affichage de l’image
face = misc.face() # on charge l’image en couleur (juste pour voir)
plt.imshow(face) #on affiche l’image
plt.show()#on lance la fenêtre qui contient l’image
print(face.shape) #(768, 1024, 3)
face = misc.face(gray=True) # on charge l’image en noir sur blanc (pour avoir 1 dim)
plt.imshow(face, cmap=plt.cm.gray) # on affiche l’image en définissant la couleur
plt.show()# on lance la fenêtre qui contient l’image
print(face.shape) #(768, 1024)
I.7. Numpy et Broadcasting
Le broadcasting est une technique assez puissante mais qui peut s’avérer dangereuse. En effet, cette
technique nous permet de faire les calcules entre deux tableaux de
manières très simple et très rapide sur Numpy.
En C, C++ et d’autres langages, pour addition les données de deux
tableaux, il faut procéder a l’addition des valeurs indice par indice dans
des boucles. Avec Numpy, si nous avons deux tableaux A et B, il suffit d’écrire
par exemple C = A + B. en fait toutes ces boucles ont déjà été implémentées dans
le module.
import numpy as np
np.random.seed(0)
A = (np.random.randint(0, 10, [2,3]))
print(A)
B = np.ones((2, 3))
print(A)
print("Somme : ", A + B)
33 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Lorsque nous faisons des opérations sur des tableaux de dimensions différentes en principe nous obtenons
une erreur.
import numpy as np
np.random.seed(0)
A = (np.random.randint(0, 10, [2,3]))
print(A)
B = np.ones((2, 2))
print(A)
print("Somme : ", A + B) #erreur
Mais avec Numpy, pas forcement. Si le tableau peut être étendu, alors l’opération peut être effectuée.Pour
cela, l’un des tableaux va être étendu: c’est ce qu’on appel le BROADCASTING. Par exemple si on fait
le tableau A + 2, où 2 est un scalaire et donc un tableau de dimension (1, 1) ; ce tableau sera étendu pour
s’additionner au reste des indices du tableau A.
import numpy as np
A = np.ones((2, 3))
B = 3
print(A+B) # résultat
De même si nous avons un vecteur B on eut faire l’opération. Ce tableau sera étendu pour s’additionner
au reste des indices du tableau A.
B = np.ones((2,1)) #B est de dimensions 2 lignes 1 colonne
print(B)
print("Somme : ", A + B) # résultat
Il y’a toutefois des règles à respecter : chacune des dimensions dans A et B doivent être égale ou égales à
1. Si les deux tableaux sont différents, l’une des dimensions doit être égale dans les deux tableaux et
l’autre égale à 1 dans l’un des tableaux. Dans le cas des matrices lignes et des matrices colonnes, les deux
tableaux font s’étendre mutuellement pour s’additionner.
A = np.ones((2, 3))
print(A)
B = np.ones((2, 1)) # B a une colonne, elle sera étendu sur les trois colonnes de A
print(B)
print("Somme : ", A + B) # résultat
A = np.ones((2, 3))
print(A)
B = np.ones((1, 3)) # B a trois colonnes et une ligne, elle sera étendu sur les deux lignes de A
print(B)
print("Somme : ", A + B) # résultat
A = np.ones((4, 1)) # Aa une colonne et quatre lignes, elle sera étendu
print(A)
B = np.ones((1, 3)) # B a trois colonnes et une ligne, elle sera étendu
print(B)
print("Somme : ", A + B) # résultat
A = np.ones((2, 3))
print(A)
B = np.ones((2, 2)) # B a deux colonnes et deux ligne, elle ne sera pas étendu
print(B)
34 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
print("Somme : ", A + B) # Erreur
Note : évitez toutefois de travailler en broadcasting avec des dimensions incomplètes du genre (3,) pour
éviter d’avoir des résultatsinattendus. En fait (3,) donnerait 3 lignes et une colonne, mais en broadcasting
ce résultat ne sera pas obtenu. Il faut donc pensez à bien redimensionner nos matrices du genre (3,1) en
utilisant la méthode reshape.
35 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 8 : Matplotlib : Graphiques de Base
Matplotlib est un outil très puissant qui va vous permettre de tracer très facilement tous les graphiques
que vous pourriez imaginer, des graphiques qui montrent réellement le comportement de vos systèmes.
De manière générale, le but d’un graphique est de :
- Voir, plutôt qu’imaginer l’abstrait,
- Mieux comprendre le problème,
- Mieux expliquer un phénomène,
- Nous aider à mieux comprendre et interpréter les chiffes dans la résolution de nos problèmes.
Matpltlib est facile si vous faite simple : évitez
de mettre trop de détails dans les courbes. Mais
surtout évitez de mélanger les méthodes OOP
(orientée objet) et pyplot (plt.plot).
Les deux méthodes donnent exactement le même
résultat donc il est préférable de travailler avec
l’une des deux.
II.1) Pyplot
Nous allons utiliser la méthode plot qui vient du module pyplot de
matplotlib, et qui est plus simple à utiliser.
import numpy as np
36 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
import matplotlib.pyplot as plt
Pour utiliser cette méthode, il faut définir les données à afficher sur l’axe X, puis celles a afficher sur
l’axe Y, à la condition que X et Y soient de dimensions égales. Plt.show() permet d’afficher le graphique.
a.1) Graphiques simples
import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0, 2, 10)
y = X**2
plt.plot(X, y)
plt.show()
La fonction scatter permet de tracer un nuage de points.
plt.scatter(X, y)
plt.show()
a.2) Styles Graphiques
Il existe beaucoup de styles à ajouter aux graphiques. Voici les plus
importants à retenir :
- c : couleur de la ligne
- lw : épaisseur de la ligne (pour les graphiques plots)
- ls : style de la ligne (pour les graphiques plots)
- size : taille du point (pour les graphiques scatter)
- marker: style de points (pour les graphiques scatter)
- alpha : transparence du graphique
plt.plot(X, y, c='red', lw=4, ls='--', alpha=0.8)
plt.show()
a.3) Cycle de vie d'une figure
Pour créer des figures proprement, on doit suivre le cycle de vie
suivant :
- plt.figure(figsize = (dim x, dim y)) : permet de créer la feuille
de travail sur laquelle la fenêtre va s’afficher. Nous devons
préciser les dimensions de la feuille en inch.
- plt.plot() : permet de tracer les courbes dans la feuille (figure) que nous avons créé. La légende du
graphe est définie dans cette fonction.
- Extras (titre, axes, légendes) : pour donner plus de renseignement sur le graphe.
- plt.show() : permet d’afficher le graphique
- plt.savefig(‘nom_im.extention’) : permet de sauvegarder notre figure dans le répertoire de
travail de notre disque dur sous forme d’image.
37 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
X = np.linspace(0, 2, 10)
plt.figure() # Création d'une figure
plt.plot(X, X**2, label='quadratique') # première courbe
plt.plot(X, X**3, label='cubique') # deuxième courbe
# Extra information
plt.title('figure 1') # titre
plt.xlabel('axe x') # axes
plt.ylabel('axe y') # axes
plt.legend() # legend
plt.savefig('figure.png') # sauvegarde la figure dans le repertoire de
travail
plt.show() # affiche la figure
a.4) Subplots
Les subplots sont un autre élémentà ajouter pour créer plusieurs graphiques sur une même figure.
Avec l’utilisation des fonctions subplot(), le cycle de vie des
fonctions est légèrement modifié. Il faut donc définir les
informations de chaque graphe dans sa section.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2, 10)
y = x**2
plt.figure() # Création d'une figure
plt.subplot(2, 1, 1)
plt.plot(x, y, c='red', label='graphe 1')
plt.title('Graphique 1')
plt.legend()
plt.subplot(2, 1, 2)
plt.plot(x, np.sin(x), c='blue', label='sinus x')
plt.plot(x, np.cos(x), c='green', label='cosinus x')
plt.title('Graphique 2')
plt.legend()
plt.show() # affiche la figure
a.5) Méthode orientée objet
Nous avons dit au début qu’il existe deux méthodes pour tracer les graphes sur matplotlib. Apres le
module pyblot, ici nous verrons quelques éléments d’orientées objet pour tracer les graphes. Mais
personnellement, je vous conseil de mémoriser la première méthode basée sur pyplot, parce qu’au final
les deux presque le même travail. Toutefois la méthode OOP est légèrement plus poussée mais pourra
également vous apporter beaucoup d’ennuie. Et n’oubliez pas de ne jamais mélanger les deux méthodes.
38 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Ici on commence par créer deux objets : une figure et un axe qui pourrons utiliser des méthodes. Pour ce
faire on utilise la fonction subplots() ici avec s contrairement à subplot() vu précédemment.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2, 10)
y = x**2
fig, ax = plt.subplots()
ax.plot(x,y)
plt.show()
La technique orientée objet est plus intéressant que la première méthode
parce qu’il y’a plus de possibilité. On peut par exemple créer des
graphiques qui partagent la même abscisse (avec l’attribut sharex = True)
ou la même ordonnée (avec l’attribut sharey = True). Mais dans ce cas, il
faut afficher chaque graphe à une position. Etant donnée que fig est un
objet, et ax un tableau ndarray qui contient des objets, il faut préciser la
position de chaque objet. Et dans la fonction subplots(), il faut définir le
nombre d’objets.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2, 10)
y = x**2
fig, ax = plt.subplots(2, 1, sharex=True) # partage le même axe pour les subplots
ax[0].plot(x, y, c='red')#on trace le premier graphe
ax[1].plot(x, np.sin(x), c='green')#on trace le deuxième graphe
plt.show()
Exercice : fonction graphique
Créez une fonction "graphique" qui permet de tracer sur une seule et même
figure une série de graphiques issue d'un dictionnaire contenant plusieurs
Dataset s. Nous utiliserons le Dataset suivant :
Def graphique(Dataset ):
# Votre code ici...
return
# Voici le Dataset utilisé
Dataset = {f"experience{i}": np.random.randn(100) for i inrange(4)}
print(Dataset )
II.2) Matplotlib Top Graphiques
Il s’agit principalement ici de présenter le top cinq des graphiques les plus utiles pour faire du machine
Learning.
a.1) Graphique de Classification avec Scatter()
En machine Learning, la grande majorité des problèmes que vous allez rencontrer sont de problèmes de
classification.
39 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Par exemple, on peut vouloir classer un mail : il sera dans notre boite de réception (non spam) ou dans la
boite de Spam en fonction de plusieurs attributs
que le mail aura : le nombre de fautes
d’orthographe, le nombre de lien internet
contenue dans le mail. Pour résoudre ce
problème, nous avons deux classes (Spam et Non-
Spam). Pour représenter un tel Dataset de
classification, le graphique plt.scatter() est un des
meilleurs choix que vous pourriez faire.
Dans ce cours, nous allons voir comment faire un tel graphique avec Dataset assez connu : celui de la
fleur de d’Iris. Ce Dataset contient 150 exemples de fleurs d’iris repartis en trois classes et on dispose de
quatre variables pour prédire de quelle classe il s’agit. Les variables sont : la longueur et la largeur du
pétale de la fleur et la longueur et la largeur du sépale de la fleur.
Pour réussir cette analyse, nous avons utilisé le Dataset de la fleur d’iris disponible dans le package
sklearn (qui contient un ensemble de datatsets que nous verrons plus tard).
import numpy as np
import matplotlib.pyplot as plt
from sklearn.Dataset s import load_iris#on importe le Dataset de la fleur d’iris à contenu dans Sklearn
iris = load_iris()# on charge le data dans un tableau nommé iris
x = iris.data#le Dataset contient les données (nos variables : longueurs et largeurs du pétale et du sépale)
y = iris.target#le Dataset contient également nos classes : 0, 1 et 2.
Nous enregistrons ses tableaux dans les variables x et y qui vont nous servir pour créer nos graphiques.
On peut parcourir les tableaux pour savoir ce qu’ils contiennent :
print(f'x contient {x.shape[0]} exemples et {x.shape[1]} variables') # x contient 150 exemples et 4 variables
print(f'il y a {np.unique(y).size} classes') # il y a 3 classes
Ou simplement afficher les tableaux et voir que x a effectivement 4 colonnes et 150 lignes et que y
contient bien 150 exemples répartis en trois classes (0, 1 et 2)
print(x)
print(y)
40 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Un des meilleurs choix pour visualiser un tel Dataset, comme nous avons dis c’est d’utiliser plt.sacatter.
On pourrait dans un premier temps se contenter de fairepasser en abscisses de des 4 variables que nous
avons :
plt.scatter(x[:, 0], x[:, 1]) #on prend toutes les lignes de la colonne 0, on fait de même pour la colonne 1
plt.show()
On obtient un nuage de point. On peur par la suite s’amuser à colorier chaque point du nuage de point en
fonction de sa classe (on sait que y contient nos classes) :
plt.scatter(x[:, 0], x[:, 1], c=y, ) #on prend toutes les lignes de la colonne 0, on fait de même pour la colonne 1
plt.xlabel('longueur sépale')
plt.ylabel('largeur sépale')
plt.show()
On aura donc notre nuage contenant trois couleurs de point où les points sont repartis par classes en
fonction de deux variables x[0] et x[1] qui représentent respectivement la longueur du sépale et la largeur
du sépale. Le paramètre alpha permet de contrôler la transparence de nos oints et s permet de contrôler la
taille.
plt.scatter(x[:, 0], x[:, 1], c=y, alpha= 0.5, s= 100) #on modifie la taille et la transparence
plt.xlabel('longueur sépale')
plt.ylabel('largeur sépale')
plt.show()
C’est encore plus intéressant parce qu’on peut contrôler la taille de nos points en fonction de nos variable
(col 0 : longueur sépale, col 1 : largeur sépale, colonne 2 : longueur pétale, col 3 : largeur pétale). Si on
prend donc la troisième variable, tous les points n’auront pas la même taille. Plus le point sera gros plus la
longueur de son pétale sera grande et inversement.
plt.scatter(x[:, 0], x[:, 1], c=y, alpha= 0.5, s= x[:, 2]*100) #on modifie la taille en fonction de la longueur
plt.xlabel('longueur sépale')
plt.ylabel('largeur sépale')
plt.show()
Une des limites de plt.scatter est que nous ne pouvons représenter
que deux des 4 variables dont nous disposons. Mais ce problème
peut être résolu en utilisant les notions déjà vues.
n = x.shape[1]
plt.figure(figsize=(12, 8))
for i inrange(n):
plt.subplot(n//2, n//2, i+1)
plt.scatter(x[:, 0], x[:, i], c=y)
plt.xlabel('0')
plt.ylabel(i)
plt.colorbar(ticks=list(np.unique(y)))
plt.show()
a.2) Graphiques 3D
Le graphique 3D nous vient de mpl_toolkits qui est l’un des sous package de maplotlib. Avec ce package
on peut faire des graphique 3D qui peuvent se montrer très utile quand on désire visualiser plusieurs
variablesd’un seul coup sur un seul et même graphique. Pour y parvenir, il faut commercer par charger les
graphiques 3D que nous avons dans mpl_toolkits ensuite il faut créer un objet axe avec la foncions axes
41 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
que nous avons dans plt avec le paramètre projection = ‘3D’. Vous aurez compris que la création de
graphique 3D avec maplotlib utilise la POO (pas vraiment compliqué). Pour afficher nos variables, on
appel la méthode scatter sur l’objet axe que nous avons crée et lui passant en paramètres les valeurs des
variables à afficher. On peut colorier par classes avec l’attribut c=y vu précédemment.
import matplotlib.pyplot as plt
from sklearn.Dataset s importload_iris
from mpl_toolkits.mplot3d importAxes3D# on charge des graphiques 3D que nous avons dans mpl_toolkits
iris = load_iris() # on charge le data dans un tableau nommé iris
x = iris.data #le Dataset contient les données (nos variables : longueurs et largeurs du pétale et du sépale)
y = iris.target #le Dataset contient également nos classes : 0, 1 et 2.
ax = plt.axes(projection='3d')# création d’un objet ax avec la foncions axes que nous avons dans plt
ax.scatter(x[:, 0], x[:, 1], x[:,2], c=y)#appel de scatter sur ax avec en paramètres les valeurs des variables à afficher
plt.show()
Vous pouvez désormais vois le graphe en 3D, tourner dans tous les sens,
zoomer, … pour afficher le rendu sur Jupiter, il faut commencer le code
par %matplotlib.
Vous pourrez désormais visualiser des surfaces et d’autres fonctions
mathématiques que vous aurez modélisées.
Prenons pour l’exemple une fonction f(x, y) = np.sin(x) + np.cos(x+y) que nous créons avec la fonction
lambda qui est un générateur de fonction anonyme. Pour afficher une fonction pareille en 3D, il faut tout
d’aborddéfinirdeux vecteurs numpy X et Y (même nombre de valeurs) et ensuite générer une grille avec
la fonction meshgrid() de numpy. La fonction meshgrid()
nous permet de créer une grille a partir de deux axes X et Y.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d importAxes3D
f = lambdax, y: np.sin(x) + np.cos(x+y)# on définie la fonction f
X = np.linspace(0, 5, 50) # on définie la plage de valeurs du vecteur X comprenant
50 valeurs
Y = np.linspace(0, 5, 50)# on définie la plage de valeurs du vecteur y comprenant
50 valeurs
X, Y = np.meshgrid(X, Y)# on génère la grille en fonction de X et Y
Z = f(X, Y)# on définie une variable Z qui est égale a notre fonction
ax = plt.axes(projection='3d')# création d’un objet ax avec la foncions axes que
nous avons dans plt
ax.plot_surface(X, Y, Z, cmap='plasma')#appel de scatter sur ax avec en paramètres les
valeurs des variables à afficher
plt.show()
a.3) Histogrammes
C’est un graphique très important, parce qu’il permet de voir la distribution des données sur lesquelles
nous travaillons. Il est parfois important de connaitre si la distribution de ns données est normale,
symétrique, asymétrique ou de visualiser où se situe la moyenne, le maximum, le minimum, …
42 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(1000)
plt.figure(figsize=(12, 3))
plt.subplot(121)
plt.hist(x, bins=10)
plt.title('bins=10')
plt.subplot(122)
plt.hist(x, bins=50)
plt.title('bins= 50')
plt.show()
Si nous reprenons notre datatset avec les fleurs d’iris, on peut décider de visualiser comment sont
distribuées nos quatre variables. On peut donc faire passer l’une de nos variables dans la fonction hist() de
matplotlib et voir comment les données sont distribuées.
from sklearn.Dataset s importload_iris
import matplotlib.pyplot as plt
iris = load_iris()
x = iris.data
plt.hist(x[:,0])# données de la variable 0
plt.xlabel('longueur sépal')
plt.show()
On peut ainsi voir la distribution des données de la variable 0 des toutes nos Feurs d’iris : sur l’axe des
abscisses nous avons toutes les valeurs que peuvent prendre la longueur d’un sépale, ainsi le sépale le
plus petit aura avirons 4,5cm et le plus long un peut moins de 8 cm. Sur l’axe des ordonnées nous avons
le nombre d’apparition de chaque catégorie ; on peut voir qu’on aura un peu plus de 25 fois les sépales de
5,5 cm de long. L’attribut bins dans la fonction hist() permet de définir le nombre de section qu’on
souhaite avoir. Ici nous avons 10 sections par défaut, mais nous pouvons décider d’avoir plus : 20, 30 …
On peut également tracer la distribution de plusieurs variables sur un même histogramme :
from sklearn.Dataset s importload_iris
import matplotlib.pyplot as plt
iris = load_iris()
x = iris.data
plt.hist(x[:,0], bins=20)# données de la variable 0
plt.hist(x[:,1], bins=20)# données de la variable 1
plt.xlabel('longueur sépal')
plt.ylabel('Nbre Apparition')
plt.show()
On peut également tracer des histogrammes en de 2D avec la méthode hist2d() pour visualiser la
distribution des données lorsqu’elles suivent deux variables. On
peut y ajouter une colorbar qui permet de voir la fréquence des
apparitions.
from sklearn.Dataset s importload_iris
import matplotlib.pyplot as plt
iris = load_iris()
x = iris.data
plt.hist2d(x[:,0], x[:,1], cmap='Blues')
plt.xlabel('longueur sépal')
plt.ylabel('largeur sépal')
plt.colorbar() #legende : a quoi correspond chacune des couleurs
plt.show()
43 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Enfin, une autre fonction très utile des histogrammes c’est l’analyse des images. Pour faire l’analyse
d’une image en une couleur (noir/blanc par exemple), il faut définir bins = 255. Nous avons vu
précédemment qu’une image comportait 255 valeurs de pixel dont les couleurs allaient de 0 pour le foncé
(noir dans le cas d’une image N/B) à 255 pour le claire (blanc).
import matplotlib.pyplot as plt
from scipy import misc#on imorte l’image depuis scipy
# histogramme d'une image
face = misc.face(gray=True) # on enregistre dans l’image dans un tableau numpy appelé face
plt.figure(figsize=(12, 4))
plt.subplot(121)
plt.imshow(face, cmap='gray') #on affiche l’image en N/B
plt.subplot(122)
plt.hist(face.ravel(), bins=255) #on affiche l’histogramme de l’image, ravel permet d’aplatir l’image sur 1 dim
plt.xlabel('Valeur de Pixels')
plt.ylabel('Apparition')
plt.show()
a.4) Graphiques ContourPlot()
Les graphiques contoursplot sont très utiles pour visualiser les modèles qui occupent trois dimensions en
vue de dessus. C’est le cas avec les problèmes d’optimisation ou il est parfois question de trouver le
minimum d’une fonction cout ou de maximiser les revenus. Ce type de graphique joue un rôle majeur
dans la compréhension des problèmes d’optimisation sur lesquels nous travaillons.
Pour exprimer, nous pouvons reprendre la fonction f(x, y) = np.sin(x) + np.cos(x+y) que nous avons
modélisée précédemment et visualiser en 3D. Essayons de la visualiser maintenant en vue de dessus.
import matplotlib.pyplot as plt
import numpy as np
f = lambdax, y: np.sin(x) + np.cos(x+y)
X = np.linspace(0, 5, 50) # on définie la plage de valeurs du vecteur X
comprenant 50 valeurs
Y = np.linspace(0, 5, 50) # on définie la plage de valeurs du vecteur y
comprenant 50 valeurs
X, Y = np.meshgrid(X, Y) # on génère la grille en fonction de X et Y
Z = f(X, Y) # on définie une variable Z qui est égale a notre fonction
plt.contour(X, Y, Z) #appel de contour plot pour visualiser la fonction en vue de
dessus
plt.show()
On obtient ainsi une vue du dessus 3D de notre fonction. On peut rendre ce graphique un peut plus lisible
en augmentant le nombre de niveau (20 par exemple) pour augmenter la précision d’affichage et en jouant
sur les couleurs.
44 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d importAxes3D
f = lambdax, y: np.sin(x) + np.cos(x+y)
X = np.linspace(0, 5, 50)
Y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(X, Y)
Z = f(X, Y)
plt.contour(X, Y, Z, 20, colors='black') #précision et couleur
plt.show()
Avec la couleur noire on obtient ce graphe en noir sur blanc ou tout
ce qui est positif est en trait continu et tout ce qui est négatif est en traits interrompus.
Que nous soyons en mathématique, en économie, en ingénierie ou que nous ayons des fonctions plus
complexeà optimiser les contourplot sont très utiles pour nous aider à y voir plus claire. On peut
également utiliser l’attribua cmap qui permet de créer une color map.
#contour plot 2
f = lambdax, y: np.sin(x) + np.cos(x+y)
X = np.linspace(0, 5, 50)
Y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(X, Y)
Z = f(X, Y)
plt.contour(X, Y, Z, 20, cmap='RdGy') #précision et relief de couleurs
plt.show()
Ainsi on pourra atteindre le maximum de notre fonction si on tend vers le petit cercle noir et le minimum
si on tend vers le petit cercle rouge (on peut utiliser colors='black' pour mieux visualiser).
Nous pouvons égaiement utiliser une autre fonction : contourf pour jouer sur les nuances de couleurs.
Ainsi on peut ajouter une légende (colorbar) qui permet d’avoir les valeurs qui maximisent et minimisent
nos fonctions.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d importAxes3D
f = lambdax, y: np.sin(x) + np.cos(x+y) * np.cos(x) #fonction un peu plus
complexe
X = np.linspace(0, 5, 50)
Y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(X, Y)
Z = f(X, Y)
plt.contourf(X, Y, Z, 20, cmap='RdGy') #utilisation de contourf et de la
colorbar
plt.colorbar()
plt.show()
On peut donc lire les valeurs des gradients sur la légende de notre contour plot. On peut également
superposer les deux styles de contour plots.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d importAxes3D
f = lambdax, y: np.sin(x) + np.cos(x+y) * np.cos(x) #fonction un peu plus complexe
X = np.linspace(0, 5, 50)
Y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(X, Y)
Z = f(X, Y)
45 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
plt.contour(X, Y, Z, 20, colors='black') #precision et couleur
plt.contourf(X, Y, Z, 20, cmap='RdGy') #utilisation de contourf et de la colorbar
plt.colorbar()
plt.show()
a.5) Imshow()
C’est le graphique qui se place a la tête de tous les graphiques vuent jusqu’ici parce qu’il permet de faire
de choses absolument fascinante. En premier lieu, il permet de visualiser les images comme celle que
nous avons visualisée précédemment.
import matplotlib.pyplot as plt
from scipy import misc #on imorte l’image depuis scipy
face = misc.face() # on enregistre dans l’image dans un tableau
numpy appelé face
plt.imshow(face) #on affiche l’image
plt.show()
Mais son utilité va beaucoup plus loin. Si on se souvient
bien, notre image nommée face est un tableau numpy qui
contient les différents pixels de notre image. Donc imshow
permet d’afficher n’importe quel tableau numpy. C’est donc
là tout l’intérêt d’imshow : pouvoir afficher n’importe quelle matrice sur un graphique. Ainsi va pouvoir
tracer des matrices de corrélation, analyser les problèmes d’optimisation en mettant tous les schémas
possible (par exemple de tracé de labyrinthe) dans une matrice, visualiser un masque avant de l’utiliser
dans le boolean indexing, bref, le nombre de possibilité est énorme.
Affichons un graphe de distribution normal :
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(12, 3))
# Simple graphique imshow()
X = np.random.randn(50, 50)
plt.subplot(131)
plt.imshow(X)
plt.title('random normal')
plt.show()
Reprenons notre Dataset des fleurs d’iris qui contient 4 variables de 150
exemples chacune repartis en 3 classes. On fait passer à l’intérieur de imshow la fonction corrcoef qui
retourne une matrice de corrélation pour la matrice X. à l’intérieur de fonction corrcoef on fait passé la
transposé (T) de X parce que ce qui nous intéresse c’et la corrélation entre les colonnes et non les lignes.
# Matrice de corrélation des iris
import matplotlib.pyplot as plt
import numpy as np
from sklearn.Dataset s importload_iris
iris = load_iris()
X = iris.data
y = iris.target
plt.imshow(np.corrcoef(X.T), cmap = 'Blues')
plt.title('Iris Corrélation')
plt.colorbar()
plt.show()
46 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Pour finir on peut représenter un problème d’optimisation pour lequel on utilisait contour plot. Ici tout ce
qu’on a faire c’est passe le tableau Z qui est un tableau de 100lignes et 100 colonnes
import matplotlib.pyplot as plt
import numpy as np
X = np.linspace(0, 5, 100)
Y = np.linspace(0, 5, 100)
X, Y = np.meshgrid(X, Y)
# Matrice f(X, Y) = sin(X) + cos(Y) * np.cos(x)
f = lambdax, y : np.sin(x) + np.cos(x+y) * np.cos(x)
plt.imshow(f(X, Y))
plt.colorbar()
plt.title('f(x, y) = sin(x) + cos(y) * np.cos(x) ')
plt.show()
Exercice : graphe
Modifier le code de l’exercice précédent afin d’afficher sur une
seule et même figure les différentes variables qu’on a pour notre
dateset de la fleur d’iris.
#Solution
import matplotlib.pyplot as plt
from sklearn.Dataset s importload_iris
iris = load_iris()
x = iris.data
n = x.shape[1]
plt.figure(figsize=(12, 8))
…#Code ici
plt.show()
47 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 9 : Scipy : Machine Learning
Scipy contient des modules très puissants pour le machine Learning, l'analyse de données, les time séries,
etc. Cette section vous montre quelques unes des fonctions les plus utiles pour faire des calculs
scientifiques. La documentation de scipy disponible sur internet présente une multitude de petits modules
qui permettent de faire des opérations scientiques bien précises.
III.1. Interpolation
Lors de l’acquisition des signaux, il arrive parfois qu’il manque des
données, dûà la fréquence d’échantillonnage ou aux caractéristiques
descapteursutilisés. Ce qui va nous produire des Dataset s qui
manquent de valeurs. Nous pouvons résoudre le problème en
supprimant les valeurs manquantes mais l’analyse devient donc très
peu satisfaisante. L’idéale est de réaliser une interpolation afin de
compléter les données manquantes.
Interpoler un signal est parfois très utile s'il vous manque des données dans un Dataset. Mais c'est une
technique dangereuse, qui peut parfois transformer la réalité des choses ! Il faut donc déterminer la
méthode d’interpolation (linéaire, cubique, quadratique, …) qui correspond mieux aux données de notre
Dataset.
Imaginons que nous ayons un capteur qui nous donne les points suivants :
import matplotlib.pyplot as plt
import numpy as np
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = x**2
plt.scatter(x, y)
plt.show()
Si nous souhaitons placer plus de point entre les points bleus, nous allons
donc faire une interpolation en utilisant le module interpol1d qui est
l’intérieur du package scipy.interpolate. Cette fonction va nous
permettre de générer une autre fonction f( ) qui est notre fonction
d’interpolation. L’attribut kind permet de définir le typez
d’interpolation que souhaite effectuer. L‘interpolation plus basique
est l’interpolation linéaire qui trace une ligne entre deux points et
c’est elle que nous nous utiliserons dans cet exemple. On peut donc
utiliser cette nouvelle fonction f( ) en lui définissant un nouvel axe
pour lequel on peu décider d’avoir 30 points ou plus au lieu de 10.
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d
48 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = x**2
f = interp1d(x, y, kind='linear') #nouvelle fonction
new_x = np.linspace(0, 10, 30) #nouvel axe des abscisses
resultat = f(new_x) #on enregistre la fonction du nouvel axe dans une variable
resultat
plt.scatter(x, y) #on affiche la 1ere fonction sur laquelle on va supperposer la
fonction interpolée
plt.scatter(new_x, resultat, c='r') #on affiche la fonction interpolée en rouge
plt.show()
Il est important d’afficher le signal original et le signal interpolé pour se rassurer que le signal interpolé
soit conforme au signal d’origine. Ainsi, le choix du type d’interpolation est important.
Imaginons maintenant que nous ayons le signal suivant :
import matplotlib.pyplot as plt
import numpy as np
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = np.sin(x)
plt.scatter(x, y)
plt.show()
Si nous utilisons une interpolation linéaire, on se rend bien compte que le résultat n’est pas vraiment
conforme à la réalité.
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = np.sin(x)
# création de la fonction interpolation f
f = interp1d(x, y, kind='linear')
# résultats de la fonction interpolation f sur de nouvelles données
new_x = np.linspace(0, 10, 50)
resultat = f(new_x)
# visualisation avec matplotlib
plt.scatter(x, y)
plt.scatter(new_x, resultat, c='r')
plt.show()
Il faut donc prendre une interpolation qui va permettre de suivre qu maximum le signal d’origine. Ici on
peut utiliser l’interpolation cubique.
49 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate importinterp1d
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = np.sin(x)
# création de la fonction interpolation f
f = interp1d(x, y, kind='cubic')
# résultats de la fonction interpolation f sur de nouvelles données
new_x = np.linspace(0, 10, 50)
resultat = f(new_x)
# visualisation avec matplotlib
plt.scatter(x, y)
plt.scatter(new_x, resultat, c='r')
plt.show()
Ici, on obtient une interpolation qui reflète plus la réalité. On peut aussi utiliser la fonction plot pour avoir
des traits continus plutôt que des points.
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate importinterp1d
# Création d'un Dataset
x = np.linspace(0, 10, 10)
y = np.sin(x)
# création de la fonction interpolation f
f = interp1d(x, y, kind='cubic')
# résultats de la fonction interpolation f sur de nouvelles
données
new_x = np.linspace(0, 10, 50)
result = f(new_x)
# visualisation avec matplotlib
plt.scatter(x, y)
plt.plot(new_x, result, c='r')
plt.show()
Vous pouvez avoir une description de tous les types d’interpolation (linear, nearest, zero, slinear,
quadratic, cubic, previous, next) sur le site internet de scipyhttps://scipy.org/. Vous pourrez également
faire des interpolations en 2D.
III.2. Optimisation
Les problèmes d’optimisation renvoient le plus souvent aux notions d’optimisation. On trouve beaucoup
de fonctions dans le module optimize. Certaines permettent de faire des minimisations locales, ou
globales, d'autres permette de développer des modèles statistiques avec la méthode des moindres carrés.
On trouve également des fonctions pour faire de la programmation linéaire qui permet de résoudre
certains problèmes d’optimisation tout en respectant certaines contraintes.
a.1) curve_fit
La fonction curve_fit permet d’optimiser le placement d’une courbe à
l’intérieur d’un nuage de points. Imaginons qu’on a ce Dataset qui est
polynôme de degré trois auquel est greffé un peu de bruit et que nous
50 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
souhaitons développer un modèle statistique qui entre bien dans ce nuage de point. On peut donc utiliser
la fonction curve_fit qui se sert de la méthode des moindres carrés pour trouver les meilleurs paramètres
a, b c, … d’un modèle qu’on aura fourni a notre fonction.
import matplotlib.pyplot as plt
import numpy as np
# Création d'un Dataset avec du bruit "normal"
x = np.linspace(0, 2, 100)
y = 1/3*x**3 - 3/5 * x**2 + 2 + np.random.randn(x.shape[0])/20
plt.scatter(x, y)
plt.show()
Donc pour utiliser cette fonction il faut d’abord définir un modèle. On créer donc un modèle f qui est
fonction de différents paramètres : x, a, b, c et d. on va donc donner ce modèle a la fonction curve_fit. On
commencer par importer le module optimize pour utiliser la fonction curve_fit à laquelle on donne le
modèle et les données (x et y) qu’il ya dans notre Dataset. Cette fonction retourne deux tableaux numpy :
params qui contiennent les différents paramètres de notre modèle (a, b, c, et d) et param_cov qui contient
les différentes covariances qu’il y’a entre ses paramètres (c’est a matrice de covariance du modèle).
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
# Création d'un Dataset avec du bruit "normal"
x = np.linspace(0, 2, 100)
y = 1/3*x**3 - 3/5 * x**2 + 2 + np.random.randn(x.shape[0])/20
# Définition d'un modèle statistique sensé "coller" au Dataset ci-
dessus
deff (x, a, b, c, d):
returna * x**3 + b * x**2 + c * x + d
# curve_fit permet de trouver les paramètres du modèle f grâceà la
méthode des moindres carrés
params, param_cov = optimize.curve_fit(f, x, y)
print(params) #paramètre du modèle
print(params_cov)#covariance être es paramètres
# Visualisation des résultats.
plt.scatter(x, y)
plt.plot(x, f(x, params[0], params[1], params[2], params[3]), c='g', lw=3)
plt.show()
a.2) Minimisation 1D
La fonction optimize.minimize est utile pour trouver un minimum
local dans une fonction à N dimensions.
import matplotlib.pyplot as plt
import numpy as np
# Définition d'une fonction a 1 Dimension
deff (x):
returnx**2 + 15*np.sin(x)
# Visualisation de la fonction
x = np.linspace(-10, 10, 100)
plt.plot(x, f(x))
plt.show()
Pour utiliser cette fonction il faut définir un point de départ
x0 (-8 par exemple) a partir duquel la fonction va exécuter
51 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
un algorithme de minimisation qui va peut a peu converger vers le premier minimum qu’il va trouver.
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
# Définition d'une fonction a 1 Dimension
deff (x):
returnx**2 + 15*np.sin(x)
# Visualisation de la fonction
x = np.linspace(-10, 10, 100)
# Définition d'un point x0 pour l'algorithme de minimisation
x0=-8
result = optimize.minimize(f, x0=x0).x # résultat de la minimisation
# result = coordonné de x0
# Visualisation du résultat
plt.plot(x, f(x), lw=3, zorder=-1) # on trace la Courbe de la fonction
plt.scatter(x0, f(x0), s=200, marker='+', c='g', zorder=1, label='initial') #
on place le point initial
plt.scatter(result, f(result), s=100, c='r', zorder=1, label='final') # on
place le point final
plt.legend()
plt.show()
Là on obtient le minimum local, or nous cherchons le minimum global.
On peut donc choisir un autre point de départ x0 = -5.
a.3) Minimisation 2D
La fonction minimize peut être utilisée sur des fonctions à 2D ou 3D, …. Si nous prenons notre dernière
fonction sur matplotlib que nous avons visualisé à l’aide d’un contourplot. On peur voir dans ce graphe la
présence de maximums et de minimums.
import matplotlib.pyplot as plt
import numpy as np
# Définition d'une fonction 2D. X est un tableau numpy a 2-Dimension
deff (x):
return np.sin(x[0]) + np.cos(x[0]+x[1])*np.cos(x[0])
# Génération de la fonction sur un espace 2D.
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
x, y = np.meshgrid(x, y)
# Visualisation de la fonction
plt.contour(x, y, f(np.array([x, y])), 20)
#plt.contour(x, y, f(np.array([x, y])), 20, colors='black')
plt.show()
On va donc essayez de trouver le minimum dans cette fonction. Ici nous on va initialiser la fonction avec
points x0 = (0, 0) (étant donné que nous sommes en 2D).
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
# Définition d'une fonction 2D. X est un tableau numpy a 2-
Dimension
deff (x):
return np.sin(x[0]) + np.cos(x[0]+x[1])*np.cos(x[0])
# Génération de la fonction sur un espace 2D.
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
x, y = np.meshgrid(x, y)
52 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# Visualisation de la fonction
#plt.contour(x, y, f(np.array([x, y])), 20, colors='black')
# Placement d'un point x0 initial aux coordonnées (0,0)
x0 = np.zeros((2, 1))
# Minimisation de la fonction
result = optimize.minimize(f, x0=x0).x
print('le minimum est aux coordonnées', result) # imprimer le résultat
# Visualisation du résultat
plt.contour(x, y, f(np.array([x, y])), 20) # on dessine la fonction 2D
plt.scatter(x0[0], x0[1], marker='+', c='r', s=100, label='initial') # on place le Point de départ
plt.scatter(result[0], result[1], c='g', s=100, label='final') # on place le Point final
plt.legend()
plt.show()
A l’aide de matplotlib on peut afficher les deux points sur le même
graphe.
III.3. Traitement du signal
Le module scipy.signal contient beaucoup de fonctions de
convolution et de filtres pour faire du traitement du signal. La
fonction signal.detrend est parfaite pour éliminer une tendance
linéaire dans un signal. Utile pour beaucoup d'applications !
import matplotlib.pyplot as plt
import numpy as np
# Création d'un Dataset avec une tendance linéaire
x = np.linspace(0, 20, 100)
y = x + 4*np.sin(x) +np.random.randn(x.shape[0])
plt.plot(x, y)
plt.show()
Essayons d’éliminer la tendance linéaire du signal :
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
# Création d'un Dataset avec une tendance linéaire
x = np.linspace(0, 20, 100)
y = x + 4*np.sin(x) +np.random.randn(x.shape[0])
# Élimination de la tendance linéaire
new_y = signal.detrend(y)
# Visualisation des résultats
plt.plot(x, y, label='originel')
plt.plot(x, new_y, label='detrend')
plt.legend()
plt.show()
a.1) Transformation de Fourier (FFT)
Le module scipy.fftpack contient des fonctions très puissantes et simples d'utilisation pour effectuer des
transformations de Fourier. La transformation de Fourier est une technique mathématique puissante et
normalement complexe à mettre en œuvre. Heureusement scipy.fftpack rend cette technique très simple a
implémenter.La transformation de Fourier permet d'analyser les fréquences qui composent un signal
périodique (qui se répété avec le temps). Cette opération produit un graphique que l'on appelle Spectre.
53 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Une fois le Spectre généré, il est possible de filtrer les bruits indésirables, ou bien de sélectionner
seulement certaines fréquences, ou d'en atténuer d'autres... les possibilités sont infinies.
Dans l’image ci dessous nous avons trois signaux périodiques ayant chacun sa propre fréquence. Si nous
combinons ses trois signaux nous obtenons le signal du milieu (c’est ce genre de signaux que nous avons
autour de nous : le son, le rythme cardiaque, les ondes, …) qui est une combinaison de fréquence. La
transformation de fourrier permet d’extraire chaque fréquence qui compose un tel signal, le résultat
obtenu est appelé un spectre de fréquences ayant en abscisses les fréquences et en ordonné les amplitudes.
Le signal tout à droite a trois piques qui représentent chacune la fréquence de l’un des signaux qu’on avait
à gauche.
Pour obtenir un tel spectre on va chargerle module fftpack a l‘intérieur duquel on va utiliser deux
fonctions fft( ) et fftfreq( ). On commence par générer le signal :
import matplotlib.pyplot as plt
import numpy as np
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) #signal composé des 3 signaux
plt.plot(x, y)
plt.show()
On importe le module fftpack de scipy pour générer le spectre :
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) #signal composé des 3
signaux
# création des variables Fourier et Fréquences, qui permettent de
construire le spectre du signal.
fourier = fftpack.fft(y)
power = np.abs(fourier) # la variable power est créée pour éliminer les
amplitudes négatives
frequence = fftpack.fftfreq(y.size)
freq = np.abs(frequence) # la variable freq est créée pour éliminer les fréquences négatives
plt.plot(freq, power) #on affiche le spectre des fréquences
plt.xlabel('Frequences')
plt.ylabel('Amplitudes')
plt.show()
Dans l'exemple ci-dessous, ajoutons du bruit au signal et nous
comment filtrer un signal noyé dans du bruit.
import matplotlib.pyplot as plt
import numpy as np
54 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) + np.random.random(x.shape[0])*10
plt.plot(x, y)
plt.show()
L’idée ici est de retrouver le signal de départ. On va donc procéder au filtrage du signal bruité en 3
étapes :
On commence par transformer ce signal en spectre de fréquences comme dans l’exemple précédant :
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) +
np.random.random(x.shape[0])*10
# création des variables Fourier et Fréquences, qui permettent de
construire le spectre du signal.
fourier = fftpack.fft(y)
power = np.abs(fourier) # la variable power est créée pour éliminer les
amplitudes négatives
frequence = fftpack.fftfreq(y.size)
freq = np.abs(frequence) # la variable freq est créée pour éliminer les
fréquences négatives
plt.plot(freq, power) #on affiche le spectre des fréquences
plt.xlabel('Frequences')
plt.ylabel('Amplitudes')
plt.show()
On constate sur le spectre qu’il ya des fréquences parasites. Nous allons donc utiliser le boolean indexing
pour supprimer toutes ses fréquences qui sont inferieur à un seuil que nous allons lire sur l’axe des
amplitudes afin de garder nos 3 pics.
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) +
np.random.random(x.shape[0])*10
# création des variables Fourier et Fréquences, qui permettent de
construire le spectre du signal.
fourier = fftpack.fft(y)
power = np.abs(fourier) # la variable power est créée pour éliminer
les amplitudes négatives
55 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
frequence = fftpack.fftfreq(y.size)
freq = np.abs(frequence) # la variable freq est créée pour éliminer les fréquences négatives
# filtre du spectre avec du boolean indexing de Numpy
fourier[power<400] = 0#on supprime toutes les fréquences dont l'amplitude est < a 400
plt.plot(freq, np.abs(fourier)) #on affiche le spectre des fréquences filtrées
plt.xlabel('Frequences')
plt.ylabel('Amplitudes')
plt.show()
On va utiliser la transformer de fourrier inverse pour revenir dans le monde du réel et afficher de nouveau
les signaux temporels.
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) +
np.random.random(x.shape[0])*10
# création des variables Fourier et Fréquences, qui permettent
de construire le spectre du signal.
fourier = fftpack.fft(y)
power = np.abs(fourier) # la variable power est créée pour
éliminer les amplitudes négatives
frequence = fftpack.fftfreq(y.size)
freq = np.abs(frequence) # la variable freq est créée pour éliminer les fréquences négatives
# filtre du spectre avec du boolean indexing de Numpy
fourier[power<400] = 0#on supprimes toutes les fréquences dont l'amplitude est < a 400
# Transformation de Fourier Inverse: génère un nouveau signal temporel depuis le spectre filtré
filtered_signal = fftpack.ifft(fourier) #transformation de fourrier inverse
# Visualisation des résultats
plt.figure(figsize=(12, 8))
plt.plot(x, y, lw=0.5, label='signal originel')
plt.plot(x, filtered_signal, lw=3, label='signal filtré')
plt.legend()
plt.xlabel('Periode')
plt.ylabel('Amplitude')
plt.show()
On constate que le signal n’est pas aligné sur l’axe (0,0), on peut donc utiliser la fonction detrend pour
ajuster la ligne de base.
import matplotlib.pyplot as plt
import numpy as np
from scipy import fftpack
from scipy import signal
# Création d'un signal périodique noyé dans du bruit.
x = np.linspace(0, 30, 1000)
y = 3*np.sin(x) + 2*np.sin(5*x) + np.sin(10*x) + np.random.random(x.shape[0])*10
# création des variables Fourier et Fréquences, qui permettent de construire le spectre du signal.
fourier = fftpack.fft(y)
power = np.abs(fourier) # la variable power est
créée pour éliminer les amplitudes négatives
frequence = fftpack.fftfreq(y.size)
freq = np.abs(frequence) # la variable freq est
créée pour éliminer les fréquences négatives
# filtre du spectre avec du boolean indexing de
Numpy
fourier[power<400] = 0#on supprimes toutes les
fréquences dont l'amplitude est < a 400
56 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
# Transformation de Fourier Inverse: génère un nouveau signal temporel depuis le spectre filtré
filtered_signal = fftpack.ifft(fourier)
# Élimination de la tendance linéaire
new_y = signal.detrend(filtered_signal)
# Visualisation des résultats
plt.figure(figsize=(12, 8))
plt.plot(x, y, lw=0.5, label='signal originel')
plt.plot(x, filtered_signal, lw=3, label='signal filtré')
plt.plot(x, new_y, label='signal detrend') #ajustement de la ligne de base
plt.legend()
plt.xlabel('Periode')
plt.ylabel('Amplitude')
plt.show()
III.4. Image processing : ndimage
scipy.ndimage propose de nombreuses actions pour le traitement d'images: convolutions, filtres de
Gauss, méthode de mesures, et morphologie.
La morphologie est une technique qui permet de transformer une matrice (et donc une image) par le
déplacement d'une structure sur chaque pixel de l'image. Lorsqu'un pixel "blanc" est visité, la structure
peut effectuer une opération :
1. De dilation : imprime des pixels
2. D’érosion : efface des pixels
Cette technique peut être utile pour nettoyer une image des artefacts qui peuvent la composer.
On peut utiliser ces techniques de morphologies pour enlever des petits artefacts qu’on retrouve sur une
image. Nous modélisons une image dans laquelle nous incrustons de petits artefacts que nous allons
essayez d’enlever avec l’image processing.
import matplotlib.pyplot as plt
import numpy as np
# Création d'une image avec quelques artefacts
np.random.seed(0)
X = np.zeros((32, 32)) #on cree une matrice carré de 32 par 32
X[10:-10, 10:-10] = 1#on fait du slicing pour modifier le milieu du carré
X[np.random.randint(0,32,30),np.random.randint(0,32,30)] = 1#ajout d'artefacts aléatoires
plt.imshow(X)
plt.show()
57 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
On importe ndimage pour utiliser les techniques de morphologie. On va utiliser la fonction
binary_opening qui est une technique de morphologie qui est une combinaison de la dilation et de
l’érosion.
import matplotlib.pyplot as plt
import numpy as np
from scipy import ndimage
# Création d'une image avec quelques artefacts
np.random.seed(0)
X = np.zeros((32, 32)) #on cree une matrice carré de 32 par 32
X[10:-10, 10:-10] = 1#on fait du slicing pour modifier le milieu du carré
X[np.random.randint(0,32,30),np.random.randint(0,32,30)] = 1#ajout d'artefacts
aléatoires
# opération de binary_opening = érosion puis dilation
open_X = ndimage.binary_opening(X) #dilation + erosion
plt.imshow(open_X)
plt.show()
III.5. Application : Image processing (cas réel)
Nous allons maintenait appliquer ces techniques sur une image réel rechargée sur internet. Pour y
parvenir nous allons réaliser trois opérations :
Extraire les bactéries de l’arrière plan de l’image
Utiliser les techniques de morphologie pour enlever les artefacts présents sur l’image
Une fois que l’image est bien nettoyée, on va utiliser une fonction de ndimage pour mesurer la
taille (relative) de chaque bactérie présente sur la photo et nous présenterons les résultats dans un
graphique matplolib.
import matplotlib.pyplot as plt
# importer l'image avec pyplot
image = plt.imread('bacteria.png')#on importe l’image présente dans le répertoire
image = image[:,:,0] # réduire l'image en 2D, on prend une seule dimension
plt.imshow(image, cmap='gray') # afficher l'image
plt.show()
print(image.shape) # (507, 537)
Une fois l’image importée sur deux dimensions, on va pouvoir commencer le traitement. On va
commencer par extraire les bactéries de l’arrière plan, pour cela nous allons utiliser du boolean indexing
avec numpy. On crée une copie de notre image que nous allons aplatir sur une seule dimension avant de
créer l’histogramme.
import matplotlib.pyplot as plt
import numpy as np
# importer l'image avec pyplot
image = plt.imread('bacteria.png')
image = image[:,:,0] # réduire l'image en 2D, on prend une seule dimension
#plt.imshow(image, cmap='gray') # afficher l'image
#plt.show()
# copy de l'image, puis création d'un histogramme
image_2 = np.copy(image) # copy de l'image
plt.hist(image_2.ravel(), bins=255) # création d'un histogramme avec
l'image aplatie
58 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
plt.xlabel('Valeur de Pixels')
plt.ylabel('Nbre d’apparitions')
plt.show()
On va supprimer les tendances claires (blanches) et grise pour ne garder les sombres qui correspondes à
nos bactéries. N va donc utiliser du boolean indexing pour fileter toutes les valeurs des pixels supérieurs
0.6 et ne garder que celles inferieurs qui correspondent aux sombres. L’image obtenue est un masque
parce que le résultat du boolean indexing est en fait une fonction logique qui retourne True ou False.
import matplotlib.pyplot as plt
# importer l'image avec pyplot
image = plt.imread('bacteria.png')
image = image[:,:,0] # réduire l'image en 2D
# boolean indexing: création d'une image binaire
image= image<0.6
plt.imshow(image)
plt.show()
On constate l’apparition de quelques artefacts, on peut utiliser la fonction
binary_opening vue précédemment pour essayer de les éliminer.
import matplotlib.pyplot as plt
from scipy import ndimage
# importer l'image avec pyplot
image = plt.imread('bacteria.png')
image = image[:,:,0] # réduire l'image en 2D
# boolean indexing: création d'une image binaire
image= image<0.6
# morphologie utilisée pour enlever les artefacts
open_image = ndimage.binary_opening(image)
plt.imshow(open_image)
plt.show()
On va utiliser la fonction label de ndimage pour segmenter cette l’image et mettre une étiquette sur
chaque bactérie qu’on peut voir. Label renvoie deux variables : label_image qui va contenir notre image
sur laquelle on a mis une étiquette sur chaque bactérie qu’on peut voir et n_labels qui va contenir le
chaque étiquette qu’on a pu placer sur l’image.
import matplotlib.pyplot as plt
from scipy import ndimage
# importer l'image avec pyplot
image = plt.imread('bacteria.png')
image = image[:,:,0] # réduire l'image en 2D
# boolean indexing: création d'une image binaire
image= image<0.6
# morphologie utilisée pour enlever les artefacts
open_image = ndimage.binary_opening(image)
# Segmentation de l'image: label_image contient les différents labels et
n_labels est le nombre de labels
label_image, n_labels = ndimage.label(open_image)
print(f'il y a {n_labels} groupes') #il y a 53 groupes
# Visualisation de l'image étiquetée
plt.imshow(label_image)
plt.show()
59 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
On peut voir que 53 petites groupes ont été créés. On peut donc afficher l’image étiqueté.
On va utiliser la fonction sum de ndimage pour compter tous les pixels qu’il y’a dans chaque grouper.
Donc on va pourvoir mesurer la taille (relative) de chaque bactérie qu’il y’a sur cette photo.
import matplotlib.pyplot as plt
from scipy import ndimage
# importer l'image avec pyplot
image = plt.imread('bacteria.png')
image = image[:,:,0] # réduire l'image en 2D
# boolean indexing: création d'une image binaire
image= image<0.6
# morphologie utilisée pour enlever les artefacts
open_image = ndimage.binary_opening(image)
# Segmentation de l'image: label_image contient les différents labels
et n_labels est le nombre de labels
label_image, n_labels = ndimage.label(open_image)
print(f'il y a {n_labels} groupes') #il y a 53 groupes
# Mesure de la taille de chaque groupe de label_images (fait la somme
des pixels)
sizes = ndimage.sum(open_image, label_image, range(n_labels))
# Visualisation des résultats
plt.scatter(range(n_labels), sizes)
plt.xlabel('bactérie ID')
plt.ylabel('taille relative')
plt.show()
A partir de là nous avons un Dataset, on peut commencer à calculer une moyenne, faire des statistiques,
…
C’est génial de pouvoir créer de tels graphiques à partir des images téléchargées sur internet.
60 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Chapitre 10 : petite introduction au machine Learning
I. Pourquoi le Machine Learning est utilisé
Pour comprendre au mieux ce qu’est le Machine Learning et comment cela fonctionne, il faut commencer
par comprendre pourquoi il est utilisé. Nous, les êtres humains, sommes quotidiennement confrontés à des
problèmes que nous cherchons à résoudre. Par
exemple : Comment construire un pont plus
solide ? Comment augmenter nos bénéfices ?
Comment éliminer le cancer ? Ou tout
simplement quelle route emprunter pour aller au
travail ?
Pour nous aider dans nos recherches, nous avons
inventé l’ordinateur, qui permet de résoudre en
quelques minutes des calculs qui nous prendraient des millions d’années à effectuer. Mais il faut savoir
qu’un ordinateur ne sait en réalité faire qu’une chose : résoudre les calculs qu’on lui donne.
À partir de là, 2 situations possibles :
1. On connait le calcul à effectuer pour résoudre notre problème.
Dans ce cas, facile ! On entre ce calcul dans l’ordinateur, c’est ce qu’on appelle la programmation, et
l’ordinateur nous donne le résultat. Exemple : Déterminer la structure d’un pont
2. On ne connait pas le calcul qui résout notre problème
Dans ce cas... on est bloqué. Impossible de donner à un ordinateur un calcul que nous ne connaissons pas.
C’est comme vouloir poster une lettre que nous n’aurions pas écrite. Exemples : Reconnaitre un
visage sur une photo, Prédire le cours de la Bourse, Eliminer le cancer, Composer de la musique,
Conduire une voiture, …
Doit-on donc perdre tout espoir de voir un jour un ordinateur nous aider dans la lutte contre le cancer ?
Bien sûr que non ! Le Machine Learning a justement été inventé pour venir débloquer la situation 2
(quand on ne connait pas le calcul) en utilisant une technique audacieuse, que je vais vous dévoiler tout de
suite.
II. Laisser la Machine apprendre à partir d’expériences
Le Machine Learning consiste à laisser l’ordinateur apprendre quel calcul effectuer, plutôt que de lui
donner ce calcul (c’est-à-dire le programmer de façon explicite). C’est en tout cas la définition du
61 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Machine Learning selon son inventeur Arthur Samuel, un mathématicien américain qui a développé un
programme pouvant apprendre tout seul comment jouer aux Dames en 1959.
Un autre américain du nom de Tom Mitchell donna en 1998 une définition un peu plus moderne du
Machine Learning en énonçant qu’une machine apprend quand sa performance à faire une certaine tâche
s’améliore avec de nouvelles expériences.
III. Mais comment apprendre ?
Pour donner à un ordinateur la capacité d’apprendre, on utilise des méthodes d’apprentissage qui sont
fortement inspirées de la façon dont nous, les êtres humains, apprenons à faire des choses. Parmi ces
méthodes, on compte :
• L’apprentissage supervisé (Supervised Learning)
• L’apprentissage non supervisé (Unsupervised Learning)
• L’apprentissage par renforcement (Reinforcement Learning)
III.1. L’Apprentissage Supervisé
Imaginez que vous commenciez à apprendre le chinois. Pour ce faire, il vous faudra soit acheter un livre
de traduction chinois-français, ou bien trouver un professeur de chinois.
Le rôle du professeur ou du livre de traduction sera de superviser
votre apprentissage en vous fournissant des exemples de traductions
français-chinois que vous devrez mémoriser. On parle ainsi
d’apprentissage supervisé lorsque l’on fournit à une machine
beaucoup d’exemples qu’elle doit étudier. Pour maîtriser
l’apprentissage supervisé, il faut absolument comprendre et connaitre
les 4 notions suivantes :
o Le Dataset
o Le Modèle et ses paramètres
o La Fonction Coût
o L’Algorithme d’apprentissage
62 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
a.1) Apprendre à partir d’exemples (Dataset)
Comme pour apprendre la langue chinoise, on parle d’apprentissage supervisé lorsque l’on fournit à une
machine beaucoup d’exemples (x, y) dans le but de lui faire apprendre la relation qui relie x à y.
En Machine Learning, on compile ces exemples (x, y) dans un tableau que l’on appelle Dataset :
• La variable y porte le nom de target (la cible). C’est la valeur que l’on cherche à prédire.
• La variable x porte le nom de feature (facteur). Un facteur influence la valeur de y, et on a en
général beaucoup de features (x1, x2, …) dans notre Dataset que l’on regroupe dans une matrice
X.
Ci-dessous, un Dataset qui regroupe des exemples d’appartements avec leur prix y ainsi que certaines de
leurs caractéristiques (features).
Ce Dataset, 99.9% des gens se contentent de
l’analyser dans Excel. La bonne nouvelle,
c’est que vous ferez bientôt partie des 0.1%
de gens qui peuvent faire du Machine
Learning avec ça !
a.2) Développer un modèle à partir du
Dataset
En Machine Learning, on développe un modèle à
partir de ce Dataset. Il peut s’agir d’un modèle
linéaire comme vous pouvez le voir à gauche, ou
bien un modèle non-linéaire comme vous pouvez le
voir à droite. Nous verrons dans ce cours comment
choisir un modèle plutôt qu’un autre.
On définit a, b, c, etc. comme étant les paramètres d’un modèle.
a.3) Les erreurs de notre modèle - la Fonction Coût
Autre chose à noter est qu’un modèle nous retourne des erreurs par
rapport à notre Dataset. On appelle Fonction Coût l’ensemble de
ces erreurs (le plus souvent on prend la moyenne quadratique des
63 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
erreurs).
Allons droit au but : Avoir un bon modèle, c’est avoir un modèle qui nous donne de petites erreurs, donc
une petite Fonction Coût.
a.4) Apprendre, c’est minimiser la Fonction Coût
Ainsi l’objectif central en Supervised Learning, c’est de trouver les paramètres du modèle qui
minimisent la Fonction Coût. Pour cela, on utilise un algorithme d’apprentissage, l’exemple le plus
courant étant l’algorithme de Gradient Descent, que vous apprendrez dans la suite du cours.
a.5) Les applications du Supervised Learning
Avec le Supervised Learning on peut développer des modèles pour résoudre 2 types de problèmes :
• Les problèmes de Régression
Dans les problèmes de régression, on cherche à prédire la valeur d’une variable continue, c’est-à-dire une
variable qui peut prendre une infinité de valeurs. Par exemple :
- Prédire le prix d’un appartement (y) selon sa surface habitable (x)
- Prédire la quantité d’essence consommée (y) selon la distance parcourue (x)
• Les problèmes de Classification
Dans un problème de classification, on cherche à classer un objet dans différentes classes, c’est-à-dire
que l’on cherche à prédire la valeur d’une variable discrète (qui ne prend qu’un nombre fini de valeurs).
Par exemple :
- Prédire si un email est un spam (classe y= 1) ou non (classe y= 0) selon le nombre de liens
présent dans l’email (x)
- Prédire si une tumeur est maligne (y = 1) ou bénigne (y =0) selon la taille de la tumeur (x1) et
l’âge du patient (x2) Dans le cas d’un problème de classification, on représente souvent les
classes par des symboles, plutôt que par leur valeur numérique (0, 1, …)
64 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
a.6) Mais tout ça, on peut le faire dans Excel ?
A ce stade, vous pourriez penser que calculer le prix d’un appartement selon sa surface habitable, tout le
monde peut le faire dans Excel (Il existe même la fonction Régression dans Excel).
La force du Machine Learning, c’est qu’il est très facile de développer des modèles très complexes qui
peuvent analyser des milliers de features (x) qu’un être humain ne serait pas capable de prendre en
compte pour faire son calcul (et Excel non plus).
Par exemple, pour prédire le prix d’un appartement (y), un modèle de Machine Learning peut prendre en
compte : sa surface (x1), sa localisation (x2), sa qualité (x3), sa proximité avec un parc (x4), etc. De même,
pour prédire si un email est un spam (y), le Machine Learning peut analyser : le nombre de liens (x1), le
nombre de fautes d’orthographe (x2), etc.
Plus il y a de features disponibles, plus il existe d’informations pour que le modèle prenne des décisions
‘intelligentes’, c’est l’intelligence artificielle.
III.2. L’Apprentissage non Supervisé
D’un certain point de vue, l’apprentissage supervisé consiste à enseigner à la machine des choses que
nous connaissons déjà, étant donné que nous construisons à l’avance un Dataset qui contient des
questions x et des réponses y.
Que faire alors si vous disposez d’un Dataset sans valeur y? Que faire si vous voulez que la machine
vous aide à compléter vos connaissances en apprenant certaines choses que vous ignorez ? Rappelez-
vous, dans la section précédente, nous avons parlé d’apprendre la langue chinoise à partir d’un livre de
traduction (x, y). Que faire alors si je vous retire le bouquin et que je vous envoie vivre seul en Chine ?
Arriverez-vous à apprendre le chinois tout seul ? Il y a forcément un moyen d’y parvenir, c’est ce qu’on
appelle l’apprentissage non-supervisé (Unsupervised Learning).
a.1) Comment apprendre sans exemple de ce qu’il faut apprendre ?
Regardez ces 6 photos. Pouvez-vous les regrouper en 2 familles selon leur ressemblance ?
65 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
Bien sûr ! C’est même plutôt simple. Nul besoin de savoir s’il s’agit de cellules animales, de bactéries ou
de protéines pour apprendre à classer ces images. Votre cerveau a en fait reconnu des structures
communes dans les données que vous lui avez montrées.
Dans l’apprentissage non-supervisé, on dispose ainsi d’un Dataset (x) sans valeur (y), et la machine
apprend à reconnaitre des structures dans les données (x) qu’on lui montre. On peut ainsi regrouper des
donnés dans des clusters (c’est le Clustering), détecter des anomalies, ou encore réduire la dimension
de données très riches en compilant les dimensions ensembles. Pour ce faire, il existe des méthodes
comme : l’Algorithme de K-Mean Clustering, le réseau de neurones, …
a.2) Algorithme de K-Mean Clustering
Le K-Mean Clustering est sans doute l’algorithme le plus populaire pour les problèmes de Clustering
(regrouper des données selon leur structure commune). Il est souvent utilisé en marketing pour cibler des
groupes de clients semblables pour certaines campagnes publicitaires.
a.3) Réseaux de Neurones
Les Réseaux de Neurones sont des modèles bien plus complexes que tous les autres modèles de Machine
Learning dans le sens où ils représentent des fonctions mathématiques avec des millions de coefficients
(les paramètres).
Avec une telle puissance, il est possible d’entraîner la machine sur des tâches bien plus avancées : La
reconnaissance d’objets et reconnaissance faciale, L’analyse de sentiments, L’analyse du langage naturel,
La création artistique, Etc. Cependant, développer une fonction aussi complexe à un coût. Pour y
66 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA
Python Avancé : pour la Data-science, l’IA, le machine et le Deep Learning
parvenir, il faut souvent fournir : Un Dataset beaucoup plus grand (des millions de données), Un temps
d’apprentissage plus long (parfois plusieurs jours), Une plus grande puissance de calcul.
III.3. L’apprentissage par renforcement
C’est une méthode d’apprentissage assez populaire en robotique.
Cette dernière méthode s’inspire de la façon dont nous éduquons nos animaux de compagnie, en leur
offrant une friandise quand ils font une bonne action. Cette méthode étant mathématiquement plus
avancée que les deux premières, je n’en parlerai pas dans ce cours, mais je vous invite à aller vus
documenter le site de Guillaume Saint-Cirgue (machinelearnia.com) si vous souhaitez en savoir plus !
IV. Les 4 notions clefs du Machine Learning que vous devez absolument retenir
Le Machine Learning est un domaine vaste et complexe, et de mon expérience les gens perdent parfois de
vue l’essentiel, même en suivant des formations. Pour sortir du lot, il faut avoir les idées claires sur les
bases du Machine Learning. Vous devez ainsi retenir 4 notions essentielles, et vous verrez qu’elles vous
suivront dans tous vos projets de Machine Learning.
IV.1. Le Dataset
En Machine Learning, tout démarre d’un Dataset qui contient nos données. Dans l’apprentissage
supervisé, le Dataset contient les questions (x) et les réponses (y) au problème que la machine doit
résoudre.
IV.2. Le modèle et ses paramètres
A partir de ce Dataset, on crée un modèle, qui n’est autre qu’une fonction mathématique. Les coefficients
de cette fonction sont les paramètres du modèle.
IV.3. La Fonction Coût
Lorsqu’on teste notre modèle sur le Dataset, celui-ci nous donne des erreurs. L’ensemble de ces erreurs,
c’est ce qu’on appelle la Fonction Coût.
IV.4. L’Algorithme d’apprentissage
L’idée centrale du Machine Learning, c’est de laisser la machine trouver quels sont les paramètres de
notre modèle qui minimisent la Fonction Coût.
67 Par : EBOA Michel A. | Enseignant – Chercheur, LGIA - ENSET DOUALA