3

J'ai expérimenté avec Hierarchical Clustering et en R c'est tellement simple hclust(as.dist(X),method="average"). J'ai trouvé une méthode dans Python qui est assez simple, sauf que je suis un peu confus sur ce qui se passe avec ma matrice de distance d'entrée.Triangle vs. Matrice de distance carrée pour Python de classification hiérarchique?

J'ai une matrice de similarité (DF_c93tom w/une version de test plus petit appelé DF_sim) que je convertir en une matrice de dissemblance DF_dissm = 1 - DF_sim.

Je l'utilise comme entrée dans linkage de scipy mais la documentation dit qu'il prend une matrice carrée ou triangulaire. Je reçois un cluster différent pour l'entrée d'un lower triangle, upper triangle et square matrix. Pourquoi est-ce? Il veut un triangle supérieur de la documentation mais le groupe de triangle inférieur semble vraiment similaire.

Ma question, pourquoi toutes les grappes sont-elles différentes? Laquelle est correcte?

Ceci est la documentation de la matrice de distance d'entrée pour linkage

y : ndarray 
A condensed or redundant distance matrix. A condensed distance matrix is a flat array containing the upper triangular of the distance matrix. 

Voici mon code:

import matplotlib.pyplot as plt 
import seaborn as sns 
import numpy as np 
import pandas as pd 
from scipy.cluster.hierarchy import dendrogram, linkage 

%matplotlib inline 

#Test Data 
DF_sim = DF_c93tom.iloc[:10,:10] #Similarity Matrix 
DF_sim.columns = DF_sim.index = range(10) 
#print(DF_test) 
#   0 1   2   3 4 5 6 7 8 9 
# 0 1.000000 0 0.395833 0.083333 0 0 0 0 0 0 
# 1 0.000000 1 0.000000 0.000000 0 0 0 0 0 0 
# 2 0.395833 0 1.000000 0.883792 0 0 0 0 0 0 
# 3 0.083333 0 0.883792 1.000000 0 0 0 0 0 0 
# 4 0.000000 0 0.000000 0.000000 1 0 0 0 0 0 
# 5 0.000000 0 0.000000 0.000000 0 1 0 0 0 0 
# 6 0.000000 0 0.000000 0.000000 0 0 1 0 0 0 
# 7 0.000000 0 0.000000 0.000000 0 0 0 1 0 0 
# 8 0.000000 0 0.000000 0.000000 0 0 0 0 1 0 
# 9 0.000000 0 0.000000 0.000000 0 0 0 0 0 1 

#Dissimilarity Matrix 
DF_dissm = 1 - DF_sim 

#Redundant Matrix 
#np.tril(DF_dissm).T == np.triu(DF_dissm) 
#True for all values 

#Hierarchical Clustering for square and triangle matrices 
fig_1 = plt.figure(1) 
plt.title("Square") 
Z_square = linkage((DF_dissm.values),method="average") 
dendrogram(Z_square) 

fig_2 = plt.figure(2) 
plt.title("Triangle Upper") 
Z_triu = linkage(np.triu(DF_dissm.values),method="average") 
dendrogram(Z_triu) 

fig_3 = plt.figure(3) 
plt.title("Triangle Lower") 
Z_tril = linkage(np.tril(DF_dissm.values),method="average") 
dendrogram(Z_tril) 

plt.show() 

enter image description here

Répondre

3

Lorsqu'un tableau 2D est passé comme premier argument à scipy.cluster.hierarchy.linkage, il est traité comme une séquence d'observation s, et scipy.spatial.pdist is used pour le convertir en une séquence de distances par paires entre les observations.

Il y a un github issue en ce qui concerne ce comportement car cela signifie que le passage d'une « matrice à distance », comme DF_dissm.values (silence) produit un résultat incorrect .

Alors the upshot of this est qu'aucun de ces

Z_square = linkage((DF_dissm.values),method="average") 
Z_triu = linkage(np.triu(DF_dissm.values),method="average") 
Z_tril = linkage(np.tril(DF_dissm.values),method="average") 

produire le résultat souhaité.Utilisez plutôt

  • np.triu_indices:

    h, w = arr.shape 
    Z = linkage(arr[np.triu_indices(h, 1)], method="average") 
    
  • ou spatial.distance.squareform:

    from scipy.spatial import distance as ssd 
    Z = linkage(ssd.squareform(arr), method="average") 
    
  • ou appliquer spatial.distance.pdist aux points d'origine:

    Z = hierarchy.linkage(ssd.pdist(points), method="average") 
    
  • ou passer le tableau 2D points:

    Z = hierarchy.linkage(points, method="average") 
    

import matplotlib.pyplot as plt 
import numpy as np 
from scipy.cluster import hierarchy as hier 
from scipy.spatial import distance as ssd 
np.random.seed(2016) 

points = np.random.random((10, 2)) 
arr = ssd.cdist(points, points) 

fig, ax = plt.subplots(nrows=4) 

ax[0].set_title("condensed upper triangular") 
Z = hier.linkage(arr[np.triu_indices(arr.shape[0], 1)], method="average") 
hier.dendrogram(Z, ax=ax[0]) 

ax[1].set_title("squareform") 
Z = hier.linkage(ssd.squareform(arr), method="average") 
hier.dendrogram(Z, ax=ax[1]) 

ax[2].set_title("pdist") 
Z = hier.linkage(ssd.pdist(points), method="average") 
hier.dendrogram(Z, ax=ax[2]) 

ax[3].set_title("sequence of observations") 
Z = hier.linkage(points, method="average") 
hier.dendrogram(Z, ax=ax[3]) 

plt.show() 

enter image description here