Avec Python + pandas + matplotlib, créez une ** heat map ** bien formatée à partir de la ** matrice de corrélation ** (une matrice de coefficients de corrélation entre chaque variable).
Ici, à titre d'exemple, je voudrais créer une carte de chaleur pour la matrice de corrélation ** 5 matières ** suivante.
Nous avons confirmé l'exécution et le fonctionnement avec Google Colab (Python 3.6.9). C'est presque le même que Jupyter Notebook.
!pip list
matplotlib 3.1.2
numpy 1.17.4
pandas 0.25.3
Rendre le japonais disponible dans le diagramme de sortie de matplotlib.
!pip install japanize-matplotlib
import japanize_matplotlib
Avec ce qui précède, japanize-matplotlib-1.0.5
sera installé et importé, et même si vous utilisez le japonais pour les étiquettes, etc., les caractères ne seront pas déformés (tofu).
La matrice de corrélation peut être facilement obtenue avec la fonction de pandas.
import pandas as pd
#Données factices
langue nationale= [76, 62, 71, 85, 96, 71, 68, 52, 85, 91]
société= [71, 85, 64, 55, 79, 72, 73, 52, 84, 84]
Math= [50, 78, 48, 64, 66, 62, 58, 50, 50, 60]
Science= [37, 90, 45, 56, 59, 56, 84, 86, 51, 61]
Anglais= [59, 97, 71, 85, 58, 82, 70, 61, 79, 70]
df = pd.DataFrame( {'langue nationale':langue nationale, 'société':société, 'Math':Math, 'Science':Science, 'Anglais':Anglais} )
#Calculer le coefficient de corrélation
df2 = df.corr()
display(df2)
Chaque élément de la matrice prend une valeur comprise entre $ -1,0 $ et 1,0 $. Plus cette valeur est proche de 1,0 $, plus la corrélation est ** positive **, et plus elle est proche de -1,0 $, la ** corrélation négative **. Dans la plage de -0,2 $ à 0,2 $, il est jugé comme ** non corrélé (non corrélé) **.
Puisque les éléments diagonaux sont le coefficient de corrélation entre les mêmes éléments, ce sera 1,0 $ (= il y a une corrélation positive parfaite).
Même si le coefficient de corrélation est organisé comme une valeur numérique comme indiqué ci-dessus, il est difficile de saisir l'ensemble, alors visualisons-le à l'aide d'une carte thermique.
Tout d'abord, créons une carte thermique avec le code minimum nécessaire sans ajuster l'apparence.
%reset -f
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
#Données factices
langue nationale= [76, 62, 71, 85, 96, 71, 68, 52, 85, 91]
société= [71, 85, 64, 55, 79, 72, 73, 52, 84, 84]
Math= [50, 78, 48, 64, 66, 62, 58, 50, 50, 60]
Science= [37, 90, 45, 56, 59, 56, 84, 86, 51, 61]
Anglais= [59, 97, 71, 85, 58, 82, 70, 61, 79, 70]
df = pd.DataFrame( {'langue nationale':langue nationale, 'société':société, 'Math':Math, 'Science':Science, 'Anglais':Anglais} )
#Calculer le coefficient de corrélation
df2 = df.corr()
display(df2)
#Sortie de la matrice des coefficients de corrélation sous forme de carte thermique
plt.figure(dpi=120)
plt.imshow(df2,interpolation='nearest',vmin=-1.0,vmax=1.0)
plt.colorbar()
#Réglage des noms d'éléments de sortie (langue nationale, société, mathématiques, sciences, anglais) sur l'axe
n = len(df2.columns) #Nombre d'objets
plt.gca().set_xticks(range(n))
plt.gca().set_xticklabels(df2.columns)
plt.gca().set_yticks(range(n))
plt.gca().set_yticklabels(df2.columns)
Vous pouvez obtenir la sortie suivante: Sur la base de la barre de couleur sur le côté droit, il y a une ** corrélation négative ** où se trouvent les couleurs violet foncé et bleu, et une ** corrélation positive où se trouvent les couleurs jaune vif et vert. Je vais lire s'il y a **.
Pour être honnête, il n'est pas possible de créer une carte thermique facile à comprendre avec les paramètres par défaut.
Nous allons le personnaliser pour obtenir une belle carte de chaleur intuitive. Les principaux points sont les suivants.
――Les composantes diagonales sont blanches et ombrées.
Une fois codé, cela ressemble à ceci:
%reset -f
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects
import matplotlib.ticker as ticker
import matplotlib.colors
#Données factices
langue nationale= [76, 62, 71, 85, 96, 71, 68, 52, 85, 91]
société= [71, 85, 64, 55, 79, 72, 73, 52, 84, 84]
Math= [50, 78, 48, 64, 66, 62, 58, 50, 50, 60]
Science= [37, 90, 45, 56, 59, 56, 84, 86, 51, 61]
Anglais= [59, 97, 71, 85, 58, 82, 70, 61, 79, 70]
df = pd.DataFrame( {'langue nationale':langue nationale, 'société':société, 'Math':Math, 'Science':Science, 'Anglais':Anglais} )
#Calculer le coefficient de corrélation
df2 = df.corr()
for i in df2.index.values :
df2.at[i,i] = 0.0
#Sortie de la matrice des coefficients de corrélation sous forme de carte thermique
plt.figure(dpi=120)
#Carte de couleurs personnalisée
cl = list()
cl.append( ( 0.00, matplotlib.colors.hsv_to_rgb((0.6, 1. ,1))) )
cl.append( ( 0.30, matplotlib.colors.hsv_to_rgb((0.6, 0.1 ,1))) )
cl.append( ( 0.50, matplotlib.colors.hsv_to_rgb((0.3, 0. ,1))) )
cl.append( ( 0.70, matplotlib.colors.hsv_to_rgb((0.0, 0.1 ,1))) )
cl.append( ( 1.00, matplotlib.colors.hsv_to_rgb((0.0, 1. ,1))) )
ccm = matplotlib.colors.LinearSegmentedColormap.from_list('custom_cmap', cl)
plt.imshow(df2,interpolation='nearest',vmin=-1.0,vmax=1.0,cmap=ccm)
#Réglage de la barre de couleur à afficher sur le côté gauche
fmt = lambda p, pos=None : f'${p:+.1f}$' if p!=0 else ' $0.0$'
cb = plt.colorbar(format=ticker.FuncFormatter(fmt))
cb.set_label('Coefficient de corrélation', fontsize=11)
#Paramètres liés à la sortie des éléments (langue nationale, société, mathématiques, sciences, anglais)
n = len(df2.columns) #Nombre d'objets
plt.gca().set_xticks(range(n))
plt.gca().set_xticklabels(df.columns)
plt.gca().set_yticks(range(n))
plt.gca().set_yticklabels(df.columns)
plt.tick_params(axis='x', which='both', direction=None,
top=True, bottom=False, labeltop=True, labelbottom=False)
plt.tick_params(axis='both', which='both', top=False, left=False )
#Paramètres de la grille
plt.gca().set_xticks(np.arange(-0.5, n-1), minor=True);
plt.gca().set_yticks(np.arange(-0.5, n-1), minor=True);
plt.grid( which='minor', color='white', linewidth=1)
#Ligne diagonale
plt.plot([-0.5,n-0.5],[-0.5,n-0.5],color='black',linewidth=0.75)
#Afficher le coefficient de corrélation (texte avec bordure)
tp = dict(horizontalalignment='center',verticalalignment='center')
ep = [path_effects.Stroke(linewidth=3, foreground='white'),path_effects.Normal()]
for y,i in enumerate(df2.index.values) :
for x,c in enumerate(df2.columns.values) :
if x != y :
t = plt.text(x, y, f'{df2.at[i,c]:.2f}',**tp)
t.set_path_effects(ep)
Recommended Posts