Zeichnen Sie die Korrelationsmatrix mit Pandas

211

Ich habe einen Datensatz mit einer großen Anzahl von Merkmalen, daher ist die Analyse der Korrelationsmatrix sehr schwierig geworden. Ich möchte eine Korrelationsmatrix zeichnen, die wir mithilfe der dataframe.corr()Funktion aus der Pandas-Bibliothek erhalten. Gibt es eine eingebaute Funktion der Pandas-Bibliothek, um diese Matrix zu zeichnen?

Gaurav Singh
quelle
Verwandte Antworten finden Sie hier Erstellen einer Heatmap aus Pandas DataFrame
joelostblom

Antworten:

291

Sie können verwenden pyplot.matshow() von matplotlib:

import matplotlib.pyplot as plt

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

Bearbeiten:

In den Kommentaren wurde gefragt, wie die Achsen-Tick-Beschriftungen geändert werden sollen. Hier ist eine Deluxe-Version, die auf einer größeren Figur gezeichnet ist, Achsenbeschriftungen hat, die mit dem Datenrahmen übereinstimmen, und eine Farbleistenlegende, um die Farbskala zu interpretieren.

Ich füge hinzu, wie die Größe und Drehung der Etiketten angepasst wird, und ich verwende ein Zahlenverhältnis, bei dem die Farbleiste und die Hauptfigur dieselbe Höhe haben.

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);

Beispiel für ein Korrelationsdiagramm

jrjc
quelle
1
Ich muss etwas vermissen:AttributeError: 'module' object has no attribute 'matshow'
Tom Russell
1
@ TomRussell Hast du getan import matplotlib.pyplot as plt?
Joelostblom
1
Ich würde gerne denken, dass ich es getan habe! :-)
Tom Russell
7
Wissen Sie, wie die tatsächlichen Spaltennamen im Plot angezeigt werden?
WebQube
2
@ Cecilia Ich hatte diese Angelegenheit gelöst, indem ich den Rotationsparameter auf 90
geändert hatte
182

Wenn Ihr Hauptziel darin besteht, die Korrelationsmatrix zu visualisieren, anstatt ein Diagramm an sich zu erstellen, sind die praktischen pandas Gestaltungsoptionen eine praktikable integrierte Lösung:

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

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass dies in einem Backend erfolgen muss, das das Rendern von HTML unterstützt, z. B. im JupyterLab-Notizbuch. (Der automatische helle Text auf dunklem Hintergrund stammt aus einer vorhandenen PR und nicht aus der neuesten veröffentlichten Version pandas0.23).


Styling

Sie können die Zifferngenauigkeit leicht einschränken:

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

Geben Sie hier die Bildbeschreibung ein

Oder entfernen Sie die Ziffern ganz, wenn Sie die Matrix ohne Anmerkungen bevorzugen:

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

Geben Sie hier die Bildbeschreibung ein

Die Styling-Dokumentation enthält auch Anweisungen zu erweiterten Styles, z. B. zum Ändern der Anzeige der Zelle, über der sich der Mauszeiger befindet. Um die Ausgabe zu speichern, können Sie den HTML-Code zurückgeben, indem Sie die render()Methode anhängen und dann in eine Datei schreiben (oder einfach einen Screenshot für weniger formale Zwecke erstellen).


Zeitvergleich

In meinen Tests style.background_gradient()war 4x schneller als plt.matshow()und 120x schneller als sns.heatmap()mit einer 10x10 Matrix. Leider skaliert es nicht so gut wie plt.matshow(): Die beiden benötigen für eine 100x100-Matrix ungefähr die gleiche Zeit und sind für eine 1000x1000-Matrix plt.matshow()10x schneller.


Sparen

Es gibt verschiedene Möglichkeiten, den stilisierten Datenrahmen zu speichern:

  • Geben Sie den HTML-Code zurück, indem Sie die render()Methode anhängen , und schreiben Sie die Ausgabe in eine Datei.
  • Speichern Sie als .xslxDatei mit bedingter Formatierung, indem Sie die to_excel()Methode anhängen .
  • Kombiniere es mit imgkit, um eine Bitmap zu speichern
  • Machen Sie einen Screenshot (für weniger formelle Zwecke).

Update für Pandas> = 0,24

Durch Einstellen axis=Noneist es jetzt möglich, die Farben basierend auf der gesamten Matrix anstatt pro Spalte oder pro Zeile zu berechnen:

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

Geben Sie hier die Bildbeschreibung ein

joelostblom
quelle
2
Wenn es eine Möglichkeit zum Exportieren als Bild gegeben hätte, wäre das großartig gewesen!
Kristada673
1
Vielen Dank! Sie brauchen auf jeden Fall eine abweichende Paletteimport 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)
StallingOne
1
@stallingOne Guter Punkt, ich hätte keine negativen Werte in das Beispiel aufnehmen sollen, das könnte ich später ändern. Nur als Referenz für Leute, die dies lesen, müssen Sie keine benutzerdefinierte divergierende cmap mit seaborn erstellen (obwohl die im obigen Kommentar ziemlich schick aussieht). Sie können auch die integrierten divergenten cmaps von matplotlib verwenden, z corr.style.background_gradient(cmap='coolwarm'). Derzeit gibt es keine Möglichkeit, die cmap auf einen bestimmten Wert zu zentrieren. Dies kann bei abweichenden cmaps eine gute Idee sein.
Joelostblom
1
@rovyko Bist du auf Pandas> = 0.24.0?
Joelostblom
2
Diese Diagramme sind optisch großartig, aber die Frage @ Kristada673 ist ziemlich relevant. Wie würden Sie sie exportieren?
Erfan
89

Probieren Sie diese Funktion aus, die auch Variablennamen für die Korrelationsmatrix anzeigt:

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);
Apogentus
quelle
6
plt.xticks(range(len(corr.columns)), corr.columns, rotation='vertical')Wenn Sie die vertikale Ausrichtung der Spaltennamen auf der x-Achse
wünschen
Eine andere grafische Sache, aber das Hinzufügen eines plt.tight_layout()kann auch für lange Spaltennamen nützlich sein.
user3017048
86

Seaborns Heatmap-Version:

import seaborn as sns
corr = dataframe.corr()
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)
rafaelvalle
quelle
9
Seaborn Heatmap ist schick, aber auf großen Matrizen schlecht. Die Matshow-Methode von Matplotlib ist viel schneller.
Anilbey
3
Seaborn kann die Ticklabels automatisch aus den Spaltennamen ableiten.
Tulio Casagrande
80

Sie können die Beziehung zwischen Merkmalen beobachten, indem Sie entweder eine Wärmekarte von Seaborn oder eine Streumatrix von Pandas zeichnen.

Streumatrix:

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

Wenn Sie auch die Schiefe der einzelnen Features visualisieren möchten, verwenden Sie seegeborene Pairplots.

sns.pairplot(dataframe)

Sns Heatmap:

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)

Die Ausgabe ist eine Korrelationskarte der Merkmale. dh siehe das folgende Beispiel.

Geben Sie hier die Bildbeschreibung ein

Die Korrelation zwischen Lebensmittel und Waschmitteln ist hoch. Ähnlich:

Produkte mit hoher Korrelation:
  1. Lebensmittel und Waschmittel.
Produkte mit mittlerer Korrelation:
  1. Milch und Lebensmittel
  2. Milch und Waschmittel_Papier
Produkte mit geringer Korrelation:
  1. Milch und Feinkost
  2. Gefroren und frisch.
  3. Gefroren und Deli.

Aus Paarplots: Sie können denselben Satz von Beziehungen aus Paarplots oder Streumatrix beobachten. Aber aus diesen können wir sagen, ob die Daten normal verteilt sind oder nicht.

Geben Sie hier die Bildbeschreibung ein

Hinweis: Das obige Diagramm stammt aus den Daten, die zum Zeichnen der Heatmap verwendet werden.

Phanindravarma
quelle
3
Ich denke, es sollte .plt nicht .pl sein (wenn dies auf matplotlib verweist)
ghukill
2
@ Ghukill Nicht unbedingt. Er hätte es alsfrom matplotlib import pyplot as pl
Jeru Luke
wie man die Grenze der Korrelation zwischen -1 bis +1 immer im Korrelationsdiagramm setzt
debaonline4u
7

Sie können die imshow () -Methode von matplotlib verwenden

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()
Khandelwal-manik
quelle
5

Wenn Sie Datenrahmen ist df, können Sie einfach verwenden:

import matplotlib.pyplot as plt
import seaborn as sns

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

Statmodels-Grafiken bieten auch eine schöne Ansicht der Korrelationsmatrix

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

corr = dataframe.corr()
sm.graphics.plot_corr(corr, xnames=list(corr.columns))
plt.show()
Shahriar Miraj
quelle
2

Der Vollständigkeit halber die einfachste Lösung, die ich mit Seaborn ab Ende 2019 kenne , wenn man Jupyter verwendet :

import seaborn as sns
sns.heatmap(dataframe.corr())
Marcin
quelle
1

Zusammen mit anderen Methoden ist es auch gut, ein Paardiagramm zu haben, das ein Streudiagramm für alle Fälle ergibt.

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)
Nishant Tyagi
quelle
0

Form Korrelationsmatrix, in meinem Fall zdf ist der Datenrahmen, den ich Korrelationsmatrix durchführen muss.

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)

Dann können wir einen Screenshot machen. oder konvertieren Sie HTML in eine Bilddatei.

smsivaprakaash
quelle