本文以kaggle的入门赛为例,介绍常用于探索数据特征的可视化技巧
泰坦尼克号
数据集下载地址:https://www.kaggle.com/c/titanic/data
首先导入数据(个别输入输出是个人探索的过程,被省略了,例如In[5]直接到In[7]了)
In [1]: %matplotlib
Using matplotlib backend: Qt5Agg
In [2]: import numpy as np
In [3]: import pandas as pd
In [4]: import matplotlib.pyplot as plt
In [5]: train=pd.read_csv('train.csv',dtype={'Age':np.float64})
In [7]: test=pd.read_csv('test.csv',dtype={'Age':np.float64})
In [8]: full_data=[train,test]
柱状图
用途一:查看某字段的各个取值的分布
#对Survived这个Series调用value_counts,返回对该列使用count聚合的结果,返回值是一个新的Series,调用plot绘制柱状图
In [24]: train.Survived.value_counts().plot(kind='bar')
Out[24]: <matplotlib.axes._subplots.AxesSubplot at 0x4cb771bcc0>
In [25]: plt.title('survived (1:survived)') #设置标题
Out[25]: Text(0.5,1,'survived (1:survived)')
In [26]: plt.ylabel('people') #设置y轴的标签(名称)
Out[26]: Text(38.3472,0.5,'people')
类似的代码可以查看乘客的船舱等级分布(先关掉前面生成的窗口)
In [30]: train.Pclass.value_counts().plot(kind='bar')
Out[30]: <matplotlib.axes._subplots.AxesSubplot at 0x4cb748d320>
In [31]: plt.ylabel('people')
Out[31]: Text(38.3472,0.5,'people')
In [32]: plt.title('cabin_level')
Out[32]: Text(0.5,1,'cabin_level')
查看各登船口岸上船的人数
In [30]: train.Embarked.value_counts().plot(kind='bar')
Out[30]: <matplotlib.axes._subplots.AxesSubplot at 0xcaa5cbecc0>
In [31]: plt.title('embarked')
Out[31]: Text(0.5,1,'embarked')
In [32]: plt.ylabel('people')
Out[32]: Text(38.3472,0.5,'people')
用途二:查看某分类字段与类标签的相关性
In [40]: survived_0=train.Pclass[train.Survived==0].value_counts()
In [41]: survived_1=train.Pclass[train.Survived==1].value_counts()
In [42]: df=pd.DataFrame({'survived':survived_1,'not_survived':survived_0})
In [44]: df
Out[44]:
not_survived survived
1 80 136
2 97 87
3 372 119
In [45]: df.plot(kind='bar',stacked=True)
Out[45]: <matplotlib.axes._subplots.AxesSubplot at 0xcaaacab860>
In [46]: plt.title('level-survived')
Out[46]: Text(0.5,1,'level-survived')
In [47]: plt.xlabel('level')
Out[47]: Text(0.5,28.3172,'level')
In [48]: plt.ylabel('people')
Out[48]: Text(38.3472,0.5,'people')
由上图可以看出,不同船舱等级的乘客,对应的获救概率不同(等级为1的橙色获救比例大)。
同理,我们可以查看性别对于获救概率的影响(性别也是分类属性)
In [49]: sur_0=train.Sex[train.Survived==0].value_counts()
In [50]: sur_1=train.Sex[train.Survived==1].value_counts()
In [51]: df=pd.DataFrame({'survived':sur_1,'not_survived':sur_0})
In [52]: df
Out[52]:
not_survived survived
female 81 233
male 468 109
In [53]: df.plot(kind='bar',stacked=True)
Out[53]: <matplotlib.axes._subplots.AxesSubplot at 0xcaa6430fd0>
可以看出,不同性别的乘客获救概率不同(女性橙色比例大,获救概率大)
还可以利用子图来同时查看性别与船舱级别对获救概率的影响,具体见 https://blog.csdn.net/xpy870663266/article/details/89745951
得到效果图如下:
饼状图
对比柱状图,饼图可以更清晰看出比例。同上面例子,这里用饼图来查看不同性别的乘客获救概率。
In [22]: Survive_m=train.Survived[train.Sex=='male'].value_counts()
In [23]: Survive_f=train.Survived[train.Sex=='female'].value_counts()
In [24]: Survive_m
Out[24]:
0 468
1 109
Name: Survived, dtype: int64
In [25]: df=pd.DataFrame({'male':Survive_m,'female':Survive_f})
In [26]: df
Out[26]:
female male
0 81 468
1 233 109
In [28]: df.plot(kind='pie',subplots=True)
Out[28]:
array([<matplotlib.axes._subplots.AxesSubplot object at 0x000000B402CC9710>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000B401A875C0>], dtype=object)
In [29]: plt.show()
手动调整一下图像的大小,得到下图:
明显看得出,女性的橙色比例更大,获救概率更大。
散点图
散点图用于查看字段间的相关性,以及查看离群点情况。
In [34]: plt.scatter(train.Survived,train.Age) #x轴为survived字段(就是我们要预测的字段),y轴为age字段
Out[34]: <matplotlib.collections.PathCollection at 0x4cb779b978>
In [35]: plt.ylabel('age')
Out[35]: Text(47.0972,0.5,'age')
In [43]: plt.grid(axis='y') #给y轴加上参考线
将图片纵向拉长后更加直观的看出未获救人员的年龄分布(x=0那列)与获救人员的年龄分布(x=1那列)
概率密度图
#绘图思路:对Series调用plot(kind='kde')即可得到Series的value的概率密度曲线
#此处先用布尔索引分别选出不同等级船舱的乘客的Age,然后再绘制概率密度曲线
In [24]: train.Age[train.Pclass==1].plot(kind='kde')
Out[24]: <matplotlib.axes._subplots.AxesSubplot at 0x2480022080>
In [25]: train.Age[train.Pclass==2].plot(kind='kde')
Out[25]: <matplotlib.axes._subplots.AxesSubplot at 0x2480022080>
In [26]: train.Age[train.Pclass==3].plot(kind='kde')
Out[26]: <matplotlib.axes._subplots.AxesSubplot at 0x2480022080>
In [27]: plt.xlabel('age')
Out[27]: Text(0.5,23.1922,'age')
In [28]: plt.legend(('level_1','level_2','level_3'),loc='best') #设置图例
Out[28]: <matplotlib.legend.Legend at 0x24800bb358>
热度图
可以将皮尔森相关系数矩阵可视化。皮尔森相关系数的概念以及作用见 https://www.cnblogs.com/renpfly/p/9555959.html
In [275]: import matplotlib.pyplot as plt
In [276]: import seaborn as sns #导入seaborn
In [277]: sns.set() #设置默认参数
In [278]: sns.heatmap(train.corr(),linewidths=0.1,vmax=1.0,square=True,cmap=plt.cm.RdBu,linecolor='white',annot=True)
Out[278]: <matplotlib.axes._subplots.AxesSubplot at 0x167603fc50>
效果图:
heatmap的参数说明:
train为DataFrame,是训练集,corr()求出相关系数矩阵;linewidths和linecolor用于控制单元格之间的间隙的宽度和颜色;square=True确保每个单元格为正方形,annot=True表示在单元格内显示数值
cmap即colormap,可以理解为颜色的变化范围,有很多选项,可以传入字符串或plt.cm.xxx。这里以传入plt.cm.xxx为例,xxx常用的有:
jet(七彩,热度图用这个感觉不太好)
gray(灰)
RdBu(蓝 -> 白 -> 红)
inferno(淡黄 -> 紫 -> 黑)
plasma(金 -> 红 -> 蓝)
viridis(金 -> 绿 -> 蓝)
vmin和vmax用于标定数值变化的最小值与最大值,不指定则自动确定,此处由于是相关系数矩阵,对角线肯定为1,因此我们可以设置vmax为1,让最小值根据数据来自动确定;
用热度图绘制相关系数矩阵之后,可以清晰地看到每对特征之间的(线性)相关性,对于相关系数接近1或-1的多个特征,只需要选择其中一个。
散点图矩阵
泰坦尼克号这个题目不太适合用这个做分析(数值型数据少,分类数据很多)