Examen
Machine Learning avec scikit-learn
Une étude s'intéresse à l'efficacité énergétique d'immeubles résidentiels, en particulier les
besoins en chauffage et en climatisation, en fonction de caractéristiques architecturales comme
la surface des murs, la surface vitrée, l'orientation, etc..
Le jeu de données utilisé contient huit attributs décrivant ces caractéristiques concernant 768
immeubles et 2 attributs cibles : les charges de chauffage et les charges de climatisation de ces
immeubles.
L'objectif de l'exercice consiste à prédire les charges de chaque immeuble, en fonction des huit
premiers attributs.
Le jeu de données est à lire dans le fichier "ENB_data.csv". Notez que les colonnes sont
séparées par des ';'.
Exécutez la cellule suivante pour importer les packages nécessaires à l'exercice.
Chargez le fichier "ENB_data.csv" et effectuez un premier audit des données dans
un data frame df.
In [1]:
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn import ensemble
from sklearn import svm
from sklearn import neighbors
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.ensemble import VotingClassifier
### Chargement du fichier "ENB_data.csv"
df = pd.read_csv("ENB_data.csv",sep=';')
df.head()
Out[1]:
Analysez les corrélations entre toutes les variables de df.
Quelles variables explicatives sont les plus corrélées aux deux variables cibles ?
In [2]:
### Analyse des corrélations entres les variables de df
df.corr()
# Les variables explicatives sont les plus corrélées aux deux variables cibles :
# overall_height, roof_area, relative_compactness, surface_area
Out[2]:
La suite consiste à présent à créer un modèle de classification optimal après regroupement des
immeubles en classes à partir des charges énergétiques totales (chauffage + climatisation).
Créez une nouvelle colonne à df, appelée total_charges, totalisant pour chaque
immeuble les charges de chauffage et de climatisation.
Dans une nouvelle variable charges_classes, découpez les immeubles en 4 classes
distinctes avec pour labels 0, 1, 2, 3 selon les 3 quantiles de la nouvelle variable crée.
Les quantiles d'une variable peuvent être trouvés grâce à la
méthode describe des pandas.Series ou à la fonction quantile
In [3]:
### Création de la colonne total_charges
df['total_charges']=df.heating_load + df.cooling_load
### découpage des immeubles en 4 classes distinctes
df['total_charges'].quantile([0.25,0.5,0.75])
df['charges_classes'] = pd.qcut(df['total_charges'], 4, labels=['0','1','2','3'])
df.head()
Out[3]:
Stockez dans une variable data, les données explicatives uniquement.
Séparez les données en un ensemble d'apprentissage et un ensemble de test (20%),
avec data comme données explicatives et charges_classes comme variable cible.
Centrer et réduire les variables explicatives des deux échantillons de manière adéquate.
In [4]:
# Stockage dans une variable data, les données explicatives uniquement
to_drop = ['heating_load', 'cooling_load', 'total_charges', 'charges_classes']
data = df.drop(to_drop,axis=1)
target = df.charges_classes
#Séparation des données en deux ensembles d'entraînement et de test
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
# Centrer et réduire les variables explicatives des deux échantillons de manière
adéquate
X_train_scaled = preprocessing.scale(X_train)
Dans la suite nous allons comparer plusieurs méthodes d'apprentissage. Pour chacune d'elles, il
conviendra d'explorer le périmètre des hyperparamètres suivant :
K-plus proches voisins. Hyperparamètre à régler :
'n_neighbors' : 2 à 50.
SVM. Hyperparamètres à régler :
kernel : 'rbf', 'linear'.
C : 0.1 ; 1 ; 10 ; 50 .
RandomForest. Hyperparamètres à régler :
'max_features': "sqrt", "log2", None
'min_samples_split': Nombres pairs allant de 2 à 30.
Pour chaque algorithme mentionné ci-dessus:
Sélectionnez les hyperparamètres sur l'échantillon d’apprentissage par validation croisée
Affichez les hyperparamètres retenus
Appliquez le modèle à l'ensemble de test, affichez la matrice de confusion et le score du
modèle sur ce dernier
Quel modèle fournit la meilleure précision ?
K plus proches voisins
In [5]:
### K-plus proches voisins
score_minko = []
score_man = []
score_cheb = []
for k in range(2, 50):
knn = neighbors.KNeighborsClassifier(n_neighbors=k, metric='minkowski')
knn.fit(X_train, y_train)
score_minko.append(knn.score(X_test, y_test))
for k in range(2, 50):
knn = neighbors.KNeighborsClassifier(n_neighbors=k, metric='manhattan')
knn.fit(X_train, y_train)
score_man.append(knn.score(X_test, y_test))
for k in range(2, 50):
knn = neighbors.KNeighborsClassifier(n_neighbors=k, metric='chebyshev')
knn.fit(X_train, y_train)
score_cheb.append(knn.score(X_test, y_test));
In [6]:
### Insérez votre code ici
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(range(2, 50), score_minko, color='blue', linestyle='dashed', lw=2,
label='Minkowski')
plt.plot(range(2, 50), score_man, color='orange', linestyle='dashed', lw=2,
label='Manhattan')
plt.plot(range(2, 50), score_cheb, color='red', linestyle='dashed', lw=2,
label='Chebyshev')
plt.title('Score - valeur de K')
plt.xlabel('Valeur de K')
plt.ylabel('Accuracy')
plt.legend();
## Les distances de Minkowski et de Manhattan donnent de meilleures performances
lorsque k est petit (<10).
SVM
In [*]:
### SVM
clf = svm.SVC()
parametres = {'C':[0.1,1,10,50], 'kernel':['rbf','linear']}
grid_clf = model_selection.GridSearchCV(estimator=clf, param_grid=parametres)
grille = grid_clf.fit(X_train,y_train)
print(pd.DataFrame.from_dict(grille.cv_results_).loc[:,['params', 'mean_test_score']])
In [ ]:
### Le résultat est meilleur pour :
grid_clf.best_estimator_
Random Forest
In [ ]:
### Random Forest
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import r2_score
model = ensemble.RandomForestClassifier( random_state=5, n_estimators= 700, n_jobs
= -1)
param_grid = {'max_features':['sqrt', 'log2'], 'min_samples_split' :range(2,30,2)}
grid_search_rf = GridSearchCV(model, param_grid, cv= 5,return_train_score=True)
grid_search_rf.fit(X_train, y_train)
train_r2_score=r2_score(y_train,grid_search_rf.predict(X_train))
test_r2_score=r2_score(y_test,grid_search_rf.predict(X_test))
output = output.append(pd.Series({'model':'Random Forest Regressor',
'train_r2_score':train_r2_score,'test_r2_score':test_r2_score}),ignore_index=True )
In [ ]:
### Le résultat est meilleur pour :