1. 相关性矩阵存在的必要性

相关性矩阵,又叫做热力图,是关联图中最重要的一张图像,它能够展现多个变量两两之间的相关性

关联图的目标是探索两个事物之间关系,它展示出一个事物随着另一个事物的变化如何变化,
但之前我们描述的关联图:折线图或散点图都只能够分析两个变量之间的相关性。在实际统计学和机器学习应用当中,我们往往需要探求多个变量两两之间的相关性。

关联图展示.png

一个最典型的例子的例子是:在统计建模中,能够使用最小二乘法求解线性回归模型的充分必要条件是特征之间没有相关性(在统计学当中标准的术语叫做共线性),否则模型就会出现偏移,因此往往要先探索相关性,排除相关性,然后再建模

要探索众多变量两两之间的相关性,不太可能对每一组变量都绘制散点图,这样非常低效。

除此之外,即便绘制出了图像,也无法判断出相关性的强弱,即如果相关,究竟有多相关呢?

所以我们要选择更加有效也更加直接的方式:

1. 引入衡量相关性的数学指标:相关系数(Correlation Coefficient)

相关系数是某种类型相关性的数值度量,通常是有界的数字。最为人所知的就是皮尔逊相关系数,这个系数在-1~1之间波动,0表示完全无关,1表示完全正相关,-1表示完全负相关。

2. 绘制相关系数矩阵图,一次性查看所有变量两两之间的相关性

这张图实际上是由相关性矩阵和热力图一起构建的,热力图(heatmap)就是用颜色深浅来表示数值大小的图像

08 矩阵图.png 横坐标:一个数据集中的所有变量(可能包括特征或标签)
纵坐标:一个数据集中的所有变量(可能包括特征或标签)
颜色:颜色越接近红和绿,相关性越强,绿色代表正相关,红色代表负相关,浅黄色代表不相关

2. 导入需要的绘图库 & 导入数据

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib as mpl
  4. import matplotlib.pyplot as plt
  5. import seaborn as sns
  6. large = 22; med = 16; small = 12
  7. params = {'axes.titlesize': large,
  8. 'legend.fontsize': med,
  9. 'figure.figsize': (16, 10),
  10. 'axes.labelsize': med,
  11. 'axes.titlesize': med,
  12. 'xtick.labelsize': med,
  13. 'ytick.labelsize': med,
  14. 'figure.titlesize': large}
  15. plt.rcParams.update(params)
  16. plt.style.use('seaborn-whitegrid')
  17. sns.set_style("white")
  18. %matplotlib inline
  1. #导入数据
  2. df = pd.read_csv("mtcars.csv")
  1. df.head()
mpg cyl disp hp drat wt qsec vs am gear carb fast cars carname
0 4.582576 6 160.0 110 3.90 2.620 16.46 0 1 4 4 1 Mazda RX4 Mazda RX4
1 4.582576 6 160.0 110 3.90 2.875 17.02 0 1 4 4 1 Mazda RX4 Wag Mazda RX4 Wag
2 4.774935 4 108.0 93 3.85 2.320 18.61 1 1 4 1 1 Datsun 710 Datsun 710
3 4.626013 6 258.0 110 3.08 3.215 19.44 1 0 3 1 1 Hornet 4 Drive Hornet 4 Drive
4 4.324350 8 360.0 175 3.15 3.440 17.02 0 0 3 2 1 Hornet Sportabout Hornet Sportabout
  1. # 所用数据集mtcars记录了32种不同品牌的轿车的11个属性
  2. name = ["英里/加仑","气缸数量","排量","总马力","驱动轴比","重量"
  3. ,"1/4英里所用时间","引擎","变速器","前进档数","化油器数量","用油是否高效"
  4. ,"汽车","汽车名称"]
  5. df.columns = name # 替换掉英文的列名
  6. # 英里/加仑:每加仑油耗可以跑的英里数,这个数值越大代表汽车越节能
  7. # 用油是否高效:不难注意到,其实这个特征中的0和1是根据特征英里/加仑来决定的,如果英里/加仑大于4,则用油高效(1),否则用油不高效(0)
  8. # 引擎:分为V(V型)和S(直型)两种,其中1为V型,0为直型
  1. df.head()
英里/加仑 气缸数量 排量 总马力 驱动轴比 重量 1/4英里所用时间 引擎 变速器 前进档数 化油器数量 用油是否高效 汽车 汽车名称
0 4.582576 6 160.0 110 3.90 2.620 16.46 0 1 4 4 1 Mazda RX4 Mazda RX4
1 4.582576 6 160.0 110 3.90 2.875 17.02 0 1 4 4 1 Mazda RX4 Wag Mazda RX4 Wag
2 4.774935 4 108.0 93 3.85 2.320 18.61 1 1 4 1 1 Datsun 710 Datsun 710
3 4.626013 6 258.0 110 3.08 3.215 19.44 1 0 3 1 1 Hornet 4 Drive Hornet 4 Drive
4 4.324350 8 360.0 175 3.15 3.440 17.02 0 0 3 2 1 Hornet Sportabout Hornet Sportabout
  1. (df.汽车 != df.汽车名称).sum()
  1. 0

cars 和 carname 内的数据完全一致,且由于这两列不是数值型变量,在相关性矩阵中不重要

3. 先实现相关性矩阵,再实现热力图

df.corr():实现相关性矩阵

method:填写相关系数类型的参数,可以选择”pearson”,”kendall”,”spearman”

  1. df.corr(method = 'pearson')
英里/加仑 气缸数量 排量 总马力 驱动轴比 重量 1/4英里所用时间 引擎 变速器 前进档数 化油器数量 用油是否高效
英里/加仑 1.000000 -0.858539 -0.867536 -0.787309 0.680312 -0.883453 0.420317 0.669260 0.593153 0.487226 -0.553703 0.730748
气缸数量 -0.858539 1.000000 0.902033 0.832447 -0.699938 0.782496 -0.591242 -0.810812 -0.522607 -0.492687 0.526988 -0.695182
排量 -0.867536 0.902033 1.000000 0.790949 -0.710214 0.887980 -0.433698 -0.710416 -0.591227 -0.555569 0.394977 -0.732073
总马力 -0.787309 0.832447 0.790949 1.000000 -0.448759 0.658748 -0.708223 -0.723097 -0.243204 -0.125704 0.749812 -0.751422
驱动轴比 0.680312 -0.699938 -0.710214 -0.448759 1.000000 -0.712441 0.091205 0.440278 0.712711 0.699610 -0.090790 0.400430
重量 -0.883453 0.782496 0.887980 0.658748 -0.712441 1.000000 -0.174716 -0.554916 -0.692495 -0.583287 0.427606 -0.611265
1/4英里所用时间 0.420317 -0.591242 -0.433698 -0.708223 0.091205 -0.174716 1.000000 0.744535 -0.229861 -0.212682 -0.656249 0.488649
引擎 0.669260 -0.810812 -0.710416 -0.723097 0.440278 -0.554916 0.744535 1.000000 0.168345 0.206023 -0.569607 0.594588
变速器 0.593153 -0.522607 -0.591227 -0.243204 0.712711 -0.692495 -0.229861 0.168345 1.000000 0.794059 0.057534 0.283129
前进档数 0.487226 -0.492687 -0.555569 -0.125704 0.699610 -0.583287 -0.212682 0.206023 0.794059 1.000000 0.274073 0.266919
化油器数量 -0.553703 0.526988 0.394977 0.749812 -0.090790 0.427606 -0.656249 -0.569607 0.057534 0.274073 1.000000 -0.461196
用油是否高效 0.730748 -0.695182 -0.732073 -0.751422 0.400430 -0.611265 0.488649 0.594588 0.283129 0.266919 -0.461196 1.000000
  1. df.corr(method = 'spearman')
英里/加仑 气缸数量 排量 总马力 驱动轴比 重量 1/4英里所用时间 引擎 变速器 前进档数 化油器数量 用油是否高效
英里/加仑 1.000000 -0.910801 -0.908882 -0.894665 0.651455 -0.886422 0.466936 0.706597 0.562006 0.542782 -0.657498 0.803735
气缸数量 -0.910801 1.000000 0.927652 0.901791 -0.678881 0.857728 -0.572351 -0.813789 -0.522071 -0.564310 0.580068 -0.706188
排量 -0.908882 0.927652 1.000000 0.851043 -0.683592 0.897706 -0.459782 -0.723664 -0.624068 -0.594470 0.539778 -0.697788
总马力 -0.894665 0.901791 0.851043 1.000000 -0.520125 0.774677 -0.666606 -0.751593 -0.362328 -0.331402 0.733379 -0.723960
驱动轴比 0.651455 -0.678881 -0.683592 -0.520125 1.000000 -0.750390 0.091869 0.447457 0.686571 0.744816 -0.125223 0.391159
重量 -0.886422 0.857728 0.897706 0.774677 -0.750390 1.000000 -0.225401 -0.587016 -0.737713 -0.676128 0.499812 -0.591733
1/4英里所用时间 0.466936 -0.572351 -0.459782 -0.666606 0.091869 -0.225401 1.000000 0.791571 -0.203332 -0.148200 -0.658718 0.467413
引擎 0.706597 -0.813789 -0.723664 -0.751593 0.447457 -0.587016 0.791571 1.000000 0.168345 0.282662 -0.633695 0.594588
变速器 0.562006 -0.522071 -0.624068 -0.362328 0.686571 -0.737713 -0.203332 0.168345 1.000000 0.807688 -0.064365 0.283129
前进档数 0.542782 -0.564310 -0.594470 -0.331402 0.744816 -0.676128 -0.148200 0.282662 0.807688 1.000000 0.114887 0.326405
化油器数量 -0.657498 0.580068 0.539778 0.733379 -0.125223 0.499812 -0.658718 -0.633695 -0.064365 0.114887 1.000000 -0.484982
用油是否高效 0.803735 -0.706188 -0.697788 -0.723960 0.391159 -0.591733 0.467413 0.594588 0.283129 0.326405 -0.484982 1.000000
  1. df.corr(method = 'kendall')
英里/加仑 气缸数量 排量 总马力 驱动轴比 重量 1/4英里所用时间 引擎 变速器 前进档数 化油器数量 用油是否高效
英里/加仑 1.000000 -0.795313 -0.768131 -0.742813 0.464549 -0.727832 0.315365 0.589679 0.469013 0.433151 -0.504395 0.670744
气缸数量 -0.795313 1.000000 0.814426 0.785186 -0.551318 0.728261 -0.448970 -0.771001 -0.494621 -0.512543 0.465430 -0.669057
排量 -0.768131 0.814426 1.000000 0.665999 -0.498983 0.743382 -0.300815 -0.603306 -0.520274 -0.475980 0.413736 -0.581733
总马力 -0.742813 0.785186 0.665999 1.000000 -0.382627 0.611308 -0.472906 -0.630593 -0.303996 -0.279446 0.595984 -0.607408
驱动轴比 0.464549 -0.551318 -0.498983 -0.382627 1.000000 -0.547150 0.032722 0.375101 0.575548 0.583925 -0.095352 0.327906
重量 -0.727832 0.728261 0.743382 0.611308 -0.547150 1.000000 -0.141988 -0.488479 -0.613879 -0.543596 0.371374 -0.492403
1/4英里所用时间 0.315365 -0.448970 -0.300815 -0.472906 0.032722 -0.141988 1.000000 0.657543 -0.168904 -0.091261 -0.506439 0.388271
引擎 0.589679 -0.771001 -0.603306 -0.630593 0.375101 -0.488479 0.657543 1.000000 0.168345 0.269748 -0.576927 0.594588
变速器 0.469013 -0.494621 -0.520274 -0.303996 0.575548 -0.613879 -0.168904 0.168345 1.000000 0.770788 -0.058599 0.283129
前进档数 0.433151 -0.512543 -0.475980 -0.279446 0.583925 -0.543596 -0.091261 0.269748 0.770788 1.000000 0.098015 0.311492
化油器数量 -0.504395 0.465430 0.413736 0.595984 -0.095352 0.371374 -0.506439 -0.576927 -0.058599 0.098015 1.000000 -0.441537
用油是否高效 0.670744 -0.669057 -0.581733 -0.607408 0.327906 -0.492403 0.388271 0.594588 0.283129 0.311492 -0.441537 1.000000

什么时候用什么相关系数?变量相关时:

分类型变量vs分类型变量 分类型变量vs连续型变量 连续型变量vs连续型变量
列联表分析
卡方检验(chi-squared)
二分类:点双列相关(皮尔逊相关系数的一种特殊情况)
多分类:Kruskal-Wallis H检验(如t检验或方差分析)
线性相关:皮尔逊相关系数
非线性相关:以斯皮尔曼相关系数为代表的一系列等级相关系数

比较特别的是kendall这个相关系数,它对比的是两个变量按数量排序时(从小到大,或者从大到小),数据排序的相似性。
其他相关系数,可以在scipy,numpy库中找到

  1. coef = df.corr()

sns.heatmap:把相关性矩阵放到热力图里去

data:输入的相关性矩阵
cmap:使用的光谱(热力图需要渐变光谱,而不是随机的一组颜色)
center:绘制有色数据时,位于光谱中心的颜色所对应的值,注意:这是一个控制颜色的参数。如果没有指定cmap,使用此参数将更改默认的cmap参数。我们一般在center中填写数据的中值,比如皮尔逊相关系数的取值范围是[-1,1],我们就在center中填写0
annot:如果为True,则在热力图的每个单元格中写入数据值。如果是一个类似于data形状的数组,那么使用它来注释热图而不是原始数据

  1. # 确保正常显示中文+负号
  2. plt.rcParams['font.sans-serif']=['SimHei']
  3. plt.rcParams['axes.unicode_minus']=False
  4. # 绘制图像
  5. plt.figure(figsize = (12, 10), dpi = 80)
  6. sns.heatmap(coef
  7. # , xticklabels = coef.columns # 横坐标标签,此时可不输入
  8. # , yticklabels = coef.columns # 纵坐标标签,此时可不输入
  9. , cmap = 'RdYlGn'
  10. , center = 0 # 控制颜色,而不是控制取值范围
  11. , annot = True)
  12. # 装饰图像
  13. plt.title('mtcars数据集的相关性矩阵', fontsize = 22)
  14. plt.xticks(fontsize = 12
  15. , rotation = 45 # 文字旋转
  16. , horizontalalignment = 'center' # 刻度的相对位置
  17. )
  18. plt.yticks(fontsize = 12)
  1. (array([ 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5,
  2. 11.5]), <a list of 12 Text yticklabel objects>)

output_17_1.png

4. 解读图像

如果人们对家用车最关心的方面是油耗,那买车时该参考哪些属性?

找到和“英里/加仑”这个指标正相关的属性:

  1. 驱动轴比 0.68
  2. 1/4英里所用时间 0.42
  3. 引擎 0.67
  4. 变速器 0.59
  5. 前进档数 0.49
  6. 用油是否高效 0.73 (这个属性由“英里/加仑”计算得出,参考意义不大)

找到和“英里/加仑”这个指标负相关的属性:

  1. 气缸数量 0.86
  2. 排量 0.87
  3. 总马力 0.79
  4. 重量 0.88
  5. 化油器数量 0.55

人们为什么购买大排量汽车?

找到和“排量”这个指标正相关的属性:

  1. 总马力 0.79
  2. 气缸数量 0.9
  3. 重量 0.89
  4. 化油器数量 0.39

找到和“排量”这个指标负相关的属性:

  1. 英里/加仑 0.87
  2. 1/4英里所用时间 0.43
  3. 引擎 0.71
  4. 变速器 0.59
  5. 前进档数 0.56
  6. 驱动轴比 0.71
  7. 用油是否高效 0.73

由上可知,人们为了追求更强的马力、加速更快才购买大排量汽车。那么还有哪些因素影响汽车的马力?

或者说,马力更强的车有哪些特征?

5. 相关性矩阵图在统计学中的应用

删除相关性高的特征

如果一个特征,对其他每一特征都有较高的相关性,那么就可以删除掉这个特征,如

英里/加仑
气缸数量
排量

如果一个特征,与某一特征的相关性很小,那么就可以保留这个特征,如

总马力