数据分析概述
数据分析完整工作流程
关于数据分析的大体流程这里以图形的形式展现给大家,就不做过多的讲述。
数据探索与相关性分析
这一部分是直接从数据分析工作流程中的数据整理与清洗开始。
数据探索,探索性数据分析(Exploratory Data Analysis),简称EDA。传统的统计方法是先假定数据服从某种分布,然后运用这种模型进行预测,以概率论为基础,做参数检验。而EDA则是强调数据,“抛开”概率的理论,从数据出发,主要手段是汇总统计,可视化。
在进行EDA时,我们可以分为三个阶段,分别是:
- 数据概况分析
- 单变量分析
- 多变量分析
用图形来展示如下:
接下来跟大家简单的分享一下数据探索性分析的流程,下面的所有过程都会使用到Python的pandas包。
数据概况分析
在数据概况分析阶段,我们主要了解数据整体的基本情况,比如数据的离散程度,数据的分布等,以及数据中是否存在异常值/缺失值。这里以二手车价格预测的数据来做个例子。(代码看不懂没关系,看结果就好,不妨碍理解)
#version:python3.6.5
#package:Pandas
#encoding=utf-8
import pandas as pd
#发现csv是以空格分割的
car=pd.read_csv('used_car.csv',sep=' ')
#查看数据维度,整体概况
print(car.shape,'\n','#'*100)
print(car.axes,'\n','#'*100)
print(car.info(),'\n','#'*100)
>>>结果:
(150000, 31) #数据维度,数据有15万行,31列(属性)
###############################################################################################
[RangeIndex(start=0, stop=150000, step=1), Index(['SaleID', 'name', 'regDate', 'model', 'brand', 'bodyType', 'fuelType',
'gearbox', 'power', 'kilometer', 'notRepairedDamage', 'regionCode',
'seller', 'offerType', 'creatDate', 'price', 'v_0', 'v_1', 'v_2', 'v_3',
'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12',
'v_13', 'v_14'],
dtype='object')]
#上面查看的是各属性的名称
###############################################################################################
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 31 columns):
SaleID 150000 non-null int64
name 150000 non-null int64
regDate 150000 non-null int64
model 149999 non-null float64
brand 150000 non-null int64
bodyType 145494 non-null float64
fuelType 141320 non-null float64
gearbox 144019 non-null float64
power 150000 non-null int64
kilometer 150000 non-null float64
notRepairedDamage 150000 non-null object
regionCode 150000 non-null int64
seller 150000 non-null int64
offerType 150000 non-null int64
creatDate 150000 non-null int64
price 150000 non-null int64
v_0 150000 non-null float64
v_1 150000 non-null float64
v_2 150000 non-null float64
v_3 150000 non-null float64
v_4 150000 non-null float64
v_5 150000 non-null float64
v_6 150000 non-null float64
v_7 150000 non-null float64
v_8 150000 non-null float64
v_9 150000 non-null float64
v_10 150000 non-null float64
v_11 150000 non-null float64
v_12 150000 non-null float64
v_13 150000 non-null float64
v_14 150000 non-null float64
dtypes: float64(20), int64(10), object(1)
memory usage: 35.5+ MB
None
#上面查看的是各数值型的数据缺失情况和类型 ###############################################################################################
查看了数据的整体情况,接下来对数据进行描述性统计分析。
#查看数据整体分布情况
np.set_printoptions(suppress=True)
#supress:设置不显示科学记数法|
pd.set_option('display.float_format', lambda x: '%.2f' % x)
car.describe()#用describe方法对整体数据进行描述统计分析
结果如下图所示。
- count:该属性下数据的总数;
- mean:平均数;
- std:标准差,数据的偏离均值程度;
- min~max:中间是四分位数,用于判断样本数据的分布情况和离群值等;
注:上面的描述统计针对的是数值型的变量,不包含类别型变量。
对于类别型的属性,首先查看一下这个属性有什么类别,如果类别数量不多的话,后面可以考虑将它转变为哑变量方便分析和建模。
类别型的统计描述与数值型的数据不一样,具体如下图所示。
类别型数据描述统计的参数含义是:
- unique: 唯一值数
- top: 频数最高者
- freq: 最高频数
单变量分析
连续型数值变量分析
这里我们拿二手车数据的price字段来举个例子,见下图。
无论是单变量分析还是多变量分析阶段,都需要做大量的图对变量进行分析,因为通过图形的展示能够更加的直观看到问题所在。除了上面的直方图,我们还可以采用箱线图对数据进行可视化分析。
通过可视化分析后,如果数据存在离群值,我们可以看看它在数据中的占比,再酌情删除,避免其对后续的模型构建造成影响。
如果变量数据存在缺失值,我们会看看缺失值占比,如果占比不高,我们可以通过填充均值的方式(适用于数值型(连续型)变量)来对缺失值进行填充。
离散型变量分析
对于离散型变量,我们可以用value_counts()函数来统计各类别数量和占总数比,也可以用直方图来进行可视化分析,如下图所示,X轴即为离散型变量的值。
如果离散型数据的类别过多,我们可以用先验知识查看各类别型数据,找到其区分点,对其进行一个特征衍生。
举个例子,如下,是邮箱属性下的类别数值。
df.xx.value_counts()
>>>结果:
邮箱 总数
gmail.com 61738
hotmail.com 25657
anonymous.com 19115
yahoo.com 9563
aol.com 3538
outlook.com 2504
comcast.net 1701
icloud.com 1422
yahoo.com.mx 1235
msn.com 846
live.com.mx 710
live.com 682
sbcglobal.net 611
verizon.net 582
me.com 539
att.net 440
outlook.es 420
cox.net 395
hotmail.fr 374
bellsouth.net 373
hotmail.es 303
web.de 277
mail.com 219
mac.com 212
hotmail.co.uk 212
ymail.com 198
yahoo.fr 178
optonline.net 163
gmx.de 150
charter.net 136
gmail 101
prodigy.net.mx 96
earthlink.net 91
hotmail.de 88
embarqmail.com 72
yahoo.co.jp 71
yahoo.es 67
yahoo.de 64
juno.com 58
frontier.com 58
rocketmail.com 57
windstream.net 57
live.fr 50
roadrunner.com 48
servicios-ta.com 45
假设通过先验知识,我们得知到某个邮箱类别是匿名的,那么我们就可以将这个邮箱属性里的类别分为两类,一类是无匿名的,一类是匿名的,经过处理后,便衍生除了一个新的特征——邮箱是否匿名,同时也方便了对值多的离散型变量的处理。
相关性分析
一般来说,相关性分析是我们建模前的最后一个步骤。为什么要相关性分析呢?
当特征(属性)间的相关性达到0.99甚至1这种程度时,需要对特征(属性)进行删除处理。当特征(属性)相关性高时,模型会偏向采样这些高相关的特征,导致最后模型会依赖这些相关性高的特征,最终结果就是降低模型的泛化性能。
通过删除高相关性的数据,一方面可以节约内存,另一方面可以提高算法模型的泛化能力。
关于计算相关性的一个问题
最好使用全量数据进行相关性计算。
Pandas的corr函数(采用的是皮尔逊相关系数)计算相关性存在一个问题,就是如果两个特征存在较多的缺失值,那么计算出来的结果的偏差是很大的。举个例子:
#version:python3.6
#packages:pandas
#encoding=utf-8
#相关性计算
dataframe.feature1=[2,4,5,np.nan,np.nan]
dataframe.feature2=[np.nan,np.nan,5,6]
df=dataframe[['feature1','feature2']]
print(df.corr())
>>>1
相关系数只会计算二者都不缺失的位置,对于上面的相关性计算来说,也就是5,那么算出来的结果是1。
显然这是错误的,所以我们要先进行缺失值的搜索,把缺失值恰好完全相同的特征放在一起,这样后续我们进行相关性的计算才是合理的
类别型数据的相关性无法使用皮尔逊相关系数去计算,需要使用一些特殊的指标去衡量。
相关性分析的可视化结果如下,采用的是热力图。
关于相关性高特征删除的一个问题
当两个特征,假设C1和C2两个特征相关性达到0.97,那么此时该删除哪个特征呢?
看C1和C2完全不相同的取值有多少个。
cols=['C1','C2']
for col in cols:
print(dataframe[col].unique().shape[0])
>>> 1495
1167
这里选择删除C4,对于数来说,取值不同的越多,相对来说可能分裂的地方也就越多,也就意味着这个特征包含的信息量越多。
当然也可以看特征的IV值,但是较为麻烦,计算耗费时间,还不如用上面的方法,更加方便快速。
建模
一般情况下,在经过探索性数据分析和相关性分析后,我们就可以利用数据进行建模分析了。在建模分析或者说数据分析开始前,我们第一个需要明确的,就是我们为什么要进行数据分析,我们数据分析的目的是什么?
拿二手车价格预测举个例子,我们对二手车的数据进行分析,目的就是为了预测某种类型的二手车它大概能卖多少钱?这就是我们建模中的因变量——价格。而二手车的型号、品牌、使用年限等数据就是自变量。
对于建模来说,我们不需要一股脑的把所有的自变量都加入模型当中,并不是喂给模型的自变量越多出来的模型就越壮,它可能会被“撑死”,即表现为训练出来的模型效果不好,跟瞎猜没两样。
我们自变量的投喂是要依据前面的相关性的分析,去除高度一致(相关性高)的自变量中的一个,选取与因变量的相关性高的自变量,来进行建模。
而对于建立的模型的选择,根据你的目的,如果你是对一连串数值的预测,你可以选择线性回归模型,也可以选择CART算法的回归树模型。
如果你是想预测分类数据,且是二分类的问题,比如预测用户是否购买,则采用二元逻辑回归模型,当然,也可以采用使用CART算法的分类树模型。
如果你是想建模解决多分类问题,则也可以采取建立多个决策树模型来解决当然也可以采用多元逻辑回归模型。
如果你是想解决空间数据的分类问题,那么SVM算法模型是个不错的选择。
当然以上都只是我个人的建议,模型并不只局限上面几种。
模型评估
输出为连续型数值的模型评估
建立好模型后,我怎么知道模型的优劣呢?这个时候就需要对建立好的模型进行一个评估,相应的,python的sklearn库中就有相应的评分函数,我们可以调用来计算。
对于模型输出的结果是连续的数值类的模型,我们通常采用偏差均值和绝对值差均值来衡量模型的效果。通过将数据切割为训练集和测试集,测试集的数据拿来进行测试,训练集的数据拿来进行训练模型。
训练集数据训练出来模型后,将测试集的数据投喂给模型,最后得出模型预测的测试集的因变量的数值,我们用Vt表示,而测试集原来的因变量用Vd表示
则绝对值偏差均值为:
则二乘偏差均值为:
模型优化的目标就是使得绝对值偏差(LAD)均值,或者二乘偏差(LSD)均值最小。
对于无划分测试集的输出问连续型的模型评估
这里可以采用K折交叉验证的方法,详情可以自行百度,这里不多解释。
输出结果为离散型数值的模型评估
这里的模型指的就是分类问题的模型,这类模型一般输出结果固定为0(是)或1(否),可以通过划分训练集,测试集的方法直接比对结果就可。
模型优化
对于评估效果不好的模型,一般我们会调整模型的自变量,带入不同的特征(自变量),看看哪个自变量组合对模型输出的结果的准确率最高,就拿哪个自变量组合作为建模变量。
此外,还可以调整模型的迭代次数或通过数据进行一些变换处理,使得模型得到优化。
这里拿二手车价格预测的模型优化前后的可视化展示来做个例子。
这是一开始的模型结果可视化图。
红色的线条是测试集因变量的数据,蓝色的线条是模型预测的测试集的因变量数据,可以看到两种颜色的线条差异较大,说明模型效果并不好。
通过对数据进行一些变换处理后的模型结果可视化如下:
可以发现,经过处理后,模型的性能得到了很大的优化。