Bonjour à tous et à toutes,

J'ai récemment commencé à étudier la classification automatique par la méthode des K-Means, une méthode qui m’intéresse énormément. Pour l'exemple, je dispose d'une base de données qui répertorie des fromages ainsi que différents composants (calorie, lipides, etc), sous cette forme :
https://zupimages.net/viewer.php?id=20/36/imce.png

Je souhaiterais créer 4 groupes, avec une homogénéité (distance moyenne des observations au centre de leur classes respective) la plus basse, et une dispersion (distance moyenne des classes entre elles) la plus élevée. Je sais qu'un logiciel de statistique comme Sphinx permet de donner ces nombre (exemple d'un rendu ici : https://zupimages.net/viewer.php?id=20/36/khlr.png). Ce que je pensais faire, c'est créer un certains nombre de combinaisons de groupe avec KMeans, puis de ne récupérer que la combinaison qui respecte les conditions citées. Malheureusement impossible pour moi de trouver comment extraire cette homogénéité et cette dispersion, malgré mes recherches.

Mes recherches m'ont cependant permis de créer un algorithme, reproductible :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
import pandas as pd
import numpy as np
 
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from sklearn import cluster, metrics
 
data = pd.DataFrame({"fromage" : ["fromage1", "fromage2", "fromage3", "fromage4", "fromage5", "fromage6", "fromage7", "fromage8", "fromage9", "fromage10", "fromage11", "fromage12", "fromage13", "fromage14", "fromage15", "fromage16", "fromage17", "fromage18", "fromage19", "fromage20", "fromage21"], "calories" : np.random.uniform(low=100, high=450, size=(21,)), "sodium" : np.random.uniform(low=20, high=450, size=(21,)), "calcium" : np.random.uniform(low=70, high=250, size=(21,)), "lipides" : np.random.uniform(low=20, high=30, size=(21,)), "retinol" : np.random.uniform(low=50, high=120, size=(21,)), "folates" : np.random.uniform(low=1, high=30, size=(21,)), "proteines" : np.random.uniform(low=7, high=20, size=(21,)), "cholesterol" : np.random.uniform(low=100, high=450, size=(21,))})
#CConvertir l'index
data = data.set_index("fromage")
#Créer mes groupes
kmeans = cluster.KMeans(n_clusters=4, init='k-means++', max_iter=300, n_init=10, random_state=0)
kmeans.fit(data)
#index triés des groupes
idk = np.argsort(kmeans.labels_)
#moyenne par variable
m = data.mean()
#TSS
TSS = data.shape[0]*data.var(ddof=0)
#data.frame conditionnellement aux groupes
gb = data.groupby(kmeans.labels_)
#effectifs conditionnels
nk = gb.size()
#MOYENNE DES FACTEURS PAR CLASSE
mk = gb.mean()
#pour chaque groupe écart à la moyenne par variable
EMk = (mk-m)**2
#pondéré par les effectifs du groupe
EM = EMk.multiply(nk,axis=0)
#somme des valeurs => BSS
BSS = np.sum(EM,axis=0)
#variance expliquée par l'appartenance aux groupes pour chaque variable
R2 = BSS/TSS
Est-il possible d'extraire ces nombres avec une des librairies que j'ai utilisé ?
Merci.