数据挖掘(⼆)⽤python实现数据探索:汇总统计和可视化今天我们来讲⼀讲有关数据探索的问题。其实这个概念还蛮容易理解的,就是我们刚拿到数据之后对数据进⾏的⼀个探索的过程,旨在了解数据的属性与分布,发现数据⼀些明显的规律,这样的话⼀⽅⾯有助于我们进⾏数据预处理,另⼀⽅⾯在进⾏特征⼯程时可以给我们⼀些思路。所以这样⼀个过程在数据挖掘中还是蛮有⽤的,相信⼤家在⽹上看过不少数据挖掘⽐赛的Kernel,⼀般⼀上来都先是个数据探索的过程。之前听过⼀个⽼师讲课,说数据探索过程其实可有可⽆,直接预处理猛搞,但典型的⼝嫌体正直,在演⽰⼀个⽐赛的流程时,还是先进⾏了汇总统计及可视化,哈哈哈,其实⼋数据探索归结到数据预处理中也未尝不可。
那回到正题,数据探索主要包括两个⽅⾯
⼀汇总统计牛尾河
⼆数据可视化
我们先对汇总统计涉及的概念进⾏⼀些梳理,然后讲解如何⽤Python完成汇总统计以及常见的数据可视化。就我个⼈经验来说,可视化真的很重要,⽂章写得好不如图画的漂亮。
====================================================================
什么是汇总统计呢?就是⽤单个数或者数的⼩集合去表⽰⼀个⼤的值的集合的特征,其实就是⼀些描述
性的统计量,概念⾮常容易理解,⽐较常见的如下
1 频率和众数
频率就是指某个值出现的次数占总体数值个数或者某个属性为某值的对象占总体对象数⽬的⽐例。频率最⾼对应的值或属性就称之为众数。通常我们会对频率值⽐较极端的情况感兴趣,需要注意的就是对于连续数据通常不存在频率或者众数的概念,不过我们可以通过阈值切分完成离散化再进⾏相关统计。
2 百分位数
百分位数就是指处于对应百分数处的数据所对应的值。这个数据可以很好地帮我们认识数据的分布,主要集中在哪个区域,是否存在很明显的离群点等等。
3 均值和中位数
这两个概念不⽤介绍了吧,⼀个是均值,⼀个是最中间的⼀个数的值或两个数的均值。⽇常⽣活中,⼈们总喜欢⽤均值来表⽰平均⽔平,但这其实有个前提,就是数据是对称分布的,⽽且均值对于离群值很敏感,这就是⼤家会吐槽国家统计局发布的什么地区平均收⼊⽔平的原因,假如马云爸爸⾝家200亿美⾦,浙江省⼈⼝5000万,那马云爸爸⼀个⼈就把均值拉升了400美⾦,你说这个均值的意义
到底在哪⾥啊……相⽐之下,中位数是⼀个更好的衡量指标,相⽐较均值,更能够体现数据中部处于怎样⼀个⽔平。
4 极差和⽅差、
极差就是数据中最⼤值最⼩值之差,可以体现数据分布范围,但是极差由于只涉及最值,所以对于数据分布⽐较倾斜或者存在离群值的时候,并不能很好刻画数据范围。⽽⽅差则是指每个数据与均值之差的平⽅和除以数据数⽬,该数据可以刻画数据的集中程度,但由于它⽤到了均值,所以它同样对离群值很敏感。
5 多元汇总统计
对于包含多个属性的数据,我们当然可以分别计算各项数据的上述属性,但是除此之外,有的时候我们需要各项属性之间的相关程度,这个时候我们通常会⽤到协⽅差矩阵,协⽅差⽤来描述属性之间的线性关系,+1线性正相关,-1线性负相关,0⽆线性相关关系,但相⽐于协⽅差矩阵,相关矩阵更适合表现数据间的相关性,因为它相当于对数据先做了⼀个标准化。
===============================================================================
这⾥⽤到的还是我在之前那个系列⾥⽤烂的鸢尾花数据,哈哈哈,没办法,谁让它简单呢。
这⾥我们⾸先从sklearn⾥引⼊鸢尾花数据,并将其转换成pandas中的dataframe,因为pandas做汇总统计真⼜轻松⼜愉快啊。
1from sklearn.datats import load_iris
2import pandas as pd
3import numpy as np
4from pandas import DataFrame as df
5
6column=load_iris().feature_names
7data=load_iris().data
8target=load_iris().target
9df1=df(data,columns=column)
10df2=df(target,columns=['target'])
word行高
古筝梅花三弄11data_at([df1,df2],axis=1)
12print data_df.shape
13data_df.describe()
结果如下
⾸先介绍以下这个数据吧。鸢尾花数据总共有150个,每个数据对应四个属性,分别是花萼和花瓣的长度与宽度,花的类型有三种。代码中,我们⾸先输出了⼀下原始数据的形状,150⾏5列,然后利⽤describe函数⼀次性输出了多个汇总统计变量。其中唯⼀⼀个要注意的就是count变量代表的是数据中⾮NA值的数量,⽐对该值和数据形状可以知道数据中是否存在⽆效值。⽽对于均值,标准差,极值和
百分位数在第⼀个表中的意义并不⼤,因为它是把三个种类的花⼀起进⾏了计算,并不能看出各个属性对分类的影响,因此我们接下来分别对每种属性进⾏⼀次describe。
1data_df[data_df['target']==0].describe()
2data_df[data_df['target']==1].describe()
3data_df[data_df['target']==2].describe()
结果如下
从这三个表我们就能看出⼀点东西了。对于第⼀种花⽽⾔,它的花瓣长度和宽度远⼩于第⼆种和第三种花,它的最⼤值都不如另外两种的最⼩值⼤,设定⼀个阈值就可以愉快的把第⼀种花与另外两种分开了。⽽第⼆种和第三种则没有那么明显的区分了,只能看出第三种花的每个属性似乎都⽐第⼆种⼤些,当然我们也不苛求⾃⼰光靠数据探索就把分类⼯作完成了啊,不然还要什么算法,光看就好了。当然汇总统计还包括协⽅差和相似矩阵,在python中可以这么算。
v()
()
结果如下
从系数矩阵中也能得到⼀些信息,⽐如花瓣的长度与宽度和⽬标的相关性明显要⾼些,⽽花萼的宽度似乎和⽬标有那么⼀点点负相关,这些都是我们后续分析的线索。
上⾯说的都是⼀些汇总统计量的计算,数据探索中还有很⼤⼀块就是数据的可视化。
对于分类数据⽽⾔,由于我们可以⽤颜⾊或者标记去区别不同的类,所以我们的坐标轴可以全部⽤于属性的表⽰,⽐如说在这⾥我们可以⽤⼀个⼆维图来表⽰每个样本对应的两个属性的分布,假如⽤花瓣的长度和宽度这两个属性,我们⽤python 来画⼀下看看
结果如下
这⾥只是举了⼀个简单的例⼦,相似的我们可以做出所有其他属性的分布。从这个图上我们其实对这个简单的分类问题有了⼀个⼤概的认知,第⼀类在右下⾓与另外两类完全分开,另外两类虽然有所重叠但是也有⼀个基本的范围。但这样的做法有⼀个缺点就是最多拓展到三维空间,也就是说你最多只能表⽰三个属性啊,并我要是属性多了想看看这种综合的影响该怎么做呢,在数据量不多的时候有⼀个⽐较有效的办法叫做平⾏坐标系法,与之前的情况的不同在于,之前各属性的坐标轴是相互正交的,⽤点去表⽰⼀个样本,⽽平⾏坐标轴各属性的坐标轴是平⾏的,因此⽤⼀条线来代表⼀个样本,下⾯是我强⾏画的⼀个图。
1
from matplotlib import pyplot as plt 2
今宵剩把银釭照plt.plot(data_df[data_df['target']==0]['petal length (cm)'],data_df[data_df['target']==0]['petal width (cm)'],'r*',label='0')3
plt.plot(data_df[data_df['target']==1]['petal length (cm)'],data_df[data_df['target']==1]['petal width (cm)'],'ro',label='1')4
plt.plot(data_df[data_df['target']==2]['petal length (cm)'],data_df[data_df['target']==2]['petal width (cm)'],'bx',label='2')5
plt.xlabel('petal length (cm)')6
表示声音plt.ylabel('petal width (cm)')7
plt.legend(loc='best')8
1
from matplotlib import pyplot as plt 2
data0=data_df[data_df['target']==0][['pal length (cm)','pal width (cm)','petal length (cm)','petal width (cm)']].T 3
data1=data_df[data_df['target']==1][['pal length (cm)','pal width (cm)','petal length (cm)','petal width (cm)']].T 4
data2=data_df[data_df['target']==2][['pal length (cm)','pal width (cm)','petal length (cm)','petal wi
dth (cm)']].T 6
for i in xrange(0,50):8
plt.plot([0,1,2,3],data0[i],'r-')9
plt.plot([0,1,2,3],data1[i],'b-')10
plt.plot([0,1,2,3],data2[i],'g-')11
12
结果如下
狐狸猎手从这个图⾥我们可以看出来前⾯两个属性交叉⽐较多分起来⽐较困难,后⾯这两个的区分度⽐较⾼,还是⽐较直观的。这⾥画的这个图其实是有我强⾏画的,是有点问题的,⼀旦把这个图例加上就会爆炸了,即使我把dataframe⾥的columns都改了,最后还是会出来很多,也是醉了,不过如果⽤最初的ndarray对象的话没有问题。
其他常见的可视化⽅法还有直⽅图和箱形图等等,在pandas⾥⾯都可以⾮常⽅便的做出来,具体代码如下:
1from matplotlib import pyplot as plt
普通话朗读作品
2plt.hist(data_df[data_df['target']==0]['petal length (cm)'],color='blue',label='Class 0',alpha=0.5,bins=20)
告知函范文3plt.hist(data_df[data_df['target']==1]['petal length (cm)'],color='red',label='Class 1',alpha=0.5,bins=20)
4plt.hist(data_df[data_df['target']==2]['petal length (cm)'],color='green',label='Class 2',alpha=0.5,bins=20)
5plt.legend(loc='best')
7plt.show()
8data_df.boxplot(by='target',layout=(2,2))
9plt.show()
结果如下