Le Choixpeau Magique⚓︎
Lien vers la documentation de la librairie PANDAS (en anglais)
Crédits
« Aidons le choixpeau magique », Prépabac 1ere NSI, éditions Hatier. Sujet adapté et remanié.
A l’entrée à l’école de Poudlard, le choixpeau magique répartit les élèves dans les différentes maisons (Gryffondor, Serpentard, Serdaigle et Poufsouffle) en fonction de leur courage, leur loyauté, leur sagesse, et leur malice.
Le choixpeau magique dispose d’un fichier CSV dans lequel sont répertoriées les données d’un échantillon d’élèves. Voici les 6 premières lignes de ce fichier :
Et voici les élèves que le choixpeau magique souhaite orienter :
L’objectif de cet exercice est d’aider le choixpeau à déterminer la maison des nouveaux élèves.
Partie I : Modéliser un élève⚓︎
On décide de modéliser chaque élève par un dictionnaire avec les données à disposition. Par exemple :
adrian = {"nom" : "Adrian", "courage":9,"loyaute":4,"sagesse":7,"malice":10,"maison":"serpentard"}
hermione = {"nom" : "Hermione", "courage":8,"loyaute":6,"sagesse":6,"malice":6}
Question 1
Donner la modélisation de l’élève Anthony
anthony = {"nom" : "anthony", "courage":2,"loyaute":8,"sagesse":8,"malice":3}
On décide d’utiliser la distance de Manhattan pour calculer la distance entre 2 élèves, c’est-à-dire :
\(distance(eleve1, eleve2) = |c1-c2|+|l1-l2|+|s1-s2|+|m1-m2|\)
Question 2
Avec cette formule, vérifier que la distance entre Hermione et Adrian est bien égale à 8
Question 3
Quelle est la distance entre Arthur et Drago ?
12
Question 4
Ecrire le code d’une fonction distance qui prend deux élèves en paramètre et qui renvoie la distance entre ces 2 élèves. Ne pas oublier de préciser la documentation (docstring) et de donner au moins un test (assert).
Note : la valeur absolue d’un nombre s’obtient par abs(nombre)
adrian = {"nom" : "Adrian", "courage":9,"loyaute":4,"sagesse":7,"malice":10,"maison":"serpentard"}
hermione = {"nom" : "Hermione", "courage":8,"loyaute":6,"sagesse":6,"malice":6}
def distance (E1,E2) :
"""
prend en paramètres 2 élèves
@param : E1 : Dictionnaire
@param : E2 : Dictionnaire
@Returns : int : renvoie la distance de Manhattan entre les 2 eleves
"""
return abs(E1["courage"]-E2["courage"])+abs(E1["loyaute"]-E2["loyaute"])+abs(E1["sagesse"]-E2["sagesse"])+abs(E1["malice"]-E2["malice"])
assert (distance(adrian,hermione)) == 8
Partie III : Charger le dataframe⚓︎
Voici le code d’une fonction qui permet de récupérer les données des élèves d’un fichier CSV pour les stocker dans un dataframe pandas.
Le jeu de données : choipeau Magique
Code charger_eleve
import pandas as pd #import du module pandas, abrégé classiquement par "pd"
def charger_eleve(fichier) :
"""
permet de charger une liste d eleves d'un fichier CSV
Return : dataframe
"""
return pd.read_csv(fichier, encoding = 'utf-8')
poudlard = charger_eleve('choixpeauMagique.csv')
Question 5
Quel est le nom du premier élève ?
poudlard.loc[0]
Nom Adrian
Courage 9
Loyauté 4
Sagesse 7
Malice 10
Maison Serpentard
Name: 0, dtype: object
Question 6
Indiquer le nombre d’élèves par maison
poudlard['Maison'].value_counts()
Gryffondor 17
Serpentard 12
Serdaigle 11
Poufsouffle 10
Name: Maison, dtype: int64
Question 7
Quel est la maison ayant le plus d’élève ?
poudlard['Maison'].describe().top
'Gryffondor'
Partie III : Maison majoritaire⚓︎
Ecrire le code d’une fonction qui prend en paramètre un dataframe Pandas et qui renvoie la maison la plus représentée dans la liste. Ne pas oublier de préciser la documentation (docstring) et de donner au moins un test (assert).
correction
def majoritaire(data) :
"""
Fonction renvoyant la maison majoritaire dans un DataFrame de données sur Poudlard.
@param : Data : DataFrame contenant les données sur les maisons des élèves de Poudlard.
@Returns: str: La maison la plus fréquente dans la colonne 'Maison' du DataFrame.
"""
return poudlard['Maison'].describe().top
assert majoritaire(poudlard)== 'Gryffondor'
Partie IV : Sept plus proches voisins⚓︎
Donner la fonction choipeauMagique
qui prend en paramètre la liste des élèves déjà présent à Poudlard sous forme de dataFrame et un nouvel élève qui n'a pas encore de maison, et qui retourne la maison choisi grace à l'algorithme des plus proche voisins avec \(k=3\), puis \(k=7\)
Note : Vous utiliserez la distance de Manhattan préparer dans les parties précédentes.
Correction
def septPlusProches(cm,nouveau):
"""
Fonction renvoyant la maison choisi par le choipeau par l'algorithme des plus proches voisins.
@param : cm : DataFrame contenant les données sur les maisons des élèves de Poudlard.
@param : nouveau : dictionnaire contenant le nouvel élève à affecter à une maison
@Returns: str : La maison choisie
"""
#On ajoute une nouvelle colonne distance à notre jeu de données pandas
#correspondant la la distance euclienne entre le nouveau et la ligne traitée
cm['distance']= abs(cm['Courage']-nouveau["courage"])+abs(cm['Loyaute']-nouveau["loyaute"])+abs(cm['Sagesse']-nouveau["sagesse"])+abs(cm['Malice']-nouveau["malice"])
# On trie le jeu de donnée sur cette nouvelle colonne
newcm = cm.sort_values(by='distance', ascending=True)
#On ne garde que les 7 premières lignes que l'on 'copie' dans un nouveau dataframe
newcmtri = newcm.head(7) #on prend les 7 eleves les plus proches
#On ne garde que le poste le plus fréquent sur ces 7 lignes
sol = newcmtri['Maison'].describe().top
return sol
Harry = {"nom" : "Harry", "courage":10,"loyaute":9,"sagesse":6,"malice":3}
assert septPlusProches(poudlard,Harry) == 'Gryffondor'