Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Black Friday: -25€ dès 75€ sur les livres en ligne, vidéos... avec le code BWEEK25. J'en profite !
  1. Livres et vidéos
  2. Intelligence artificielle vulgarisée
  3. Machine Learning et Pokémons : seconde partie
Extrait - Intelligence artificielle vulgarisée Le Machine Learning et le Deep Learning par la pratique
Extraits du livre
Intelligence artificielle vulgarisée Le Machine Learning et le Deep Learning par la pratique
2 avis
Revenir à la page d'achat du livre

Machine Learning et Pokémons : seconde partie

Ce que nous allons découvrir et les prérequis

Dans le chapitre précédent, nous avons constitué un jeu d’observations qui va nous permettre d’entamer la démarche d’analyse et de recherche de solution à notre problème, à savoir déterminer le Pokémon à utiliser lors d’un combat dans le but de le gagner.

Nous allons commencer ce chapitre par un peu de statistiques, mais n’ayez crainte, cela reste simple de compréhension.

Prérequis nécessaires pour bien aborder ce chapitre : avoir lu les chapitres Les fondamentaux du langage Python, Des statistiques pour comprendre les données, Principaux algorithmes du machine learning, et avoir réalisé les différentes étapes du chapitre Machine Learning et Pokémons - première partie.

Un peu de statistiques

Avant d’entrer dans le vif du sujet, nous allons faire un peu de statistiques sur notre jeu d’observations à l’aide de la fonction describe() du module Pandas.

print(nouveauPokedex.describe()) 

Cette fonction a pour but d’expliquer statistiquement chaque feature de notre ensemble d’observations dans le but d’en dégager quelques caractéristiques intéressantes.

À titre d’exemple, prenons le résultat de l’analyse statistique de la feature  NIVEAU_ATTAQUE.

Module

Définition

Valeur

Count

Nombre d’observations

800

Mean

La moyenne des observations

79.001250

Std

L’écart type

32.457366

min

La valeur minimale des observations

5

25 %

55

50 %

75

75 %

100

Max

La valeur maximale des observations

190

1. Le nombre de données (count)

On constate que 800 observations ont été renseignées pour la feature  NIVEAU_ATTAQUE. Cela signifie qu’il ne manque pas de données.

2. La moyenne (mean)

Le niveau d’attaque moyen des Pokémons est de 79, c’est-à-dire qu’en dessous de cette moyenne on peut considérer que le Pokémon a un niveau faible, et au-dessus qu’il a un niveau fort, pouvant alors aider à gagner le combat. Nous disposons donc d’une première information intéressante.

3. L’écart type (Std pour Standard Deviation)

L’écart type est une valeur statistique, permettant de montrer la répartition des données autour de la moyenne. Plus sa valeur est petite, plus les données sont proches de la moyenne, dans le cas contraire, elles sont éloignées....

Quels sont les types de Pokémons qu’un dresseur doit posséder ?

Répondre à notre problématique, c’est se mettre à la place d’un dresseur de Pokémons. Afin de maximiser les chances de gagner, il faut que le dresseur de Pokémons dispose des principaux Pokémons du Pokédex dans sa collection.

En effet, en ayant les Pokémons les plus fréquemment rencontrés, cela signifie que les adversaires ont de grandes chances de posséder les mêmes. Sachant que deux Pokémons de même type peuvent contrer les attaques, cela peut donc éviter de perdre le combat (https://pokemondb.net/type/dual).

Pour connaître ces Pokémons indispensables à tout dresseur, nous allons utiliser un graphique qui nous permettra de visualiser rapidement leur nombre en fonction de leur type. Voici le code à utiliser :

On note l’import du module matplotlib, et l’utilisation du module seaborn, tous deux nécessaires à la représentation graphique des données.

import matplotlib.pyplot as plt 
import seaborn as sns 
 
axe_X = sns.countplot(x="TYPE_1", hue="LEGENDAIRE", 
data=nouveauPokedex) 
plt.xticks(rotation= 90) 
plt.xlabel('TYPE_1') 
plt.ylabel('Total ') 
plt.title("POKEMONS DE TYPE_1") 
plt.show() 
images/07FL02.png

Visualisation du nombre...

Les types de Pokémons gagnants et perdants

Il est à notre sens important de connaître les types de Pokémons gagnants. En effet, en s’assurant de les avoir dans sa collection et de les utiliser dans les combats, le dresseur a de fortes chances de gagner.

Pour obtenir cette information, on calcule la moyenne des pourcentages de victoires de chaque Pokémon. Cette moyenne, calculée et groupée par type de Pokémon, est ensuite triée par ordre croissant :

print(nouveauPokedex.groupby('TYPE_1').agg({"POURCENTAGE_VICTOIRE": 
"mean"}).sort_values(by = "POURCENTAGE_VICTOIRE")) 

La figure nous montre le résultat obtenu :

images/07FL04.png

Classement des Pokémons par le pourcentage moyen de leur victoire

On peut donc en déduire que les Pokémons gagnants sont de type :

  • Obscur

  • Électrique

  • Dragon

  • Vol

Nous pouvons également affirmer que les types de Pokémons suivants sont souvent voués à perdre leur combat :

  • Fée

  • Eau

  • Roche

  • Acier

  • Poison

Peut-on déjà en déduire quelque chose ? Si l’on prend le Pokémon, héros de la série, nommé Pikachu, de type électrique et qu’on le compare à un Pokémon Fée, on peut en déduire que Pikachu a de grandes chances de remporter le combat.

Si vous jouez personnellement aux Pokémons...

Essayons de trouver une corrélation entre les données

Une corrélation entre deux données signifie que celles-ci ont un lien fort entre elles. Exemple le statut d’adulte et l’âge de 18 ans, le fait de savoir voler et d’être pourvu d’ailes…

Dans notre cas, il s’agit de déterminer l’existence de features ayant un lien fort avec la capacité à gagner un combat. Faut-il être rapide ? Faut-il avoir un grand niveau d’attaque ? C’est ce que nous allons découvrir.

Avant toute chose, nous devons nous questionner sur l’utilité de l’ensemble des données en nous posant la question : "Cette feature peut-elle avoir un impact sur le fait de gagner ou non le combat ?"

  • Le numéro : non, car différent pour chaque Pokémon.

  • Le nom : non, car différent pour chaque Pokémon.

  • Le type_1 : oui, car nous venons de voir que certains types de Pokémons sont propices à la victoire.

  • Le type_2 : non, car tous les Pokémons n’ont pas de second type.

  • Les points de vie : oui, car plus on a de points de vie, plus on a de chance de gagner.

  • Les différents niveaux (attaque, défense, attaque spéciale, défense spéciale) : oui, car ce sont des caractéristiques propres au combat.

  • La vitesse : oui, car c’est aussi une caractéristique...

Résumé de nos observations

Si l’on résume les observations que nous avons effectuées, nous pouvons dire que pour remporter la victoire lors d’un combat, le dresseur de Pokémons doit :

  • Posséder des Pokémons de type herbe, eau, insecte et normal, ce qui lui permet de contrer les attaques,

  • Posséder des Pokémons de type obscur, électrique, dragon et vol, car ce sont eux qui ont un taux supérieur de victoire,

  • Utiliser un Pokémon ayant une grande vitesse,

  • Utiliser un Pokémon ayant un bon niveau d’attaque.

Vérifions nos hypothèses

Il nous faut à présent vérifier nos hypothèses en sélectionnant quelques combats dans le fichier combats.csv.

155,321,155 
101,583,583 
404,32,32 

NUMERO

NOM

TYPE

NIVEAU

ATTAQUE

VITESSE

VAINQUEUR

155

Méga-Ptéra

Roche

135

150

OUI

321

Makuhita

Combat

60

25

NUMERO

NOM

TYPE

NIVEAU

ATTAQUE

VITESSE

VAINQUEUR

101

Spectrum

Spectre

50

95

583

Zéblitz

Électrique

100

116

OUI

NUMERO

NOM

TYPE

NIVEAU

ATTAQUE

VITESSE

VAINQUEUR

275

Jungko

Herbe

85

120

155

Méga-Ptéra

Roche

135

150

OUI

NUMERO

NOM

TYPE

NIVEAU

ATTAQUE

VITESSE

VAINQUEUR

404

Rosabyss

Eau

84

52

32

Raichu

Électrique

90

110

OUI

Au vu de ces résultats, nos hypothèses semblent donc vérifiées.

Passons à la phase d’apprentissage

Le problème que nous devons résoudre consiste à déterminer si lors d’un combat, un Pokémon a de grandes chances de gagner.

Comme nous disposons de données d’apprentissage, nous sommes donc dans un cas de Machine Learning dit "supervisé". C’est-à-dire que la machine va apprendre en fonction de ce qu’on lui fournit en entrée.

Dans ce type de cas, nous disposons alors de deux types d’algorithmes : ceux dédiés à la classification ou ceux dédiés à la régression.

La classification permet d’organiser les prédictions en groupe, quant à la régression elle permet de définir une valeur.

Dans notre cas, nous devons prédire le pourcentage de victoire, c’est donc une valeur et c’est naturellement que nous utiliserons les algorithmes de régression que nous avons découverts dans le chapitre Principaux algorithmes du machine learning, à savoir :

  • La régression linéaire

  • Les arbres de décisions

  • Les forêts aléatoires

1. Découpage des observations en jeu d’apprentissage et jeu de tests

La première étape avant tout apprentissage est de découper les observations dont nous disposons en un jeu d’apprentissage avec lequel la machine va réaliser son apprentissage et en jeu de tests avec lequel la machine va évaluer son apprentissage. Pour cela, nous allons utiliser le module Scikit-Learn que nous vous invitons à ajouter à votre projet.

Afin d’éviter d’exécuter les différentes tâches d’analyse de données et de préparation de celles-ci avant chaque apprentissage, nous avons sauvegardé le Dataframe dans un fichier nommé dataset.csv avec pour séparateur des tabulations (sep=’\t’).

#Sauvegarde du Dataframe Pokedex 
dataset = nouveauPokedex 
dataset.to_csv("datas/dataset.csv", sep='\t') 

Dans un nouveau fichier de script Python, nous allons donc dans un premier temps charger ce fichier et supprimer les lignes pour lesquelles des valeurs sont manquantes comme à la ligne 12 du fichier :

images/07FL06.png

Données manquantes dans le fichier dataset.csv

#Chargement du dataset avec pour séparateur...

Phénomènes de surapprentissage (overfitting)  et de sous-apprentissage (underfitting)

Lorsque l’on cherche une solution à un problème en Machine Learning, nous souhaitons que celle-ci soit généralisable.

C’est-à-dire que la solution trouvée doit être applicable sur des données inconnues de celles utilisées lors de l’apprentissage. Pour cela, il faut que les données utilisées lors de la phase d’apprentissage soient les plus proches possible de la réalité et du problème à résoudre.

Le surapprentissage (overfitting) est un phénomène se traduisant par le fait que la solution est trop adaptée aux données d’apprentissage et ne se généralise pas à de nouvelles données qui lui sont inconnues. Ainsi, si pour un algorithme nous obtenons une précision 99 % sur les données d’apprentissage et que nous obtenons une valeur de 20 % sur les données de tests, il y fort à parier que nous sommes en présence d’un surapprentissage. C’est pourquoi il est conseillé de mesurer la précision à la fois sur les données d’apprentissage et sur les données de validation :

predictions = algorithme.predict(X_VALIDATION) 
precision_apprentissage = 
algorithme.score(X_APPRENTISSAGE,Y_APPRENTISSAGE) ...

Utiliser le modèle d’apprentissage dans une application

Nous disposons d’un modèle d’apprentissage capable de nous prédire le pourcentage de victoire de chaque Pokémon. Nous allons à présent créer une application utilisant ce modèle d’apprentissage et ayant pour objectif de prédire le vainqueur d’un combat opposant deux Pokémons choisis dans le Pokédex.

La première étape consiste à créer un nouveau fichier Python dans notre projet que l’on nommera quiSeraLeVainqueur.py.

Dans ce fichier, nous allons tout d’abord importer les modules dont nous avons besoin.

#Module de lecture de fichiers CSV 
import csv 
 
#Module de chargement du modèle d'apprentissage 
from sklearn.externals import joblib 

Nous allons ensuite écrire une première fonction qui sera chargée de chercher les informations d’un Pokémon dans le Pokédex à partir de son numéro et utiles à notre modèle de prédiction.

def rechercheInformationsPokemon(numPokemon,Pokedex): 
   infosPokemon = [] 
   for pokemon in Pokedex: 
       if (int(pokemon[0])==numPokemon): 
           infosPokemon = 
[pokemon[0],pokemon[1],pokemon[4],pokemon[5],pokemon[6],pokemon[7], 
pokemon[8],pokemon[9],pokemon[10]] 
           break 
   return infosPokemon 

On crée tout d’abord...

Fin du cas d’étude

Nous voici à présent au terme du cas d’étude dédié au Pokémon. Celui-ci nous a permis dans sa première partie de découvrir les étapes de préparation de données pour la résolution d’un problème lié au Machine Learning supervisé.

Dans la seconde partie, nous nous sommes attardés sur l’analyse plus fine des données afin de pouvoir déterminer celles ayant une incidence forte (corrélation) sur la résolution de notre problème. Une fois cette étape réalisée, nous avons émis des hypothèses sur la prédiction de la victoire d’un Pokémon par rapport à son adversaire et vérifié celles-ci.

Nous avons ensuite testé divers algorithmes de prédiction, liés à la régression (car nous cherchions à prédire une valeur) afin de déterminer celui qui nous permettra d’obtenir un modèle de prédiction fiable. Modèle que nous avons ensuite utilisé dans une application.

Ce qu’il faut retenir de cette expérience est que la préparation et l’analyse des données est une phase, si ce n’est la phase la plus importante d’un projet de Machine Learning. Des données bien préparées et de bonne qualité...