Importation des données¶

In [ ]:
#changer de dossier
import os
os.chdir("C:/Users/ricco/Desktop/demo")

#charger les données
import pandas
DAll = pandas.read_excel("wave_kmeans.xlsx")
DAll.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 22 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   V01     1000 non-null   float64
 1   V02     1000 non-null   float64
 2   V03     1000 non-null   float64
 3   V04     1000 non-null   float64
 4   V05     1000 non-null   float64
 5   V06     1000 non-null   float64
 6   V07     1000 non-null   float64
 7   V08     1000 non-null   float64
 8   V09     1000 non-null   float64
 9   V10     1000 non-null   float64
 10  V11     1000 non-null   float64
 11  V12     1000 non-null   float64
 12  V13     1000 non-null   float64
 13  V14     1000 non-null   float64
 14  V15     1000 non-null   float64
 15  V16     1000 non-null   float64
 16  V17     1000 non-null   float64
 17  V18     1000 non-null   float64
 18  V19     1000 non-null   float64
 19  V20     1000 non-null   float64
 20  V21     1000 non-null   float64
 21  onde    1000 non-null   object 
dtypes: float64(21), object(1)
memory usage: 172.0+ KB
In [ ]:
#variables actives
D = DAll[DAll.columns[:-1]]
D.columns
Out[ ]:
Index(['V01', 'V02', 'V03', 'V04', 'V05', 'V06', 'V07', 'V08', 'V09', 'V10',
       'V11', 'V12', 'V13', 'V14', 'V15', 'V16', 'V17', 'V18', 'V19', 'V20',
       'V21'],
      dtype='object')
In [ ]:
#distribution des "vraies" classes
DAll.onde.value_counts()
Out[ ]:
onde
C    352
B    338
A    310
Name: count, dtype: int64
In [ ]:
#récupérer le nombre d'observations
n = D.shape[0]
print(n)
1000

Elaboration et inspection du Pipeline¶

In [ ]:
#pour éviter le warning de KMeans
os.environ['OMP_NUM_THREADS'] = '1'

#pour éviter les future warning
from warnings import simplefilter
simplefilter(action='ignore', category=FutureWarning)
In [ ]:
#librairies et classes de calcul
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans

#création du Pipeline
#tous les axes factoriels
# => travail dans l'espace initial
# => avec les variables centrées et réduites
pipe = Pipeline([
    ('std',StandardScaler()),
    ('acp',PCA(n_components=D.shape[1],svd_solver='full')),
    ('km',KMeans(n_clusters=3,n_init=1,random_state=0))
])

#entraînement
pipe.fit(D)
Out[ ]:
Pipeline(steps=[('std', StandardScaler()),
                ('acp', PCA(n_components=21, svd_solver='full')),
                ('km', KMeans(n_clusters=3, n_init=1, random_state=0))])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Pipeline(steps=[('std', StandardScaler()),
                ('acp', PCA(n_components=21, svd_solver='full')),
                ('km', KMeans(n_clusters=3, n_init=1, random_state=0))])
StandardScaler()
PCA(n_components=21, svd_solver='full')
KMeans(n_clusters=3, n_init=1, random_state=0)
In [ ]:
#clusters attribués par les K-Means
import numpy
print(numpy.unique(pipe.named_steps['km'].labels_,return_counts=True))
(array([0, 1, 2]), array([371, 300, 329], dtype=int64))
In [ ]:
#variance expliquée par les facteurs
print(pipe.named_steps['acp'].explained_variance_)
[7.92906237 3.23587903 1.08394537 0.9782318  0.91425025 0.87747201
 0.70942885 0.66518272 0.54373093 0.48466718 0.42840355 0.38879518
 0.38105573 0.36657858 0.33902593 0.3206349  0.31776678 0.29223653
 0.2805236  0.25240011 0.23174965]

Détermination du "bon" nombre de facteurs¶

Stratégie pour identifier le nombre de facteurs¶

In [ ]:
#nombre max de facteurs
max_fact = 10
In [ ]:
#mesure de performance
from sklearn.metrics import v_measure_score

#vecteur pour récolter la qualité de la partition
#mesuré à l'aide de la v_measure_score
perfs = numpy.zeros(max_fact)

#faire varier le nombre de facteurs de l'ACP
#de 1 à max_facteurs
for nb_fact in range(max_fact):
    #spécifier valeur du param. nb_de_facteurs
    #puis lancer l'entraînement
    res = pipe.set_params(acp__n_components=nb_fact+1).fit(D)
    #v-measure
    vm = v_measure_score(DAll.onde,res.named_steps['km'].labels_)
    #stockage du rapport
    perfs[nb_fact] = vm

#afficher les valeurs
print(perfs)
[0.28453578 0.36381586 0.36381586 0.36326351 0.36341359 0.36341359
 0.36364035 0.36341359 0.36330934 0.36330934]
In [ ]:
#graphique : nb de facteurs vs. v_measure_score
import seaborn as sns
sns.lineplot(x=numpy.arange(1,max_fact+1,1),y=perfs)
Out[ ]:
<Axes: >
No description has been provided for this image

Modèle (pipeline) final à instancier¶

In [ ]:
#revenir à 'n_components = 2' facteurs pour l'ACP
pipe.set_params(acp__n_components=2)

#relancer l'entraînement
pipe.fit(D)

#vérif.
print(pipe.named_steps['km'].inertia_)
2705.105124646918
In [ ]:
#projection dans l'espace'
coordFact = pipe.named_steps['acp'].transform(pipe.named_steps['std'].transform(D))
coordFact = pandas.DataFrame(coordFact,columns=['F'+str(i+1) for i in range(pipe.named_steps['acp'].n_components_)])

#vérif.
coordFact.head()
Out[ ]:
F1 F2
0 -2.218517 -2.981534
1 3.813923 -1.361467
2 -4.281852 -0.801897
3 0.057505 -1.294641
4 -4.839566 -2.334639
In [ ]:
#rajouter les groupes d'appartenance
coordFact['groupes'] = pipe.named_steps['km'].labels_
coordFact.head()
Out[ ]:
F1 F2 groupes
0 -2.218517 -2.981534 2
1 3.813923 -1.361467 1
2 -4.281852 -0.801897 2
3 0.057505 -1.294641 2
4 -4.839566 -2.334639 2
In [ ]:
#représentation dans le plan
sns.scatterplot(coordFact,x='F1',y='F2',hue='groupes')
Out[ ]:
<Axes: xlabel='F1', ylabel='F2'>
No description has been provided for this image