Aller au contenu

Clustering avec KMeans

L'algorithme des K Moyennes communément appelé KMeans est un algorithme de clustering.

L'algorithme du KMeans

Les pre-réquis

Pour utiliser l'algorithme du KMeans pour former un modèle, il faut des données numériques.

Fonction de coût

L'écart

Méthode d'optimisation

Condition d'arrêt

Évaluation

Pour évaluer un modèle de KMeans, on peut s'intéresser à : - la forme des clusters - la stabilité de l'algorithme - la compatibilté des résuktats avec des


.

Module 3: Apprentissage non supervisé

Partie 3.2: Clustering avec KMEANS

Il s'agit d'une technique linéaire permettant de projeter des données X de dimenson p en d'autres données T de dimmension d < p.

Objectifs * Visualiser les données * Étudier les liens de corrélation linéaire entre les variables * Réduire le nombre de dimensions

L'idée de l'ACP est de projeter les données sur des axes préservant la variance des données. Avec p=2 ou p=3, on peut visualiser ls données.

Principe : approximer un nuage de points X de dimension p par sa projection linéaire en dimension d < p.
L'ACP maximise la variance des points projectés.

On cherche à réaliser la projection x app Rp-->Rd, d<p
L'espace de projection P inclus dans Rd sera construit de manière progressive. * D'abord on va chercher le meilleur axe de projection (1D) u1 * Ensuite le meilleur plan en trouvant le deuxième axe u2 * Et ainsi de suite jusqu'à obtenir P

Importation des données

Le jeu de donnés contient des donnés récuellies sur les pays pour l'année 2015, il comporte 158 lignes et 12 colonnes. Nous travaillerons avec les 8 dernières colonnes soit p=8 et la colonne Region pour évaluer notre ACP.

import pandas as pd
dt = pd.read_csv('datasets/cost-of-living.csv', index_col=0).T
dt.head()
Meal, Inexpensive Restaurant Meal for 2 People, Mid-range Restaurant, Three-course McMeal at McDonalds (or Equivalent Combo Meal) Domestic Beer (0.5 liter draught) Imported Beer (0.33 liter bottle) Coke/Pepsi (0.33 liter bottle) Water (0.33 liter bottle) Milk (regular), (1 liter) Loaf of Fresh White Bread (500g) Eggs (regular) (12) ... Lettuce (1 head) Cappuccino (regular) Rice (white), (1kg) Tomato (1kg) Banana (1kg) Onion (1kg) Beef Round (1kg) (or Equivalent Back Leg Red Meat) Toyota Corolla 1.6l 97kW Comfort (Or Equivalent New Car) Preschool (or Kindergarten), Full Day, Private, Monthly for 1 Child International Primary School, Yearly for 1 Child
Saint Petersburg, Russia 7.34 29.35 4.40 2.20 2.20 0.76 0.53 0.98 0.71 1.18 ... 0.86 1.96 0.92 1.91 0.89 0.48 7.18 19305.29 411.83 5388.86
Istanbul, Turkey 4.58 15.28 3.82 3.06 3.06 0.64 0.24 0.71 0.36 1.62 ... 0.61 1.84 1.30 0.80 1.91 0.62 9.73 20874.72 282.94 6905.43
Izmir, Turkey 3.06 12.22 3.06 2.29 2.75 0.61 0.22 0.65 0.38 1.51 ... 0.57 1.56 1.31 0.70 1.78 0.58 8.61 20898.83 212.18 4948.41
Helsinki, Finland 12.00 65.00 8.00 6.50 6.75 2.66 1.89 0.96 2.27 2.02 ... 2.30 3.87 2.13 2.91 1.61 1.25 12.34 24402.77 351.60 1641.00
Chisinau, Moldova 4.67 20.74 4.15 1.04 1.43 0.64 0.44 0.68 0.33 1.11 ... 0.84 1.25 0.93 1.56 1.37 0.59 5.37 17238.13 210.52 2679.30

5 rows × 55 columns

dt.shape
(160, 55)
X = dt.values
fig = plt.figure(figsize=(16, 8))
gs = fig.add_gridspec(2, 2)

fig.add_subplot(gs[0, 0])
plt.scatter(X[:, 1], X[:, 4])

fig.add_subplot(gs[0, 1])
plt.scatter(X[:, 10], X[:, 25])

fig.add_subplot(gs[1, 0])
plt.scatter(X[:, 7], X[:, 14])

fig.add_subplot(gs[1, 1])
plt.scatter(X[:, 6], X[:, 40])
plt.show()

KMEANS avec Scikit-learn

Comment choisir le nombre de clusters ?

from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

n_clusters_range = [2, 3, 4, 5, 6, 7]

silouettes = []
for n in n_clusters_range:
    kmeans = KMeans(n_clusters=n)
    kmeans.fit(X)

    silouettes.append(silhouette_score(X, kmeans.predict(X)))

plt.plot(n_clusters_range, silouettes)
plt.xlabel("Nombre de clusters")
plt.ylabel("Coefficient de silhouette")
plt.title("Coefficient de silhouette en fonction du nombre de clusters")
plt.show()
n_clusters = 4
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=n_clusters)
kmeans.fit(X)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
       n_clusters=4, n_init=10, n_jobs=None, precompute_distances='auto',
       random_state=None, tol=0.0001, verbose=0)
fig = plt.figure(figsize=(16, 8))
gs = fig.add_gridspec(2, 2)

fig.add_subplot(gs[0, 0])
plt.scatter(X[:, 1], X[:, 4], c=kmeans.predict(X))

fig.add_subplot(gs[0, 1])
plt.scatter(X[:, 10], X[:, 25], c=kmeans.predict(X))

fig.add_subplot(gs[1, 0])
plt.scatter(X[:, 7], X[:, 14], c=kmeans.predict(X))

fig.add_subplot(gs[1, 1])
plt.scatter(X[:, 6], X[:, 40], c=kmeans.predict(X))
plt.show()

Interprétaion

Le premier axe conserve 41,2% le deuxième axe 19,4% et le troisème axe 14,3%. Les trois axes permettent de conserver environ 75% de variance des données. Si l'on souhaite conserver plus de variance, on peut ajouter un axe supplémentaire ou plus. Remarquons qu'il est peu pertinent de conserver toute la variance, autant travailler avec les données initiales, il ne faut pas perdre de vue que l'un des objectifs de l'ACP, c'est la réduction du nombre de dimensions.

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(8, 8))
ax = fig.gca(projection='3d')
ax.scatter(X_projected[:, 0], X_projected[:, 1], X_projected[:, 2])
plt.show()