Corrélations et corrélogramme

en python

L'essentiel de cette page.

Faire des corrélations ou des matrices de corrélations est assez simple. Il suffit de voir les bases des statistiques dans la page Un tuto simple pour l'analyse de données.

En revanche, obtenir un corrélogramme qui nous permettent immédiatement de voir les corrélations uniquement significatives avec un code couleur simple (rouge : si négatif, bleu : si positif) impose de faire un corrélogramme.

Ma fonction corrigraph() (version béta, une version plus complète disponible sous R) permet de faire cela. Code à copier-coller ci-dessous.

Exemple d'application après avoir collé le code de la fonction :

import seaborn as sns

iris= sns.load_dataset("iris")

corrigraph(iris,pval=0.01)

corrigraph() - fonction de corrélogramme - code à copier-coller après avoir cliquer sur ce titre

###############################

# corrigraph() - version 11/11/2021

# par Antoine Massé (merci de ne pas copier sans citer)

###############################

import seaborn as sns

import numpy as np

import networkx as nx

import matplotlib.pyplot as plt

import scipy

def corrigraph(x,pval=0.05) :

# Créer une matrice d'adjacence de type matrice de corrélation

mycor = x.corr() # Matrice de corrélation non filtrée par les p-values

# Nettoyage en fonction de la p-value

titres_retenus = mycor.columns.values

for i in range(len(titres_retenus)-1) :

for j in range((i+1),len(titres_retenus)) :

titre = titres_retenus[i]

#print("titre",titre)

sous_titre = titres_retenus[j]

#print("sous_titre",sous_titre)

temp = x[[titre,sous_titre]].dropna()

pvalue = scipy.stats.pearsonr(temp[titre],temp[sous_titre])[1]

#print("pvalue",pvalue)

if pvalue > pval :

mycor.iloc[i,j] = 0

mycor.iloc[j,i] = 0

mycor2 = np.array(mycor) # Conversion de la matrice pandas en matrice array

labels = list(mycor.columns.values) # Conversion au format list des noms de variables

key_list = list( range(len(labels)))

dic = dict(zip(key_list, labels))

# Définir les couleurs en fonction des valeurs de corrélation

# (>0 : rouge, <0 : bleu)

G = nx.from_numpy_array(mycor2)

edges,weights = zip(*nx.get_edge_attributes(G,'weight').items())

# Coloration conditionnelle

weights = list(weights)

for i in range(len(weights)) :

if weights[i] < 0 :

weights[i] = "red"

else :

weights[i] = "blue"

weights = tuple(weights)

# Tracer le réseau

# Nommer les labels

G = nx.relabel_nodes(G, dic)

position = nx.spring_layout(G)

plt.figure(figsize=(6,6))

nx.draw(G,position,with_labels=True,font_size=8, alpha=0.8,node_color="#FFFFD3",edge_color=weights)

#nx.draw_networkx_edges(G, position, alpha=0.3,edgelist=edges,)

plt.show()


Un cahier des charges pour améliorer corrigraph()

  1. Forme : adapter la taille de vertices au nombre d'interconnexion - plus un rond est interconnecté, plus il est grand

  2. Forme : adapter l'épaisseur des traits au p-values. Plus la valeur de p-value (en log10) est faible, plus le trait est épais (épaisseur max à partir de 0,00001).

  3. Forme : adapter le code pour que les traits ne soient pas trop longs ! (cf. figure ci-dessous)

  4. Forme : adapter le code pour que le réseau soit aussi esthétique que possible de façon automatisée (pas de cercles anormalement gros, ou de traits...).

  5. Forme : coloriser les groupes/clusteriser automatiquement si pas trop de variables.

  6. Robustesse : adapter le code pour qu'il fonctionne sur un grand nombre de jeux de données (diamonds, titanic (disponible dans seaborn), iris, les commentaires de la database du site) sans que cela renvoie de message d'erreur.

  7. Fonction : intégrer le test de Kruskal-Wallis pour intégrer les liens entre variables quantitative et qualitative. Fonction activée par l'argument mu=TRUE.

  8. Fonction : intégrer un lien entre les variables quantitatives selon la logique suivante, mais idéalement en remplaçant le test de Khi² par le G-test (plus robuste) : recherches sur le web nécessaires. Fonction activée par l'argument prop=TRUE.