Traccia la matrice di correlazione usando i panda


212

Ho un set di dati con un numero enorme di funzionalità, quindi l'analisi della matrice di correlazione è diventata molto difficile. Voglio tracciare una matrice di correlazione che otteniamo usando la dataframe.corr()funzione dalla libreria panda. Esiste una funzione integrata fornita dalla libreria Panda per tracciare questa matrice?


Le risposte correlate sono disponibili qui Creazione di una mappa di
calore

Risposte:


292

Puoi usare pyplot.matshow() da matplotlib:

import matplotlib.pyplot as plt

plt.matshow(dataframe.corr())
plt.show()

Modificare:

Nei commenti c'era una richiesta su come cambiare le etichette dei tick degli assi. Ecco una versione deluxe che è disegnata su una dimensione di figura più grande, ha etichette degli assi per abbinare il frame di dati e una legenda della barra dei colori per interpretare la scala dei colori.

Sto includendo come regolare le dimensioni e la rotazione delle etichette e sto usando un rapporto tra figure che fa apparire la barra dei colori e la figura principale alla stessa altezza.

f = plt.figure(figsize=(19, 15))
plt.matshow(df.corr(), fignum=f.number)
plt.xticks(range(df.shape[1]), df.columns, fontsize=14, rotation=45)
plt.yticks(range(df.shape[1]), df.columns, fontsize=14)
cb = plt.colorbar()
cb.ax.tick_params(labelsize=14)
plt.title('Correlation Matrix', fontsize=16);

esempio di diagramma di correlazione


1
Mi manca qualcosa:AttributeError: 'module' object has no attribute 'matshow'
Tom Russell,

1
@TomRussell Hai fatto import matplotlib.pyplot as plt?
joelostblom,

1
Mi piacerebbe pensare di averlo fatto! :-)
Tom Russell,

7
sai come visualizzare i nomi delle colonne attuali sulla trama?
WebQube

2
@Cecilia Avevo risolto la questione modificando il parametro di rotazione su 90
ikbel benabdessamad

182

Se il tuo obiettivo principale è quello di visualizzare la matrice di correlazione, piuttosto che creare un grafico di per sé, le convenienti pandas opzioni di stile sono una soluzione integrata praticabile:

import pandas as pd
import numpy as np

rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(10, 10))
corr = df.corr()
corr.style.background_gradient(cmap='coolwarm')
# 'RdBu_r' & 'BrBG' are other good diverging colormaps

inserisci qui la descrizione dell'immagine

Si noti che questo deve essere in un back-end che supporta il rendering HTML, come il Notebook JupyterLab. (Il testo chiaro automatico su sfondi scuri proviene da un PR esistente e non dall'ultima versione rilasciata, pandas0.23).


Messa in piega

Puoi facilmente limitare la precisione delle cifre:

corr.style.background_gradient(cmap='coolwarm').set_precision(2)

inserisci qui la descrizione dell'immagine

Oppure elimina del tutto le cifre se preferisci la matrice senza annotazioni:

corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})

inserisci qui la descrizione dell'immagine

La documentazione relativa allo stile include anche istruzioni su stili più avanzati, come ad esempio come modificare la visualizzazione della cella su cui è posizionato il puntatore del mouse. Per salvare l'output è possibile restituire l'HTML aggiungendo il render()metodo e quindi scriverlo in un file (o semplicemente fare uno screenshot per scopi meno formali).


Confronto temporale

Nei miei test, sono style.background_gradient()stato 4 volte più veloce di plt.matshow()e 120 volte più veloce rispetto sns.heatmap()a una matrice 10x10. Sfortunatamente non si adatta bene plt.matshow(): i due impiegano all'incirca lo stesso tempo per una matrice 100x100 ed plt.matshow()è 10 volte più veloce per una matrice 1000x1000.


Salvataggio

Esistono alcuni modi possibili per salvare il frame di dati stilizzato:

  • Restituisce il codice HTML aggiungendo il render() metodo e quindi scrivere l'output in un file.
  • Salvare come .xslxfile con formattazione condizionale aggiungendo il fileto_excel() metodo.
  • Combina con imgkit per salvare una bitmap
  • Fai uno screenshot (per scopi meno formali).

Aggiornamento per i panda> = 0,24

Impostando axis=None, ora è possibile calcolare i colori in base all'intera matrice anziché per colonna o per riga:

corr.style.background_gradient(cmap='coolwarm', axis=None)

inserisci qui la descrizione dell'immagine


2
Se ci fosse un modo per esportare è come un'immagine, sarebbe fantastico!
Kristada673,

1
Grazie! Hai sicuramente bisogno di una tavolozza divergenteimport seaborn as sns corr = df.corr() cm = sns.light_palette("green", as_cmap=True) cm = sns.diverging_palette(220, 20, sep=20, as_cmap=True) corr.style.background_gradient(cmap=cm).set_precision(2)
stallo del

1
@stallingOne Un buon punto, non avrei dovuto includere valori negativi nell'esempio, potrei cambiarlo in seguito. Solo per riferimento per le persone che leggono questo, non è necessario creare un cmap divergente personalizzato con seaborn (anche se quello nel commento sopra sembra piuttosto liscio), puoi anche usare i cmaps divergenti incorporati da matplotlib, ad es corr.style.background_gradient(cmap='coolwarm'). Al momento non è possibile centrare il cmap su un valore specifico, il che può essere una buona idea con cmap divergenti.
joelostblom,

1
@rovyko Sei sui panda> = 0.24.0?
joelostblom,

2
Questi grafici sono visivamente fantastici, ma la domanda @ Kristada673 è abbastanza rilevante, come li esporteresti?
Erfan,

89

Prova questa funzione, che visualizza anche i nomi delle variabili per la matrice di correlazione:

def plot_corr(df,size=10):
    '''Function plots a graphical correlation matrix for each pair of columns in the dataframe.

    Input:
        df: pandas DataFrame
        size: vertical and horizontal size of the plot'''

    corr = df.corr()
    fig, ax = plt.subplots(figsize=(size, size))
    ax.matshow(corr)
    plt.xticks(range(len(corr.columns)), corr.columns);
    plt.yticks(range(len(corr.columns)), corr.columns);

6
plt.xticks(range(len(corr.columns)), corr.columns, rotation='vertical')se vuoi l'orientamento verticale dei nomi delle colonne sull'asse x
nishant

Un'altra cosa grafica, ma l'aggiunta di un plt.tight_layout()potrebbe essere utile anche per i nomi di colonne lunghe.
user3017048,

86

Versione di Heatmap di Seaborn:

import seaborn as sns
corr = dataframe.corr()
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)

9
La mappa di calore di Seaborn è elegante ma funziona male su matrici di grandi dimensioni. Il metodo matshow di matplotlib è molto più veloce.
anilbey,

3
Seaborn può inferire automaticamente i ticklabel dai nomi delle colonne.
Tulio Casagrande,

80

Puoi osservare la relazione tra le caratteristiche o disegnando una mappa di calore da un bambino o una matrice di dispersione dai panda.

Matrice a dispersione:

pd.scatter_matrix(dataframe, alpha = 0.3, figsize = (14,8), diagonal = 'kde');

Se si desidera visualizzare anche l'asimmetria di ogni caratteristica, utilizzare i diagrammi di coppie marine.

sns.pairplot(dataframe)

Heatmap Sns:

import seaborn as sns

f, ax = pl.subplots(figsize=(10, 8))
corr = dataframe.corr()
sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True),
            square=True, ax=ax)

L'output sarà una mappa di correlazione delle funzionalità. cioè vedi l'esempio sotto.

inserisci qui la descrizione dell'immagine

La correlazione tra drogheria e detergenti è alta. Allo stesso modo:

Prodotti con alta correlazione:
  1. Drogheria e detergenti.
Prodotti con correlazione media:
  1. Latte e generi alimentari
  2. Latte e detergenti_Carta
Prodotti a bassa correlazione:
  1. Milk and Deli
  2. Congelato e fresco.
  3. Frozen and Deli.

Dai grafici a coppie: è possibile osservare lo stesso insieme di relazioni da coppie di grafici o matrice a dispersione. Ma da questi possiamo dire che i dati sono normalmente distribuiti o meno.

inserisci qui la descrizione dell'immagine

Nota: quanto sopra è lo stesso grafico preso dai dati, che viene utilizzato per disegnare la mappa di calore.


3
Penso che dovrebbe essere .plt non .pl (se questo si riferisce a matplotlib)
ghukill

2
@ghukill Non necessariamente. Avrebbe potuto from matplotlib import pyplot as pl
chiamarlo

come impostare sempre il limite della correlazione tra -1 e +1, nel diagramma di correlazione
debaonline4u

7

Puoi usare il metodo imshow () da matplotlib

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')

plt.imshow(X.corr(), cmap=plt.cm.Reds, interpolation='nearest')
plt.colorbar()
tick_marks = [i for i in range(len(X.columns))]
plt.xticks(tick_marks, X.columns, rotation='vertical')
plt.yticks(tick_marks, X.columns)
plt.show()

5

Se il tuo dataframe è dfpuoi semplicemente usare:

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(15, 10))
sns.heatmap(df.corr(), annot=True)

3

la grafica di statmodels offre anche una buona visione della matrice di correlazione

import statsmodels.api as sm
import matplotlib.pyplot as plt

corr = dataframe.corr()
sm.graphics.plot_corr(corr, xnames=list(corr.columns))
plt.show()

3

Per completezza, la soluzione più semplice che conosco con Seaborn alla fine del 2019, se si utilizza Jupyter :

import seaborn as sns
sns.heatmap(dataframe.corr())

1

Insieme ad altri metodi è anche utile avere un diagramma di coppia che fornirà un diagramma a dispersione per tutti i casi-

import pandas as pd
import numpy as np
import seaborn as sns
rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(10, 10))
sns.pairplot(df)

0

Matrice di correlazione dei moduli, nel mio caso zdf è il frame di dati di cui ho bisogno per eseguire la matrice di correlazione.

corrMatrix =zdf.corr()
corrMatrix.to_csv('sm_zscaled_correlation_matrix.csv');
html = corrMatrix.style.background_gradient(cmap='RdBu').set_precision(2).render()

# Writing the output to a html file.
with open('test.html', 'w') as f:
   print('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-widthinitial-scale=1.0"><title>Document</title></head><style>table{word-break: break-all;}</style><body>' + html+'</body></html>', file=f)

Quindi possiamo fare uno screenshot. o converti html in un file immagine.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.