Clustering : R to Python

Hello tout le monde.

Petite question pour les personnes maitrisant R et Python.

Je “traduis” un script R en Python. Dans ce script, nous effectuons un clustering avec :

  1. Calcul d’une matrice de distance
  2. Clustering avec la fonction hclust de la librairie fastcluster

Voici le code en R :

require(fastcluster)

## Matrix de distance
genes.dist<-lapply(ngl.gene.counts.list.mgSs.pa.clean, function(x) vegdist(x, method="jaccard", binary = TRUE))
# ngl.gene.counts.list.mgSs.pa.clean est une liste de DataFrame


## Overview of the dist matrix for the first element
[1] 0.2382979 0.2277563 0.3868330 0.2807250 0.3720317 0.2801627

## Clustering
genes.hc<-lapply(genes.dist, function(x) hclust(x, method="ward.D"))

## Overview of the hclust object of the first element
List of 7
 $ merge      : int [1:182, 1:2] -173 -174 -37 -175 -99 -100 -162 -143 -98 -103 ...
 $ height     : num [1:182] 0.0373 0.0373 0.0403 0.0414 0.0415 ...
 $ order      : int [1:183] 49 47 48 97 33 143 144 103 104 54 ...
 $ labels     : chr [1:183] "323785_MG" "323830_MG" "323858_MG" "323880_MG" ...
 $ method     : chr "ward.D"
 $ call       : language hclust(d = x, method = "ward.D")
 $ dist.method: chr "binary jaccard"

Voici le code en Python :

# Define a function to calculate Jaccard distance
def jaccard_distance(x):
    return distance.pdist(x, metric='jaccard')

genes_dist = {}
for key, value in ngl_gene_counts_list_mgSs_pa_clean.items():
    genes_dist[key] = (jaccard_distance(value))

## Overview of the dist matrix for the first element
[0.23829787 0.22775629 0.38683305 ... 0.12770043 0.28746177 0.32835821]

# Define a function to perform hierarchical clustering
def hierarchical_clustering(x):
    linkage_matrix = linkage(x, method='ward', metric='euclidean')
    return linkage_matrix

genes_hc = {}
for k,v in genes_dist.items():
    genes_hc[k] = hierarchical_clustering(v)

## Overview of the clustering in Python for the first element
[1.72000000e+02 1.79000000e+02 3.73423860e-02 2.00000000e+00]
 [1.73000000e+02 1.76000000e+02 3.73482726e-02 2.00000000e+00]
 [3.60000000e+01 3.90000000e+01 4.03009135e-02 2.00000000e+00]
 [1.74000000e+02 1.75000000e+02 4.13829230e-02 2.00000000e+00]
 [9.80000000e+01 1.01000000e+02 4.15153088e-02 2.00000000e+00]

Mon probleme est le suivant : les 2 matrices de distances obtenues sont similaires mais le résultat du clustering semble retourner une matrice de dim 182x2 en R ($ merge) et 182x4 en Python avec des valeurs différentes.

Si quelqu’un a une piste de reflexion à ce sujet je suis preneur !
J’espère que ce sujet trouve sa place sur ce forum, si ce n’est pas le cas je m’en excuse par avance

Merci,
Amaury

Sur la linkage matrice en sortie (Python), la doc est là:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html

Tu as la distance entre les deux clusters fusionnés & le nombre d’observation dans le nouveau cluster dans les deux dernières colonnes.
Je ne sais pas si ça répond à ta question ceci dit.

Yes j’avais bien vu cette documentation merci, elle est top pour comprendre la structure de la matrice. Je continue de chercher les diff’ avec R

Bonjour tout le monde.

Pour info, si jamais cela peut servir pour quelqu’un plus tard :

WARNING

R and Matlab/SciPy use different conventions for the “Ward”, “centroid” and “median” methods. R assumes that the dissimilarity matrix consists of squared Euclidean distances, while Matlab and SciPy expect non-squared Euclidean distances. The fastcluster package respects these conventions and uses different formulas in the two interfaces.

If you want the same results in both interfaces, then feed R with the entry-wise square of the distance matrix, d^2, for the “Ward”, “centroid” and “median” methods and later take the square root of the height field in the dendrogram. For the “average” and “weighted” alias “mcquitty” methods, you must still take the same distance matrix d as in the Python interface for the same results. The “single” and “complete” methods only depend on the relative order of the distances, hence it does not make a difference whether one operates on the distances or the squared distances.

The code example in the R documentation (enter ?hclust or example(hclust) in R) contains an instance where the squared distance matrix is generated from Euclidean data.

source : fastcluster: Fast hierarchical clustering routines for R and Python