Aller au contenu

Le Choixpeau Magique⚓︎

a l'école des sorciers choipeau

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 :

extrait

Et voici les élèves que le choixpeau magique souhaite orienter :

a 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 :

🐍 Script Python
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)

🐍 Script Python
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
🐍 Script Python
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 ?

🐍 Script Python
poudlard.loc[0]
📋 Texte
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

🐍 Script Python
poudlard['Maison'].value_counts()
📋 Texte
Gryffondor     17
Serpentard     12
Serdaigle      11
Poufsouffle    10
Name: Maison, dtype: int64

Question 7

Quel est la maison ayant le plus d’élève ?

🐍 Script Python
poudlard['Maison'].describe().top
📋 Texte
'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
🐍 Script Python
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
🐍 Script Python
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'