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()

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 :

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 :

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é...