用熊猫绘制相关矩阵

我有一个具有大量特征的数据集,因此分析相关矩阵变得非常困难。我想绘制一个相关矩阵,我们从pandas库中使用dataframe.corr()函数得到。pandas库是否提供了任何内置函数来绘制这个矩阵?

761502 次浏览

你可以从matplotlib中使用pyplot.matshow():

import matplotlib.pyplot as plt


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

编辑:

在评论中有一个关于如何更改轴勾标签的请求。这是一个豪华版,它画在一个更大的图形尺寸上,有轴标签来匹配数据框架,还有一个颜色条图例来解释颜色尺度。

我包括如何调整标签的大小和旋转,我正在使用一个图形比例,使颜色条和主要图形出来的高度相同。


< p >编辑2: 由于df.corr()方法忽略非数值列,因此在定义x和y标签时应该使用.select_dtypes(['number']),以避免不必要的标签移位(包括在下面的代码中)
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);

correlation plot example .

试试这个函数,它也会显示相关矩阵的变量名:

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)

Seaborn的热图版本:

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

你可以通过绘制海洋出生的热图或熊猫的散射矩阵来观察特征之间的关系。

散射矩阵:

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

如果你想可视化每个特征的偏度,也可以使用海运配对图。

sns.pairplot(dataframe)

Sns的热图:

import seaborn as sns


f, ax = pl.subplots(figsize=(10, 8))
corr = dataframe.corr()
sns.heatmap(corr,
cmap=sns.diverging_palette(220, 10, as_cmap=True),
vmin=-1.0, vmax=1.0,
square=True, ax=ax)

输出将是特征的相关映射。参见下面的例子。

enter image description here

杂货店和洗涤剂之间的相关性很高。类似的:

高相关性产品:

  1. 杂货和洗涤剂。

相关性中等的产品:

  1. 牛奶和杂货
  2. 牛奶和洗涤剂。纸

低相关性产品:

  1. 牛奶和熟食
  2. 冷冻和新鲜。
  3. 冷冻熟食店。

从配对图中:你可以从配对图或散射矩阵中观察到相同的一组关系。但从这些可以判断数据是否正态分布。

enter image description here

注:上图为取自数据的同一张图,用于绘制热图。

如果你的主要目标是可视化相关矩阵,而不是创建一个图形本身,方便的pandas 样式选择是一个可行的内置解决方案:

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_r', & PuOr_r are other good diverging colormaps

enter image description here

请注意,这需要在支持呈现HTML的后端中,例如JupyterLab Notebook。


样式

您可以轻松地限制数字精度:

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

enter image description here

如果你更喜欢没有注释的矩阵,也可以把数字都去掉:

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

enter image description here

样式文档还包括更高级样式的说明,例如如何更改鼠标指针悬停的单元格的显示。


时间比较

在我的测试中,style.background_gradient()plt.matshow()快4倍,比sns.heatmap()用10x10矩阵快120倍。不幸的是,它的伸缩性不如plt.matshow():对于100x100的矩阵,两者需要相同的时间,而对于1000x1000的矩阵,plt.matshow()要快10倍。


储蓄

有几种可能的方法来保存风格化的数据框架:

  • 通过追加render()方法返回HTML,然后将输出写入文件。
  • 通过追加to_excel()方法保存为带有条件格式的.xslx文件。
  • 结合imgkit保存位图
  • 截屏(就像我在这里所做的那样)。

将整个矩阵的颜色归一化(pandas >= 0.24)

通过设置axis=None,现在可以基于整个矩阵而不是每一列或每一行来计算颜色:

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

enter image description here


单角热图

由于很多人正在阅读这个答案,我想我应该添加一个技巧,如何只显示相关矩阵的一个角落。我发现这个更容易阅读,因为它删除了多余的信息。

# Fill diagonal and upper half with NaNs
mask = np.zeros_like(corr, dtype=bool)
mask[np.triu_indices_from(mask)] = True
corr[mask] = np.nan
(corr
.style
.background_gradient(cmap='coolwarm', axis=None, vmin=-1, vmax=1)
.highlight_null(null_color='#f1f1f1')  # Color NaNs grey
.set_precision(2))

enter image description here

可以使用matplotlib中的imshow()方法

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

如果你的dataframe是df,你可以简单地使用:

import matplotlib.pyplot as plt
import seaborn as sns


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

Statmodels图形也提供了一个很好的相关矩阵视图

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


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

为了完整起见,截至2019年底,我所知道的seaborn最简单的解决方案(如果使用Jupyter):

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

除了其他方法,还有对图也很好,它将给出所有情况下的散点图

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)

形成相关矩阵,在我的情况下,zdf是我需要执行相关矩阵的数据框架。

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)

然后我们可以截屏。或者将HTML转换为图像文件。

令人惊讶的是,没有人提到功能更强、交互性更强、更容易使用的替代品。

A)你可以用plotly:

  1. 只要两行,你就得到:

  2. < p >互动,

  3. < p >光滑的规模,

  4. 颜色基于整个数据框架而不是单个列,

  5. 列名&轴上的行下标,

  6. < p >放大,

  7. < p >平移,

  8. 内置一键保存为PNG格式的功能,

  9. < p >伸缩,

  10. 比较悬停,

  11. 气泡显示值,热图仍然看起来很好,你可以看到

import plotly.express as px
fig = px.imshow(df.corr())
fig.show()

enter image description here

B)你也可以使用Bokeh:

所有相同的功能,只是有点麻烦。但如果你不想选择剧情,仍然想要所有这些东西,这仍然是值得的:

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)

enter image description here

你可以使用seaborn中的heatmap()来查看b/w不同特征的相关性:

import matplot.pyplot as plt
import seaborn as sns


co_matrics=dataframe.corr()
plot.figure(figsize=(15,20))
sns.heatmap(co_matrix, square=True, cbar_kws={"shrink": .5})

请检查下面可读的代码

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(36, 26))
heatmap = sns.heatmap(df.corr(), vmin=-1, vmax=1, annot=True)
heatmap.set_title('Correlation Heatmap', fontdict={'fontsize':12}, pad=12)```


[1]: https://i.stack.imgur.com/I5SeR.png
corrmatrix = df.corr()
corrmatrix *= np.tri(*corrmatrix.values.shape, k=-1).T
corrmatrix = corrmatrix.stack().sort_values(ascending = False).reset_index()
corrmatrix.columns = ['Признак 1', 'Признак 2', 'Корреляция']
corrmatrix[(corrmatrix['Корреляция'] >= 0.7) + (corrmatrix['Корреляция'] <= -0.7)]
drop_columns = corrmatrix[(corrmatrix['Корреляция'] >= 0.82) + (corrmatrix['Корреляция'] <= -0.7)]['Признак 2']
df.drop(drop_columns, axis=1, inplace=True)
corrmatrix[(corrmatrix['Корреляция'] >= 0.7) + (corrmatrix['Корреляция'] <= -0.7)]

我认为有很多好的答案,但我把这个答案添加给那些需要处理特定列和显示不同情节的人。

import numpy as np
import seaborn as sns
import pandas as pd
from matplotlib import pyplot as plt


rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(18, 18))
df= df.iloc[: , [3,4,5,6,7,8,9,10,11,12,13,14,17]].copy()
corr = df.corr()
plt.figure(figsize=(11,8))
sns.heatmap(corr, cmap="Greens",annot=True)
plt.show()

enter image description here

我更喜欢用Plotly,因为它的图表更具交互性,也更容易理解。可以使用下面的代码片段。

import plotly.express as px


def plotly_corr_plot(df,w,h):
fig = px.imshow(df.corr())
fig.update_layout(
autosize=False,
width=w,
height=h,)
fig.show()