使用 pandas 绘制相关矩阵
Plot correlation matrix using pandas
我有一个包含大量特征的数据集,因此分析相关矩阵变得非常困难。我想绘制一个我们使用 pandas 库中的 dataframe.corr()
函数得到的相关矩阵。 pandas 库是否提供任何内置函数来绘制此矩阵?
您可以使用 pyplot.matshow()
来自 matplotlib
:
import matplotlib.pyplot as plt
plt.matshow(dataframe.corr())
plt.show()
编辑:
评论中有关于如何更改轴刻度标签的请求。这是在更大尺寸的图形上绘制的豪华版,具有与数据框匹配的轴标签,以及解释色标的颜色条图例。
我介绍了如何调整标签的大小和旋转,并且我使用的图形比例使颜色栏和主要图形的高度相同。
编辑 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);
试试这个函数,它还会显示相关矩阵的变量名称:
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)
您可以通过绘制来自 seaborn 的热图或来自 pandas 的散点矩阵来观察特征之间的关系。
散点矩阵:
pd.scatter_matrix(dataframe, alpha = 0.3, figsize = (14,8), diagonal = 'kde');
如果您还想可视化每个特征的偏度 - 使用 seaborn pairplots。
sns.pairplot(dataframe)
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)
输出将是特征的相关图。即见下面的例子。
杂货和洗涤剂之间的相关性很高。同样:
具有高相关性的产品:
- 杂货和洗涤剂。
具有中等相关性的产品:
- 牛奶和杂货
- 牛奶和Detergents_Paper
相关性低的产品:
- 牛奶和熟食
- 冷冻和新鲜。
- 冷冻和熟食。
来自 Pairplots:您可以从 pairplots 或散点矩阵观察到相同的关系集。但是从这些我们可以说数据是否是正态分布的。
注:上图是从数据中截取的同一张图,用于绘制热图。
如果您的主要目标是可视化相关矩阵,而不是创建绘图本身,方便的 pandas
styling options 是一个可行的内置解决方案:
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
请注意,这需要在支持渲染的后端中 HTML,例如 JupyterLab Notebook。
造型
您可以轻松限制数字精度:
corr.style.background_gradient(cmap='coolwarm').set_precision(2)
如果您更喜欢没有注释的矩阵,则完全删除数字:
corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})
样式文档还包括更高级样式的说明,例如如何更改鼠标指针悬停在其上的单元格的显示。
时间比较
在我的测试中,使用 10x10 矩阵,style.background_gradient()
比 plt.matshow()
快 4 倍,比 sns.heatmap()
快 120 倍。不幸的是,它的缩放比例不如 plt.matshow()
:对于 100x100 矩阵,两者花费的时间大致相同,而对于 1000x1000 矩阵,plt.matshow()
快 10 倍。
节省
有几种可能的方法来保存程式化数据框:
- Return HTML 通过附加
render()
方法,然后将输出写入文件。
- 通过附加
to_excel()
方法以条件格式保存为 .xslx
文件。
- Combine with imgkit to save a bitmap
- 截图(就像我在这里做的那样)。
标准化整个矩阵的颜色(pandas >= 0.24)
通过设置 axis=None
,现在可以根据整个矩阵而不是每列或每行计算颜色:
corr.style.background_gradient(cmap='coolwarm', axis=None)
单角热图
因为很多人都在阅读这个答案,所以我想我会添加一个关于如何只显示相关矩阵的一个角的提示。我自己发现这更容易阅读,因为它删除了冗余信息。
# 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))
您可以使用 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()
如果你的数据框是 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()
为了完整起见,我知道的最简单的解决方案是 seaborn as of late 2019, if one is using Jupyter:
import seaborn as sns
sns.heatmap(dataframe.corr())
与其他方法一起使用 pairplot 也很好,它将给出所有情况的散点图-
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:
只需两行,您将得到:
互动性,
平滑比例,
基于整个数据框而不是单个列的颜色,
轴上的列名和行索引,
正在放大,
平移,
内置一键保存为PNG格式的功能,
自动缩放,
悬停比较,
显示值的气泡,因此热图看起来仍然不错,您可以看到
任何你想要的值:
import plotly.express as px
fig = px.imshow(df.corr())
fig.show()
B) 你也可以使用散景:
所有相同的功能,只是有点麻烦。但如果你不想选择 plotly 并且仍然想要所有这些东西,那仍然是值得的:
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)
您可以使用 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()
我有一个包含大量特征的数据集,因此分析相关矩阵变得非常困难。我想绘制一个我们使用 pandas 库中的 dataframe.corr()
函数得到的相关矩阵。 pandas 库是否提供任何内置函数来绘制此矩阵?
您可以使用 pyplot.matshow()
来自 matplotlib
:
import matplotlib.pyplot as plt
plt.matshow(dataframe.corr())
plt.show()
编辑:
评论中有关于如何更改轴刻度标签的请求。这是在更大尺寸的图形上绘制的豪华版,具有与数据框匹配的轴标签,以及解释色标的颜色条图例。
我介绍了如何调整标签的大小和旋转,并且我使用的图形比例使颜色栏和主要图形的高度相同。
编辑 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);
试试这个函数,它还会显示相关矩阵的变量名称:
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)
您可以通过绘制来自 seaborn 的热图或来自 pandas 的散点矩阵来观察特征之间的关系。
散点矩阵:
pd.scatter_matrix(dataframe, alpha = 0.3, figsize = (14,8), diagonal = 'kde');
如果您还想可视化每个特征的偏度 - 使用 seaborn pairplots。
sns.pairplot(dataframe)
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)
输出将是特征的相关图。即见下面的例子。
杂货和洗涤剂之间的相关性很高。同样:
具有高相关性的产品:- 杂货和洗涤剂。
- 牛奶和杂货
- 牛奶和Detergents_Paper
- 牛奶和熟食
- 冷冻和新鲜。
- 冷冻和熟食。
来自 Pairplots:您可以从 pairplots 或散点矩阵观察到相同的关系集。但是从这些我们可以说数据是否是正态分布的。
注:上图是从数据中截取的同一张图,用于绘制热图。
如果您的主要目标是可视化相关矩阵,而不是创建绘图本身,方便的 pandas
styling options 是一个可行的内置解决方案:
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
请注意,这需要在支持渲染的后端中 HTML,例如 JupyterLab Notebook。
造型
您可以轻松限制数字精度:
corr.style.background_gradient(cmap='coolwarm').set_precision(2)
如果您更喜欢没有注释的矩阵,则完全删除数字:
corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})
样式文档还包括更高级样式的说明,例如如何更改鼠标指针悬停在其上的单元格的显示。
时间比较
在我的测试中,使用 10x10 矩阵,style.background_gradient()
比 plt.matshow()
快 4 倍,比 sns.heatmap()
快 120 倍。不幸的是,它的缩放比例不如 plt.matshow()
:对于 100x100 矩阵,两者花费的时间大致相同,而对于 1000x1000 矩阵,plt.matshow()
快 10 倍。
节省
有几种可能的方法来保存程式化数据框:
- Return HTML 通过附加
render()
方法,然后将输出写入文件。 - 通过附加
to_excel()
方法以条件格式保存为.xslx
文件。 - Combine with imgkit to save a bitmap
- 截图(就像我在这里做的那样)。
标准化整个矩阵的颜色(pandas >= 0.24)
通过设置 axis=None
,现在可以根据整个矩阵而不是每列或每行计算颜色:
corr.style.background_gradient(cmap='coolwarm', axis=None)
单角热图
因为很多人都在阅读这个答案,所以我想我会添加一个关于如何只显示相关矩阵的一个角的提示。我自己发现这更容易阅读,因为它删除了冗余信息。
# 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))
您可以使用 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()
如果你的数据框是 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()
为了完整起见,我知道的最简单的解决方案是 seaborn as of late 2019, if one is using Jupyter:
import seaborn as sns
sns.heatmap(dataframe.corr())
与其他方法一起使用 pairplot 也很好,它将给出所有情况的散点图-
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:
只需两行,您将得到:
互动性,
平滑比例,
基于整个数据框而不是单个列的颜色,
轴上的列名和行索引,
正在放大,
平移,
内置一键保存为PNG格式的功能,
自动缩放,
悬停比较,
显示值的气泡,因此热图看起来仍然不错,您可以看到 任何你想要的值:
import plotly.express as px
fig = px.imshow(df.corr())
fig.show()
B) 你也可以使用散景:
所有相同的功能,只是有点麻烦。但如果你不想选择 plotly 并且仍然想要所有这些东西,那仍然是值得的:
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)
您可以使用 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()