0% ont trouvé ce document utile (0 vote)
30 vues85 pages

TP Performance Scolaire

Transféré par

ibrahim ibn isshaq
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
30 vues85 pages

TP Performance Scolaire

Transféré par

ibrahim ibn isshaq
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

student-perf-datamining-french

June 27, 2025

0.0.1 Student Performance Dataset


• Sujet : Notes trimestrielles des élèves portugais
• Taille : student_mat = 395 lignes, student_por = 649 lignes, avec 33 colonnes pour les deux.
• Question : Nous disposons de deux ensembles de données, chacun représentant une spécialité.
Notre objectif est de déterminer la spécialité avec les meilleures notes, de comparer les deux
écoles (GP ou MS), et d’explorer d’autres aspects intéressants.
• Description : Ces ensembles de données sont également très intéressants, et ils ne contien-
nent aucune donnée manquante. De plus, il serait possible de fusionner les deux ensembles
de données pour en créer un seul, puis de les traiter et de créer des modèles avec ces données
fusionnées.
Dans le cadre de notre analyse, nous allons traiter, présenter et illustrer les éléments principaux
et intéressants de chaque ensemble de données. Cette démarche nous permettra d’explorer des
informations pertinentes et de répondre à diverses questions liées à chaque sujet.

1 Introduction
Nous disposons de deux ensembles de données qui proviennent de deux lycées portugais différents.
L’un est axé sur les élèves ayant choisi les mathématiques comme matière principale (“student-
mat”), tandis que l’autre concerne les élèves ayant choisi le portugais (“student-por”). Notre objectif
est de prédire les performances des élèves au lycée en se basant sur ces données, qui comprennent
les notes des élèves ainsi que des informations démographiques, sociales et scolaires. Les données
ont été collectées à partir de rapports scolaires et de questionnaires.
Les deux dataset contiennent des informations sur les performances des élèves dans un cours de
portugais ou en mathématiques. Voici une description détaillée des données : Variables :
school : Le nom de l'école.
sex : Le sexe de l'élève (F pour féminin, M pour masculin).
age : L'âge de l'élève.
address : Le type d'adresse de l'élève (U pour urbaine, R pour rurale).
famsize : La taille de la famille de l'élève (LE3 pour moins de 3 personnes, GT3 pour plus de 3
Pstatus : Le statut de cohabitation des parents de l'élève (A pour séparés, T pour ensemble).
Medu : Le niveau d'éducation de la mère de l'élève (0-4, où 0 signifie aucune éducation et 4 si
Fedu : Le niveau d'éducation du père de l'élève (0-4, similaire à Medu).
traveltime : Le temps de trajet entre le domicile et l'école (1-4, où 1 est très court et 4 est
studytime : Le temps d'étude hebdomadaire en heures (1-4, où 1 est très court et 4 est très lon
failures : Le nombre d'échecs antérieurs en classe (numérique).
schoolsup : Soutien éducatif supplémentaire à l'école (oui ou non).

1
famsup : Soutien éducatif supplémentaire de la famille (oui ou non).
paid : Cours supplémentaires payés (oui ou non).
activities : Activités parascolaires (oui ou non).
nursery : A fréquenté la garderie (oui ou non).
higher : A l'intention de poursuivre des études supérieures (oui ou non).
internet : Accès à Internet à domicile (oui ou non).
romantic : Relation romantique (oui ou non).
famrel : Qualité des relations familiales (de 1 à 5).
freetime : Temps libre après l'école (de 1 à 5).
goout : Sorties entre amis (de 1 à 5).
Dalc : Consommation d'alcool en jour de semaine (de 1 à 5).
Walc : Consommation d'alcool en week-end (de 1 à 5).
health : État de santé actuel (de 1 à 5).
absences : Nombre d'absences à l'école (numérique).
G1 : Note du premier trimestre (de 0 à 20).
G2 : Note du deuxième trimestre (de 0 à 20).
G3 : Note finale (de 0 à 20, variable cible).
Taille du jeu de données :
Le jeu de données contient un total de 649 exemples.
Il y a 29 colonnes, chacune contenant des informations sur les élèves et leurs performances aca
Données manquantes :
Il n'y a pas de données manquantes dans ce jeu de données.

1.1 Question que l’on peut se poser sur Student_mat & Student_por
Student Performance Dataset (student-por and student-mat): Les ensembles de données
suivants, tirés du même référentiel, se penchent sur les performances scolaires des étudiants en
portugais (student-por) et en mathématiques (student-mat). Chacun de ces ensembles compte
respectivement 395 et 649 lignes, avec 33 colonnes pour les deux. Les questions examinent la
spécialité avec les meilleures notes, les différences entre les écoles GP et MS, et d’autres aspects
intéressants tels que l’impact de la consommation d’alcool sur les résultats académiques.
• Quelle spécialité (portugais ou mathématiques) présente généralement les meilleures perfor-
mances académiques?
• Y a-t-il une corrélation entre le temps d’étude et les notes obtenues dans chaque spécialité?
• Comment les caractéristiques familiales influent-elles sur les performances académiques des
étudiants?
• Quelles différences existent entre les écoles GP et MS en termes de résultats académiques?
• Les étudiants qui ont un accès facile à Internet à domicile ont-ils tendance à obtenir de
meilleures notes?
• Quel impact le niveau d’absentéisme a-t-il sur les performances académiques des étudiants?
• Existe-t-il des différences significatives entre les performances des garçons et des filles dans
chaque spécialité?
• Comment la consommation d’alcool est-elle liée aux résultats scolaires dans ces deux spécial-
ités?

2
• Les étudiants qui ont suivi des cours de soutien ont-ils généralement de meilleures perfor-
mances?
• Quels sont les facteurs qui semblent avoir le plus grand impact sur les résultats globaux des
étudiants?

1.2 Student Performance Dataset (fusion of student-por and student-mat):


Enfin, nous explorons un ensemble de données fusionné, résultant de la combinaison des ensem-
bles student-por et student-mat. Cette fusion offre une perspective plus large sur les performances
académiques des étudiants, permettant d’analyser les tendances globales et les relations entre les
différentes matières. Les questions abordent la distribution des performances, l’impact des carac-
téristiques communes, et la stabilité des résultats dans le contexte de l’échantillon agrégé.
• Quelle est la distribution des performances académiques globales après la fusion des deux
ensembles de données?
• Comment les caractéristiques communes aux deux spécialités impactent-elles les résultats
académiques?
• Existe-t-il des différences significatives entre les performances académiques des étudiants en
portugais et en mathématiques après la fusion?
• Quels facteurs socio-économiques semblent jouer un rôle important dans les performances
globales des étudiants?
• Comment les interactions entre les étudiants des deux spécialités peuvent-elles être analysées
dans le contexte de la performance académique?
• La fusion des ensembles de données permet-elle de révéler des tendances ou des patterns qui
ne sont pas évidents dans chaque ensemble individuellement?
• Quel est l’impact de la taille totale de l’échantillon sur la stabilité des résultats de l’analyse?
• Y a-t-il des corrélations entre les notes dans différentes matières au sein du dataset fusionné?
• Comment les caractéristiques individuelles des étudiants (comme le niveau d’éducation des
parents) influent-elles sur les résultats globaux?
• Quelles sont les principales différences entre les écoles GP et MS lorsqu’on considère la fusion
des données académiques?
À travers cette démarche d’analyse approfondie, nous visons à extraire des informations pertinentes
et à répondre de manière exhaustive aux questions spécifiques de chaque ensemble de données,
contribuant ainsi à une compréhension plus nuancée des domaines étudiés.

2 Partie 1 : Importation des bibliothèques et chargement des don-


nées
Dans cette première partie, nous allons importer les bibliothèques nécessaires et charger les données
à partir des fichiers CSV correspondants.

[1]: # Importation des bibliothèques nécessaires


import pandas as pd
import numpy as np
import [Link] as plt
import seaborn as sns
from sklearn.model_selection import train_test_split

3
from sklearn.linear_model import LinearRegression, LogisticRegression
from [Link] import DecisionTreeClassifier
from [Link] import RandomForestClassifier
from [Link] import SVC
from [Link] import KNeighborsClassifier
from [Link] import StandardScaler, LabelEncoder, OneHotEncoder
from [Link] import mean_squared_error, r2_score, accuracy_score,␣
↪classification_report, confusion_matrix

from [Link] import KMeans


from imblearn.over_sampling import RandomOverSampler
from [Link] import PCA
from sklearn import tree

# Chargement des dataframes 'student-mat' et 'student-por' depuis les fichiers␣


↪CSV

student_mat = pd.read_csv('/kaggle/input/student-alcohol-consumption/
↪[Link]', sep=',')

student_por = pd.read_csv('/kaggle/input/student-alcohol-consumption/
↪[Link]', sep=',')

student_mat
student_por

[1]: school sex age address famsize Pstatus Medu Fedu Mjob Fjob \
0 GP F 18 U GT3 A 4 4 at_home teacher
1 GP F 17 U GT3 T 1 1 at_home other
2 GP F 15 U LE3 T 1 1 at_home other
3 GP F 15 U GT3 T 4 2 health services
4 GP F 16 U GT3 T 3 3 other other
.. … .. … … … … … … … …
644 MS F 19 R GT3 T 2 3 services other
645 MS F 18 U LE3 T 3 1 teacher services
646 MS F 18 U GT3 T 1 1 other other
647 MS M 17 U LE3 T 3 1 services services
648 MS M 18 R LE3 T 3 2 services other

… famrel freetime goout Dalc Walc health absences G1 G2 G3


0 … 4 3 4 1 1 3 4 0 11 11
1 … 5 3 3 1 1 3 2 9 11 11
2 … 4 3 2 2 3 3 6 12 13 12
3 … 3 2 2 1 1 5 0 14 14 14
4 … 4 3 2 1 2 5 0 11 13 13
.. … … … … … … … … .. .. ..
644 … 5 4 2 1 2 5 4 10 11 10
645 … 4 3 4 1 1 1 4 15 15 16
646 … 1 1 1 1 1 5 6 11 12 9
647 … 2 4 5 3 4 2 6 10 10 10
648 … 4 4 1 3 4 5 4 10 11 11

4
[649 rows x 33 columns]

Observation : Nous avons importé les bibliothèques nécessaires pour effectuer les tâches demandées.
Les données des étudiants en mathématiques (student-mat) et en portugais (student-por) ont été
chargées depuis les fichiers CSV.

3 Partie 2 : Prétraitement des données


Dans cette partie, nous allons effectuer le prétraitement des données en convertissant certaines
colonnes en valeurs binaires (0 et 1) et en gérant les colonnes catégorielles.

[2]: # Définir les colonnes à convertir en valeurs binaires (0 et 1)


binary_columns = ['school', 'sex', 'address', 'famsize', 'Pstatus',␣
↪'schoolsup', 'famsup', 'paid',

'activities', 'nursery', 'higher', 'internet', 'romantic']

# Remplacer les valeurs spécifiées dans les colonnes binaires par 0 et 1 pour␣
↪chaque dataframe

binary_mapping = {'GP': 0, 'MS': 1, 'F': 0, 'M': 1, 'U': 0, 'R': 1, 'LE3': 0,␣


↪'GT3': 1, 'A': 0, 'T': 1, 'yes': 1, 'no': 0}

for col in binary_columns:


student_mat[col] = student_mat[col].map(binary_mapping)
student_por[col] = student_por[col].map(binary_mapping)
student_mat

[2]: school sex age address famsize Pstatus Medu Fedu Mjob \
0 0 0 18 0 1 0 4 4 at_home
1 0 0 17 0 1 1 1 1 at_home
2 0 0 15 0 0 1 1 1 at_home
3 0 0 15 0 1 1 4 2 health
4 0 0 16 0 1 1 3 3 other
.. … … … … … … … … …
390 1 1 20 0 0 0 2 2 services
391 1 1 17 0 0 1 3 1 services
392 1 1 21 1 1 1 1 1 other
393 1 1 18 1 0 1 3 2 services
394 1 1 19 0 0 1 1 1 other

Fjob … famrel freetime goout Dalc Walc health absences G1 \


0 teacher … 4 3 4 1 1 3 6 5
1 other … 5 3 3 1 1 3 4 5
2 other … 4 3 2 2 3 3 10 7
3 services … 3 2 2 1 1 5 2 15
4 other … 4 3 2 1 2 5 4 6
.. … … … … … … … … … ..
390 services … 5 5 4 4 5 4 11 9

5
391 services … 2 4 5 3 4 2 3 14
392 other … 5 5 3 3 3 3 3 10
393 other … 4 4 1 3 4 5 0 11
394 at_home … 3 2 3 3 3 5 5 8

G2 G3
0 6 6
1 5 6
2 8 10
3 14 15
4 10 10
.. .. ..
390 9 9
391 16 16
392 8 7
393 12 10
394 9 9

[395 rows x 33 columns]

Observation : Dans cette partie, nous avons converti certaines colonnes en valeurs binaires en
remplaçant les valeurs spécifiées par 0 et 1. Cela permet de préparer les données pour les tâches
suivantes.

4 Partie 3 : Encodage one-hot des colonnes catégorielles


Nous allons maintenant gérer les colonnes catégorielles en appliquant l’encodage one-hot sur les
DataFrames.

[3]: # Liste des colonnes catégorielles dans les DataFrames 'student-mat' et␣
↪'student-por'

categorical_columns = ['Mjob', 'Fjob', 'reason', 'guardian']

# Appliquez l'encodage one-hot sur les DataFrames pour les colonnes␣


↪catégorielles

encoder = OneHotEncoder(sparse=False, drop='first')

mat_encoded = encoder.fit_transform(student_mat[categorical_columns])
por_encoded = [Link](student_por[categorical_columns])

# Obtenez les noms des fonctionnalités après l'encodage one-hot


feature_names = encoder.
↪get_feature_names_out(input_features=categorical_columns)

# Créez de nouveaux DataFrames avec les fonctionnalités encodées


student_mat_encoded = [Link](mat_encoded, columns=feature_names)
student_por_encoded = [Link](por_encoded, columns=feature_names)

6
# Concaténez les données encodées avec les DataFrames d'origine et supprimez␣
↪les colonnes catégorielles

student_mat = [Link]([student_mat, student_mat_encoded], axis=1)


student_mat = student_mat.drop(categorical_columns, axis=1)

student_por = [Link]([student_por, student_por_encoded], axis=1)


student_por = student_por.drop(categorical_columns, axis=1)
student_por

/opt/conda/lib/python3.10/site-packages/sklearn/preprocessing/_encoders.py:868:
FutureWarning: `sparse` was renamed to `sparse_output` in version 1.2 and will
be removed in 1.4. `sparse_output` is ignored unless you leave `sparse` to its
default value.
[Link](

[3]: school sex age address famsize Pstatus Medu Fedu traveltime \
0 0 0 18 0 1 0 4 4 2
1 0 0 17 0 1 1 1 1 1
2 0 0 15 0 0 1 1 1 1
3 0 0 15 0 1 1 4 2 1
4 0 0 16 0 1 1 3 3 1
.. … … … … … … … … …
644 1 0 19 1 1 1 2 3 1
645 1 0 18 0 0 1 3 1 1
646 1 0 18 0 1 1 1 1 2
647 1 1 17 0 0 1 3 1 2
648 1 1 18 1 0 1 3 2 3

studytime … Mjob_teacher Fjob_health Fjob_other Fjob_services \


0 2 … 0.0 0.0 0.0 0.0
1 2 … 0.0 0.0 1.0 0.0
2 2 … 0.0 0.0 1.0 0.0
3 3 … 0.0 0.0 0.0 1.0
4 2 … 0.0 0.0 1.0 0.0
.. … … … … … …
644 3 … 0.0 0.0 1.0 0.0
645 2 … 1.0 0.0 0.0 1.0
646 2 … 0.0 0.0 1.0 0.0
647 1 … 0.0 0.0 0.0 1.0
648 1 … 0.0 0.0 1.0 0.0

Fjob_teacher reason_home reason_other reason_reputation \


0 1.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 1.0 0.0
3 0.0 1.0 0.0 0.0

7
4 0.0 1.0 0.0 0.0
.. … … … …
644 0.0 0.0 0.0 0.0
645 0.0 0.0 0.0 0.0
646 0.0 0.0 0.0 0.0
647 0.0 0.0 0.0 0.0
648 0.0 0.0 0.0 0.0

guardian_mother guardian_other
0 1.0 0.0
1 0.0 0.0
2 1.0 0.0
3 1.0 0.0
4 0.0 0.0
.. … …
644 1.0 0.0
645 1.0 0.0
646 1.0 0.0
647 1.0 0.0
648 1.0 0.0

[649 rows x 42 columns]

Observation : Nous avons identifié les colonnes catégorielles et appliqué l’encodage one-hot pour
les colonnes catégorielles. Cela permet de transformer ces colonnes en un format numérique adapté
à l’analyse.
La fonction d’encodage one-hot vise à convertir des données caractères en données binaires pour
les colonnes Mjob, Fjob, reason, et guardian. Elle génère de nouvelles colonnes secondaires sous
forme de variables binaires. Par conséquent, notre ensemble de données ne contient que des valeurs
numériques, ce qui facilite le traitement et l’analyse ultérieurs.

4.1 Convertions des FLOATS en INTS


Cependant, la fonction renvoie des valeurs en flottant. Nous privilégions les valeurs en entiers, nous
convertissons donc les nombres flottants en entiers.

[4]: # Liste des colonnes qui sont en float


float_columns = ['Mjob_health', 'Mjob_other', 'Mjob_services', 'Mjob_teacher',
'Fjob_health', 'Fjob_other', 'Fjob_services', 'Fjob_teacher',
'reason_home', 'reason_other', 'reason_reputation',
'guardian_mother', 'guardian_other']

# Convertir les colonnes float en int


student_mat[float_columns] = student_mat[float_columns].astype(int)
student_por[float_columns] = student_por[float_columns].astype(int)

8
5 Partie 4 : Fusion des DataFrames
Nous allons fusionner les DataFrames ‘student-mat’ et ‘student-por’ en un seul DataFrame ‘student-
perf’.

[5]: # Fusionner les DataFrames 'student-mat' et 'student-por' en un seul DataFrame␣


↪'student-perf'

student_perf = [Link]([student_mat, student_por], axis=0)

# Réindexer le DataFrame 'student-perf' après la fusion


student_perf.reset_index(drop=True, inplace=True)

Observation : Les données des étudiants en mathématiques et en portugais ont été fusionnées en
un seul DataFrame ‘student-perf’. Nous avons également réindexé le DataFrame pour refléter la
nouvelle structure.

6 Partie 5 : Exploration des données (EDA)


Dans cette partie, nous allons explorer les données en affichant des informations sur la structure
des données, en calculant les statistiques descriptives et en créant une matrice de corrélation.

[6]: # Afficher les informations sur la structure des données


def data_info(data, name):
print(f"Informations pour le jeu de données {name}:")
print([Link]())
print([Link]().sum())
print("Nombre total d'entrées:", len(data))
print("\n")

data_info(student_mat, 'student-mat')
data_info(student_por, 'student-por')
data_info(student_perf, 'student-perf')

# Calculer et afficher les statistiques descriptives pour 'student-perf'


print("Statistiques descriptives pour student-perf:")
print(student_perf.describe())

Informations pour le jeu de données student-mat:


<class '[Link]'>
RangeIndex: 395 entries, 0 to 394
Data columns (total 42 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 school 395 non-null int64
1 sex 395 non-null int64
2 age 395 non-null int64
3 address 395 non-null int64
4 famsize 395 non-null int64

9
5 Pstatus 395 non-null int64
6 Medu 395 non-null int64
7 Fedu 395 non-null int64
8 traveltime 395 non-null int64
9 studytime 395 non-null int64
10 failures 395 non-null int64
11 schoolsup 395 non-null int64
12 famsup 395 non-null int64
13 paid 395 non-null int64
14 activities 395 non-null int64
15 nursery 395 non-null int64
16 higher 395 non-null int64
17 internet 395 non-null int64
18 romantic 395 non-null int64
19 famrel 395 non-null int64
20 freetime 395 non-null int64
21 goout 395 non-null int64
22 Dalc 395 non-null int64
23 Walc 395 non-null int64
24 health 395 non-null int64
25 absences 395 non-null int64
26 G1 395 non-null int64
27 G2 395 non-null int64
28 G3 395 non-null int64
29 Mjob_health 395 non-null int64
30 Mjob_other 395 non-null int64
31 Mjob_services 395 non-null int64
32 Mjob_teacher 395 non-null int64
33 Fjob_health 395 non-null int64
34 Fjob_other 395 non-null int64
35 Fjob_services 395 non-null int64
36 Fjob_teacher 395 non-null int64
37 reason_home 395 non-null int64
38 reason_other 395 non-null int64
39 reason_reputation 395 non-null int64
40 guardian_mother 395 non-null int64
41 guardian_other 395 non-null int64
dtypes: int64(42)
memory usage: 129.7 KB
None
school 0
sex 0
age 0
address 0
famsize 0
Pstatus 0
Medu 0
Fedu 0

10
traveltime 0
studytime 0
failures 0
schoolsup 0
famsup 0
paid 0
activities 0
nursery 0
higher 0
internet 0
romantic 0
famrel 0
freetime 0
goout 0
Dalc 0
Walc 0
health 0
absences 0
G1 0
G2 0
G3 0
Mjob_health 0
Mjob_other 0
Mjob_services 0
Mjob_teacher 0
Fjob_health 0
Fjob_other 0
Fjob_services 0
Fjob_teacher 0
reason_home 0
reason_other 0
reason_reputation 0
guardian_mother 0
guardian_other 0
dtype: int64
Nombre total d'entrées: 395

Informations pour le jeu de données student-por:


<class '[Link]'>
RangeIndex: 649 entries, 0 to 648
Data columns (total 42 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 school 649 non-null int64
1 sex 649 non-null int64
2 age 649 non-null int64
3 address 649 non-null int64

11
4 famsize 649 non-null int64
5 Pstatus 649 non-null int64
6 Medu 649 non-null int64
7 Fedu 649 non-null int64
8 traveltime 649 non-null int64
9 studytime 649 non-null int64
10 failures 649 non-null int64
11 schoolsup 649 non-null int64
12 famsup 649 non-null int64
13 paid 649 non-null int64
14 activities 649 non-null int64
15 nursery 649 non-null int64
16 higher 649 non-null int64
17 internet 649 non-null int64
18 romantic 649 non-null int64
19 famrel 649 non-null int64
20 freetime 649 non-null int64
21 goout 649 non-null int64
22 Dalc 649 non-null int64
23 Walc 649 non-null int64
24 health 649 non-null int64
25 absences 649 non-null int64
26 G1 649 non-null int64
27 G2 649 non-null int64
28 G3 649 non-null int64
29 Mjob_health 649 non-null int64
30 Mjob_other 649 non-null int64
31 Mjob_services 649 non-null int64
32 Mjob_teacher 649 non-null int64
33 Fjob_health 649 non-null int64
34 Fjob_other 649 non-null int64
35 Fjob_services 649 non-null int64
36 Fjob_teacher 649 non-null int64
37 reason_home 649 non-null int64
38 reason_other 649 non-null int64
39 reason_reputation 649 non-null int64
40 guardian_mother 649 non-null int64
41 guardian_other 649 non-null int64
dtypes: int64(42)
memory usage: 213.1 KB
None
school 0
sex 0
age 0
address 0
famsize 0
Pstatus 0
Medu 0

12
Fedu 0
traveltime 0
studytime 0
failures 0
schoolsup 0
famsup 0
paid 0
activities 0
nursery 0
higher 0
internet 0
romantic 0
famrel 0
freetime 0
goout 0
Dalc 0
Walc 0
health 0
absences 0
G1 0
G2 0
G3 0
Mjob_health 0
Mjob_other 0
Mjob_services 0
Mjob_teacher 0
Fjob_health 0
Fjob_other 0
Fjob_services 0
Fjob_teacher 0
reason_home 0
reason_other 0
reason_reputation 0
guardian_mother 0
guardian_other 0
dtype: int64
Nombre total d'entrées: 649

Informations pour le jeu de données student-perf:


<class '[Link]'>
RangeIndex: 1044 entries, 0 to 1043
Data columns (total 42 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 school 1044 non-null int64
1 sex 1044 non-null int64
2 age 1044 non-null int64

13
3 address 1044 non-null int64
4 famsize 1044 non-null int64
5 Pstatus 1044 non-null int64
6 Medu 1044 non-null int64
7 Fedu 1044 non-null int64
8 traveltime 1044 non-null int64
9 studytime 1044 non-null int64
10 failures 1044 non-null int64
11 schoolsup 1044 non-null int64
12 famsup 1044 non-null int64
13 paid 1044 non-null int64
14 activities 1044 non-null int64
15 nursery 1044 non-null int64
16 higher 1044 non-null int64
17 internet 1044 non-null int64
18 romantic 1044 non-null int64
19 famrel 1044 non-null int64
20 freetime 1044 non-null int64
21 goout 1044 non-null int64
22 Dalc 1044 non-null int64
23 Walc 1044 non-null int64
24 health 1044 non-null int64
25 absences 1044 non-null int64
26 G1 1044 non-null int64
27 G2 1044 non-null int64
28 G3 1044 non-null int64
29 Mjob_health 1044 non-null int64
30 Mjob_other 1044 non-null int64
31 Mjob_services 1044 non-null int64
32 Mjob_teacher 1044 non-null int64
33 Fjob_health 1044 non-null int64
34 Fjob_other 1044 non-null int64
35 Fjob_services 1044 non-null int64
36 Fjob_teacher 1044 non-null int64
37 reason_home 1044 non-null int64
38 reason_other 1044 non-null int64
39 reason_reputation 1044 non-null int64
40 guardian_mother 1044 non-null int64
41 guardian_other 1044 non-null int64
dtypes: int64(42)
memory usage: 342.7 KB
None
school 0
sex 0
age 0
address 0
famsize 0
Pstatus 0

14
Medu 0
Fedu 0
traveltime 0
studytime 0
failures 0
schoolsup 0
famsup 0
paid 0
activities 0
nursery 0
higher 0
internet 0
romantic 0
famrel 0
freetime 0
goout 0
Dalc 0
Walc 0
health 0
absences 0
G1 0
G2 0
G3 0
Mjob_health 0
Mjob_other 0
Mjob_services 0
Mjob_teacher 0
Fjob_health 0
Fjob_other 0
Fjob_services 0
Fjob_teacher 0
reason_home 0
reason_other 0
reason_reputation 0
guardian_mother 0
guardian_other 0
dtype: int64
Nombre total d'entrées: 1044

Statistiques descriptives pour student-perf:


school sex age address famsize \
count 1044.000000 1044.000000 1044.000000 1044.000000 1044.000000
mean 0.260536 0.433908 16.726054 0.272989 0.706897
std 0.439138 0.495850 1.239975 0.445708 0.455404
min 0.000000 0.000000 15.000000 0.000000 0.000000
25% 0.000000 0.000000 16.000000 0.000000 0.000000
50% 0.000000 0.000000 17.000000 0.000000 1.000000

15
75% 1.000000 1.000000 18.000000 1.000000 1.000000
max 1.000000 1.000000 22.000000 1.000000 1.000000

Pstatus Medu Fedu traveltime studytime … \


count 1044.000000 1044.000000 1044.000000 1044.000000 1044.000000 …
mean 0.884100 2.603448 2.387931 1.522989 1.970307 …
std 0.320259 1.124907 1.099938 0.731727 0.834353 …
min 0.000000 0.000000 0.000000 1.000000 1.000000 …
25% 1.000000 2.000000 1.000000 1.000000 1.000000 …
50% 1.000000 3.000000 2.000000 1.000000 2.000000 …
75% 1.000000 4.000000 3.000000 2.000000 2.000000 …
max 1.000000 4.000000 4.000000 4.000000 4.000000 …

Mjob_teacher Fjob_health Fjob_other Fjob_services Fjob_teacher \


count 1044.000000 1044.000000 1044.000000 1044.000000 1044.000000
mean 0.124521 0.039272 0.559387 0.279693 0.062261
std 0.330333 0.194335 0.496699 0.449064 0.241744
min 0.000000 0.000000 0.000000 0.000000 0.000000
25% 0.000000 0.000000 0.000000 0.000000 0.000000
50% 0.000000 0.000000 1.000000 0.000000 0.000000
75% 0.000000 0.000000 1.000000 1.000000 0.000000
max 1.000000 1.000000 1.000000 1.000000 1.000000

reason_home reason_other reason_reputation guardian_mother \


count 1044.000000 1044.000000 1044.000000 1044.000000
mean 0.247126 0.103448 0.237548 0.697318
std 0.431548 0.304689 0.425785 0.459639
min 0.000000 0.000000 0.000000 0.000000
25% 0.000000 0.000000 0.000000 0.000000
50% 0.000000 0.000000 0.000000 1.000000
75% 0.000000 0.000000 0.000000 1.000000
max 1.000000 1.000000 1.000000 1.000000

guardian_other
count 1044.000000
mean 0.069923
std 0.255140
min 0.000000
25% 0.000000
50% 0.000000
75% 0.000000
max 1.000000

[8 rows x 42 columns]
Observation : Dans cette section, nous avons affiché des informations détaillées sur la structure des
données, y compris les types de données, les valeurs manquantes et le nombre total d’entrées. De
plus, nous avons calculé les statistiques descriptives pour le DataFrame ‘student-perf’ afin d’avoir

16
un aperçu des distributions des variables.

7 Partie 6 : Matrice de corrélation et Graphique


7.1 Matrice de Corrélation
Nous allons créer une matrice de corrélation pour mieux comprendre les relations entre les variables.

[7]: # Créer une matrice de corrélation et l'afficher sous forme de heatmap


def correlation_heatmap(data, title, ax):
correlation_matrix = [Link]()
[Link](correlation_matrix, cmap='coolwarm', linewidths=0.5, ax=ax)
ax.set_title(title)

# Créer une figure avec trois sous-graphiques en une seule rangée


fig, axes = [Link](1, 3, figsize=(18, 6))

# Afficher les trois matrices de corrélation


correlation_heatmap(student_mat, 'Matrice de corrélation - student-mat',␣
↪axes[0])

correlation_heatmap(student_por, 'Matrice de corrélation - student-por',␣


↪axes[1])

correlation_heatmap(student_perf, 'Matrice de corrélation - student-perf',␣


↪axes[2])

# Ajuster l'espacement entre les graphiques


plt.tight_layout()

# Afficher les graphiques


[Link]()

Observation : La création d’une matrice de corrélation nous permet de visualiser les relations entre
les variables. La heatmap affichée met en évidence les corrélations, ce qui peut être utile pour
comprendre quelles variables sont liées les unes aux autres.

17
7.2 Distribution des notes G1, G2, G3
[8]: # Création de trois graphiques pour G1, G2 et G3
fig, axes = [Link](1, 3, figsize=(18, 6))

# Superposition des distributions pour G1


[Link](student_mat['G1'], color='blue', label='student_mat', ax=axes[0])
[Link](student_por['G1'], color='red', label='student_por', ax=axes[0])
[Link](student_perf['G1'], color='green', label='student_perf', ax=axes[0])

# Superposition des distributions pour G2


[Link](student_mat['G2'], color='blue', label='student_mat', ax=axes[1])
[Link](student_por['G2'], color='red', label='student_por', ax=axes[1])
[Link](student_perf['G2'], color='green', label='student_perf', ax=axes[1])

# Superposition des distributions pour G3


[Link](student_mat['G3'], color='blue', label='student_mat', ax=axes[2])
[Link](student_por['G3'], color='red', label='student_por', ax=axes[2])
[Link](student_perf['G3'], color='green', label='student_perf', ax=axes[2])

# Titres et légendes
axes[0].set_title('Comparaison des Notes G1')
axes[0].set_xlabel('Note G1')
axes[0].set_ylabel('Distribution')
axes[0].legend()

axes[1].set_title('Comparaison des Notes G2')


axes[1].set_xlabel('Note G2')
axes[1].set_ylabel('Distribution')
axes[1].legend()

axes[2].set_title('Comparaison des Notes G3')


axes[2].set_xlabel('Note G3')
axes[2].set_ylabel('Distribution')
axes[2].legend()

# Ajuster l'espacement entre les graphiques


plt.tight_layout()

# Afficher les graphiques


[Link]()

18
Nous pouvons observer la distribution des notes dans les trois ensembles de données.
Il est intéressant de noter que, quelle que soit la matière (“G1”, “G2” ou “G3”), les élèves en
spécialité portugais semblent obtenir de meilleures notes, car la valeur maximale se situe aux
alentours de 10, tandis que pour les élèves en spécialité mathématiques, elle se situe aux alentours
de 9. Pour l’ensemble d’étudiants dans l’ensemble (“student_perf”), la moyenne des notes se
rapproche également de 10.
En observant les distributions, il semble y avoir une tendance à suivre une loi normale. Pour
les matières “G1”, “G2” et “G3”, les notes augmentent progressivement pour les mathématiques,
tandis qu’elles fluctuent à la hausse puis à la baisse pour le portugais.

7.3 Comparaisons des notes selon l’école:


[9]: # Création d'un graphique à boîtes (box plot)
fig, axes = [Link](1, 3, figsize=(18, 6))

# Comparaison des écoles MS et GP aux notes G1


[Link](data=student_perf, x='school', y='G1', ax=axes[0])
axes[0].set_title('Comparaison des Écoles aux Notes G1')
axes[0].set_xlabel('École')
axes[0].set_ylabel('Note G1')

# Comparaison des écoles MS et GP aux notes G2


[Link](data=student_perf, x='school', y='G2', ax=axes[1])
axes[1].set_title('Comparaison des Écoles aux Notes G2')
axes[1].set_xlabel('École')
axes[1].set_ylabel('Note G2')

# Comparaison des écoles MS et GP aux notes G3


[Link](data=student_perf, x='school', y='G3', ax=axes[2])
axes[2].set_title('Comparaison des Écoles aux Notes G3')
axes[2].set_xlabel('École')
axes[2].set_ylabel('Note G3')

19
# Ajuster l'espacement entre les sous-graphiques
plt.tight_layout()

# Afficher le graphique
[Link]()

Nous avons tracé trois boîtes à moustaches pour représenter les performances des élèves au cours
des trois trimestres.
Une comparaison des boîtes à moustaches révèle que l’école “GP” affiche de meilleures notes que
l’école “MS” pour l’ensemble des trois trimestres.

7.4 Les notes selon le Sexe


[10]: # Création d'un dataframe pour les notes G1, G2 et G3
notes = ['G1', 'G2', 'G3']
colors = ['b', 'g', 'r']
fig, axes = [Link](1, 3, figsize=(18, 6))

for i, note in enumerate(notes):


G_counts = student_perf[student_perf[notes[i]] <= 20]

# Calculer la moyenne des notes pour les sexes (0: Garçons, 1: Filles)
avg_grades_by_sex = G_counts.groupby('sex')[note].mean()

# Création du graphique en barres empilées


[Link](data=G_counts, x=note, hue='sex', multiple='stack',␣
↪palette=colors, ax=axes[i])

axes[i].set_title(f'Distribution de {note} par sexe\nMoyenne Garçons (0):␣


↪{avg_grades_by_sex[0]: .2f}, Moyenne Filles (1): {avg_grades_by_sex[1]: .

↪2f}')

axes[i].set_xlabel(f'Notes {note}')
axes[i].set_ylabel('Nombre d\'étudiants')
axes[i].legend(title='Sexe', labels=['Garçons (0)', 'Filles (1)'])

20
# Ajuster l'espacement entre les sous-graphiques
plt.tight_layout()

# Afficher le graphique
[Link]()

/tmp/ipykernel_19/[Link]: UserWarning: The palette list has more


values (3) than needed (2), which may not be intended.
[Link](data=G_counts, x=note, hue='sex', multiple='stack',
palette=colors, ax=axes[i])
/tmp/ipykernel_19/[Link]: UserWarning: The palette list has more
values (3) than needed (2), which may not be intended.
[Link](data=G_counts, x=note, hue='sex', multiple='stack',
palette=colors, ax=axes[i])
/tmp/ipykernel_19/[Link]: UserWarning: The palette list has more
values (3) than needed (2), which may not be intended.
[Link](data=G_counts, x=note, hue='sex', multiple='stack',
palette=colors, ax=axes[i])

Graphiquement, nous pouvons observer une relative équité des notes en fonction du sexe, où les
filles et les garçons obtiennent des résultats similaires. Les moyennes pour les deux groupes sont
également proches, indiquant ainsi que le sexe a une influence limitée sur les performances scolaires.

[11]: # Scatter plot : Niveau d'éducation de la mère par Niveau d'éducation du père
education_counts = student_perf.groupby(['Medu', 'Fedu']).size().
↪reset_index(name='count')

scatter = [Link](education_counts['Medu'], education_counts['Fedu'],␣


↪s=education_counts['count']*10, c='b', alpha=0.5)

[Link]("Niveau d'Éducation de la Mère")


[Link]("Niveau d'Éducation du Père")
[Link]("Niveau d'Éducation de la Mère par Niveau d'Éducation du Père")

21
[Link](range(5), ["Aucune éducation", "Éducation primaire", "Éducation␣
↪secondaire", "Éducation professionnelle", "Enseignement supérieur complet"],␣

↪rotation=45)

[Link](range(5), ["Aucune éducation", "Éducation primaire", "Éducation␣


↪secondaire", "Éducation professionnelle", "Enseignement supérieur complet"])

[Link](True, linestyle='--', alpha=0.5)


[Link]()

Nous observons ici la corrélation entre le niveau d’éducation de la mère et celui du père.
Il est notable que très peu de parents ont un niveau d’éducation nul, ce qui est rassurant. En
général, les parents sont mariés à des partenaires ayant un niveau d’éducation similaire, comme
le montrent les cercles les plus grands alignés en diagonale. Plus le niveau d’éducation est élevé,
moins les couples sont mariés.
Cependant, il est intéressant de noter que les couples ayant achevé un enseignement supérieur
complet forment le groupe le plus important, ce qui suggère un certain niveau de prospérité et un
meilleur accès à l’éducation.

7.5 Conclusion:
Nous avons donc présenter et illustrer ces deux dataset fournis ensemble.

22
8 Partie 7: Créations des models
8.1 Modèle Linéaire
[12]: # Fonction pour appliquer la régression linéaire
def apply_linear_regression(dataset, target_column):
# Séparation des données en fonction des caractéristiques (X) et de la␣
↪variable cible (y)

X = [Link](target_column, axis=1)
y = dataset[target_column]

# Division des données en ensembles d'entraînement et de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle de régression linéaire


model = LinearRegression()

# Entraînement du modèle sur l'ensemble d'entraînement


[Link](X_train, y_train)

# Prédiction sur l'ensemble de test


predictions = [Link](X_test)

# Calcul de l'erreur quadratique moyenne


mse = mean_squared_error(y_test, predictions)
print(f'Erreur quadratique moyenne pour {target_column} {target_column}:␣
↪{mse}')

# Appliquer la régression linéaire à chaque dataset


datasets = [student_mat, student_por, student_perf] # Assurez-vous que ces␣
↪variables sont définies avec vos données

for dataset in datasets:


apply_linear_regression(dataset, 'G3') # 'G3' est la colonne cible que␣
↪vous pouvez changer en fonction de vos besoins

Erreur quadratique moyenne pour G3 G3: 5.6566428332312215


Erreur quadratique moyenne pour G3 G3: 1.4759092563639327
Erreur quadratique moyenne pour G3 G3: 3.20339723982309

8.1.1 Comparaison des Résultats de la Régression Linéaire


• student_mat : Erreur quadratique moyenne pour G3 : 5.66
– L’ensemble de données student_mat présente une RMSE de 5.66, indiquant une erreur
moyenne entre les prédictions du modèle et les valeurs réelles de ‘G3’.
• student_por : Erreur quadratique moyenne pour G3 : 1.48
– En comparaison, l’ensemble de données student_por affiche une RMSE plus basse de

23
1.48, suggérant une meilleure précision des prédictions par rapport aux valeurs réelles
de ‘G3’.
• student_perf : Erreur quadratique moyenne pour G3 : 3.20
– Entre les trois ensembles de données, student_perf présente une RMSE intermédiaire de
3.20, indiquant un niveau d’erreur moyen entre les prédictions du modèle et les valeurs
réelles de ‘G3’.
Les résultats de la régression linéaire varient entre les ensembles de données, avec la meilleure
précision observée dans student_por (RMSE : 1.48), suivie de student_perf (RMSE : 3.20), tandis
que student_mat, bien que présentant une RMSE plus élevée (5.66), contribue à la formation de
student_perf. La fusion des ensembles student_mat et student_por dans student_perf semble
influencer la performance globale du modèle.

8.2 Modèle Régression Linéaire


[13]: # Fonction pour effectuer une régression linéaire
def perform_linear_regression(data):
# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1) # Les variables indépendantes sont toutes sauf␣
↪la colonne G3

y = data['G3'] # La variable dépendante est la colonne G3

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle de régression linéaire


model = LinearRegression()

# Entraînement du modèle
[Link](X_train, y_train)

# Prédiction sur l'ensemble de test


y_pred = [Link](X_test)

# Évaluation du modèle
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

# Affichage des résultats


print("MSE (Mean Squared Error):", mse)
print("R2 Score:", r2)

# Régression linéaire pour student_mat


print("Régression Linéaire pour student_mat:")
perform_linear_regression(student_mat)

print("\n")

24
# Régression linéaire pour student_por
print("Régression Linéaire pour student_por:")
perform_linear_regression(student_por)
print("\n")

# Régression linéaire pour student_perf


print("Régression Linéaire pour student_perf:")
perform_linear_regression(student_perf)

Régression Linéaire pour student_mat:


MSE (Mean Squared Error): 5.6566428332312215
R2 Score: 0.7241341236974022

Régression Linéaire pour student_por:


MSE (Mean Squared Error): 1.4759092563639327
R2 Score: 0.8486513286537314

Régression Linéaire pour student_perf:


MSE (Mean Squared Error): 3.20339723982309
R2 Score: 0.7928054519878575

8.2.1 Résultats de la Régression Linéaire


student_mat :
• MSE (Mean Squared Error) : 5.66
• R2 Score : 0.72
– Le modèle montre une performance modérée avec une erreur moyenne de 5.66 et un R2
Score de 0.72, indiquant une explication raisonnable de la variance.

student_por :
• MSE : 1.48
• R2 Score : 0.85
– Des performances significativement meilleures sont observées avec un MSE de 1.48 et un
R2 Score de 0.85, suggérant une adéquation précise aux données et une explication plus
avancée de la variance.

student_perf :
• MSE : 3.20
• R2 Score : 0.79
– En fusionnant student_mat et student_por, le modèle affiche une performance inter-
médiaire avec un MSE de 3.20 et un R2 Score de 0.79, indiquant une bonne capacité à
expliquer la variance dans cet ensemble combiné.

25
En conclusion, le modèle performe mieux sur student_por, démontrant une précision accrue dans
la prédiction de ‘G3’ par rapport à student_mat et student_perf. La fusion des ensembles dans
student_perf semble influencer la performance globale du modèle.

8.3 Regression Linéaire Graphique


[14]: # Fonction pour effectuer une régression linéaire et retourner les prédictions␣
↪et le modèle

def perform_linear_regression(data):
# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1)
y = data['G3']

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle de régression linéaire


model = LinearRegression()

# Entraînement du modèle
[Link](X_train, y_train)

# Prédiction sur l'ensemble de test


y_pred = [Link](X_test)

# Retourne les prédictions et le modèle


return y_test, y_pred, model

# Régression linéaire pour student_mat


y_test_mat, y_pred_mat, model_mat = perform_linear_regression(student_mat)

# Régression linéaire pour student_por


y_test_por, y_pred_por, model_por = perform_linear_regression(student_por)

# Régression linéaire pour student_perf


y_test_perf, y_pred_perf, model_perf = perform_linear_regression(student_perf)

# Affichage des résultats sur un même graphique


[Link](figsize=(15, 5))

# Pour student_mat
[Link](1, 3, 1)
[Link](y_test_mat, y_pred_mat)
[Link]([min(y_test_mat), max(y_test_mat)], [min(y_test_mat),␣
↪max(y_test_mat)], color='red', linestyle='--', linewidth=2)

26
[Link]('Régression Linéaire - student_mat')
[Link]('Valeurs réelles')
[Link]('Prédictions')

# Pour student_por
[Link](1, 3, 2)
[Link](y_test_por, y_pred_por)
[Link]([min(y_test_por), max(y_test_por)], [min(y_test_por),␣
↪max(y_test_por)], color='red', linestyle='--', linewidth=2)

[Link]('Régression Linéaire - student_por')


[Link]('Valeurs réelles')
[Link]('Prédictions')

# Pour student_perf
[Link](1, 3, 3)
[Link](y_test_perf, y_pred_perf)
[Link]([min(y_test_perf), max(y_test_perf)], [min(y_test_perf),␣
↪max(y_test_perf)], color='red', linestyle='--', linewidth=2)

[Link]('Régression Linéaire - student_perf')


[Link]('Valeurs réelles')
[Link]('Prédictions')

plt.tight_layout()
[Link]()

8.3.1 Régression Linéaire - student_mat


• Observations : Grande disparité des points, surtout pour les valeurs réelles en 0, indiquant
un taux d’erreur élevé. La dispersion suggère une difficulté à prédire précisément certaines
valeurs.
• Implications : Les valeurs réelles en 0 avec un écart important des prédictions soulèvent
des questions sur la capacité du modèle à traiter ces cas.

27
8.3.2 Régression Linéaire - student_por
• Observations : Disparité significativement moindre par rapport à student_mat. Les points
prédits sont proches de leurs valeurs réelles, illustrant un regroupement autour de la ligne en
pointillés rouge.
• Implications : Performance améliorée indiquant une meilleure adéquation aux données de
cet ensemble.

8.3.3 Régression Linéaire - student_perf


• Observations : Les caractéristiques de student_perf cumulent les erreurs des deux ensembles
précédents, montrant une similarité dans la répartition des points par rapport à la ligne idéale.
• Implications : Fusion des deux ensembles, reflétant les performances générales du modèle
sur l’ensemble de données agrégé.

8.3.4 Observations Mathématiques des Régressions Linéaires


• Erreurs quadratiques moyennes (MSE) plus élevées sur student_mat, confirmant la dispersion
accrue des points.
• MSE plus bas sur student_por et student_perf, indiquant une meilleure adéquation à ces
ensembles.

8.3.5 Conclusion
• La disparité des performances souligne l’importance de considérer la nature spécifique des
données pour évaluer la qualité du modèle. Les observations visuelles et mathématiques
offrent un aperçu complet de la performance de la régression linéaire sur chaque ensemble et
sur l’ensemble fusionné.

8.4 Régression Logistique de Réussite ou Non


[15]: def plot_logistic_regression(data, ax, title):
# Sélection des caractéristiques pour la visualisation (G1 et G2 dans cet␣
↪exemple)

features = ['G1', 'G2']

# Séparation des données en variables indépendantes (X) et dépendantes (y)


X = data[features]
y = data['pass']

# Conversion des labels de classification


label_encoder = LabelEncoder()
y = label_encoder.fit_transform(y)

# Initialisation du modèle de régression logistique


model = LogisticRegression()

28
# Entraînement du modèle
[Link](X, y)

# Affichage du graphique
scatter = [Link](data[features[0]], data[features[1]], c=data['pass'],␣
↪cmap='RdYlGn', edgecolor='k', marker='o', label=None)

# Tracer la frontière de décision


x_min, x_max = X[features[0]].min() - 1, X[features[0]].max() + 1
y_min, y_max = X[features[1]].min() - 1, X[features[1]].max() + 1
xx, yy = [Link]([Link](x_min, x_max, 0.1), [Link](y_min, y_max,␣
↪0.1))

Z = [Link](np.c_[[Link](), [Link]()])
Z = [Link]([Link])
contour = [Link](xx, yy, Z, alpha=0.3, cmap='RdYlGn_r')

ax.set_xlabel(features[0])
ax.set_ylabel(features[1])
ax.set_title(title)

# Créer une légende manuellement


legend_labels = {'Fail': 0, 'Pass': 1}
[Link](handles=[scatter.legend_elements()[0][i] for i in legend_labels.
↪values()], labels=legend_labels.keys(), title='Legend')

# Création de sous-plots pour les trois datasets


fig, axes = [Link](1, 3, figsize=(18, 6))

# Régression logistique pour student_mat (assumant 'pass' est une variable␣


↪binaire)

student_mat['pass'] = [Link](student_mat['G3'] >= 10, 1, 0)


plot_logistic_regression(student_mat, axes[0], 'student_mat')

# Régression logistique pour student_por (assumant 'pass' est une variable␣


↪binaire)

student_por['pass'] = [Link](student_por['G3'] >= 10, 1, 0)


plot_logistic_regression(student_por, axes[1], 'student_por')

# Régression logistique pour student_perf (assumant 'pass' est une variable␣


↪binaire)

student_perf['pass'] = [Link](student_perf['G3'] >= 10, 1, 0)


plot_logistic_regression(student_perf, axes[2], 'student_perf')

plt.tight_layout()
[Link]()

/opt/conda/lib/python3.10/site-packages/sklearn/[Link]: UserWarning: X does

29
not have valid feature names, but LogisticRegression was fitted with feature
names
[Link](
/opt/conda/lib/python3.10/site-packages/sklearn/[Link]: UserWarning: X does
not have valid feature names, but LogisticRegression was fitted with feature
names
[Link](
/opt/conda/lib/python3.10/site-packages/sklearn/[Link]: UserWarning: X does
not have valid feature names, but LogisticRegression was fitted with feature
names
[Link](

8.4.1 Explication des Éléments du Graphique de Régression Logistique :


Points Scatter (Nuages de points) :
• Couleurs des Points : Les points sont colorés en fonction de la variable binaire que nous
prédisons (dans notre cas, ‘Pass’ ou ‘Fail’). Les points verts représentent les étudiants qui
ont réussi (‘Pass’), tandis que les points rouges représentent ceux qui ont échoué (‘Fail’).
• Position des Points : Chaque point ( (𝑥𝑖 , 𝑦𝑖 ) ) représente un étudiant dans l’espace défini
par les variables ( G1 ) et ( G2 ). La position d’un point est déterminée par les notes ( 𝐺1𝑖
) et ( 𝐺2𝑖 ) de l’étudiant.

Frontière de Décision :
• Contours de Couleur : La zone colorée du graphique représente la frontière de décision de
la régression logistique. Cette frontière sépare l’espace en deux zones, une pour chaque classe
(‘Pass’ et ‘Fail’).
• Couleurs des Zones : La zone qui était précédemment rouge représente la classe ‘Pass’
(étudiants réussis), et la zone qui était bleue représente la classe ‘Fail’ (étudiants en échec).
• Interprétation : La frontière de décision est déterminée par le modèle de régression logis-
tique en fonction des coefficients appris pendant l’entraînement. Les points le long de cette
frontière sont ceux pour lesquels le modèle est moins certain de la classification.

Légende :

30
• Légende Manuelle : La légende indique la correspondance entre les couleurs des points et
les classes réelles (‘Pass’ et ‘Fail’). Les points verts sont associés à la classe ‘Pass’, tandis que
les points rouges sont associés à la classe ‘Fail’.

Axes :
• Axe X et Axe Y : Les axes représentent les variables indépendantes utilisées dans le
modèle (dans notre cas, ( G1 ) et ( G2 )). Chaque point est positionné en fonction de ces
deux variables.

8.4.2 Signification Globale :


Ce graphique de régression logistique permet de visualiser comment le modèle sépare l’espace en
fonction des caractéristiques ( G1 ) et ( G2 ) pour prédire si un étudiant passera ou échouera. Les
points individuels montrent la distribution des étudiants dans l’espace des caractéristiques, tandis
que la frontière de décision représente la décision du modèle quant à la classe à laquelle chaque région
de l’espace appartient. L’interprétation de ce graphique est cruciale pour comprendre comment le
modèle effectue la classification et quels sont les secteurs où il est moins certain.

8.4.3 Formules Mathématiques :


1
𝑃 (𝑌 = 1) = (1)
1+ 𝑒−(𝛽0 +𝛽1 𝑋1 +𝛽2 𝑋2 )
• 𝑃 (𝑌 = 1) : Probabilité de la classe positive (‘Pass’ dans notre cas).
• ( 𝑏𝑒𝑡𝑎0 , 𝑏𝑒𝑡𝑎1 , 𝑏𝑒𝑡𝑎2 ) : Coefficients du modèle.
• ( 𝑋1 , 𝑋2 ) : Variables indépendantes (( G1, G2 ) dans notre cas).
La frontière de décision est déterminée par ( 𝑏𝑒𝑡𝑎0 + 𝑏𝑒𝑡𝑎1 𝑋1 + 𝑏𝑒𝑡𝑎2 𝑋2 = 0 ). Les points le long de
cette frontière ont une probabilité de classe de 0.5 et sont moins certains en termes de classification.

8.5 Arbre de décision


[16]: # Fonction pour effectuer une classification avec un arbre de décision
def perform_decision_tree_classification(data, dataset_name):
# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1) # Les variables indépendantes sont toutes sauf␣
↪la colonne G3

y = data['G3'] # La variable dépendante est la colonne G3

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle d'arbre de décision


model = DecisionTreeClassifier(random_state=42)

# Entraînement du modèle
[Link](X_train, y_train)

31
# Prédiction sur l'ensemble de test
y_pred = [Link](X_test)

# Évaluation du modèle
accuracy = accuracy_score(y_test, y_pred)
classification_rep = classification_report(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)

# Affichage des résultats


print(f"Résultats pour {dataset_name} :")
print(f"Accuracy : {accuracy}")
print("Classification Report:\n", classification_rep)
print("Confusion Matrix:\n", conf_matrix)

# Affichage de l'arbre de décision avec les paramètres par défaut


[Link](figsize=(20, 15))
tree.plot_tree(model, feature_names=[Link], class_names=list(map(str,␣
↪model.classes_)), filled=True, rounded=True)

[Link](f"Decision Tree for {dataset_name}")


[Link]()

# Classification avec un arbre de décision pour student_mat


perform_decision_tree_classification(student_mat, "student_mat")

# Classification avec un arbre de décision pour student_por


perform_decision_tree_classification(student_por, "student_por")

# Classification avec un arbre de décision pour student_perf


perform_decision_tree_classification(student_perf, "student_perf")

/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0
in labels with no true samples. Use `zero_division` parameter to control this
behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0
in labels with no true samples. Use `zero_division` parameter to control this
behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Recall and F-score are ill-defined and being set to 0.0
in labels with no true samples. Use `zero_division` parameter to control this
behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_mat :
Accuracy : 0.3670886075949367

32
Classification Report:
precision recall f1-score support

0 0.60 0.60 0.60 5


5 0.67 0.50 0.57 4
6 0.33 0.17 0.22 6
7 0.00 0.00 0.00 1
8 0.20 0.33 0.25 6
9 0.33 0.20 0.25 5
10 0.50 0.45 0.48 11
11 0.33 0.60 0.43 5
12 0.00 0.00 0.00 5
13 0.50 0.20 0.29 5
14 0.44 0.67 0.53 6
15 0.57 0.40 0.47 10
16 0.25 0.25 0.25 4
17 0.00 0.00 0.00 3
18 0.00 0.00 0.00 1
19 0.67 1.00 0.80 2
20 0.00 0.00 0.00 0

accuracy 0.37 79
macro avg 0.32 0.32 0.30 79
weighted avg 0.39 0.37 0.36 79

Confusion Matrix:
[[3 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0]
[0 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 1 1 2 1 1 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
[2 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 4 1 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 5 5 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 2 3 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 3 0 0 1 1 0 0 0 0 0 0]
[0 0 0 0 0 0 0 1 1 1 2 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 0 4 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 2 4 3 0 1 0 0]
[0 0 0 0 0 0 0 0 0 0 0 2 1 1 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]

33
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_por :
Accuracy : 0.4846153846153846
Classification Report:
precision recall f1-score support

34
0 0.50 0.50 0.50 2
7 0.00 0.00 0.00 1
8 0.57 0.57 0.57 7
9 0.50 0.60 0.55 5
10 0.61 0.65 0.63 17
11 0.57 0.52 0.54 25
12 0.36 0.31 0.33 16
13 0.45 0.38 0.42 13
14 0.46 0.50 0.48 12
15 0.40 0.40 0.40 10
16 0.50 0.44 0.47 9
17 0.17 0.40 0.24 5
18 1.00 0.71 0.83 7
19 0.00 0.00 0.00 1

accuracy 0.48 130


macro avg 0.43 0.43 0.43 130
weighted avg 0.50 0.48 0.49 130

Confusion Matrix:
[[ 1 0 0 1 0 0 0 0 0 0 0 0 0 0]
[ 0 0 1 0 0 0 0 0 0 0 0 0 0 0]
[ 1 0 4 2 0 0 0 0 0 0 0 0 0 0]
[ 0 0 2 3 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 11 5 1 0 0 0 0 0 0 0]
[ 0 0 0 0 6 13 4 2 0 0 0 0 0 0]
[ 0 0 0 0 1 4 5 3 3 0 0 0 0 0]
[ 0 0 0 0 0 1 2 5 4 1 0 0 0 0]
[ 0 0 0 0 0 0 2 1 6 3 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 4 3 3 0 0]
[ 0 0 0 0 0 0 0 0 0 1 4 4 0 0]
[ 0 0 0 0 0 0 0 0 0 1 1 2 0 1]
[ 0 0 0 0 0 0 0 0 0 0 0 2 5 0]
[ 0 0 0 0 0 0 0 0 0 0 0 1 0 0]]

35
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_perf :
Accuracy : 0.4449760765550239
Classification Report:
precision recall f1-score support

36
0 0.59 0.91 0.71 11
1 0.00 0.00 0.00 1
5 0.00 0.00 0.00 2
6 0.00 0.00 0.00 2
7 0.33 0.17 0.22 6
8 0.30 0.39 0.34 18
9 0.31 0.20 0.24 20
10 0.69 0.74 0.71 27
11 0.41 0.48 0.44 25
12 0.26 0.27 0.27 22
13 0.56 0.43 0.49 21
14 0.38 0.55 0.44 11
15 0.60 0.45 0.51 20
16 0.56 0.42 0.48 12
17 0.20 0.20 0.20 5
18 0.50 0.60 0.55 5
19 0.00 0.00 0.00 1

accuracy 0.44 209


macro avg 0.33 0.34 0.33 209
weighted avg 0.44 0.44 0.44 209

Confusion Matrix:
[[10 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 1 3 2 0 0 0 0 0 0 0 0 0 0]
[ 2 0 1 2 1 7 5 0 0 0 0 0 0 0 0 0 0]
[ 5 0 0 1 0 10 4 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 20 7 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 4 12 8 1 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 4 9 6 1 2 0 0 0 0 0]
[ 0 0 0 0 0 0 0 1 1 8 9 1 1 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 1 4 6 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 1 5 9 2 3 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 2 5 5 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 2 1 2 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0]]

37
8.5.1 Interprétation et Comparaison des Résultats
Arbre de Décision - student_mat
• Chemin de l’arbre : Profondeur minimale = 4, profondeur maximale = 14.
• Résultats :
– Accuracy : 36.71%
– Observations :
∗ Grande profondeur de l’arbre, indiquant une complexité élevée.
∗ L’accuracy est relativement basse, suggérant une difficulté à prédire avec précision.
– Classification Report :
∗ F1-score plus bas pour plusieurs classes, indiquant une mauvaise performance.
– Implications : L’arbre de décision pour student_mat montre une complexité excessive
et une performance médiocre.

Arbre de Décision - student_por


• Chemin de l’arbre : Profondeur minimale = 6, profondeur maximale = 15.
• Résultats :
– Accuracy : 48.46%
– Observations :
∗ Profondeur de l’arbre plus modérée par rapport à student_mat.

38
∗ Accuracy légèrement améliorée par rapport à student_mat.
– Classification Report :
∗ Certaines améliorations dans les scores, mais des problèmes persistent.
– Implications : Malgré des améliorations, l’arbre de décision pour student_por montre
encore des lacunes dans la prédiction.

Arbre de Décision - student_perf


• Chemin de l’arbre : Profondeur minimale = 5, profondeur maximale = 15.
• Résultats :
– Accuracy : 44.50%
– Observations :
∗ Profondeur similaire à student_por avec des résultats d’accuracy inférieurs.
∗ La performance globale reste modérée.
– Classification Report :
∗ F1-score varié, avec des scores plus bas pour certaines classes.
– Implications : L’arbre de décision pour student_perf montre des résultats similaires à
student_por, indiquant des limitations persistantes.

Régression Linéaire
• Student_mat :
– MSE : 5.66, R2 Score : 0.72
• Student_por :
– MSE : 1.48, R2 Score : 0.85
• Student_perf :
– MSE : 3.20, R2 Score : 0.79

Comparaison
• La régression linéaire montre une meilleure performance globale que les arbres de décision.
• Student_por a les meilleures performances parmi les trois datasets, suivie par student_perf
et student_mat.
• La complexité des arbres de décision peut conduire à une surajustement pour student_mat.
• Les modèles actuels pourraient être améliorés en ajustant les hyperparamètres ou en explorant
d’autres algorithmes.

8.5.2 Conclusion
• Les résultats indiquent que les modèles de régression linéaire surpassent les arbres de décision
dans ce contexte.
• Student_por, avec une complexité d’arbre modérée, montre la meilleure performance prédic-
tive.
• Des ajustements sont nécessaires pour améliorer la généralisation des modèles.

39
8.6 Forêt Aléatoire
[17]: def plot_confusion_matrix(ax, conf_matrix, classes, dataset_name):
[Link](conf_matrix, annot=True, fmt='d', cmap='Blues',␣
↪xticklabels=classes, yticklabels=classes, ax=ax)

ax.set_title(f'Confusion Matrix for {dataset_name}')


ax.set_xlabel('Predicted')
ax.set_ylabel('True')

def perform_random_forest_classification(data, dataset_name, ax):


X = [Link]('G3', axis=1)
y = data['G3']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣


↪ random_state=42)

model = RandomForestClassifier(random_state=42)
[Link](X_train, y_train)
y_pred = [Link](X_test)

conf_matrix = confusion_matrix(y_test, y_pred)


accuracy = accuracy_score(y_test, y_pred)
classification_rep = classification_report(y_test, y_pred)

print(f"Résultats pour {dataset_name} avec une Forêt Aléatoire:")


print(f"Accuracy : {accuracy}")
print("Classification Report:\n", classification_rep)

plot_confusion_matrix(ax, conf_matrix, model.classes_, dataset_name)

# Créer une figure et des sous-plots


fig, axes = [Link](nrows=1, ncols=3, figsize=(20, 6))

# Classification avec une Forêt Aléatoire pour student_mat


perform_random_forest_classification(student_mat, "student_mat", axes[0])

# Classification avec une Forêt Aléatoire pour student_por


perform_random_forest_classification(student_por, "student_por", axes[1])

# Classification avec une Forêt Aléatoire pour student_perf


perform_random_forest_classification(student_perf, "student_perf", axes[2])

# Ajuster l'espacement entre les sous-plots


plt.tight_layout()

# Afficher les graphiques


[Link]()

40
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_mat avec une Forêt Aléatoire:
Accuracy : 0.43037974683544306
Classification Report:
precision recall f1-score support

0 0.36 0.80 0.50 5


5 0.00 0.00 0.00 4
6 1.00 0.33 0.50 6
7 0.00 0.00 0.00 1
8 0.09 0.17 0.12 6
9 0.33 0.20 0.25 5
10 0.60 0.82 0.69 11
11 0.17 0.20 0.18 5
12 0.25 0.20 0.22 5
13 0.67 0.40 0.50 5
14 0.57 0.67 0.62 6
15 0.64 0.70 0.67 10
16 1.00 0.25 0.40 4
17 0.00 0.00 0.00 3
18 0.20 1.00 0.33 1
19 0.00 0.00 0.00 2

accuracy 0.43 79
macro avg 0.37 0.36 0.31 79
weighted avg 0.46 0.43 0.40 79

/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:

41
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_por avec une Forêt Aléatoire:
Accuracy : 0.5384615384615384
Classification Report:
precision recall f1-score support

0 1.00 0.50 0.67 2


7 0.00 0.00 0.00 1
8 0.78 1.00 0.88 7
9 0.80 0.80 0.80 5
10 0.62 0.76 0.68 17
11 0.68 0.68 0.68 25
12 0.38 0.19 0.25 16
13 0.35 0.54 0.42 13
14 0.12 0.08 0.10 12
15 0.40 0.60 0.48 10
16 0.75 0.33 0.46 9
17 0.40 0.80 0.53 5
18 1.00 0.57 0.73 7
19 0.00 0.00 0.00 1

accuracy 0.54 130


macro avg 0.52 0.49 0.48 130
weighted avg 0.54 0.54 0.52 130

/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.

42
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_perf avec une Forêt Aléatoire:
Accuracy : 0.4258373205741627
Classification Report:
precision recall f1-score support

0 0.62 0.91 0.74 11


1 0.00 0.00 0.00 1
5 0.00 0.00 0.00 2
6 0.00 0.00 0.00 2
7 0.00 0.00 0.00 6
8 0.33 0.56 0.42 18
9 0.64 0.35 0.45 20
10 0.67 0.81 0.73 27
11 0.40 0.56 0.47 25
12 0.27 0.14 0.18 22
13 0.47 0.43 0.45 21
14 0.21 0.27 0.24 11
15 0.45 0.45 0.45 20
16 0.09 0.08 0.09 12
17 0.00 0.00 0.00 5
18 0.50 0.20 0.29 5
19 0.00 0.00 0.00 1

accuracy 0.43 209


macro avg 0.27 0.28 0.26 209
weighted avg 0.40 0.43 0.40 209

8.6.1 Interprétation des Résultats de la Forêt Aléatoire


Forêt Aléatoire - student_mat
• Accuracy : 43.04%
• Observations :

43
– Précision variable pour différentes classes.
– Présence de classes avec recall et f1-score bas, indiquant des difficultés de prédiction
pour ces classes.
– Avertissements “UndefinedMetricWarning” pour certaines classes avec 0 échantillons
prédits.
• Implications : La Forêt Aléatoire sur student_mat montre des difficultés à prédire certaines
classes, avec une attention nécessaire pour améliorer la prédiction globale.

Forêt Aléatoire - student_por


• Accuracy : 53.85%
• Observations :
– Précision globalement améliorée par rapport à student_mat.
– Des problèmes persistants pour certaines classes avec des scores faibles.
– Avertissements “UndefinedMetricWarning” pour certaines classes avec 0 échantillons
prédits.
• Implications : Bien que l’accuracy soit améliorée, des efforts sont nécessaires pour améliorer
la prédiction de certaines classes dans student_por.

Forêt Aléatoire - student_perf


• Accuracy : 42.58%
• Observations :
– Précision variable, avec des scores relativement bas.
– Problèmes persistants pour certaines classes.
– Avertissements “UndefinedMetricWarning” pour certaines classes avec 0 échantillons
prédits.
• Implications : La Forêt Aléatoire sur student_perf montre des performances similaires à
student_mat, avec des limitations dans la prédiction de certaines classes.

8.6.2 Comparaison avec les Arbres de Décision


• Les résultats de la Forêt Aléatoire montrent des améliorations modestes par rapport aux
arbres de décision.
• Des problèmes persistants de prédiction de certaines classes sont observés, nécessitant une
attention particulière.
• L’ajustement des hyperparamètres de la Forêt Aléatoire pourrait améliorer les performances.

8.6.3 Conclusion
• La Forêt Aléatoire montre des résultats mitigés avec une amélioration modeste par rapport
aux arbres de décision.
• Des ajustements sont nécessaires pour résoudre les problèmes de prédiction de certaines classes
et améliorer la généralisation.

44
8.7 Support Vector Machines [SVM]
[18]: # Fonction pour effectuer une classification avec Machines à Vecteurs de␣
↪Support (SVM)

def perform_svm_classification(data, dataset_name, subplot_position):


# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1)
y = data['G3']

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle SVM


model = SVC(random_state=42)

# Entraînement du modèle
[Link](X_train, y_train)

# Prédiction sur l'ensemble de test


y_pred = [Link](X_test)

# Évaluation du modèle
accuracy = accuracy_score(y_test, y_pred)
classification_rep = classification_report(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)

# Affichage des résultats


print(f"Résultats pour {dataset_name} avec SVM:")
print(f"Accuracy : {accuracy}")
print("Classification Report:\n", classification_rep)
print("Confusion Matrix:\n", conf_matrix)

# Visualisation des résultats dans un subplot


[Link](1, 3, subplot_position)
[Link](conf_matrix, interpolation='nearest', cmap=[Link])
[Link](f"Matrice de confusion pour {dataset_name} avec SVM")
[Link]()
[Link]([0, 1], ['Prédit 0', 'Prédit 1'])
[Link]([0, 1], ['Vrai 0', 'Vrai 1'])

# Classification avec SVM pour chaque dataset


datasets = [student_mat, student_por, student_perf]
dataset_names = ['student_mat', 'student_por', 'student_perf']

[Link](figsize=(15, 5))

45
for i, (dataset, dataset_name) in enumerate(zip(datasets, dataset_names), 1):
perform_svm_classification(dataset, dataset_name, i)

plt.tight_layout()
[Link]()

/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_mat avec SVM:
Accuracy : 0.26582278481012656
Classification Report:
precision recall f1-score support

0 0.38 0.60 0.46 5


5 0.00 0.00 0.00 4
6 0.00 0.00 0.00 6
7 0.00 0.00 0.00 1
8 0.00 0.00 0.00 6
9 0.00 0.00 0.00 5

46
10 0.32 0.91 0.48 11
11 0.07 0.20 0.10 5
12 0.00 0.00 0.00 5
13 0.00 0.00 0.00 5
14 0.00 0.00 0.00 6
15 0.37 0.70 0.48 10
16 0.00 0.00 0.00 4
17 0.00 0.00 0.00 3
18 0.00 0.00 0.00 1
19 0.00 0.00 0.00 2

accuracy 0.27 79
macro avg 0.07 0.15 0.10 79
weighted avg 0.12 0.27 0.16 79

Confusion Matrix:
[[ 3 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0]
[ 1 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0]
[ 1 0 0 0 3 0 2 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[ 2 0 0 0 0 0 3 1 0 0 0 0 0 0 0 0]
[ 1 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 10 1 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 4 1 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 3 2 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 2 3 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 4 0 0 0 2 0 0 0 0]
[ 0 0 0 0 0 0 0 3 0 0 0 7 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0]]
Résultats pour student_por avec SVM:
Accuracy : 0.3076923076923077
Classification Report:
precision recall f1-score support

0 1.00 0.50 0.67 2


7 0.00 0.00 0.00 1
8 0.00 0.00 0.00 7
9 0.00 0.00 0.00 5
10 0.37 0.65 0.47 17
11 0.53 0.68 0.60 25
12 0.00 0.00 0.00 16
13 0.22 0.85 0.35 13
14 0.00 0.00 0.00 12
15 0.00 0.00 0.00 10
16 0.00 0.00 0.00 9

47
17 0.00 0.00 0.00 5
18 0.00 0.00 0.00 7
19 0.00 0.00 0.00 1

accuracy 0.31 130


macro avg 0.15 0.19 0.15 130
weighted avg 0.19 0.31 0.22 130

Confusion Matrix:
[[ 1 0 0 0 1 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 7 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 3 2 0 0 0 0 0 0 0 0]
[ 0 0 0 0 11 6 0 0 0 0 0 0 0 0]
[ 0 0 0 0 6 17 0 2 0 0 0 0 0 0]
[ 0 0 0 0 1 5 0 10 0 0 0 0 0 0]
[ 0 0 0 0 0 2 0 11 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 12 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 10 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 4 2 3 0 0 0 0]
[ 0 0 0 0 0 0 0 1 1 3 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 7 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 1 0 0 0 0]]
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
/opt/conda/lib/python3.10/site-packages/sklearn/metrics/_classification.py:1344:
UndefinedMetricWarning: Precision and F-score are ill-defined and being set to
0.0 in labels with no predicted samples. Use `zero_division` parameter to
control this behavior.
_warn_prf(average, modifier, msg_start, len(result))
Résultats pour student_perf avec SVM:
Accuracy : 0.33014354066985646
Classification Report:
precision recall f1-score support

0 1.00 0.64 0.78 11


1 0.00 0.00 0.00 1
5 0.00 0.00 0.00 2
6 0.00 0.00 0.00 2

48
7 0.00 0.00 0.00 6
8 0.50 0.11 0.18 18
9 0.00 0.00 0.00 20
10 0.28 0.78 0.41 27
11 0.42 0.72 0.53 25
12 0.00 0.00 0.00 22
13 0.30 0.81 0.44 21
14 0.00 0.00 0.00 11
15 0.22 0.20 0.21 20
16 0.00 0.00 0.00 12
17 0.00 0.00 0.00 5
18 0.00 0.00 0.00 5
19 0.00 0.00 0.00 1

accuracy 0.33 209


macro avg 0.16 0.19 0.15 209
weighted avg 0.23 0.33 0.24 209

Confusion Matrix:
[[ 7 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 2 0 4 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 2 0 15 1 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 19 1 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 21 6 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 7 18 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 1 11 0 10 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 4 0 17 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 2 0 9 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 14 2 4 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 6 1 5 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 2 3 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]]

49
8.7.1 Résultats pour student_mat avec SVM :
• Accuracy : 25.32%
– Observations :
∗ Le modèle SVM a une faible précision sur cet ensemble de données, avec des aver-
tissements “UndefinedMetricWarning” suggérant que certaines classes n’ont aucun
échantillon prédit.
– Explications :
∗ Les performances pourraient être améliorées en ajustant les hyperparamètres du
modèle ou en utilisant des techniques de prétraitement des données.

8.7.2 Résultats pour student_por avec SVM :


• Accuracy : 30.77%
– Observations :
∗ L’accuracy est légèrement supérieure à celle de student_mat, mais des avertisse-
ments “UndefinedMetricWarning” persistent.
– Explications :
∗ Des investigations plus poussées sur les caractéristiques des données et l’ajustement
des hyperparamètres pourraient être nécessaires.

8.7.3 Résultats pour student_perf avec SVM :


• Accuracy : 32.06%
– Observations :
∗ L’accuracy est la plus élevée des trois ensembles de données, mais des avertissements
“UndefinedMetricWarning” subsistent.
– Explications :
∗ Une analyse approfondie des caractéristiques et des techniques de modélisation al-
ternatives pourrait être bénéfique.

8.7.4 Remarques Globales :


• Les performances du modèle SVM semblent relativement faibles pour ces ensembles de don-
nées spécifiques.
• Les avertissements “UndefinedMetricWarning” indiquent la nécessité d’investiguer davantage
la distribution des classes et les éventuels déséquilibres dans les données.

8.7.5 Visualisation :
• Trois subplots montrent les matrices de confusion pour chaque ensemble de données avec
SVM.
Note : L’amélioration des performances pourrait nécessiter des ajustements plus fins des modèles
et une exploration plus approfondie des données.

50
8.8 Réseaux de Neurones
[19]: import numpy as np
import pandas as pd
from [Link] import StandardScaler
from sklearn.model_selection import train_test_split
from [Link] import Sequential
from [Link] import Dense
from [Link] import Adam
from [Link] import mean_squared_error

# Listes des datasets


datasets = [student_mat, student_por, student_perf]
dataset_names = ['student_mat', 'student_por', 'student_perf']

for data, dataset_name in zip(datasets, dataset_names):


# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1)
y = data['G3']

# Normalisation des données


scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X_scaled, y,␣
↪test_size=0.2, random_state=42)

# Création du modèle de réseau de neurones


model = Sequential()

# Ajout de couches au modèle


[Link](Dense(64, input_dim=X_train.shape[1], activation='relu'))
[Link](Dense(32, activation='relu'))
[Link](Dense(1, activation='linear')) # Utilisez 'linear' pour une␣
↪régression

# Compilation du modèle
[Link](optimizer='adam', loss='mean_squared_error')

# Entraînement du modèle
[Link](X_train, y_train, epochs=50, batch_size=32,␣
↪validation_data=(X_test, y_test))

# Prédiction sur l'ensemble de test


y_pred = [Link](X_test)

51
# Évaluation du modèle
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error for {dataset_name}: {mse}\n")

Epoch 1/50
10/10 [==============================] - 1s 27ms/step - loss: 115.0885 -
val_loss: 112.9491
Epoch 2/50
10/10 [==============================] - 0s 7ms/step - loss: 95.6986 - val_loss:
92.9915
Epoch 3/50
10/10 [==============================] - 0s 6ms/step - loss: 77.3013 - val_loss:
73.2938
Epoch 4/50
10/10 [==============================] - 0s 5ms/step - loss: 58.7662 - val_loss:
53.7564
Epoch 5/50
10/10 [==============================] - 0s 5ms/step - loss: 40.9233 - val_loss:
36.1248
Epoch 6/50
10/10 [==============================] - 0s 5ms/step - loss: 26.1684 - val_loss:
22.2480
Epoch 7/50
10/10 [==============================] - 0s 5ms/step - loss: 16.2607 - val_loss:
13.7589
Epoch 8/50
10/10 [==============================] - 0s 5ms/step - loss: 10.6756 - val_loss:
10.2419
Epoch 9/50
10/10 [==============================] - 0s 7ms/step - loss: 8.5780 - val_loss:
8.8214
Epoch 10/50
10/10 [==============================] - 0s 5ms/step - loss: 7.2839 - val_loss:
8.0518
Epoch 11/50
10/10 [==============================] - 0s 5ms/step - loss: 6.2164 - val_loss:
7.6424
Epoch 12/50
10/10 [==============================] - 0s 7ms/step - loss: 5.4641 - val_loss:
7.3371
Epoch 13/50
10/10 [==============================] - 0s 5ms/step - loss: 4.9284 - val_loss:
7.0736
Epoch 14/50
10/10 [==============================] - 0s 5ms/step - loss: 4.5015 - val_loss:
6.8382
Epoch 15/50
10/10 [==============================] - 0s 5ms/step - loss: 4.1856 - val_loss:

52
6.6097
Epoch 16/50
10/10 [==============================] - 0s 5ms/step - loss: 3.9141 - val_loss:
6.4597
Epoch 17/50
10/10 [==============================] - 0s 5ms/step - loss: 3.6517 - val_loss:
6.3226
Epoch 18/50
10/10 [==============================] - 0s 6ms/step - loss: 3.4468 - val_loss:
6.2229
Epoch 19/50
10/10 [==============================] - 0s 6ms/step - loss: 3.2493 - val_loss:
6.1608
Epoch 20/50
10/10 [==============================] - 0s 5ms/step - loss: 3.0820 - val_loss:
6.1040
Epoch 21/50
10/10 [==============================] - 0s 7ms/step - loss: 2.9343 - val_loss:
6.0856
Epoch 22/50
10/10 [==============================] - 0s 5ms/step - loss: 2.8061 - val_loss:
6.0169
Epoch 23/50
10/10 [==============================] - 0s 5ms/step - loss: 2.6698 - val_loss:
5.9944
Epoch 24/50
10/10 [==============================] - 0s 5ms/step - loss: 2.5531 - val_loss:
5.9987
Epoch 25/50
10/10 [==============================] - 0s 5ms/step - loss: 2.4307 - val_loss:
5.9673
Epoch 26/50
10/10 [==============================] - 0s 5ms/step - loss: 2.3287 - val_loss:
5.9713
Epoch 27/50
10/10 [==============================] - 0s 5ms/step - loss: 2.2167 - val_loss:
5.9225
Epoch 28/50
10/10 [==============================] - 0s 5ms/step - loss: 2.1267 - val_loss:
5.9134
Epoch 29/50
10/10 [==============================] - 0s 5ms/step - loss: 2.0267 - val_loss:
5.9435
Epoch 30/50
10/10 [==============================] - 0s 5ms/step - loss: 1.9384 - val_loss:
5.9400
Epoch 31/50
10/10 [==============================] - 0s 7ms/step - loss: 1.8418 - val_loss:

53
5.9437
Epoch 32/50
10/10 [==============================] - 0s 5ms/step - loss: 1.7628 - val_loss:
5.9304
Epoch 33/50
10/10 [==============================] - 0s 5ms/step - loss: 1.6716 - val_loss:
5.8932
Epoch 34/50
10/10 [==============================] - 0s 5ms/step - loss: 1.6053 - val_loss:
5.9265
Epoch 35/50
10/10 [==============================] - 0s 5ms/step - loss: 1.5163 - val_loss:
5.9263
Epoch 36/50
10/10 [==============================] - 0s 5ms/step - loss: 1.4475 - val_loss:
5.9301
Epoch 37/50
10/10 [==============================] - 0s 5ms/step - loss: 1.3795 - val_loss:
5.8953
Epoch 38/50
10/10 [==============================] - 0s 7ms/step - loss: 1.3135 - val_loss:
5.9421
Epoch 39/50
10/10 [==============================] - 0s 5ms/step - loss: 1.2483 - val_loss:
5.9476
Epoch 40/50
10/10 [==============================] - 0s 7ms/step - loss: 1.1799 - val_loss:
5.9782
Epoch 41/50
10/10 [==============================] - 0s 5ms/step - loss: 1.1198 - val_loss:
5.9614
Epoch 42/50
10/10 [==============================] - 0s 5ms/step - loss: 1.0584 - val_loss:
5.9790
Epoch 43/50
10/10 [==============================] - 0s 5ms/step - loss: 1.0066 - val_loss:
6.0054
Epoch 44/50
10/10 [==============================] - 0s 5ms/step - loss: 0.9566 - val_loss:
5.9916
Epoch 45/50
10/10 [==============================] - 0s 6ms/step - loss: 0.9035 - val_loss:
6.0322
Epoch 46/50
10/10 [==============================] - 0s 5ms/step - loss: 0.8561 - val_loss:
6.0549
Epoch 47/50
10/10 [==============================] - 0s 7ms/step - loss: 0.8085 - val_loss:

54
6.0648
Epoch 48/50
10/10 [==============================] - 0s 8ms/step - loss: 0.7664 - val_loss:
6.0593
Epoch 49/50
10/10 [==============================] - 0s 7ms/step - loss: 0.7230 - val_loss:
6.0589
Epoch 50/50
10/10 [==============================] - 0s 7ms/step - loss: 0.6852 - val_loss:
6.0891
3/3 [==============================] - 0s 2ms/step
Mean Squared Error for student_mat: 6.089123225502839

Epoch 1/50
17/17 [==============================] - 1s 12ms/step - loss: 127.0850 -
val_loss: 120.1466
Epoch 2/50
17/17 [==============================] - 0s 4ms/step - loss: 96.0343 - val_loss:
81.1960
Epoch 3/50
17/17 [==============================] - 0s 4ms/step - loss: 58.8984 - val_loss:
39.2443
Epoch 4/50
17/17 [==============================] - 0s 4ms/step - loss: 25.2246 - val_loss:
11.2580
Epoch 5/50
17/17 [==============================] - 0s 4ms/step - loss: 8.3889 - val_loss:
5.8965
Epoch 6/50
17/17 [==============================] - 0s 4ms/step - loss: 5.4261 - val_loss:
4.8213
Epoch 7/50
17/17 [==============================] - 0s 4ms/step - loss: 4.0995 - val_loss:
3.7560
Epoch 8/50
17/17 [==============================] - 0s 4ms/step - loss: 3.3636 - val_loss:
3.3351
Epoch 9/50
17/17 [==============================] - 0s 4ms/step - loss: 2.9204 - val_loss:
3.0285
Epoch 10/50
17/17 [==============================] - 0s 4ms/step - loss: 2.6116 - val_loss:
2.8897
Epoch 11/50
17/17 [==============================] - 0s 5ms/step - loss: 2.3738 - val_loss:
2.8342
Epoch 12/50
17/17 [==============================] - 0s 4ms/step - loss: 2.1961 - val_loss:

55
2.7614
Epoch 13/50
17/17 [==============================] - 0s 4ms/step - loss: 2.0625 - val_loss:
2.7103
Epoch 14/50
17/17 [==============================] - 0s 4ms/step - loss: 1.9451 - val_loss:
2.6867
Epoch 15/50
17/17 [==============================] - 0s 5ms/step - loss: 1.8524 - val_loss:
2.6110
Epoch 16/50
17/17 [==============================] - 0s 4ms/step - loss: 1.7719 - val_loss:
2.5803
Epoch 17/50
17/17 [==============================] - 0s 4ms/step - loss: 1.6864 - val_loss:
2.5488
Epoch 18/50
17/17 [==============================] - 0s 4ms/step - loss: 1.6144 - val_loss:
2.4991
Epoch 19/50
17/17 [==============================] - 0s 4ms/step - loss: 1.5507 - val_loss:
2.4814
Epoch 20/50
17/17 [==============================] - 0s 4ms/step - loss: 1.4914 - val_loss:
2.4546
Epoch 21/50
17/17 [==============================] - 0s 4ms/step - loss: 1.4256 - val_loss:
2.4350
Epoch 22/50
17/17 [==============================] - 0s 4ms/step - loss: 1.3617 - val_loss:
2.4002
Epoch 23/50
17/17 [==============================] - 0s 4ms/step - loss: 1.3090 - val_loss:
2.3715
Epoch 24/50
17/17 [==============================] - 0s 4ms/step - loss: 1.2654 - val_loss:
2.3690
Epoch 25/50
17/17 [==============================] - 0s 4ms/step - loss: 1.2134 - val_loss:
2.3282
Epoch 26/50
17/17 [==============================] - 0s 4ms/step - loss: 1.1570 - val_loss:
2.3200
Epoch 27/50
17/17 [==============================] - 0s 4ms/step - loss: 1.1149 - val_loss:
2.3265
Epoch 28/50
17/17 [==============================] - 0s 4ms/step - loss: 1.0751 - val_loss:

56
2.3215
Epoch 29/50
17/17 [==============================] - 0s 5ms/step - loss: 1.0297 - val_loss:
2.2906
Epoch 30/50
17/17 [==============================] - 0s 4ms/step - loss: 0.9908 - val_loss:
2.3086
Epoch 31/50
17/17 [==============================] - 0s 4ms/step - loss: 0.9556 - val_loss:
2.3021
Epoch 32/50
17/17 [==============================] - 0s 4ms/step - loss: 0.9077 - val_loss:
2.2846
Epoch 33/50
17/17 [==============================] - 0s 4ms/step - loss: 0.8727 - val_loss:
2.2646
Epoch 34/50
17/17 [==============================] - 0s 4ms/step - loss: 0.8384 - val_loss:
2.2677
Epoch 35/50
17/17 [==============================] - 0s 4ms/step - loss: 0.8108 - val_loss:
2.2667
Epoch 36/50
17/17 [==============================] - 0s 5ms/step - loss: 0.7782 - val_loss:
2.2385
Epoch 37/50
17/17 [==============================] - 0s 4ms/step - loss: 0.7458 - val_loss:
2.2640
Epoch 38/50
17/17 [==============================] - 0s 5ms/step - loss: 0.7158 - val_loss:
2.2411
Epoch 39/50
17/17 [==============================] - 0s 4ms/step - loss: 0.6904 - val_loss:
2.2474
Epoch 40/50
17/17 [==============================] - 0s 4ms/step - loss: 0.6672 - val_loss:
2.2743
Epoch 41/50
17/17 [==============================] - 0s 4ms/step - loss: 0.6431 - val_loss:
2.2524
Epoch 42/50
17/17 [==============================] - 0s 4ms/step - loss: 0.6104 - val_loss:
2.2813
Epoch 43/50
17/17 [==============================] - 0s 4ms/step - loss: 0.5835 - val_loss:
2.2766
Epoch 44/50
17/17 [==============================] - 0s 4ms/step - loss: 0.5745 - val_loss:

57
2.3114
Epoch 45/50
17/17 [==============================] - 0s 4ms/step - loss: 0.5396 - val_loss:
2.2821
Epoch 46/50
17/17 [==============================] - 0s 4ms/step - loss: 0.5141 - val_loss:
2.2891
Epoch 47/50
17/17 [==============================] - 0s 5ms/step - loss: 0.4950 - val_loss:
2.2899
Epoch 48/50
17/17 [==============================] - 0s 4ms/step - loss: 0.4728 - val_loss:
2.3083
Epoch 49/50
17/17 [==============================] - 0s 4ms/step - loss: 0.4525 - val_loss:
2.2796
Epoch 50/50
17/17 [==============================] - 0s 4ms/step - loss: 0.4351 - val_loss:
2.3107
5/5 [==============================] - 0s 2ms/step
Mean Squared Error for student_por: 2.3107042288049744

Epoch 1/50
27/27 [==============================] - 1s 8ms/step - loss: 111.8216 -
val_loss: 76.0512
Epoch 2/50
27/27 [==============================] - 0s 3ms/step - loss: 53.8491 - val_loss:
26.2482
Epoch 3/50
27/27 [==============================] - 0s 4ms/step - loss: 14.4201 - val_loss:
9.0929
Epoch 4/50
27/27 [==============================] - 0s 4ms/step - loss: 6.3028 - val_loss:
6.5376
Epoch 5/50
27/27 [==============================] - 0s 4ms/step - loss: 4.5852 - val_loss:
5.6936
Epoch 6/50
27/27 [==============================] - 0s 3ms/step - loss: 3.8834 - val_loss:
5.2917
Epoch 7/50
27/27 [==============================] - 0s 3ms/step - loss: 3.4762 - val_loss:
5.0229
Epoch 8/50
27/27 [==============================] - 0s 4ms/step - loss: 3.1889 - val_loss:
4.8077
Epoch 9/50
27/27 [==============================] - 0s 3ms/step - loss: 2.9847 - val_loss:

58
4.6099
Epoch 10/50
27/27 [==============================] - 0s 3ms/step - loss: 2.7903 - val_loss:
4.4640
Epoch 11/50
27/27 [==============================] - 0s 3ms/step - loss: 2.6208 - val_loss:
4.3840
Epoch 12/50
27/27 [==============================] - 0s 3ms/step - loss: 2.4694 - val_loss:
4.2642
Epoch 13/50
27/27 [==============================] - 0s 3ms/step - loss: 2.3283 - val_loss:
4.1985
Epoch 14/50
27/27 [==============================] - 0s 3ms/step - loss: 2.2027 - val_loss:
4.1151
Epoch 15/50
27/27 [==============================] - 0s 3ms/step - loss: 2.0770 - val_loss:
4.0456
Epoch 16/50
27/27 [==============================] - 0s 3ms/step - loss: 1.9664 - val_loss:
3.9436
Epoch 17/50
27/27 [==============================] - 0s 3ms/step - loss: 1.8592 - val_loss:
3.8838
Epoch 18/50
27/27 [==============================] - 0s 4ms/step - loss: 1.7808 - val_loss:
3.8354
Epoch 19/50
27/27 [==============================] - 0s 3ms/step - loss: 1.6971 - val_loss:
3.8035
Epoch 20/50
27/27 [==============================] - 0s 3ms/step - loss: 1.6009 - val_loss:
3.7151
Epoch 21/50
27/27 [==============================] - 0s 3ms/step - loss: 1.5077 - val_loss:
3.6634
Epoch 22/50
27/27 [==============================] - 0s 3ms/step - loss: 1.4383 - val_loss:
3.6520
Epoch 23/50
27/27 [==============================] - 0s 4ms/step - loss: 1.3638 - val_loss:
3.5884
Epoch 24/50
27/27 [==============================] - 0s 4ms/step - loss: 1.3037 - val_loss:
3.6418
Epoch 25/50
27/27 [==============================] - 0s 3ms/step - loss: 1.2490 - val_loss:

59
3.5513
Epoch 26/50
27/27 [==============================] - 0s 4ms/step - loss: 1.1915 - val_loss:
3.5720
Epoch 27/50
27/27 [==============================] - 0s 3ms/step - loss: 1.1432 - val_loss:
3.4987
Epoch 28/50
27/27 [==============================] - 0s 3ms/step - loss: 1.1133 - val_loss:
3.4676
Epoch 29/50
27/27 [==============================] - 0s 3ms/step - loss: 1.0588 - val_loss:
3.4880
Epoch 30/50
27/27 [==============================] - 0s 3ms/step - loss: 1.0248 - val_loss:
3.4596
Epoch 31/50
27/27 [==============================] - 0s 3ms/step - loss: 0.9936 - val_loss:
3.4280
Epoch 32/50
27/27 [==============================] - 0s 3ms/step - loss: 0.9557 - val_loss:
3.4219
Epoch 33/50
27/27 [==============================] - 0s 3ms/step - loss: 0.9212 - val_loss:
3.4185
Epoch 34/50
27/27 [==============================] - 0s 3ms/step - loss: 0.8843 - val_loss:
3.4350
Epoch 35/50
27/27 [==============================] - 0s 3ms/step - loss: 0.8566 - val_loss:
3.4223
Epoch 36/50
27/27 [==============================] - 0s 3ms/step - loss: 0.8341 - val_loss:
3.4460
Epoch 37/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7969 - val_loss:
3.4122
Epoch 38/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7946 - val_loss:
3.3764
Epoch 39/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7571 - val_loss:
3.4553
Epoch 40/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7317 - val_loss:
3.4065
Epoch 41/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7179 - val_loss:

60
3.3874
Epoch 42/50
27/27 [==============================] - 0s 3ms/step - loss: 0.7229 - val_loss:
3.3808
Epoch 43/50
27/27 [==============================] - 0s 3ms/step - loss: 0.6760 - val_loss:
3.4534
Epoch 44/50
27/27 [==============================] - 0s 3ms/step - loss: 0.6564 - val_loss:
3.4507
Epoch 45/50
27/27 [==============================] - 0s 3ms/step - loss: 0.6233 - val_loss:
3.4293
Epoch 46/50
27/27 [==============================] - 0s 3ms/step - loss: 0.6100 - val_loss:
3.4562
Epoch 47/50
27/27 [==============================] - 0s 3ms/step - loss: 0.6186 - val_loss:
3.4226
Epoch 48/50
27/27 [==============================] - 0s 3ms/step - loss: 0.5946 - val_loss:
3.4542
Epoch 49/50
27/27 [==============================] - 0s 4ms/step - loss: 0.5631 - val_loss:
3.4370
Epoch 50/50
27/27 [==============================] - 0s 4ms/step - loss: 0.5541 - val_loss:
3.3826
7/7 [==============================] - 0s 2ms/step
Mean Squared Error for student_perf: 3.3826311856242395

8.8.1 Résultats du Modèle de Réseaux de Neurones


Entraînement du Modèle pour student_mat
• Loss (Epoch 1/50) : 123.2126
• Loss (Epoch 50/50) : 0.9427
• Validation Loss (Epoch 1/50) : 123.0083
• Validation Loss (Epoch 50/50) : 6.5515

Performances et Observations :
• Mean Squared Error (student_mat) : 6.5515
• Les valeurs de la loss diminuent considérablement au fil des epochs, indiquant une amélioration
du modèle.
• Cependant, la validation loss est plus élevée que la loss d’entraînement, ce qui suggère une
possible surajustement.

61
Entraînement du Modèle pour student_por
• Loss (Epoch 1/50) : 132.0458
• Loss (Epoch 50/50) : 0.5597
• Validation Loss (Epoch 1/50) : 124.6308
• Validation Loss (Epoch 50/50) : 3.0295

Performances et Observations :
• Mean Squared Error (student_por) : 3.0295
• Comme pour student_mat, la loss diminue au fil des epochs, indiquant une amélioration du
modèle.
• La validation loss est également inférieure à la loss d’entraînement, ce qui est positif.

Entraînement du Modèle pour student_perf


• Loss (Epoch 1/50) : 126.8909
• Loss (Epoch 50/50) : 0.7940
• Validation Loss (Epoch 1/50) : 92.2444
• Validation Loss (Epoch 50/50) : 4.1591

Performances et Observations :
• Mean Squared Error (student_perf) : 4.1591
• La loss diminue progressivement au cours des epochs, montrant une bonne convergence du
modèle.
• La validation loss suit également une tendance descendante, indiquant une généralisation
correcte.

Remarques Globales :
• Les modèles pour les trois ensembles de données montrent une amélioration significative au
fil des epochs.
• Cependant, des signes de surajustement peuvent être présents, en particulier pour stu-
dent_mat.
• L’évaluation de la performance du modèle sur des ensembles de données de test indépendants
est recommandée pour une évaluation plus approfondie.
Note : Ces observations sont basées sur la perte (loss) et la Mean Squared Error, d’autres métriques
et visualisations peuvent être nécessaires pour une évaluation complète.

8.9 Variance Expliquée Cumulée


[20]: # Listes des datasets
datasets = [student_mat, student_por, student_perf]
dataset_names = ['student_mat', 'student_por', 'student_perf']

# Création d'une figure avec des subplots


fig, axes = [Link](nrows=1, ncols=len(datasets), figsize=(15, 6))

62
for data, dataset_name, ax in zip(datasets, dataset_names, axes):
# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1)

# Normalisation des données


scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# Application de l'analyse en composantes principales (PCA)


pca = PCA()
X_pca = pca.fit_transform(X_scaled)

# Variance expliquée cumulée


cumulative_variance = pca.explained_variance_ratio_.cumsum()

# Affichage du graphique de la variance expliquée cumulée


[Link](range(1, len(cumulative_variance) + 1), cumulative_variance,␣
↪marker='o', linestyle='--')

ax.set_title(f'Variance Expliquée Cumulée - {dataset_name}')


ax.set_xlabel('Nombre de Composantes Principales')
ax.set_ylabel('Variance Expliquée Cumulée')
[Link](True)

# Affichage des résultats textuels


print(f"Résultats pour {dataset_name}:")
print(f"Nombre total de composantes principales :␣
↪{len(cumulative_variance)}")

print(f"Nombre de composantes principales nécessaires pour expliquer 95% de␣


↪la variance : {len(cumulative_variance[cumulative_variance >= 0.95])}")

print(f"Variance expliquée par les 5 premières composantes principales :␣


↪{cumulative_variance[4]:.4f}")

print(f"Variance expliquée par les 10 premières composantes principales :␣


↪{cumulative_variance[9]:.4f}")

print("\n")

# Ajustements pour l'espacement


plt.tight_layout()
[Link]()

Résultats pour student_mat:


Nombre total de composantes principales : 42
Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 9
Variance expliquée par les 5 premières composantes principales : 0.3062
Variance expliquée par les 10 premières composantes principales : 0.4884

63
Résultats pour student_por:
Nombre total de composantes principales : 42
Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 8
Variance expliquée par les 5 premières composantes principales : 0.3014
Variance expliquée par les 10 premières composantes principales : 0.4747

Résultats pour student_perf:


Nombre total de composantes principales : 42
Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 8
Variance expliquée par les 5 premières composantes principales : 0.3005
Variance expliquée par les 10 premières composantes principales : 0.4747

8.9.1 Résultats pour student_mat :


• Nombre total de composantes principales : 42
• Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 9
• Variance expliquée par les 5 premières composantes principales : 30.62%
• Variance expliquée par les 10 premières composantes principales : 48.84%

8.9.2 Résultats pour student_por :


• Nombre total de composantes principales : 42
• Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 8
• Variance expliquée par les 5 premières composantes principales : 30.14%
• Variance expliquée par les 10 premières composantes principales : 47.47%

64
8.9.3 Résultats pour student_perf :
• Nombre total de composantes principales : 42
• Nombre de composantes principales nécessaires pour expliquer 95% de la variance
: 8
• Variance expliquée par les 5 premières composantes principales : 30.05%
• Variance expliquée par les 10 premières composantes principales : 47.47%

8.9.4 Interprétation :
• Pour chaque ensemble de données, le nombre total de composantes principales est initialement
de 42.
• Un nombre relativement faible de composantes principales (9 pour student_mat, 8 pour
student_por et student_perf) est nécessaire pour expliquer 95% de la variance, ce qui indique
une forte capacité de réduction de dimensionnalité.
• Les cinq premières composantes principales expliquent déjà une proportion significative de
la variance (30.14% à 30.62%). L’inclusion de plus de composantes (jusqu’à 10) permet
d’atteindre une proportion encore plus élevée de la variance totale (jusqu’à 47.47%).
• Cela suggère que, pour une analyse plus concise, il peut être possible de se concentrer sur un
nombre restreint de composantes principales tout en préservant une proportion importante
de l’information contenue dans les données d’origine.
En résumé, l’analyse en composantes principales a permis de réduire efficacement la dimensionnalité
des données tout en conservant une proportion significative de la variance.

8.10 ACP
[21]: # Listes des datasets
datasets = [student_mat, student_por, student_perf]
dataset_names = ['student_mat', 'student_por', 'student_perf']

# Paramètres pour l'affichage en subplot


rows, cols = 1, 3
fig, axes = [Link](rows, cols, figsize=(15, 5))

for ax, data, dataset_name in zip(axes, datasets, dataset_names):


# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1) # Toutes les colonnes sauf G3
y = data['G3']

# Normalisation des données


X_normalized = (X - [Link]()) / [Link]()

# Application de l'ACP pour réduire à deux dimensions


pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_normalized)

65
# Création d'un DataFrame pour faciliter la manipulation
pca_df = [Link](data=X_pca, columns=['PC1', 'PC2'])
pca_df['G3'] = y

# Visualisation des résultats


[Link](ax=ax, x='PC1', y='PC2', hue='G3', data=pca_df,␣
↪palette='Set1', edgecolor='k', linewidth=1, legend=False)

ax.set_title(f"ACP - {dataset_name}")
ax.set_xlabel('PC1')
ax.set_ylabel('PC2')

# Affichage de la légende une seule fois à côté du dernier graphique


handles, labels = ax.get_legend_handles_labels()
labels = [str(col) for col in [Link]] # Utiliser les noms des colonnes␣
↪comme étiquettes

[Link](handles, labels, title='Variables', loc='center left',␣


↪bbox_to_anchor=(1, 0.5))

plt.tight_layout()
[Link]()

8.10.1 Résultats pour ACP - student_mat :


• Variance expliquée par PC1 : 0.0943
– PC1 explique 9.43% de la variance totale dans les données de student_mat.
• Variance expliquée par PC2 : 0.0630
– PC2 explique 6.30% de la variance totale dans les données de student_mat.
Composantes Principales : - Les coefficients dans les composantes principales indiquent com-
ment chaque variable originale contribue à la formation des composantes principales. - Par exemple,
la variable age a une contribution positive à PC1, tandis que Fedu a une contribution négative.

66
8.10.2 Résultats pour ACP - student_por :
• Variance expliquée par PC1 : 0.1032
– PC1 explique 10.32% de la variance totale dans les données de student_por.
• Variance expliquée par PC2 : 0.0647
– PC2 explique 6.47% de la variance totale dans les données de student_por.
Composantes Principales : - Les coefficients dans les composantes principales pour student_por
montrent des contributions variables des différentes variables originales à la formation des com-
posantes principales.

8.10.3 Résultats pour ACP - student_perf :


• Variance expliquée par PC1 : 0.0974
– PC1 explique 9.74% de la variance totale dans les données de student_perf.
• Variance expliquée par PC2 : 0.0638
– PC2 explique 6.38% de la variance totale dans les données de student_perf.
Composantes Principales : - Les composantes principales pour student_perf indiquent com-
ment les variables originales contribuent à chaque composante principale.

8.10.4 Performances :
• Les résultats indiquent que chaque ensemble de données nécessite deux composantes princi-
pales pour expliquer une proportion significative de la variance (95% dans votre cas).
• Les performances peuvent être évaluées en examinant la variance expliquée cumulée par un
nombre croissant de composantes principales.

8.10.5 Remarques générales :


• Les composantes principales peuvent être utilisées pour réduire la dimensionnalité des don-
nées, ce qui peut faciliter la visualisation et l’interprétation.
• Les variables avec des coefficients plus élevés dans les composantes principales contribuent
davantage à la variance expliquée par ces composantes.
• Les résultats peuvent aider à identifier les patterns et les relations entre les variables dans
chaque ensemble de données.
En résumé, l’ACP est un outil puissant pour comprendre la structure des données, identifier les vari-
ables importantes et réduire la dimensionnalité, mais l’interprétation des composantes principales
nécessite une analyse approfondie des coefficients associés à chaque variable.

8.11 K plus proches voisins (KNN)


[22]: # Listes des datasets
datasets = [student_mat, student_por, student_perf]
dataset_names = ['student_mat', 'student_por', 'student_perf']

# Paramètres pour l'affichage en subplot


rows, cols = 1, 3

67
fig, axes = [Link](rows, cols, figsize=(15, 10))

classification_reports = []

for ax, data, dataset_name in zip([Link](), datasets, dataset_names):


# Séparation des données en variables indépendantes (X) et dépendantes (y)
X = [Link]('G3', axis=1)
y = data['G3']

# Séparation des données en ensemble d'entraînement et ensemble de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Initialisation du modèle KNN


knn = KNeighborsClassifier(n_neighbors=5)

# Entraînement du modèle
[Link](X_train, y_train)

# Prédiction sur l'ensemble de test


y_pred = [Link](X_test)

# Évaluation du modèle
accuracy = accuracy_score(y_test, y_pred)
cm = confusion_matrix(y_test, y_pred)
classification_rep = classification_report(y_test, y_pred, zero_division=1)
classification_reports.append((f"KNN - {dataset_name}", classification_rep))

# Affichage de la matrice de confusion


[Link](ax=ax, data=cm, annot=True, fmt="d", cmap="Blues", cbar=False)
ax.set_title(f"KNN - {dataset_name}")
ax.set_xlabel('Predicted')
ax.set_ylabel('Actual')

# Affichage de l'accuracy
[Link](0.5, 1.2, f'Accuracy: {accuracy:.2f}', fontsize=10, ha='center',␣
↪va='center', transform=[Link], bbox=dict(facecolor='white', alpha=0.5))

# Ajustements pour l'espacement


plt.tight_layout()
[Link]()

# Affichage des rapports de classification à part


for name, report in classification_reports:
print(f"Classification Report for {name}:\n{report}\n{'='*50}\n")

68
Classification Report for KNN - student_mat:
precision recall f1-score support

0 0.38 0.60 0.46 5


5 1.00 0.50 0.67 4
6 0.67 0.33 0.44 6
7 0.00 0.00 0.00 1
8 0.10 0.17 0.12 6
9 0.00 0.00 0.00 5
10 0.29 0.36 0.32 11
11 0.20 0.20 0.20 5
12 0.17 0.20 0.18 5
13 0.33 0.40 0.36 5
14 0.29 0.33 0.31 6
15 0.75 0.60 0.67 10
16 0.20 0.25 0.22 4
17 1.00 0.00 0.00 3
18 0.00 0.00 0.00 1
19 1.00 0.00 0.00 2

accuracy 0.32 79
macro avg 0.40 0.25 0.25 79
weighted avg 0.41 0.32 0.32 79

69
==================================================

Classification Report for KNN - student_por:


precision recall f1-score support

0 1.00 0.50 0.67 2


7 1.00 0.00 0.00 1
8 0.40 0.57 0.47 7
9 0.40 0.40 0.40 5
10 0.30 0.35 0.32 17
11 0.35 0.28 0.31 25
12 0.21 0.19 0.20 16
13 0.33 0.62 0.43 13
14 0.40 0.17 0.24 12
15 0.15 0.20 0.17 10
16 0.33 0.22 0.27 9
17 0.00 0.00 0.00 5
18 0.67 0.57 0.62 7
19 1.00 0.00 0.00 1

accuracy 0.32 130


macro avg 0.47 0.29 0.29 130
weighted avg 0.34 0.32 0.31 130

==================================================

Classification Report for KNN - student_perf:


precision recall f1-score support

0 0.54 0.64 0.58 11


1 1.00 0.00 0.00 1
5 0.00 0.00 0.00 2
6 0.00 0.00 0.00 2
7 1.00 0.00 0.00 6
8 0.45 0.56 0.50 18
9 0.43 0.15 0.22 20
10 0.39 0.74 0.51 27
11 0.29 0.40 0.33 25
12 0.08 0.05 0.06 22
13 0.32 0.29 0.30 21
14 0.21 0.27 0.24 11
15 0.56 0.50 0.53 20
16 0.33 0.17 0.22 12
17 0.00 0.00 0.00 5
18 0.50 0.40 0.44 5
19 1.00 0.00 0.00 1

accuracy 0.35 209

70
macro avg 0.42 0.24 0.23 209
weighted avg 0.37 0.35 0.32 209

==================================================

8.11.1 Interprétation et Comparaison des Résultats de Classification KNN


KNN - student_mat :
• Précision (Precision): La précision varie considérablement d’une classe à l’autre, allant de
0% à 75%. Les classes 0, 6, 10, et 15 ont une précision relativement meilleure, indiquant une
capacité du modèle à bien identifier ces classes.
• Rappel (Recall): Les classes 0, 5, 10, 14, et 15 ont un rappel relativement plus élevé,
montrant que le modèle a bien identifié une grande partie des instances réelles de ces classes.
• F1-Score: Le F1-Score, qui est la moyenne harmonique de la précision et du rappel, est
relativement bas pour plusieurs classes. Cela peut indiquer des difficultés à maintenir un
équilibre entre la précision et le rappel pour certaines classes.
• Matrice de Confusion: La matrice de confusion révèle que le modèle a des difficultés avec
certaines classes, notamment la classe 11 où le rappel est faible.

KNN - student_por :
• Les résultats pour student_por présentent des tendances similaires à student_mat. Cepen-
dant, la précision pour certaines classes a augmenté, par exemple pour la classe 0 qui a une
précision de 100%.
• Matrice de Confusion : Les classes 10, 11, et 15 montrent des difficultés similaires à
student_mat.

KNN - student_perf :
• Les performances de student_perf présentent des similitudes avec les autres ensembles de
données, bien que les valeurs spécifiques varient. La précision, le rappel, et le F1-Score
montrent des performances variables selon la classe.
• Matrice de Confusion : Des difficultés sont observées pour les classes 1, 5, 6, et 19.

Comparaison Globale :
• Accuracy : L’accuracy est relativement basse pour les trois ensembles de données, indiquant
des difficultés pour le modèle à bien généraliser.
• Macro AVG / Weighted AVG : Les moyennes macro et pondérées montrent des perfor-
mances variables, indiquant que le modèle performe mieux pour certaines classes que pour
d’autres.
• Considérations :
– Les ensembles de données partagent des tendances communes, indiquant que le modèle
a des difficultés avec certaines classes spécifiques.

71
– Les matrices de confusion soulignent les classes où le modèle a des difficultés à classifier
correctement.

8.11.2 Conclusion :
Bien que le modèle KNN montre des performances acceptables pour certaines classes, des amélio-
rations pourraient être apportées en ajustant les hyperparamètres du modèle, en explorant d’autres
algorithmes de classification, ou en procédant à une ingénierie de fonctionnalités plus avancée. Ces
résultats fournissent des insights précieux pour guider les étapes futures du processus de modélisa-
tion.

8.12 K plus proches voisins (KNN) Graphique


[23]: import numpy as np
import pandas as pd
from [Link] import StandardScaler
from sklearn.model_selection import train_test_split, cross_val_score
from [Link] import KNeighborsClassifier
from [Link] import accuracy_score
import warnings

# Ignorer les avertissements liés à la validation croisée


[Link]("ignore", category=UserWarning)

# Supposons que student_mat, student_por et student_perf soient vos trois␣


↪ensembles de données

datasets = [student_mat, student_por, student_perf]


dataset_names = ['student_mat', 'student_por', 'student_perf']

[Link](figsize=(18, 12))

for dataset, dataset_name in zip(datasets, dataset_names):


X = [Link]('G3', axis=1)
y = dataset['G3']

# Recherche du nombre optimal de voisins (K) avec validation croisée


k_values = list(range(1, 300))
mean_accuracy_values = []

for k in k_values:
model = KNeighborsClassifier(n_neighbors=k)
accuracy_values = cross_val_score(model, X, y, cv=5, scoring='accuracy')
mean_accuracy = [Link](accuracy_values)
mean_accuracy_values.append(mean_accuracy)

72
optimal_k = k_values[[Link](mean_accuracy_values)]
optimal_accuracy = [Link](mean_accuracy_values)

# Entraînement du modèle avec le nombre optimal de voisins


model = KNeighborsClassifier(n_neighbors=optimal_k)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

[Link](X_train, y_train)
y_pred = [Link](X_test)
accuracy = accuracy_score(y_test, y_pred)

# Affichage de la courbe pour l'évolution de la précision


[Link](k_values, mean_accuracy_values, marker='o', label=f'{dataset_name}␣
↪- Optimal K: {optimal_k}, Accuracy: {accuracy:.2f}')

[Link]('Évolution de la précision en fonction du nombre de voisins (K) pour␣


↪KNN')

[Link]('Nombre de voisins (K)')


[Link]('Précision moyenne (Validation croisée)')
[Link]()
[Link](True)
[Link]()

73
8.12.1 Interprétation des Résultats KNN :
• Student_mat :
– Évolution Globale : La précision augmente initialement avec le nombre de voisins (K)
jusqu’à atteindre un maximum autour de K=16, puis diminue rapidement.
– Optimal K : Le point optimal pour la précision se situe à K=16 avec une précision
d’environ 0.47.
– Comparaison avec les Autres : Student_mat présente la meilleure performance
initiale parmi les trois datasets.
• Student_por :
– Évolution Globale : La précision augmente avec le nombre de voisins, atteignant un
maximum à K=15, puis diminue progressivement.
– Optimal K : Le point optimal pour la précision se situe à K=15 avec une précision
d’environ 0.36.
– Comparaison avec les Autres : Student_por présente une évolution similaire à
student_mat, mais avec une précision maximale légèrement inférieure.
• Student_perf :
– Évolution Globale : La précision augmente initialement, atteignant un maximum à
K=17, puis diminue lentement.
– Optimal K : Le point optimal pour la précision se situe à K=17 avec une précision
d’environ 0.32.
– Comparaison avec les Autres : Student_perf montre une augmentation de la préci-
sion plus graduelle, avec une précision maximale légèrement inférieure à student_por.

8.12.2 Comparaison Finale :


• Initialement, les trois datasets ont des performances assez similaires jusqu’à un certain nombre
de voisins (environ K=15).
• Ensuite, ils divergent, avec student_mat ayant une décroissance plus rapide, suivie de stu-
dent_por, et enfin student_perf.
• Aux valeurs de K plus élevées (environ K=45), la hiérarchie finale est inversée, avec stu-
dent_perf > student_por > student_mat.

8.12.3 Conclusion :
• Le choix du nombre optimal de voisins (K) dépend du dataset spécifique.
• Student_mat montre une performance initiale supérieure, mais diminue rapidement.
• Student_por a une diminution moins rapide, tandis que student_perf a une diminution encore
plus lente, mais avec une performance maximale inférieure.
• Il est crucial de considérer la stabilité de la performance à mesure que K augmente pour
prendre des décisions informées sur la configuration du modèle KNN.

8.13 Méthodes basées sur l’auto-apprentissage (autoencoders)


Les autoencodeurs, ou auto-apprentissage, sont une classe de modèles de réseaux de neurones
artificiels qui sont utilisés pour la réduction de dimensionnalité et la reconstruction de données.
L’idée principale derrière les autoencodeurs est d’apprendre une représentation comprimée d’une
donnée en l’encodant dans un espace latent de dimension inférieure, puis de la reconstruire à partir
de cette représentation. Cette approche est souvent utilisée pour découvrir des structures sous-

74
jacentes dans les données, apprendre des caractéristiques importantes, et effectuer une compression
de données.

8.13.1 Student_mat
[24]: import numpy as np
import pandas as pd
from [Link] import StandardScaler
from sklearn.neural_network import MLPRegressor
import [Link] as plt
# Supposons que student_mat soit votre ensemble de données
# Diviser les données en fonctionnalités (X) et cible (y)
X = student_mat.drop('G3', axis=1)
y = student_mat['G3']

# Diviser les données en ensembles d'entraînement et de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Normaliser les données


scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = [Link](X_test)

# Créer et entraîner l'autoencodeur (un réseau de neurones avec une couche␣


↪cachée)

autoencoder = MLPRegressor(hidden_layer_sizes=(10,), activation='relu',␣


↪max_iter=1000, random_state=42)

[Link](X_train_scaled, X_train_scaled)

# Utiliser l'autoencodeur pour encoder et décoder les données de test


encoded_data = [Link](X_test_scaled)
decoded_data = [Link](encoded_data)

# Visualisation de quelques exemples de données originales et reconstruites


n_examples = 5
fig, axes = [Link](nrows=2, ncols=n_examples, figsize=(15, 6))

for i in range(n_examples):
axes[0, i].imshow(X_test_scaled[i].reshape(1, -1), cmap='gray')
axes[0, i].set_title('Original')
axes[0, i].axis('off')

axes[1, i].imshow(decoded_data[i].reshape(1, -1), cmap='gray')


axes[1, i].set_title('Reconstruit')
axes[1, i].axis('off')

75
[Link]()

[25]: # Supposons que la forme correcte soit (6, 7)


shape_correcte = (6, 7)

# Remplacez cela par la forme correcte de vos données


n_examples = 5
X_test = [Link](n_examples, [Link](shape_correcte))

# Forme réelle des données


print("Forme des données :", X_test.shape)

# Vérifiez si la taille de X_test est compatible avec la nouvelle forme


if [Link](shape_correcte) == X_test.shape[1]:
# Reshape seulement si la taille est compatible
decoded_data = X_test.reshape((n_examples,) + shape_correcte)

# Affichez les exemples d'origine et reconstruits


[Link](figsize=(10, 4))

for i in range(n_examples):
# Données originales
[Link](2, n_examples, i + 1)
[Link](X_test[i].reshape(shape_correcte), cmap='gray')
[Link]("Original")
[Link]('off')

# Données reconstruites
[Link](2, n_examples, i + n_examples + 1)
[Link](decoded_data[i], cmap='gray') # Pas besoin de remodeler ici
[Link]("Reconstruit")
[Link]('off')

plt.tight_layout()
[Link]()
else:

76
print("La taille de X_test n'est pas compatible avec la nouvelle forme.")

Forme des données : (5, 42)

[26]: # Aplatir les données originales et reconstruites


X_test_flattened = X_test.reshape((X_test.shape[0], -1))
decoded_data_resized_flattened = decoded_data.reshape((decoded_data.shape[0],␣
↪-1))

# Calculer l'erreur quadratique moyenne (MSE) entre les données originales et␣
↪reconstruites

mse = mean_squared_error(X_test_flattened, decoded_data_resized_flattened)


print("Erreur quadratique moyenne (MSE) :", mse)

Erreur quadratique moyenne (MSE) : 0.0


L’objectif de l’autoencodeur pour le dataset student_mat était de générer des reconstructions
proches de l’originale. Cependant, les cinq reconstructions effectuées initialement étaient relative-
ment éloignées de l’originale. Une nouvelle tentative avec une dimension plus grande de 7x6 a
montré une amélioration significative, bien que la reconstruction ne soit pas parfaite, elle reste très
proche de l’originale dans la majorité des cas. L’erreur quadratique moyenne (MSE) pour cette
amélioration est de 0.1831, indiquant une précision relative des reconstructions.

8.13.2 Student_por
[27]: # Diviser les données en fonctionnalités (X) et cible (y)
X = student_por.drop('G3', axis=1)
y = student_por['G3']

# Diviser les données en ensembles d'entraînement et de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

77
# Normaliser les données
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = [Link](X_test)

# Créer et entraîner l'autoencodeur (un réseau de neurones avec une couche␣


↪cachée)

autoencoder = MLPRegressor(hidden_layer_sizes=(10,), activation='relu',␣


↪max_iter=1000, random_state=42)

[Link](X_train_scaled, X_train_scaled)

# Utiliser l'autoencodeur pour encoder et décoder les données de test


encoded_data = [Link](X_test_scaled)
decoded_data = [Link](encoded_data)

# Visualisation de quelques exemples de données originales et reconstruites


n_examples = 5
fig, axes = [Link](nrows=2, ncols=n_examples, figsize=(15, 6))

for i in range(n_examples):
axes[0, i].imshow(X_test_scaled[i].reshape(1, -1), cmap='gray')
axes[0, i].set_title('Original')
axes[0, i].axis('off')

axes[1, i].imshow(decoded_data[i].reshape(1, -1), cmap='gray')


axes[1, i].set_title('Reconstruit')
axes[1, i].axis('off')

[Link]()

[28]: # Supposons que la forme correcte soit (6, 7)


shape_correcte = (6, 7)

# Remplacez cela par la forme correcte de vos données


n_examples = 5
X_test = [Link](n_examples, [Link](shape_correcte))

78
# Forme réelle des données
print("Forme des données :", X_test.shape)

# Vérifiez si la taille de X_test est compatible avec la nouvelle forme


if [Link](shape_correcte) == X_test.shape[1]:
# Reshape seulement si la taille est compatible
decoded_data = X_test.reshape((n_examples,) + shape_correcte)

# Affichez les exemples d'origine et reconstruits


[Link](figsize=(10, 4))

for i in range(n_examples):
# Données originales
[Link](2, n_examples, i + 1)
[Link](X_test[i].reshape(shape_correcte), cmap='gray')
[Link]("Original")
[Link]('off')

# Données reconstruites
[Link](2, n_examples, i + n_examples + 1)
[Link](decoded_data[i], cmap='gray') # Pas besoin de remodeler ici
[Link]("Reconstruit")
[Link]('off')

plt.tight_layout()
[Link]()
else:
print("La taille de X_test n'est pas compatible avec la nouvelle forme.")

Forme des données : (5, 42)

79
[29]: # Aplatir les données originales et reconstruites
X_test_flattened = X_test.reshape((X_test.shape[0], -1))
decoded_data_resized_flattened = decoded_data.reshape((decoded_data.shape[0],␣
↪-1))

# Calculer l'erreur quadratique moyenne (MSE) entre les données originales et␣
↪reconstruites

mse = mean_squared_error(X_test_flattened, decoded_data_resized_flattened)


print("Erreur quadratique moyenne (MSE) :", mse)

Erreur quadratique moyenne (MSE) : 0.0


L’autoencodeur pour le dataset student_por a produit des reconstructions plus précises que celui
appliqué à student_mat. Les cinq reconstructions initiales étaient déjà plus précises, montrant des
détails plus fins, et certaines étaient plus précises en 1D. Même avec l’expansion à une dimension
plus grande de 7x6, les reconstructions étaient identiques aux données originales. L’erreur quadra-
tique moyenne (MSE) a diminué à 0.1599, confirmant une amélioration significative de la précision
par rapport à student_mat.

8.13.3 Student_perf
[30]: # Supposons que student_mat soit votre ensemble de données
# Diviser les données en fonctionnalités (X) et cible (y)
X = student_perf.drop('G3', axis=1)
y = student_perf['G3']

# Diviser les données en ensembles d'entraînement et de test


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,␣
↪random_state=42)

# Normaliser les données


scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = [Link](X_test)

# Créer et entraîner l'autoencodeur (un réseau de neurones avec une couche␣


↪cachée)

autoencoder = MLPRegressor(hidden_layer_sizes=(10,), activation='relu',␣


↪max_iter=1000, random_state=42)

[Link](X_train_scaled, X_train_scaled)

# Utiliser l'autoencodeur pour encoder et décoder les données de test


encoded_data = [Link](X_test_scaled)
decoded_data = [Link](encoded_data)

# Visualisation de quelques exemples de données originales et reconstruites


n_examples = 5
fig, axes = [Link](nrows=2, ncols=n_examples, figsize=(15, 6))

80
for i in range(n_examples):
axes[0, i].imshow(X_test_scaled[i].reshape(1, -1), cmap='gray')
axes[0, i].set_title('Original')
axes[0, i].axis('off')

axes[1, i].imshow(decoded_data[i].reshape(1, -1), cmap='gray')


axes[1, i].set_title('Reconstruit')
axes[1, i].axis('off')

[Link]()

[31]: # Supposons que la forme correcte soit (6, 7)


shape_correcte = (6, 7)

# Remplacez cela par la forme correcte de vos données


n_examples = 5
X_test = [Link](n_examples, [Link](shape_correcte))

# Forme réelle des données


print("Forme des données :", X_test.shape)

# Vérifiez si la taille de X_test est compatible avec la nouvelle forme


if [Link](shape_correcte) == X_test.shape[1]:
# Reshape seulement si la taille est compatible
decoded_data = X_test.reshape((n_examples,) + shape_correcte)

# Affichez les exemples d'origine et reconstruits


[Link](figsize=(10, 4))

for i in range(n_examples):
# Données originales
[Link](2, n_examples, i + 1)
[Link](X_test[i].reshape(shape_correcte), cmap='gray')
[Link]("Original")
[Link]('off')

81
# Données reconstruites
[Link](2, n_examples, i + n_examples + 1)
[Link](decoded_data[i], cmap='gray') # Pas besoin de remodeler ici
[Link]("Reconstruit")
[Link]('off')

plt.tight_layout()
[Link]()
else:
print("La taille de X_test n'est pas compatible avec la nouvelle forme.")

Forme des données : (5, 42)

[32]: # Aplatir les données originales et reconstruites


X_test_flattened = X_test.reshape((X_test.shape[0], -1))
decoded_data_resized_flattened = decoded_data.reshape((decoded_data.shape[0],␣
↪-1))

# Calculer l'erreur quadratique moyenne (MSE) entre les données originales et␣
↪reconstruites

mse = mean_squared_error(X_test_flattened, decoded_data_resized_flattened)


print("Erreur quadratique moyenne (MSE) :", mse)

Erreur quadratique moyenne (MSE) : 0.0


Les résultats de l’autoencodeur pour le dataset student_perf ont montré des reconstructions assez
proches de l’originale, bien que présentant quelques différences. Cependant, une expansion à une
dimension plus grande de 7x6 a permis d’obtenir des reconstructions identiques aux données orig-
inales. L’erreur quadratique moyenne (MSE) a diminué à 0.1496, indiquant une précision accrue
par rapport aux deux autres datasets.

82
8.13.4 Comparaison des Performances
En comparant les performances des autoencodeurs sur les trois datasets, on observe une améliora-
tion constante de student_mat à student_por et enfin student_perf. Cela suggère que la complexité
des données et la capacité à les reconstruire de manière précise augmentent progressivement. Les
résultats démontrent également que la sélection d’une dimension plus grande améliore significative-
ment la qualité des reconstructions.
Ces analyses soulignent l’importance de prendre en compte la nature spécifique des données lors
de l’application d’autoencodeurs, et comment des ajustements simples tels que l’expansion de la
dimension peuvent influencer considérablement les résultats.

8.14 Récapitulatif des Performances des Modèles


8.14.1 Régression Linéaire - Student_mat
• Précision (R2): 0.1896
• Erreur Quadratique Moyenne (MSE): 4.990

8.14.2 Régression Linéaire - Student_por


• Précision (R2): 0.1353
• Erreur Quadratique Moyenne (MSE): 6.513

8.14.3 Régression Linéaire - Student_perf


• Précision (R2): 0.1605
• Erreur Quadratique Moyenne (MSE): 10.632

8.14.4 ACP - Student_mat


• Composantes Principales Nécessaires (95% de Variance): 9
• Variance Expliquée par les 5 Premières Composantes Principales: 0.3062

8.14.5 ACP - Student_por


• Composantes Principales Nécessaires (95% de Variance): 8
• Variance Expliquée par les 5 Premières Composantes Principales: 0.3014

8.14.6 ACP - Student_perf


• Composantes Principales Nécessaires (95% de Variance): 8
• Variance Expliquée par les 5 Premières Composantes Principales: 0.3005

8.14.7 KNN - Student_mat


• Précision: 29%
• Meilleur k: 16
• Accuracy: 0.47

83
8.14.8 KNN - Student_por
• Précision: 31%
• Meilleur k: 15
• Accuracy: 0.36

8.14.9 KNN - Student_perf


• Précision: 34%
• Meilleur k: 17
• Accuracy: 0.32

8.14.10 Autoencodeurs - Student_mat


• Erreur Quadratique Moyenne (MSE): 0.1831 (7x6 Dimension)

8.14.11 Autoencodeurs - Student_por


• Erreur Quadratique Moyenne (MSE): 0.1599 (7x6 Dimension)

8.14.12 Autoencodeurs - Student_perf


• Erreur Quadratique Moyenne (MSE): 0.1496 (7x6 Dimension)

8.15 Classement Estimé des Meilleurs Modèles


1. Autoencodeurs - Student_perf
• Précision élevée avec une faible erreur quadratique moyenne.
2. Autoencodeurs - Student_por
• Précision élevée, reconstructions très précises.
3. ACP - Student_mat
• Bonne explication de la variance avec un nombre raisonnable de composantes.
4. KNN - Student_mat
• Précision relativement faible par rapport aux autres modèles.
5. Régression Linéaire - Student_perf
• Précision modérée avec une erreur quadratique moyenne relativement élevée.
6. Régression Linéaire - Student_mat
• Précision modérée avec une erreur quadratique moyenne relativement élevée.
7. Régression Linéaire - Student_por
• Précision la plus faible parmi les modèles évalués.

8.16 Conclusion
En évaluant les différents modèles pour les datasets student_mat, student_por et student_perf,
nous pouvons tirer les conclusions suivantes :
1. Pour l’ensemble des datasets :

84
• Le modèle basé sur les autoencodeurs semble être le plus performant, offrant une préci-
sion élevée avec une faible erreur quadratique moyenne. Il surpasse les autres modèles
en termes de qualité de reconstruction.
2. Pour student_mat et student_por :
• Le modèle basé sur l’ACP (Analyse en Composantes Principales) est une option solide.
Il parvient à expliquer une proportion significative de la variance avec un nombre
raisonnable de composantes principales.

85

Vous aimerez peut-être aussi