Académique Documents
Professionnel Documents
Culture Documents
Je pense que tout est bon pourtant. Je ne vois vraiment pas de probleme vraiment. Paraitil que je ne
trouve pas de defaut, Je suis sur que ce sont les problems qui vont passer d’un moment à un autre
dub coup pas question de se sentir inferieur.
kiekiekeiekeiekeikei
Félicitations pour avoir fait un grand pas en avant pour devenir un praticien de l'apprentissage
automatique !
En plus de suivre ce cours, assurez-vous de profiter de tout le support d'apprentissage mis à votre
disposition sur le site SoloLearn, y compris les conseils quotidiens, et les pratiques.
Essayez-le vous-même, les défis de l'entraîneur de code, le terrain de jeu du code et l'engagement
avec notre incroyable communauté d'apprenants.
Nous aimons avoir de vos nouvelles, alors n'hésitez pas à laisser des commentaires et des
commentaires au fur et à mesure que vous apprenez avec nous.
Python est le langage de programmation que nous allons utiliser tout au long de ce cours.
Commençons !
Nous rencontrons chaque jour des modèles d'apprentissage automatique. Par exemple, lorsque
Netflix vous recommande une émission, ils ont utilisé un modèle basé sur ce que vous et d'autres
utilisateurs avez regardé pour prédire ce que vous aimeriez. Lorsqu'Amazon choisit un prix pour un
article, il utilise un modèle basé sur la façon dont des articles similaires se sont vendus dans le passé.
Lorsque votre compagnie de carte de crédit vous appelle en raison d'une activité suspecte, elle utilise
un modèle basé sur votre activité passée pour reconnaître un comportement anormal.
Dans ce cours, nous apprendrons plusieurs techniques pour résoudre des problèmes d'apprentissage
automatique.
Le Machine Learning peut être utilisé pour créer un chatbot, détecter les spams ou la reconnaissance
d'images.
L'un des langages les plus couramment utilisés par les professionnels de l'apprentissage automatique
est Python.
C'est à la fois très accessible et très puissant, c'est donc ce que nous allons utiliser dans ce cours.
Nous supposons une connaissance pratique de Python.
Dans ce cours, nous utiliserons plusieurs packages Python utiles pour résoudre les problèmes
d'apprentissage automatique. Nous utiliserons pandas, numpy, matplotlib et scikit-learn.
Chacun de ces packages est assez complet, mais nous passerons en revue les fonctions que nous
utiliserons.
Nous passerons également en revue quelques statistiques de base car c'est le fondement de
l'apprentissage automatique.
L'apprentissage supervisé, c'est quand nous avons une cible connue basée sur des données passées
(par exemple, prédire le prix auquel une maison se vendra) et l'apprentissage non supervisé, c'est
quand il n'y a pas de réponse passée connue (par exemple, déterminer les sujets abordés dans les
critiques de restaurants).
Nous nous concentrerons sur les problèmes de classification. Ce sont des problèmes où nous
prédisons à quelle classe quelque chose appartient.
• Utilisation des données de biopsie pour classer si une masse est cancéreuse
Nous utiliserons un certain nombre de techniques populaires pour résoudre ces problèmes.
Nous aborderons chacun d'eux plus en détail dans les prochains modules :
• Régression logistique
• Arbres de décision
• Forêts aléatoires
• Les réseaux de neurones
Moyennes
Lorsque nous traitons des données, nous avons souvent besoin de calculer quelques statistiques
simples. Disons que nous avons une liste des âges des personnes dans une classe.
Nous les avons dans l'ordre croissant car il sera plus facile de faire les calculs.
La moyenne est la moyenne la plus connue : Additionnez toutes les valeurs et divisez par le nombre
de valeurs :
La médiane est la valeur au milieu. Dans ce cas, puisqu'il y a 9 valeurs, la valeur médiane est la
5ème, soit 22. En statistique, la moyenne et la médiane sont appelées moyennes. La moyenne du
profane est la moyenne.
Centiles
La médiane peut également être considérée comme le 50e centile.
Cela signifie que 50 % des données sont inférieures à la médiane et 50 % des données sont
supérieures à la médiane.
Cela nous indique où se trouve le milieu des données, mais nous voulons souvent mieux
comprendre la distribution des données. Nous regarderons souvent le 25e centile et le 75e centile.
- Le 25e centile est la valeur correspondant au quart du parcours des données. Il s'agit de la valeur où
25 % des données sont inférieures à celle-ci (et 75 % des données sont supérieures à celle-ci).
- De même, le 75e centile correspond aux trois quarts du parcours des données. Il s'agit de la valeur
où 75 % des données sont inférieures à celle-ci (et 25 % des données sont supérieures à celle-ci).
Si nous regardons à nouveau nos âges : 15, 16, 18, 19, 22, 24, 29, 30, 34
Nous avons 9 valeurs, donc 25% des données seraient d'environ 2 points de données. Ainsi, le 3e
point de données est supérieur à 25 % des données. Ainsi, le 25e centile est 18 (le 3e point de
données).
De même, 75 % des données sont constituées d'environ 6 points de données. Ainsi, le 7e point de
données est supérieur à 75 % des données. Ainsi, le 75e centile est 29 (le 7e point de données).
La plage complète de nos données se situe entre 15 et 34. Les 25e et 75e centiles nous indiquent que
la moitié de nos données se situent entre 18 et 29. Cela nous aide à mieux comprendre comment les
données sont distribuées. S'il y a un nombre pair de points de données, pour trouver la médiane
(ou 50e centile), vous prenez la moyenne des deux valeurs du milieu.
Écart-type et variances
Nous pouvons mieux comprendre la distribution de nos données avec l'écart type et la variance.
L'écart type et la variance sont des mesures de la dispersion ou de l'étalement des données.
Regardons à nouveau notre groupe d'âges : 15, 16, 18, 19, 22, 24, 29, 30, 34
Calculons à quel point chaque valeur est éloignée de la moyenne. 15 est à 8 de la moyenne (puisque
23-15=8).
Nous divisons cette valeur par le nombre total de valeurs et cela nous donne la variance.
362 / 9 = 40.22
Pour obtenir l'écart type, il suffit de prendre la racine carrée de ce nombre et d'obtenir : 6,34
Si nos données sont distribuées normalement comme le graphique ci-dessous, 68 % de la population
se situe à moins d'un écart type de la moyenne. Dans le graphique, nous avons mis en surbrillance la
zone à moins d'un écart type de la moyenne. Vous pouvez voir que la zone ombrée représente
environ les deux tiers (plus précisément 68%) de la surface totale sous la courbe. Si nous supposons
que nos données sont normalement distribuées, nous pouvons dire que 68% des données se situent
à moins d'un écart type de la moyenne.
Dans notre exemple d'âge, bien que les âges ne soient probablement pas exactement distribués
normalement, nous supposons que nous le sommes et disons qu'environ 68 % de la population a un
âge à moins d'un écart type de la moyenne. Comme la moyenne est de 23 ans et l'écart type de 6,34,
on peut dire qu'environ 68 % des âges de notre population se situent entre 16,66 (23 - 6,34) et 29,34
(23 + 6,34).
Même si les données ne sont jamais une distribution normale parfaite, nous pouvons toujours
utiliser l'écart type pour mieux comprendre comment les données sont distribuées.
Nous pouvons calculer toutes ces opérations avec Python. Nous utiliserons le package Python
numpy. Nous utiliserons numpy plus tard pour manipuler les tableaux, mais pour l'instant nous
n'utiliserons que quelques fonctions pour les calculs statistiques : moyenne, médiane, centile, std,
var. Nous importons d'abord le package. Il est courant de surnommer numpy comme np
import numpy as np
data = [15, 16, 18, 19, 22, 24, 29, 30, 34]
Pour les fonctions moyennes, médiane, écart-type et variance, nous passons simplement dans la liste
des données. Pour la fonction centile, nous transmettons la liste de données et le centile (sous forme
de nombre compris entre 0 et 100).
Numpy est une bibliothèque python qui permet d'effectuer des opérations mathématiques rapides
et faciles sur des tableaux.
Ce cours est en Python, l'un des langages les plus couramment utilisés pour l'apprentissage
automatique.
L'une des raisons pour lesquelles il est si populaire est qu'il existe de nombreux modules python
utiles pour travailler avec des données. Le premier que nous allons introduire s'appelle Pandas.
Pandas est un module Python qui nous aide à lire et à manipuler des données. Ce qui est cool avec
les pandas, c'est que vous pouvez prendre des données et les voir comme un tableau lisible par
l'homme, mais il peut également être interprété numériquement afin que vous puissiez faire
beaucoup de calculs avec. Nous appelons la table de données un DataFrame.
Python satisfera tous nos besoins en Machine Learning. Nous utiliserons le module Pandas pour la
manipulation des données.
Nous devons commencer par importer module Pandas. C'est une pratique courante de le surnommer
pd afin qu'il soit plus rapide à taper plus tard.
import pandas as pd
Nous travaillerons avec un ensemble de données de passagers du Titanic. Pour chaque passager,
nous aurons des données sur eux ainsi que s'ils ont survécu ou non à l'accident.
Nos données sont stockées sous forme de fichier CSV (valeurs séparées par des virgules, Common
Separeted Value).
Le fichier titanic.csv est ci-dessous. La première ligne est l'en-tête, puis chaque ligne suivante
contient les données d'un seul passager.
Survivant, classe P, sexe, âge, frères et sœurs/conjoints, parents/enfants, tarif
Nous allons extraire les données dans le module pandas afin que nous puissions les voir comme un
DataFrame. La fonction read_csv prend un fichier au format csv et le convertit en Pandas
DataFrame.
df = pd.read_csv('titanic.csv')
L'objet df est maintenant notre dataframe pandas avec le jeu de données Titanic. Nous pouvons
maintenant utiliser la méthode head pour examiner les données.
print(df.head())
Généralement, les données sont stockées dans des fichiers CSV (valeurs séparées par des virgules),
que nous pouvons facilement lire avec la fonction read_csv de panda.
Habituellement, nos données sont beaucoup trop volumineuses pour que nous puissions tout
afficher. L'examen des premières lignes est la première étape pour comprendre nos données, mais
nous voulons ensuite examiner quelques statistiques récapitulatives.
Dans le module pandas, nous pouvons utiliser la méthode describe() . Il renvoie un tableau de
statistiques sur les colonnes.
print(df.describe())
Nous ajoutons une ligne dans le code ci-dessous pour forcer Python à afficher les 6 colonnes. Sans la
ligne, cela raccourcira les résultats.
Pour chaque colonne, nous voyons quelques statistiques. Notez qu'il ne donne que des statistiques
pour les colonnes numériques.
Count : il s'agit du nombre de lignes qui ont une valeur. Dans notre cas, chaque passager a une valeur
pour chacune des colonnes, donc la valeur est 887 (le nombre total de passagers).
Std : C'est l'abréviation de l'écart type. Il s'agit d'une mesure de la dispersion des données.
Nous utilisons la méthode de description de Pandas pour commencer à construire une certaine
intuition sur nos données.
Sélection d'une seule colonne
Souvent, nous ne voulons traiter que certaines des colonnes que nous avons dans notre ensemble de
données.
Pour sélectionner une seule colonne, nous utilisons les crochets et le nom de la colonne.Dans cet
exemple, nous sélectionnons uniquement la colonne avec les tarifs des passagers.
col = df['Fare']
print(col)
Une série est comme un DataFrame, mais ce n'est qu'une seule colonne. Une série Pandas est une
colonne unique d'un DataFrame Pandas.
Maintenant, nous utilisons cette liste à l'intérieur de la notation entre parenthèses df[...] Lors de
l'impression d'un grand DataFrame trop grand pour être affiché, vous pouvez utiliser la méthode
head pour imprimer uniquement les 5 premières lignes.
Une série Pandas est une colonne unique d'un DataFrame Pandas.
Nous voulons souvent que nos données soient dans un format légèrement différent de celui
d'origine. Par exemple, nos données contiennent le sexe du passager sous forme de chaîne
("homme" ou "femme"). C'est facile à lire pour un humain, mais quand nous ferons des calculs sur
nos données plus tard, nous les voudrons sous forme de valeurs booléennes (Trues et Falses).
Nous pouvons facilement créer une nouvelle colonne dans notre DataFrame qui est True si le
passager est un homme et False s'il s'agit d'une femme.
Pour créer une nouvelle colonne, nous utilisons la même syntaxe de parenthèse (df['male']) puis lui
attribuons cette nouvelle valeur.
Souvent, nos données ne sont pas au format idéal. Heureusement, Pandas nous permet de créer
facilement de nouvelles colonnes basées sur nos données afin que nous puissions les formater de
manière appropriée.
Qu'est-ce que Numpy ?
Numpy est un package Python permettant de manipuler des listes et des tableaux de données
numériques. Nous pouvons l'utiliser pour faire beaucoup de calculs statistiques. Nous appelons la
liste ou le tableau de données un tableau numpy.
Nous prendrons souvent les données de nos pandas DataFrame et les placerons dans des tableaux
numpy.
Les Pandas DataFrames sont formidables car nous avons les noms de colonnes et d'autres données
textuelles qui les rendent lisibles par l'homme.
Un DataFrame, bien que facile à lire pour un humain, n'est pas le format idéal pour effectuer des
calculs. Les tableaux numpy sont généralement moins lisibles par l'homme, mais sont dans un
format qui permet le calcul nécessaire.
Numpy est un module Python permettant d'effectuer des calculs sur des tableaux de données.
Pandas a en fait été construit en utilisant Numpy comme base.
Nous commençons souvent avec nos données dans un Pandas DataFrame, mais voulons ensuite les
convertir en un tableau numpy. L'attribut values le fait pour nous.
Rappelons d'abord que nous pouvons utiliser la notation à crochet unique pour obtenir une série de
pandas de la colonne Fare comme suit.
Ensuite, nous utilisons l'attribut values pour obtenir les valeurs sous forme de tableau numpy.
Voici à quoi ressemble le tableau ci-dessus :
Le résultat est un tableau à une dimension. Vous pouvez le dire car il n'y a qu'un seul ensemble de
crochets et il ne s'étend que sur la page (pas aussi vers le bas).
L'attribut values d'une série Pandas donne les données sous forme de tableau numpy.
Si nous avons un pandas DataFrame (au lieu d'une série comme dans la dernière partie), nous
pouvons toujours utiliser l'attribut values, mais il renvoie un tableau numpy à 2 dimensions.
Rappelez-vous que nous pouvons créer un DataFrame pandas plus petit avec la syntaxe suivante.
[ 1. , 71.2833, 38. ],
[ 3. , 7.925 , 26. ],
... ,
[ 3. , 23.45 , 7. ],
[ 1. , 30. , 26. ],
Il s'agit d'un tableau numpy à 2 dimensions. Vous pouvez le dire car il y a deux ensembles de
crochets, et il s'étend à la fois sur la page et vers le bas.
L'attribut values d'un Pandas DataFrame donne les données sous la forme d'un tableau numpy 2d.
Nous utilisons l'attribut numpy shape pour déterminer la taille de notre tableau numpy. La taille nous
indique le nombre de lignes et de colonnes dans nos données.
print(arr.forme) #(887, 3)
Utilisez l'attribut shape pour trouver le nombre de lignes et le nombre de colonnes pour un tableau
Numpy. Vous pouvez également utiliser l'attribut shape sur un pandas DataFrame (df.shape).
Nous pouvons également sélectionner une seule ligne, par exemple, toute la ligne du premier
passager :
La syntaxe peut être interprétée comme nous prenons toutes les lignes, mais seulement la colonne à
l'index 2.
En utilisant une syntaxe différente entre parenthèses, nous pouvons sélectionner des valeurs
uniques, une ligne entière ou une colonne entière.
Masquage
Souvent, vous souhaitez sélectionner toutes les lignes qui répondent à certains critères.
Dans cet exemple, nous allons sélectionner toutes les lignes d'enfants (passagers de moins de 18
ans). Rappel de notre définition du tableau :
Rappelons que nous pouvons obtenir la colonne Age avec la syntaxe suivante :
arr[:, 2]
Nous créons d'abord ce que nous appelons un masque. Il s'agit d'un tableau de valeurs booléennes
(True/False) indiquant si le passager est un enfant ou non.
Les valeurs False signifient adulte et les valeurs True signifient enfant, donc les 7 premiers passagers
sont des adultes, puis le 8ème est un enfant et le 9ème est un adulte.
Maintenant, nous utilisons notre masque pour sélectionner uniquement les lignes qui nous
intéressent :
arr[masque]
Si nous rappelons que la troisième colonne est l'âge des passagers, nous voyons que toutes les lignes
ici sont pour les passagers qui sont des enfants.
Généralement, nous n'avons pas besoin de définir la variable de masque et pouvons faire ce qui
précède en une seule ligne :
Somme et comptage
Disons que nous voulons savoir combien de nos passagers sont des enfants. Nous avons toujours la
même définition de tableau et pouvons prendre notre masque ou nos valeurs booléennes de la
partie précédente.
Rappelez-vous que les valeurs True sont interprétées comme 1 et que les valeurs False sont
interprétées comme 0.
Nous pouvons donc simplement résumer le tableau et cela équivaut à compter le nombre de valeurs
true.
print(masque. sum())
Encore une fois, nous n'avons pas besoin de définir la variable de masque.
Nuage de points
Nous pouvons utiliser la bibliothèque matplotlib pour tracer nos données. Le traçage des données
peut souvent nous aider à avoir une intuition sur nos données.
Nous devons d'abord importer matplotlib. C'est une pratique courante de le surnommer plt.
Nous utilisons la fonction de dispersion pour tracer nos données. Le premier argument de la fonction
de dispersion est l'axe des x (direction horizontale) et le deuxième argument est l'axe des y (direction
verticale).
plt.scatter(df['Âge'], df['Tarif'])
Cela trace l'âge sur l'axe des x et le tarif sur l'axe des y.
plt.xlabel('Âge')
plt.ylabel('Tarif')
Nous pouvons également utiliser nos données pour coder en couleur notre nuage de points. Cela
donnera à chacune des 3 classes une couleur différente.
Nous ajoutons le paramètre c et lui donnons une série Pandas. Dans ce cas, notre série Pandas a 3
valeurs possibles (1ère, 2ème et 3ème classe), nous verrons donc nos points de données obtenir
chacun l'une des trois couleurs.
plt.scatter(df['Age'], df['Tarif'], c=df['Pclass'])
Les points violets sont de première classe, les points verts sont de deuxième classe et les points
jaunes sont de troisième classe.
Un nuage de points est utilisé pour afficher toutes les valeurs de vos données sur un graphique. Afin
d'obtenir une représentation visuelle de nos données, nous devons limiter nos données à deux
caractéristiques.
Ligne
Maintenant que nous pouvons placer des points de données individuels sur un graphique, voyons
comment tracer la ligne. C'est exactement ce que fait la fonction plot. Ce qui suit trace une ligne pour
séparer approximativement la 1ère classe de la 2ème et 3ème classe.
À partir du globe oculaire, nous mettrons la ligne de (0, 85) à (80, 5). Notre syntaxe ci-dessous
contient une liste des valeurs x et une liste des valeurs y.
Dans matplotlib, nous utilisons la fonction scatter pour créer un nuage de points et la fonction plot
pour une ligne.
CLASSIFICATION
L'apprentissage supervisé signifie que nous aurons des données historiques étiquetées que nous
utiliserons pour informer notre modèle. Nous appelons l'étiquette ou la chose que nous essayons de
prédire, la cible.
Ainsi, dans l'apprentissage supervisé, il existe une cible connue pour les données historiques, et pour
l'apprentissage non supervisé, il n'y a pas de cible connue.
Les problèmes de classification se produisent lorsque la cible est une valeur catégorique (souvent
Vrai ou Faux, mais peut être plusieurs catégories).
Les problèmes de régression sont ceux où la cible est une valeur numérique.
Par exemple, prévoir les prix des logements est un problème de régression.
C'est encadré, puisque nous avons des données historiques sur les ventes de maisons dans le passé.
C'est une régression, car le prix du logement est une valeur numérique.
Prédire si quelqu'un fera défaut sur son prêt est un problème de classification. Encore une fois, c'est
supervisé, puisque nous avons les données historiques indiquant si les anciens prêteurs ont fait
défaut, et c'est un problème de classification parce que nous essayons de prédire si le prêt est dans
l'une des deux catégories (défaut ou non).
La régression logistique, bien qu'elle ait la régression dans son nom, est un algorithme permettant
de résoudre des problèmes de classification, et non des problèmes de régression.
Terminologie de la classification
Revenons à notre jeu de données Titanic. Voici à nouveau le Pandas DataFrame des données :
La colonne Survived est ce que nous essayons de prédire. Nous appelons cela la cible. Vous pouvez
voir qu'il s'agit d'une liste de 1 et de 0. Un 1 signifie que le passager a survécu et un 0 signifie que le
passager n'a pas survécu.
Les colonnes restantes sont les informations sur le passager que nous pouvons utiliser pour prédire la
cible. Nous appelons chacune de ces colonnes une caractéristique. Les caractéristiques sont les
données que nous utilisons pour faire notre prédiction.
Bien que nous sachions si chaque passager de l'ensemble de données a survécu, nous aimerions
pouvoir faire des prédictions sur les passagers supplémentaires pour lesquels nous n'avons pas pu
collecter ces données.
Nous allons créer un modèle d'apprentissage automatique pour nous aider à le faire.
Classement graphique
Nous voudrons éventuellement utiliser toutes les fonctionnalités, mais pour plus de simplicité,
commençons par seulement deux des fonctionnalités (tarif et âge). L'utilisation de deux
fonctionnalités nous permet de visualiser les données dans un graphique.
En abscisse, nous avons le tarif du passager et en ordonnée son âge. Les points jaunes sont les
passagers qui ont survécu et les points violets sont les passagers qui n'ont pas survécu.
Vous pouvez voir qu'il y a plus de points jaunes en bas du graphique qu'en haut.
En effet, les enfants avaient plus de chances de survivre que les adultes, ce qui correspond à notre
intuition. De même, il y a plus de points jaunes à droite du graphique, ce qui signifie que les
personnes qui ont payé plus étaient plus susceptibles de survivre.
La tâche d'un modèle linéaire est de trouver la ligne qui sépare le mieux les deux classes, de sorte
que les points jaunes soient d'un côté et les points violets de l'autre.
Voici un exemple d'une bonne ligne. La ligne est utilisée pour faire des prédictions sur les nouveaux
passagers. Si le point de données d'un passager se trouve du côté droit de la ligne, nous prédisons
qu'il survivra. Si sur le côté gauche, nous prédirions qu'ils n'ont pas survécu.
Le défi de la construction du modèle sera de déterminer quelle est la meilleure ligne possible.
Les valeurs a, b et c sont les coefficients. Trois valeurs définiront une ligne unique.
Regardons un exemple spécifique d'une ligne où les coefficients sont a=1, b=-1 et c=-30.
d = (1)x + (-1)y + (-30)
Rappelez-vous que nous avons tracé nos données avec l'axe x le tarif et l'axe y l'âge du passager.
Pour tracer une droite à partir d'une équation, nous avons besoin de deux points qui se trouvent sur
la droite.
Nous pouvons voir, par exemple, que le point (30, 0) se trouve juste sur la ligne (Fare 30, Age 0). Si on
le branche dans l'équation, ça marche.
30 - 0 - 30 = 0
Nous pouvons également voir que le point (50, 20) est sur la ligne (Fare 50, Age 20).
50 - 20 - 30 = 0
Comme cette valeur est positive, le point se trouve du côté droit de la ligne et nous prédisons que le
passager a survécu.
Supposons maintenant qu'un passager ait un tarif de 10 et que son âge soit de 50 ans. Ajoutons ces
valeurs à l'équation.
Comme cette valeur est négative, le point se trouve sur le côté gauche de la ligne et nous prévoyons
que le passager n'a pas survécu. Nous pouvons voir ces deux points sur le graphique ci-dessous.
De quel côté de la ligne se trouve un point détermine si nous pensons que ce passager survivra ou
non.
Nous avons d'abord la ligne avec laquelle nous avons travaillé jusqu'à présent. Appelons cette ligne 1.
d = (1)x + (-1)y – 30
Ensuite, nous avons une autre équation pour une droite. Appelons cette ligne 2.
Cela fait de la ligne 1 la ligne préférée car elle réussit mieux à séparer les points jaunes et violets.
Nous devons définir mathématiquement cette idée afin de pouvoir trouver algorithmiquement la
meilleure ligne.
Probabilité de survie
Afin de déterminer la meilleure ligne possible pour diviser nos données, nous devons avoir un moyen
de marquer la ligne. Examinons d'abord un seul point de données.
Idéalement, si le point de données est un passager qui a survécu, il serait du côté droit de la ligne et
loin de la ligne. S'il s'agit d'un point de données pour un passager qui n'a pas survécu, il serait loin de
la ligne à gauche. Plus il est éloigné de la ligne, plus nous sommes convaincus qu'il se trouve du bon
côté de la ligne.
Pour chaque point de données, nous aurons un score qui est une valeur comprise entre 0 et 1.
Nous pouvons le considérer comme la probabilité que le passager survive. Si la valeur est proche de
0, ce point serait loin à gauche de la ligne et cela signifie que nous sommes convaincus que le
passager n'a pas survécu.
Si la valeur est proche de 1, ce point serait loin à droite de la ligne et cela signifie que nous sommes
convaincus que le passager a survécu. Une valeur de 0,5 signifie que le point tombe directement sur
la ligne et nous ne savons pas si le passager survit.
L'équation pour calculer ce score est ci-dessous, bien que l'intuition soit bien plus importante que
l'équation réelle.
Rappelons que l'équation de la ligne est sous la forme d = ax+by+c (x est le Fare, y est l'Age, et a, b &
c sont les coefficients que nous contrôlons).
Probabilité
Pour calculer la qualité de notre ligne, nous devons noter si nos prédictions sont correctes.
Idéalement, si nous prédisons avec une forte probabilité qu'un passager survit (ce qui signifie que le
point de données est loin à droite de la ligne), alors ce passager survit réellement.
Nous serons donc récompensés lorsque nous prédisons quelque chose correctement et pénalisés si
nous prédisons quelque chose de manière incorrecte.
Voici l'équation de vraisemblance. Encore une fois, l'intuition est plus importante que l'équation.
La probabilité sera une valeur comprise entre 0 et 1. Plus la valeur est élevée, meilleure est notre
ligne.
• Si la probabilité prédite p est de 0,25 et que le passager n'a pas survécu, nous obtenons un score de
0,75 (bon).
• Si la probabilité prédite p est de 0,25 et que le passager a survécu, nous obtenons un score de 0,25
(mauvais).
Nous multiplions tous les scores individuels pour chaque point de données ensemble pour obtenir un
score pour notre ligne. Ainsi, nous pouvons comparer différentes lignes pour déterminer la meilleure.
Disons pour faciliter le calcul que nous avons 4 points de données.
La valeur sera toujours très petite car c'est la probabilité que notre modèle prédise tout
parfaitement. Un modèle parfait aurait une probabilité prédite de 1 pour tous les cas positifs et de 0
pour tous les cas négatifs.
La vraisemblance est la façon dont nous notons et comparons les choix possibles d'une droite de
meilleur ajustement.
Pour cela, nous allons introduire un nouveau module Python appelé scikit-learn.
Notez que scikit-learn est continuellement mis à jour. Si vous avez une version légèrement différente
du module installé sur votre ordinateur, tout fonctionnera toujours correctement, mais vous pourriez
voir des valeurs légèrement différentes de celles du terrain de jeu.
Scikit-learn est l'un des modules Python les mieux documentés. Vous pouvez trouver de nombreux
exemples de code sur scikit-learn.org
Avant de pouvoir utiliser sklearn pour créer un modèle, nous devons préparer les données avec
Pandas. Revenons à notre ensemble de données complet et examinons les commandes Pandas.
Tout d'abord, nous devons rendre toutes nos colonnes numériques. Rappelez-vous comment créer la
colonne booléenne pour Sex.
Maintenant, prenons toutes les fonctionnalités et créons un tableau numpy appelé X. Nous
sélectionnons d'abord toutes les colonnes qui nous intéressent, puis utilisons la méthode des valeurs
pour le convertir en un tableau numpy.
y = df['Survived'].values
Il est courant d'appeler notre tableau 2d de caractéristiques X et notre tableau 1d de valeurs cibles y.
PY
Tous les modèles sklearn sont construits en tant que classes Python. Nous instancions d'abord la
classe.
modèle = LogisticRegression()
PY
Nous pouvons maintenant utiliser nos données que nous avons précédemment préparées pour
former le modèle. La méthode d'ajustement est utilisée pour construire le modèle. Il prend deux
arguments : X (les fonctionnalités sous forme de tableau numpy 2d) et y (la cible sous forme de
tableau numpy 1d).
Pour plus de simplicité, supposons d'abord que nous construisons un modèle de régression logistique
en utilisant uniquement les colonnes Fare et Age. Nous définissons d'abord X comme étant la matrice
de caractéristiques et y le tableau cible.
X = df[['Tarif', 'Âge']].values
y = df['Survived'].values
PY
model.fit(X, y)
PY
Ajuster le modèle signifie utiliser les données pour choisir une ligne de meilleur ajustement. Nous
pouvons voir les coefficients avec les attributs coef_ et intercept_.
print(model.coef_, model.intercept_)
PY
Il peut être difficile de se souvenir des instructions d'importation pour les différents modèles sklearn.
Si vous ne vous en souvenez pas, consultez simplement la documentation de scikit-learn.
Droit sur!
y = df['Survived'].values
modèle = LogisticRegression()
model.fit(X, y)
PY
Nous pouvons maintenant utiliser la méthode de prédiction pour faire des prédictions.
modèle.prédire(X)
PY
Cela signifie que le passager est en classe P 3, qu'il est un homme, qu'il a 22 ans, qu'il a 1
frère/sœur/conjoint à bord, 0 parent/enfant à bord et qu'il a payé 7,25 $. Voyons ce que le modèle
prédit pour ce passager. Notez que même avec un point de données, la méthode predict prend un
tableau numpy à 2 dimensions et renvoie un tableau numpy à 1 dimension.
# [0]
PY
Le résultat est 0, ce qui signifie que le modèle prédit que ce passager n'a pas survécu.
Voyons ce que le modèle prédit pour les 5 premières lignes de données et comparons-le à notre
tableau cible. Nous obtenons les 5 premières lignes de données avec X[:5] et les 5 premières valeurs
de la cible avec y[:5].
print(model.predict(X[:5]))
# [0 1 1 1 0]
imprimer(y[:5])
# [0 1 1 1 0]
PY
Noter le modèle
Nous pouvons avoir une idée de la qualité de notre modèle en comptant le nombre de points de
données qu'il prédit correctement. C'est ce qu'on appelle le score de précision.
y_pred = model.predict(X)
PY
Maintenant, nous créons un tableau de valeurs booléennes indiquant si notre modèle a prédit
correctement ou non chaque passager.
y == y_pred
PY
Pour obtenir le nombre de celles-ci qui sont vraies, nous pouvons utiliser la méthode numpy sum.
Cela signifie que sur les 887 points de données, le modèle fait la prédiction correcte pour 714 d'entre
eux.
Pour obtenir le pourcentage correct, nous le divisons par le nombre total de passagers. Nous
obtenons le nombre total de passagers en utilisant l'attribut shape.
y.forme[0]
PY
Ainsi, la précision du modèle est de 80 %. En d'autres termes, le modèle fait la prédiction correcte sur
80 % des points de données.
C'est un calcul assez courant, que sklearn a déjà implémenté pour nous. Nous pouvons donc obtenir
le même résultat en utilisant la méthode du score. La méthode de score utilise le modèle pour faire
une prédiction pour X et compte quel pourcentage d'entre eux correspond à y.
Avec cette méthode alternative de calcul de la précision, nous obtenons la même valeur, 80 %.
Nous verrons dans le module suivant qu'il y a beaucoup plus à évaluer un modèle.
Dans l'ensemble de données sur le cancer du sein, chaque point de données contient des mesures à
partir d'une image d'une masse mammaire et si elle est cancéreuse ou non. Le but sera d'utiliser ces
mesures pour prédire si la masse est cancéreuse.
Cet ensemble de données est intégré directement dans scikit-learn, nous n'aurons donc pas besoin
de lire un csv.
Commençons par charger le jeu de données et examinons les données et leur formatage.
cancer_data = load_breast_cancer()
PY
L'objet renvoyé (que nous avons stocké dans la variable cancer_data) est un objet similaire à un
dictionnaire Python. Nous pouvons voir les clés disponibles avec la méthode keys.
imprimer(cancer_data.keys())
PY
Nous commencerons par examiner DESCR, qui donne une description détaillée de l'ensemble de
données.
imprimer(cancer_data['DESCR'])
Nous pouvons voir qu'il y a 30 caractéristiques, 569 points de données et que la cible est soit maligne
(cancéreuse), soit bénigne (non cancéreuse). Pour chacun des points de données, nous avons des
mesures de la masse mammaire (rayon, texture, périmètre, etc.). Pour chacune des 10 mesures,
plusieurs valeurs ont été calculées, nous avons donc la moyenne, l'erreur standard et la pire valeur. Il
en résulte 10 * 3 ou 30 fonctionnalités au total.
Dans l'ensemble de données sur le cancer du sein, plusieurs caractéristiques sont calculées en
fonction d'autres colonnes. Le processus de détermination des fonctionnalités supplémentaires à
calculer est l'ingénierie des fonctionnalités.
Tout d'abord, les données de caractéristiques sont stockées avec la clé 'data'. Quand on le regarde,
on voit que c'est un tableau numpy avec 569 lignes et 30 colonnes. C'est parce que nous avons 569
points de données et 30 fonctionnalités.
données_cancer['données']
PY
Nous utilisons la forme pour voir qu'il s'agit d'un tableau de 569 lignes et 30 colonnes.
Nous pouvons voir que nous avons 30 colonnes dans le DataFrame, puisque nous avons 30
fonctionnalités. La sortie est tronquée pour tenir sur l'écran. Nous avons utilisé la méthode de la tête,
donc notre résultat n'a que 5 points de données.
Nous devons encore mettre les données cibles dans notre DataFrame, qui peuvent être trouvées
avec la clé 'target'. Nous pouvons voir que la cible est un tableau numérique unidimensionnel de 1 et
de 0.
Il est important de vérifier que vous interprétez correctement les colonnes booléennes. Dans notre
cas, une cible de 0 signifie maligne et 1 signifie bénigne.
Construire un modèle de régression logistique
Maintenant que nous avons examiné nos données et les avons mises dans un format confortable,
nous pouvons créer notre matrice de caractéristiques X et notre tableau cible y afin de pouvoir créer
un modèle de régression logistique.
X = df[cancer_data.feature_names].values
y = df['cible'].values
PY
Nous créons maintenant un objet de régression logistique et utilisons la méthode d'ajustement pour
créer le modèle.
modèle = LogisticRegression()
model.fit(X, y)
PY
Lorsque nous exécutons ce code, nous obtenons un avertissement de convergence. Cela signifie que
le modèle a besoin de plus de temps pour trouver la solution optimale. Une option consiste à
augmenter le nombre d'itérations. Vous pouvez également passer à un autre solveur, ce que nous
ferons. Le solveur est l'algorithme que le modèle utilise pour trouver l'équation de la droite. Vous
pouvez voir les solveurs possibles dans la documentation de la régression logistique
model = LogisticRegression(solver='liblinear')
model.fit(X, y)
PY
Voyons ce que le modèle prédit pour le premier point de données de notre ensemble de données.
Rappelez-vous que la méthode predict prend un tableau à 2 dimensions, nous devons donc mettre le
point de données dans une liste.
modèle.prédire([X[0]])
PY
Pour voir les performances du modèle sur l'ensemble de l'ensemble de données, nous utilisons la
méthode des scores pour voir la précision du modèle.
modèle.score(X, y)
Nous voyons que le modèle obtient 96 % des points de données corrects.
Avec les outils que nous avons développés, nous pouvons créer un modèle pour n'importe quel
ensemble de données de classification.
Tâche
Vous disposez d'une matrice de caractéristiques et d'un seul point de données à prédire. Votre travail
consistera à créer un modèle de régression logistique avec la matrice de caractéristiques et à faire
une prédiction (1 ou 0) du point de données unique.
Format d'entrée
Dernière ligne : valeurs (séparées par des espaces) d'un seul point de données sans valeur cible
Format de sortie
Soit 1 soit 0
Exemple d'entrée
13
35
57
31
53
75
111000
24
Exemple de sortie
1
Nous pouvons voir les points tracés sur le graphique ci-dessus et
la ligne qui sépare les données. Le point (2, 4) est noté sur le graphique et vous pouvez voir qu'il est
du côté positif de la ligne, donc le résultat est 1.
Model Evaluation
Précision
Dans le module précédent, nous avons calculé les performances de notre modèle en utilisant la
précision. La précision est le pourcentage de prédictions qui sont correctes.
Si vous avez 100 points de données et que vous en prédisez 70 correctement et 30 de manière
incorrecte, la précision est de 70 %.
La précision est une mesure très simple et facile à comprendre, mais ce n'est pas toujours la
meilleure. Par exemple, disons que j'ai un modèle pour prédire si un débit de carte de crédit est
frauduleux. Sur 10 000 cartes de crédit, nous avons 9 900 frais légitimes et 100 frais frauduleux. Je
pourrais construire un modèle qui prédit simplement que chaque charge est légitime et il obtiendrait
9900/10000 (99%) des prédictions correctes !
La précision est une bonne mesure si nos classes sont également réparties, mais elle est très
trompeuse si nous avons des classes déséquilibrées.
Soyez toujours prudent avec précision. Vous devez connaître la distribution des classes pour savoir
comment interpréter la valeur.
Matrice de confusion
Comme nous l'avons remarqué dans la partie précédente, nous nous soucions non seulement du
nombre de points de données pour lesquels nous prédisons la bonne classe, nous nous soucions du
nombre de points de données positifs pour lesquels nous prédisons correctement ainsi que du
nombre de points de données négatifs que nous prédisons correctement.
Nous pouvons voir toutes les valeurs importantes dans ce qu'on appelle la matrice de confusion (ou
matrice d'erreur ou table de confusion).
• Points de données que nous avons prédits positifs qui sont en fait positifs
• Points de données que nous avons prédits positifs qui sont en fait négatifs
• Points de données que nous avons prédits négatifs qui sont en réalité positifs
• Points de données que nous avons prédits négatifs qui sont en fait négatifs
Les premier et quatrième sont les points de données que nous avons prédits correctement et les
deuxième et troisième sont les points de données que nous avons prédits de manière incorrecte.
Dans notre jeu de données Titanic, nous avons 887 passagers, 342 ont survécu (positif) et 545 n'ont
pas survécu (négatif). Le modèle que nous avons construit dans le module précédent a la matrice de
confusion suivante.
Les carrés ombragés bleus sont les décomptes des prédictions que nous avons eues correctes. Ainsi,
sur les 342 passagers qui ont survécu, nous en avons prédit 233 ou eux correctement (et 109 d'entre
eux incorrectement). Sur les 545 passagers qui n'ont pas survécu, nous en avons prédit 480
correctement (et 65 incorrectement).
Nous pouvons utiliser la matrice de confusion pour calculer la précision. Pour rappel, la précision est
le nombre de points de données prédits correctement divisé par le nombre total de points de
données.
C'est en effet la même valeur que nous avons obtenue dans le module précédent.
La matrice de confusion décrit entièrement les performances d'un modèle sur un ensemble de
données, bien qu'elle soit difficile à utiliser pour comparer des modèles.
Un vrai positif (TP) est un point de données pour lequel nous avons prédit positivement que nous
avions raison. Un vrai négatif (TN) est un point de données pour lequel nous avons prédit
négativement que nous avions raison.
Un faux positif (FP) est un point de données sur lequel nous avons prédit positivement que nous nous
étions trompés.
Un faux négatif (FN) est un point de données sur lequel nous avons prédit négativement que nous
nous étions trompés.
Les termes peuvent être un peu difficiles à suivre. La façon de se souvenir est que le deuxième mot
est ce qu'est notre prédiction (positive ou négative) et le premier mot est si cette prédiction était
correcte (vraie ou fausse).
Précision
Deux métriques couramment utilisées pour la classification sont la précision et le rappel.
Conceptuellement, la précision fait référence au pourcentage de résultats positifs qui sont pertinents
et le rappel au pourcentage de cas positifs correctement classés.
Les deux peuvent être définis à l'aide des quadrants de la matrice de confusion, dont nous rappelons
qu'elle est la suivante :
La précision est le pourcentage de prédictions positives du modèle qui sont correctes. Nous le
définissons comme suit :
Si nous regardons notre matrice de confusion pour notre modèle pour l'ensemble de données du
Titanic, nous pouvons calculer la précision
.
La précision est une mesure de la précision du modèle avec ses prédictions positives.
Rappel
Le rappel est le pourcentage de cas positifs que le modèle prédit correctement. Encore une fois, nous
utiliserons la matrice de confusion pour calculer notre résultat.
Le rappel est une mesure du nombre de cas positifs que le modèle peut rappeler.
Nous serons souvent dans une situation de choix entre augmenter le rappel (tout en diminuant la
précision) ou augmenter la précision (et diminuer le rappel). Cela dépendra de la situation que nous
voudrons maximiser.
Par exemple, disons que nous construisons un modèle pour prédire si un débit de carte de crédit est
frauduleux. Les cas positifs pour notre modèle sont des accusations frauduleuses et les cas négatifs
sont des accusations légitimes.
Dans le cas 1, c'est un énorme inconvénient pour le client lorsque le modèle prédit la fraude de
manière incorrecte (un faux positif). Dans le cas 2, un faux positif est un inconvénient mineur pour le
client.
Plus les faux positifs sont élevés, plus la précision est faible. En raison du coût élevé des faux positifs
dans le premier cas, il serait intéressant d'avoir un faible rappel afin d'avoir une très grande
précision. Dans le cas 2, vous voudriez plus d'un équilibre entre la précision et le rappel.
Il n'y a pas de règle absolue sur les valeurs de précision et de rappel pour lesquelles vous visez. Cela
dépend toujours du jeu de données et de l'application.
Note F1
La précision était une mesure attrayante car il s'agissait d'un nombre unique. La précision et le rappel
sont deux nombres, il n'est donc pas toujours évident de choisir entre deux modèles si l'un a une
précision plus élevée et l'autre un rappel plus élevé. Le score F1 est une moyenne de précision et de
rappel afin que nous ayons un score unique pour notre modèle.
Nous utiliserons les nombres de précision et de rappel que nous avons calculés précédemment. La
précision est de 0,7819 et le rappel est de 0,6813.
Pour les utiliser, commençons par rappeler notre code du module précédent pour construire un
modèle de régression logistique.
Le code lit le jeu de données Titanic à partir du fichier csv et le place dans un Pandas DataFrame.
Ensuite, nous créons une matrice de caractéristiques X et des valeurs cibles y. Nous créons un
modèle de régression logistique et l'adaptons à notre ensemble de données. Enfin, nous créons une
variable y_pred de nos prédictions.
Chaque fonction prend deux tableaux numpy unidimensionnels : les vraies valeurs de la cible et les
valeurs prédites de la cible. Nous avons les vraies valeurs de la cible et les valeurs prédites de la cible.
Ainsi, nous pouvons utiliser les fonctions métriques comme suit.
On voit que la précision est de 80% ce qui signifie que 80% des prédictions du modèle sont correctes.
La précision est de 78 %, ce qui, rappelons-le, est le pourcentage de prédictions positives du modèle
qui sont correctes. Le rappel est de 68 %, soit le pourcentage de cas positifs que le modèle a
correctement prédits. Le score F1 est de 73%, ce qui est une moyenne de la précision et du rappel.
Avec un seul modèle, les valeurs métriques ne nous disent pas grand-chose. Pour certains problèmes,
une valeur de 60 % est bonne, et pour d'autres, une valeur de 90 % est bonne, selon la difficulté du
problème. Nous utiliserons les valeurs métriques pour comparer différents modèles afin de choisir le
meilleur.
Scikit-learn a une fonction de matrice de confusion que nous pouvons utiliser pour obtenir les quatre
valeurs de la matrice de confusion (vrais positifs, faux positifs, faux négatifs et vrais négatifs). En
supposant que y est nos vraies valeurs cibles et que y_pred est les valeurs prédites, nous pouvons
utiliser la fonction confusion_matrix comme suit :
Scikit-learn inverse la matrice de confusion pour afficher les nombres négatifs en premier ! Voici
comment cette matrice de confusion devrait être étiquetée.
Étant donné que les valeurs cibles négatives correspondent à 0 et positives à 1, scikit-learn les a
classées dans cet ordre. Assurez-vous de bien vérifier que vous interprétez correctement les valeurs !
Sur-ajustement
Jusqu'à présent, nous avons construit un modèle avec toutes nos données, puis nous avons vu ses
performances sur les mêmes données. Cela gonfle artificiellement nos chiffres puisque notre modèle,
en effet, a pu voir les réponses au quiz avant que nous lui donnions le quiz. Cela peut conduire à ce
que nous appelons le surajustement.
Le surajustement, c'est quand nous obtenons de bons résultats sur les données que le modèle a déjà
vues, mais que nous n'obtenons pas de bons résultats sur les nouvelles données.
Nous pouvons visuellement voir un modèle de surajustement comme suit. La ligne essaie trop
étroitement d'obtenir chaque point de données du bon côté de la ligne, mais il manque l'essence des
données.
Dans le graphique, vous pouvez voir que nous avons fait un assez bon travail pour obtenir les points
jaunes en haut et les points violets en bas, mais cela ne capture pas ce qui se passe. Un seul point
aberrant pourrait vraiment fausser l'emplacement de la ligne. Bien que le modèle obtienne un
excellent score sur les données qu'il a déjà vues, il est peu probable qu'il fonctionne bien sur de
nouvelles données.
Plus nous avons de fonctionnalités dans notre ensemble de données, plus nous serons enclins au
surajustement.
Pour donner à un modèle une évaluation juste, nous aimerions savoir dans quelle mesure nos
données fonctionneraient sur des données qu'il n'a pas encore vues.
En action, notre modèle fera des prédictions sur des données dont nous ne connaissons pas la
réponse, nous aimerions donc évaluer les performances de notre modèle sur de nouvelles données,
pas seulement sur les données qu'il a déjà vues. Pour simuler la réalisation de prédictions sur de
nouvelles données invisibles, nous pouvons diviser notre ensemble de données en un ensemble
d'apprentissage et un ensemble de test. L'ensemble d'apprentissage est utilisé pour construire les
modèles. L'ensemble de test est utilisé pour évaluer les modèles.
Nous divisons nos données avant de construire le modèle, ainsi le modèle n'a aucune connaissance
de l'ensemble de test et nous lui donnerons une évaluation juste.
Une répartition standard consiste à placer 70 à 80 % de nos données dans l'ensemble
d'apprentissage et 20 à 30 % dans l'ensemble de test. Utiliser moins de données dans l'ensemble de
formation signifie que notre modèle n'aura pas autant de données à apprendre, nous voulons donc
lui en donner autant que possible tout en laissant suffisamment pour l'évaluation.
Scikit-learn a une fonction intégrée pour diviser les données en un ensemble d'apprentissage et un
ensemble de test.
Maintenant que nous savons comment diviser nos données en un ensemble d'apprentissage
et un ensemble de test, nous devons modifier la façon dont nous construisons et évaluons le modèle.
Toute la construction du modèle est effectuée avec l'ensemble d'apprentissage et toute l'évaluation
est effectuée avec l'ensemble de test.
Dans le dernier module, nous avons construit un modèle et l'avons évalué sur le même jeu de
données. Nous construisons maintenant le modèle à l'aide de l'ensemble d'apprentissage.
Nos valeurs d'exactitude, de précision, de rappel et de score F1 sont en fait très similaires aux
valeurs lorsque nous avons utilisé l'ensemble de données complet. C'est un signe que notre modèle
n'est pas surfait !
Si vous exécutez le code, vous remarquerez que vous obtenez des scores différents à chaque
fois. En effet, la répartition du test de train est effectuée de manière aléatoire et, en fonction des
points qui atterrissent dans l'ensemble d'entraînement et le test, les scores seront différents. Nous
verrons quand nous arriverons à la leçon de validation croisée que nous avons des moyens plus
précis de mesurer ces scores.
Comme nous l'avons remarqué dans la partie précédente, lorsque nous divisons
aléatoirement les données en un ensemble d'apprentissage et un ensemble de test, nous nous
retrouvons avec des points de données différents dans chaque ensemble à chaque fois que nous
exécutons le code. C'est le résultat du hasard, et nous avons besoin qu'il soit aléatoire pour qu'il soit
efficace, mais cela peut parfois rendre difficile le test du code.
Par exemple, chaque fois que nous exécutons le code suivant, nous obtiendrons des résultats
différents.
Pour obtenir la même répartition à chaque fois, nous pouvons utiliser l'attribut
random_state. Nous choisissons un nombre arbitraire pour lui donner, puis chaque fois que nous
exécutons le code, nous obtiendrons la même répartition.
Si vous vous souvenez dans la leçon 2, nous avons parlé du compromis entre précision et
rappel. Avec un modèle de régression logistique, nous avons un moyen facile de passer de l'accent
mis sur la précision à l'accent mis sur le rappel. Le modèle de régression logistique ne renvoie pas
seulement une prédiction, mais il renvoie une valeur de probabilité entre 0 et 1. En règle générale,
nous disons que si la valeur est >=0,5, nous prédisons que le passager a survécu, et si la valeur est
<0,5, le le passager n'a pas survécu. Cependant, nous pourrions choisir n'importe quel seuil entre 0 et
1.
Si nous augmentons le seuil, nous aurons moins de prédictions positives, mais nos
prédictions positives sont plus susceptibles d'être correctes. Cela signifie que la précision serait plus
élevée et le rappel plus faible. D'un autre côté, si nous abaissons le seuil, nous aurons plus de
prédictions positives, donc nous aurons plus de chances d'attraper tous les cas positifs. Cela signifie
que le rappel serait plus élevé et la précision plus faible.
Chaque choix de seuil correspond à un modèle différent. Une courbe ROC (Receiver
operating feature) est un graphique montrant tous les modèles possibles et leurs performances.
Sensibilité et spécificité
Une courbe ROC est un graphique de la sensibilité par rapport à la spécificité. Ces valeurs
démontrent le même compromis que la précision et le rappel démontrent.
Revenons à la matrice de confusion, car nous l'utiliserons pour définir la sensibilité et la spécificité.
La sensibilité est un autre terme pour le rappel, qui est le taux de vrais positifs. Rappelons qu'il est
calculé comme suit :
Nous avons effectué un test de train sur notre ensemble de données Titanic et obtenu la matrice de
confusion suivante. Nous avons 96 cas positifs et 126 cas négatifs dans notre ensemble de tests.
L'objectif est de maximiser ces deux valeurs, bien qu'en augmentant généralement l'une, l'autre
diminue. Cela dépendra de la situation si nous mettons davantage l'accent sur la sensibilité ou la
spécificité.
Alors que nous examinons généralement les valeurs de précision et de rappel, pour représenter
graphiquement la norme, il faut utiliser la sensibilité et la spécificité. Il est possible de construire une
courbe de rappel de précision, mais cela n'est pas courant.
Sensibilité et spécificité dans Scikit-learn
Scikit-learn n'a pas défini de fonctions de sensibilité et de spécificité, mais nous pouvons le faire
nous-mêmes. La sensibilité est la même que le rappel, elle est donc facile à définir.
Le deuxième tableau est le rappel, nous pouvons donc ignorer les trois autres tableaux. Il y a deux
valeurs. Le premier est le rappel de la classe négative et le second est le rappel de la classe positive.
La deuxième valeur est la valeur de rappel ou de sensibilité standard, et vous pouvez voir que la
valeur correspond à ce que nous avons obtenu ci-dessus. La première valeur est la spécificité.
Écrivons donc une fonction pour obtenir uniquement cette valeur.
La sensibilité est la même que le rappel (ou le rappel de la classe positive) et la spécificité est
le rappel de la classe négative.
Lorsque vous utilisez la méthode de prédiction de scikit-learn, vous recevez les valeurs 0 et 1
de la prédiction. Cependant, dans les coulisses, le modèle de régression logistique obtient une valeur
de probabilité entre 0 et 1 pour chaque point de données, puis arrondit à 0 ou 1. Si nous voulons
choisir un seuil différent de 0,5, nous voulons ces valeurs de probabilité. Nous pouvons utiliser la
fonction predict_proba pour les obtenir.
(modèle.predict_proba(X_test)
Le résultat est un tableau numpy avec 2 valeurs pour chaque point de données (par exemple
[0,78, 0,22]). Vous remarquerez que les deux valeurs totalisent 1. La première valeur est la
probabilité que le point de données soit dans la classe 0 (n'a pas survécu) et la seconde est la
probabilité que le point de données soit dans la classe 1 (survécu). Nous n'avons besoin que de la
deuxième colonne de ce résultat, que nous pouvons extraire avec la syntaxe numpy suivante.
model.predict_proba(X_test)[:, 1]
Maintenant, nous voulons juste comparer ces valeurs de probabilité avec notre seuil. Disons
que nous voulons un seuil de 0,75. Nous comparons le tableau ci-dessus à 0,75. Cela nous donnera
un tableau de valeurs Vrai/Faux qui sera notre tableau de valeurs cibles prédites.
Un seuil de 0,75 signifie que nous devons être plus confiants pour faire une prédiction
positive. Il en résulte moins de prédictions positives et plus de prédictions négatives.
Nous pouvons maintenant utiliser toutes les métriques scikit-learn d'avant d'utiliser y_test
comme valeurs réelles et y_pred comme valeurs prédites.
Notez que nous traçons en fait la sensibilité par rapport à (1-spécificité). Il n'y a aucune
raison valable de procéder de cette façon, à part le fait que c'est la norme.
Commençons par regarder le code pour construire la courbe ROC. Scikit-learn a une fonction
roc_curve que nous pouvons utiliser. La fonction prend les vraies valeurs cibles et les probabilités
prédites de notre modèle.
Nous utilisons d'abord la méthode predict_proba sur le modèle pour obtenir les probabilités.
Ensuite, nous appelons la fonction roc_curve. La fonction roc_curve renvoie un tableau des taux de
faux positifs, un tableau des taux de vrais positifs et les seuils. Le taux de faux positifs est la spécificité
1 (axe des x) et le taux de vrais positifs est un autre terme de la sensibilité (axe des y). Les valeurs de
seuil ne seront pas nécessaires dans le graphique.
Voici le code pour tracer la courbe ROC dans matplotlib. Notez que nous avons également du
code pour tracer une ligne diagonale. Cela peut nous aider à voir visuellement à quel point notre
modèle est éloigné d'un modèle qui prédit de manière aléatoire.
Nous supposons que nous avons déjà un ensemble de données qui a été divisé en un
ensemble d'apprentissage et un ensemble de test.
modèle = LogisticRegression()
model.fit(X_train, y_train)
y_pred_proba = model.predict_proba(X_test)
plt.plot(fpr, tpr)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.xlabel('1 - spécificité')
plt.ylabel('sensibilité')
plt.show()
Comme nous n'utilisons pas les valeurs de seuil pour construire le graphique, le graphique ne
nous dit pas quel seuil donnerait chacun des modèles possibles.
Le modèle A a une sensibilité de 0,6 et une spécificité de 0,9 (rappelons que le graphique montre une
spécificité de 1). Le modèle B a une sensibilité de 0,8 et une spécificité de 0,7. Le modèle C a une
sensibilité de 0,9 et une spécificité de 0,5.
Comment choisir entre ces modèles dépendra des spécificités de notre situation.
Plus la courbe se rapproche du coin supérieur gauche, meilleures sont les performances. La
ligne ne doit jamais tomber en dessous de la ligne diagonale car cela signifierait qu'elle fonctionne
moins bien qu'un modèle aléatoire.
Choisir un modèle à partir de la courbe ROC
Lorsque nous sommes prêts à finaliser notre modèle, nous devons choisir un seuil unique que
nous utiliserons pour faire nos prédictions. La courbe ROC est un moyen de nous aider à choisir le
seuil idéal pour notre problème.
Regardons à nouveau notre courbe ROC avec trois points mis en évidence :
Si nous sommes dans une situation où il est plus important que toutes nos prédictions
positives soient correctes que d'attraper tous les cas positifs (ce qui signifie que nous prédisons
correctement la plupart des cas négatifs), nous devrions choisir le modèle avec une spécificité plus
élevée (modèle A ).
Si nous sommes dans une situation où il est important que nous attrapions autant de cas
positifs que possible, nous devrions choisir le modèle avec la sensibilité la plus élevée (modèle C).
Si nous voulons un équilibre entre sensibilité et spécificité, nous devons choisir le modèle B.
Il peut être difficile de garder une trace de tous ces termes. Même les experts doivent les
consulter à nouveau pour s'assurer qu'ils interprètent correctement les valeurs.
Aire sous la courbe
Nous verrons parfois quoi utiliser la courbe ROC pour comparer deux modèles différents. Voici une
comparaison des courbes ROC de deux modèles.
Vous pouvez voir que la courbe bleue surpasse la courbe orange puisque la ligne bleue est presque
toujours au-dessus de la ligne orange.
Pour obtenir une mesure empirique de cela, nous calculons l'aire sous la courbe, également appelée
AUC. C'est l'aire sous la courbe ROC. C'est une valeur comprise entre 0 et 1, plus elle est élevée,
mieux c'est.
Étant donné que le ROC est un graphique de tous les différents modèles de régression logistique avec
différents seuils, l'AUC ne mesure pas les performances d'un seul modèle. Il donne une idée générale
de la performance du modèle de régression logistique. Pour obtenir un modèle unique, vous devez
encore trouver le seuil optimal pour votre problème.
Utilisons scikit-learn pour nous aider à calculer l'aire sous la courbe. Nous pouvons utiliser la fonction
roc_auc_score.
(roc_auc_score(y_test, y_pred_proba[:,1])
PY
Nous pouvons utiliser la fonction roc_auc_score pour calculer le score AUC d'un modèle de
régression logistique sur l'ensemble de données Titanic. Nous construisons deux modèles de
régression logistique, le modèle 1 avec 6 fonctionnalités et le modèle 2 avec uniquement la classe P
et les fonctionnalités masculines. Nous voyons que le score AUC du modèle1 est plus élevé.
Il est important de noter que cette métrique nous indique la performance générale d'un modèle de
régression logistique sur nos données. Comme une courbe ROC montre les performances de
plusieurs modèles, l'AUC ne mesure pas les performances d'un seul modèle.
Étant donné que notre objectif est d'obtenir la meilleure mesure possible de nos paramètres
(exactitude, précision, rappel et score F1), nous pouvons faire un peu mieux qu'un seul ensemble
d'entraînement et de test.
Comme nous pouvons le voir, toutes les valeurs de l'ensemble d'apprentissage ne sont jamais
utilisées pour évaluer. Il serait injuste de construire le modèle avec l'ensemble d'apprentissage, puis
de l'évaluer avec l'ensemble d'apprentissage, mais nous n'obtenons pas une image aussi complète
que possible des performances du modèle.
Pour voir cela de manière empirique, essayons d'exécuter le code de la leçon 3 qui effectue une
séparation train/test. Nous allons le relancer plusieurs fois et voir les résultats. Chaque ligne est le
résultat d'une répartition aléatoire différente entre l'entraînement et le test.
Vous pouvez voir qu'à chaque fois que nous l'exécutons, nous obtenons des valeurs différentes pour
les métriques. La précision varie de 0,79 à 0,84, la précision de 0,75 à 0,81 et le rappel de 0,63 à 0,75.
Ce sont de larges plages qui dépendent simplement de la chance ou de la malchance que nous avons
eue dans les points de données qui se sont retrouvés dans l'ensemble de test.
Voici le code si vous voulez essayer de vous lancer et de voir les différentes valeurs des métriques.
Au lieu de faire une seule séparation train/test, nous allons diviser nos données en un ensemble
d'apprentissage et un ensemble de tests plusieurs fois.
Au lieu de simplement prendre un morceau de données comme jeu de test, divisons notre jeu de
données en 5 morceaux. Supposons que nous ayons 200 points de données dans notre ensemble de
données.
Chacun de ces 5 morceaux servira de jeu de test. Lorsque le bloc 1 est l'ensemble de test, nous
utilisons les 4 blocs restants comme ensemble d'apprentissage. Ainsi, nous avons 5 ensembles
d'entraînement et de test comme suit.
Chacune des 5 fois, nous avons un ensemble de test de 20 % (40 points de données) et un ensemble
d'apprentissage de 80 % (160 points de données).
Dans la partie précédente, nous avons vu comment nous pouvions créer 5 ensembles de test, chacun
avec un ensemble d'apprentissage différent.
Si nous venions de faire un seul ensemble d'entraînement et de test et que nous avions obtenu le
premier au hasard, nous aurions rapporté une précision de 0,83. Si nous avions obtenu le dernier au
hasard, nous aurions rapporté une précision de 0,75. La moyenne de toutes ces valeurs possibles
permet d'éliminer l'impact de l'ensemble de tests dans lequel un point de données atterrit.
Vous ne verrez des valeurs aussi différentes que lorsque vous avez un petit ensemble de données.
Avec de grands ensembles de données, nous ne faisons souvent qu'un ensemble d'entraînement et
de test pour plus de simplicité.
Notre objectif dans la validation croisée est d'obtenir des mesures précises pour nos métriques
(exactitude, précision, rappel). Nous construisons des modèles supplémentaires afin d'avoir
confiance dans les chiffres que nous calculons et rapportons.
Maintenant, nous avons construit 5 modèles au lieu d'un seul. Comment décidons-nous d'utiliser un
modèle unique ?
Ces 5 modèles ont été construits uniquement à des fins d'évaluation, afin que nous puissions
rapporter les valeurs métriques. Nous n'avons pas réellement besoin de ces modèles et voulons
construire le meilleur modèle possible. Le meilleur modèle possible sera un modèle qui utilise toutes
les données. Nous gardons donc une trace de nos valeurs calculées pour nos métriques d'évaluation,
puis construisons un modèle en utilisant toutes les données.
Cela peut sembler incroyablement inutile, mais les ordinateurs ont beaucoup de puissance de calcul,
il vaut donc la peine d'en utiliser un peu plus pour s'assurer que nous rapportons les bonnes valeurs
pour nos métriques d'évaluation. Nous utiliserons ces valeurs pour prendre des décisions, il est donc
très important de les calculer correctement.
La puissance de calcul pour la construction d'un modèle peut être un problème lorsque l'ensemble
de données est volumineux. Dans ces cas, nous faisons juste une scission de test de train.
Classe KFoldName
Scikit-learn a déjà implémenté le code pour diviser l'ensemble de données en k morceaux et créer k
ensembles d'apprentissage et de test.
Pour simplifier, prenons un jeu de données avec seulement 6 points de données et 2 fonctionnalités
et une validation croisée triple sur le jeu de données. Nous prendrons les 6 premières lignes de
l'ensemble de données Titanic et n'utiliserons que les colonnes Age et Fare.
X = df[['Âge', 'Tarif']].values[:6]
y = df['Survived'].values[:6]
PY
Nous commençons par instancier un objet de classe KFold. Il prend deux paramètres : n_splits (c'est-
à-dire k, le nombre de morceaux à créer) et shuffle (pour randomiser ou non l'ordre des données). Il
est généralement recommandé de mélanger les données, car vous obtenez souvent un ensemble de
données trié.
kf = KFold(n_splits=3, shuffle=True)
PY
La classe KFold a une méthode split qui crée les 3 divisions pour nos données.
Regardons la sortie de la méthode split. La méthode split renvoie un générateur, nous utilisons donc
la fonction list pour le transformer en liste.
liste(kf.split(X))
Comme nous pouvons le voir, nous avons 3 ensembles de formation et de test comme prévu. Le
premier ensemble d'apprentissage est composé des points de données 0, 2, 3, 5 et l'ensemble de test
est composé des points de données 1, 4.
La division est effectuée de manière aléatoire, attendez-vous donc à voir différents points de
données dans les ensembles chaque fois que vous exécutez le code.
Nous avons utilisé la classe KFold et la méthode split pour obtenir les indices qui se trouvent dans
chacun des splits. Utilisons maintenant ce résultat pour obtenir notre premier (sur 3)
fractionnements train/test.
splits = list(kf.split(X))
imprimer (premier_split)
PY
Le premier tableau contient les indices de l'ensemble d'apprentissage et le second les indices de
l'ensemble de test. Créons ces variables.
PY
Nous pouvons maintenant créer un X_train, un y_train, un X_test et un y_test basés sur ces indices.
X_train = X[train_indices]
X_test = X[test_indices]
y_train = y[train_indices]
y_test = y[test_indices]
PY
Si nous imprimons chacun d'entre eux, nous verrons que nous avons quatre des points de données
dans X_train et leurs valeurs cibles dans y_train. Les 2 points de données restants sont dans X_test et
leurs valeurs cibles dans y_test.
print("X_train")
impression(X_train)
print("y_train", y_train)
print("X_test")
impression(X_test)
print("y_test", y_test)
PY
À ce stade, nous avons des ensembles d'entraînement et de test dans le même format que nous
avons utilisé la fonction train_test_split.
Construire un modèle
Nous pouvons maintenant utiliser les ensembles d'entraînement et de test pour construire un
modèle et faire une prédiction comme avant. Revenons à l'utilisation de l'ensemble de données
complet (puisque 4 points de données ne suffisent pas pour construire un modèle décent).
Voici l'intégralité du code pour construire et marquer le modèle sur le premier pli d'une validation
croisée à 5 volets. Notez que le code d'ajustement et de notation du modèle est exactement le
même que lorsque nous avons utilisé la fonction train_test_split.
Jusqu'à présent, nous avons essentiellement effectué une seule séparation train/test. Afin de faire
une validation croisée k-fold, nous devons utiliser chacune des 4 autres divisions pour construire un
modèle et marquer le modèle.
Nous avons fait un pli à la fois, mais nous voulons vraiment boucler sur tous les plis pour obtenir
toutes les valeurs. Nous allons mettre le code de la partie précédente dans notre boucle for.
scores = []
kf = KFold(n_splits=5, shuffle=True)
pour train_index, test_index dans kf.split(X) :
modèle = LogisticRegression()
model.fit(X_train, y_train)
scores.append(model.score(X_test, y_test))
impression (partitions)
PY
Puisque nous avons 5 plis, nous obtenons 5 valeurs de précision. Rappelez-vous, pour obtenir une
valeur finale unique, nous devons prendre la moyenne de ces valeurs.
print(np.mean(scores))
# 0.79029
PY
Maintenant que nous avons calculé la précision, nous n'avons plus besoin des 5 modèles différents
que nous avons construits. Pour une utilisation future, nous voulons juste un seul modèle. Pour
obtenir le meilleur modèle possible, nous construisons un modèle sur l'ensemble de données. Si on
nous demande la précision de ce modèle, nous utilisons la précision calculée par validation croisée
(0,79029) même si nous n'avons pas réellement testé ce modèle particulier avec un jeu de test.
Attendez-vous à obtenir des valeurs légèrement différentes à chaque fois que vous exécutez le code.
La classe KFold divise les données de manière aléatoire à chaque fois, donc une division différente
entraînera des scores différents, bien que vous deviez vous attendre à ce que la moyenne des 5
scores soit généralement à peu près la même.