Wykres macierzy korelacji za pomocą pand
Mam zbiór danych z ogromną liczbą funkcji, więc analiza macierzy korelacji stała się bardzo trudna. Chcę wykreślić macierz korelacji, którą otrzymamy za pomocą funkcji dataframe.corr()
z biblioteki pandas. Czy jest jakaś wbudowana funkcja dostarczana przez Bibliotekę pandas do wykreślania tej macierzy?
12 answers
Możesz użyć pyplot.matshow()
from matplotlib
:
import matplotlib.pyplot as plt
plt.matshow(dataframe.corr())
plt.show()
Edit:
W komentarzach pojawiła się prośba o zmianę etykiet Axis tick. Oto wersja deluxe, która jest rysowana na większym rozmiarze rysunku, ma etykiety osi pasujące do ramki danych i legendę paska kolorów do interpretacji skali kolorów.
Piszę o tym, jak dostosować rozmiar i obrót etykiet, i używam proporcji, która sprawia, że pasek kolorów i główna figura wychodzą tak samo wzrost.
Edycja 2:
Jako df.metoda corr() ignoruje nie-numeryczne Kolumny, .select_dtypes(['number'])
powinna być używana przy definiowaniu etykiet x i y, aby uniknąć niepożądanego przesunięcia etykiet (zawartych w kodzie poniżej).
f = plt.figure(figsize=(19, 15))
plt.matshow(df.corr(), fignum=f.number)
plt.xticks(range(df.select_dtypes(['number']).shape[1]), df.select_dtypes(['number']).columns, fontsize=14, rotation=45)
plt.yticks(range(df.select_dtypes(['number']).shape[1]), df.select_dtypes(['number']).columns, fontsize=14)
cb = plt.colorbar()
cb.ax.tick_params(labelsize=14)
plt.title('Correlation Matrix', fontsize=16);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-08 19:10:08
Jeśli twoim głównym celem jest wizualizacja macierzy korelacji, a nie Tworzenie wykresu per se, wygodny pandas
opcje stylizacji jest realnym rozwiązaniem wbudowanym:
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
Zauważ, że to musi być w backendzie obsługującym renderowanie HTML, takim jak Notatnik JupyterLab. (Automatyczny jasny tekst na ciemnym tle pochodzi z istniejącej PR, a nie najnowszej wersji, pandas
0.23).
Stylizacja
Można łatwo ograniczyć precyzję cyfr:
corr.style.background_gradient(cmap='coolwarm').set_precision(2)
Lub pozbądź się całkowicie cyfr, jeśli wolisz matrycę bez adnotacji:
corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})
Dokumentacja stylów zawiera również instrukcje bardziej zaawansowanych stylów, na przykład jak zmienić wyświetlanie komórki, nad którą znajduje się wskaźnik myszy. Aby zapisać wyjście, możesz zwrócić kod HTML, dołączając render()
metoda, a następnie zapisać go do pliku(lub po prostu zrobić zrzut ekranu dla mniej formalnych celów).
Porównanie czasu
W moich testach style.background_gradient()
był 4x szybszy niż plt.matshow()
i 120x szybszy niż sns.heatmap()
z matrycą 10x10. Niestety nie skaluje się tak dobrze jak plt.matshow()
: obie matryce zajmują mniej więcej ten sam czas dla matrycy 100x100, a plt.matshow()
jest 10x Szybsze dla matrycy 1000x1000.
Zapisywanie
Istnieje kilka możliwych sposobów, aby zapisać stylizowane dataframe:
- zwraca kod HTML, dołączając metodę
render()
, a następnie zapisuje wyjście do pliku. - Zapisz jako plik
.xslx
z formatowaniem warunkowym poprzez dodanie metodyto_excel()
. - Połącz z imgkit, aby zapisać bitmapę
- Zrób zrzut ekranu (dla mniej formalnych celów).
Aktualizacja dla pand >= 0.24
Ustawiając axis=None
, można teraz obliczyć kolory na podstawie całej matrycy, a nie na kolumna lub w wierszu:
corr.style.background_gradient(cmap='coolwarm', axis=None)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-20 05:28:21
Wersja heatmap Seaborna:
import seaborn as sns
corr = dataframe.corr()
sns.heatmap(corr,
xticklabels=corr.columns.values,
yticklabels=corr.columns.values)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-24 22:45:06
Wypróbuj tę funkcję, która wyświetla również nazwy zmiennych dla macierzy korelacji:
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-13 13:16:16
Można zaobserwować zależność między cechami, rysując mapę ciepła z seaborna lub macierz rozproszenia z pand.
Macierz Rozpraszania:
pd.scatter_matrix(dataframe, alpha = 0.3, figsize = (14,8), diagonal = 'kde');
Jeśli chcesz również wizualizować skośność każdej funkcji-Użyj pairplotów seaborn.
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)
Wyjściem będzie Mapa korelacji cech. czyli patrz poniższy przykład.
Korelacja między produktami spożywczymi i detergentami jest wysoka. Podobnie:
Pdodukty O Wysokiej Korelacji:- Artykuły spożywcze i detergenty.
- mleko i produkty spożywcze
- mleko i Detergenty_papier
- mleko i Delikatesy Mrożone i świeże. Mrożonki i Delikatesy.
From Pairplots: możesz obserwować ten sam zbiór relacji z pairplots lub macierzy rozproszonej. Ale z nich możemy powiedzieć, że czy dane są normalnie dystrybuowane lub nie.
Uwaga: powyższy wykres jest tym samym wykresem pobranym z danych, który jest używany do rysowania heatmap.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-23 13:54:05
Dla kompletności, najprostsze rozwiązanie jakie znam z seaborn z końca 2019 roku, jeśli ktoś używa Jupyter :
import seaborn as sns
sns.heatmap(dataframe.corr())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-08 08:01:37
Jeśli dataframe jest df
możesz po prostu użyć:
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(15, 10))
sns.heatmap(df.corr(), annot=True)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-15 21:06:18
Możesz użyć metody imshow () z 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()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-19 05:20:29
Statmodels grafika daje również ładny widok macierzy korelacji
import statsmodels.api as sm
import matplotlib.pyplot as plt
corr = dataframe.corr()
sm.graphics.plot_corr(corr, xnames=list(corr.columns))
plt.show()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-18 05:07:05
Wraz z innymi metodami dobrze jest również mieć parplot, który da wykres punktowy dla wszystkich przypadków -
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-24 07:11:20
Form correlation matrix, w moim przypadku zdf jest ramką danych, która musi wykonać macierz korelacji.
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)
Wtedy możemy zrobić zrzut ekranu. lub przekonwertować html na plik obrazu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-05 04:56:26
Zaskoczony, że nikt nie wspomniał o bardziej zdolnych, interaktywnych i łatwiejszych w użyciu alternatywach.
A) możesz użyć plotly:
-
Tylko dwie linijki i otrzymujesz:
-
Interaktywność,
-
Gładka skala,
-
Kolory oparte na całej ramce danych zamiast pojedynczych kolumn,
-
Nazwy kolumn i indeksy wierszy na osiach,
-
Zooming w,
-
Panning,
-
Wbudowana możliwość zapisania go jednym kliknięciem w formacie PNG,
-
Automatyczne skalowanie,
-
Porównanie na zawisanie,
-
Bąbelki pokazujące wartości, dzięki czemu heatmap nadal wygląda dobrze i widać wartości gdziekolwiek chcesz:
import plotly.express as px
fig = px.imshow(df.corr())
fig.show()
B) Możesz również użyć Bokeh:
Wszystkie te same funkcje z trochę dużo kłopotów. Ale nadal warto, jeśli nie chcesz do opt-in for plotly and still want all these things:
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import ColumnDataSource, LinearColorMapper
from bokeh.transform import transform
output_notebook()
colors = ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a', '#1a9641']
TOOLS = "hover,save,pan,box_zoom,reset,wheel_zoom"
data = df.corr().stack().rename("value").reset_index()
p = figure(x_range=list(df.columns), y_range=list(df.index), tools=TOOLS, toolbar_location='below',
tooltips=[('Row, Column', '@level_0 x @level_1'), ('value', '@value')], height = 500, width = 500)
p.rect(x="level_1", y="level_0", width=1, height=1,
source=data,
fill_color={'field': 'value', 'transform': LinearColorMapper(palette=colors, low=data.value.min(), high=data.value.max())},
line_color=None)
color_bar = ColorBar(color_mapper=LinearColorMapper(palette=colors, low=data.value.min(), high=data.value.max()), major_label_text_font_size="7px",
ticker=BasicTicker(desired_num_ticks=len(colors)),
formatter=PrintfTickFormatter(format="%f"),
label_standoff=6, border_line_color=None, location=(0, 0))
p.add_layout(color_bar, 'right')
show(p)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-26 00:22:00