In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.io as pio
pio.renderers.default = "notebook"

Clustering de voitures

Ce notebook est un exemple de clustering de données. Nous souhaitons diviser des voitures en plusieurs groupes. Commençons par regarder les données.

Aperçu des données

In [2]:
data = pd.read_excel("voitures_clustering.xlsx")
data.T
Out[2]:
0 1 2 3 4 5 6 7 8 9 ... 20 21 22 23 24 25 26 27 28 29
Modele PANDA TWINGO YARIS CITRONC2 CORSA FIESTA CLIO P1007 MODUS MUSA ... P307CC PTCRUISER MONDEO MAZDARX8 VELSATIS CITRONC5 P607 MERC_E ALFA 156 BMW530
puissance 54 60 65 61 70 68 100 75 113 100 ... 180 223 145 231 150 210 204 204 250 231
cylindree 1108 1149 998 1124 1248 1399 1461 1360 1598 1910 ... 1997 2429 1999 1308 2188 2496 2721 3222 3179 2979
vitesse 150 151 155 158 165 164 185 165 188 179 ... 225 200 215 235 200 230 230 243 250 250
longueur 354 344 364 367 384 392 382 374 380 399 ... 435 429 474 443 486 475 491 482 443 485
largeur 159 163 166 166 165 168 164 169 170 170 ... 176 171 194 177 186 178 184 183 175 185
hauteur 154 143 150 147 144 144 142 161 159 169 ... 143 154 143 134 158 148 145 146 141 147
poids 860 840 880 932 1035 1138 980 1181 1170 1275 ... 1490 1595 1378 1390 1735 1589 1723 1735 1410 1495
C02 135 143 134 141 127 117 113 153 163 146 ... 210 235 189 284 188 238 223 183 287 231

9 rows × 30 columns

L'histogramme de chaque paramètre donne des indications sur sa répartition :

In [3]:
data.hist(bins=10, figsize=(20, 10));

Pour utiliser un algorithme de machine learning, il est toujours conseillé de standardiser les données.

In [4]:
from sklearn import preprocessing

data_scaled = preprocessing.scale(data.iloc[:, 1:])  # standardisation

Réduction de la dimension par PCA

Pour visualiser les données, nous allons utiliser une analyse par composantes principales (PCA), permettant de réduire le nombre de dimensions (ici, de 9 à 2) :

In [5]:
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
data2d = pd.DataFrame(pca.fit_transform(data_scaled), index=data["Modele"], columns=["x", "y"])
pca.explained_variance_ratio_ # variance expliquée par les deux axes principaux
Out[5]:
array([0.70547537, 0.13780777])

Le pourcentage de variance expliquée par les deux axes principaux est environ 0.84, ce qui permet donc de conserver beaucoup d'information.

In [6]:
pd.DataFrame(pca.components_, index=["x", "y"], columns=data.columns[1:])  # coordonnées des deux axes principaux
Out[6]:
puissance cylindree vitesse longueur largeur hauteur poids C02
x -0.393466 -0.364012 -0.400973 -0.386224 -0.348839 0.120983 -0.384690 -0.344120
y -0.099743 0.240731 -0.113762 0.060612 0.153163 0.868122 0.282546 -0.241984

On voit que l'axe x discrimine les grosses voitures : plus cette valeur est petite, plus la voiture correspondante est puissante, rapide, large, polluante... Étonnamment, la hauteur rentre peu en compte sur cet axe et est même inversement proportionnelle aux autre coordonnées.
L'axe y discrimine les voitures selon leur hauteur principalement.
Il y a donc 2 informations particulièrement importantes : la largeur générale de la voiture et sa hauteur.

In [7]:
fig = px.scatter(x=data2d.iloc[:, 0], y=data2d.iloc[:, 1], text=data2d.index)
fig.update_traces(textposition='top center')
fig.show()