数据挖掘实战<1>:数据质量检查

数据行业有一句很经典的话——“垃圾进,垃圾出”(Garbage in, Garbage out, GIGO),意思就是,如果使用的基础数据有问题,那基于这些数据得到的任何产出都是没有价值的。而对于数据分析挖掘而言,只有一份高质量的基础数据,才可能得到正确、有用的结论。本文主要介绍数据质量检查的基本思路和方法,并基于Python进行具体实现。
另外,数据质量检查是数据治理中的一个重要课题,涉及内容广,由于笔者经验水平有限,本文不做涉及,只从分析挖掘中的数据质量检查工作说起。

数据质量检查是在完成宽表数据开发后进行的,主要包括四个方面:重复值检查、缺失值检查、数据倾斜问题、异常值检查。

1. 重复值检查

1.1 什么是重复值

重复值的检查首先要明确一点,即重复值的定义。对于一份二维表形式的数据集来说,什么是重复值?主要有两个层次
① 关键字段出现重复记录,比如主索引字段出现重复;
② 所有字段出现重复记录。
第一个层次是否是重复,必须从这份数据的业务含义进行确定。比如一张表,从业务上讲,一个用户应该只会有一条记录,那么如果某个用户出现了超过一条的记录,那么这就是重复值。第二个层次,就一定是重复值了。

1.2 重复值产生的原因

重复值的产生主要有两个原因,一是上游源数据造成的,二是数据准备脚本中的数据关联造成的。从数据准备角度来看,首先检查数据准备的脚本,判断使用的源表是否有重复记录,同时检查关联语句的正确性和严谨性,比如关联条件是否合理、是否有限定数据周期等等。
比如:检查源表数据是否重复的SQL:

SELECT MON_ID,COUNT(*),COUNT(DISTINCT USER_ID)
FROM TABLE_NAME
GROUP BY MON_ID;

如果是上游源数据出现重复,那么应该及时反映给上游进行修正;如果是脚本关联造成的,修改脚本,重新生成数据即可。
还有一份情况,这份数据集是一份单独的数据集,并不是在数据仓库中开发得到的数据,既没有上游源数据,也不存在生成数据的脚本,比如公开数据集,那么如何处理其中的重复值?一般的处理方式就是直接删除重复值。

import pandas as pd
dataset = pd.read_excel("/labcenter/python/dataset.xlsx")
#判断重复数据
dataset.duplicated()    #全部字段重复是重复数据
dataset.duplicated(['col2'])    #col2字段重复是重复数据
#删除重复数据
dataset.drop_duplicates()     #全部字段重复是重复数据
dataset.drop_duplicates(['col2'])   #col2字段重复是重复数据

附:本文数据集:dataset.xlsx


2. 缺失值检查

缺失值主要是指数据集中部分记录存在部分字段的信息缺失。

2.1 缺失值出现的原因

出现趋势值主要有三种原因
① 上游源系统因为技术或者成本原因无法完全获取到这一信息,比如对用户手机APP上网记录的解析;
② 从业务上讲,这一信息本来就不存在,比如一个学生的收入,一个未婚者的配偶姓名;
③ 数据准备脚本开发中的错误造成的。
第一种原因,短期内无法解决;第二种原因,数据的缺失并不是错误,无法避免;第三种原因,则只需通过查证修改脚本即可。
缺失值的存在既代表了某一部分信息的丢失,也影响了挖掘分析结论的可靠性与稳定性,因此,必须对缺失值进行处理。
如果缺失值记录数超过了全部记录数的50%,则应该从数据集中直接剔除掉该字段,尝试从业务上寻找替代字段;
如果缺失值记录数没有超过50%,则应该首先看这个字段在业务上是否有替代字段,如果有,则直接剔除掉该字段,如果没有,则必须对其进行处理。

#查看哪些字段有缺失值   
dataset.isnull().any()    #获取含有NaN的字段
#统计各字段的缺失值个数
dataset.isnull().apply(pd.value_counts)
#删除含有缺失值的字段
nan_col = dataset.isnull().any()
dataset.drop(nan_col[nan_col].index,axis=1)

2.2 缺失值的处理

缺失值的处理主要有两种方式:过滤和填充。

(1)缺失值的过滤

直接删除含有缺失值的记录,总体上会影响样本个数,如果删除样本过多或者数据集本来就是小数据集时,这种方式并不建议采用。

#删除含有缺失值的记录
dataset.dropna()

(2)缺失值的填充

缺失值的填充主要三种方法
① 方法一:使用特定值填充
使用缺失值字段的平均值、中位数、众数等统计量填充。
优点:简单、快速;
缺点:容易产生数据倾斜;
② 方法二:使用算法预测填充
将缺失值字段作为因变量,将没有缺失值字段作为自变量,使用决策树、随机森林、KNN、回归等预测算法进行缺失值的预测,用预测结果进行填充。
优点:相对精确
缺点:效率低,如果缺失值字段与其他字段相关性不大,预测效果差
③ 方法三:将缺失值单独作为一个分组,指定值进行填充
从业务上选择一个单独的值进行填充,使缺失值区别于其他值而作为一个分组,从而不影响算法计算。
优点:简单,实用
缺点:效率低

#使用Pandas进行特定值填充
dataset.fillna(0)   #不同字段的缺失值都用0填充
dataset.fillna({'col2':20,'col5':0})    #不同字段使用不同的填充值
dataset.fillna(dataset.mean())   #分别使用各字段的平均值填充
dataset.fillna(dataset.median())     #分别使用个字段的中位数填充

#使用sklearn中的预处理方法进行缺失值填充(只适用于连续型字段)
from sklearn.preprocessing import Imputer
dataset2 = dataset.drop(['col4'],axis=1)
colsets = dataset2.columns
nan_rule1 = Imputer(missing_values='NaN',strategy='mean',axis=0)    #创建填充规则(平均值填充)
pd.DataFrame(nan_rule1.fit_transform(dataset2),columns=colsets)    #应用规则
nan_rule2 = Imputer(missing_values='median',strategy='mean',axis=0) #创建填充规则(中位数填充)
pd.DataFrame(nan_rule2.fit_transform(dataset2),columns=colsets)    #应用规则
nan_rule3 = Imputer(missing_values='most_frequent',strategy='mean',axis=0)  #创建填充规则(众数填充)
pd.DataFrame(nan_rule3.fit_transform(dataset2),columns=colsets)    #应用规则


3. 数据倾斜问题

数据倾斜是指字段的取值分布主要集中在某个特定类别或者特定区间。

3.1 数据倾斜问题的原因

出现这一问题的原因主要有三种
① 上游源数据存在问题;
② 数据准备脚本的问题;
③ 数据本身的分布就是如此。
如果某个字段出现数据倾斜问题,必须首先排查上述第一、二种原因,如果都没有问题或者无法检查(如:单独的数据集),那么就要考虑这个字段对后续的分析建模是否有价值。一般来说,有严重的数据倾斜的字段对目标变量的区分能力很弱,对分析建模的价值不大,应该直接剔除掉。

3.2 如何衡量数据的倾斜程度

衡量数据的倾斜程度,主要采用频数分析方法,但因数据类别的不同而有所差异:
① 针对连续型字段,需要首先采用等宽分箱方式进行离散化,然后计算各分箱的记录数分布;
② 针对离散型字段,直接计算各类别的记录数分布。
一般来说,如果某个字段90%以上的记录数,主要集中在某个特定类别或者特定区间,那么这个字段就存在严重的数据倾斜问题。

#对于连续型变量进行等宽分箱
pd.value_counts(pd.cut(dataset['col3'],5))  #分成5箱
#对于离散型变量进行频数统计
pd.value_counts(dataset['col4'])


4. 异常值检查

异常值是指数据中出现了处于特定分布、范围或者趋势之外的数据,这些数据一般会被成为异常值、离群点、噪音等。

4.1 异常值产生的原因

异常值的产生主要有两类原因
① 数据采集、生成或者传递过程中发生的错误;
② 业务运营过程出现的一些特殊情况。
将第一种原因产生的异常值称为统计上的异常,这是错误带来的数据问题,需要解决;将第二种原因产生的异常值称为业务上的异常,反映了业务运营过程的某种特殊结果,它不是错误,但需要深究,在数据挖掘中的一种典型应用就是异常检测模型,比如信用卡欺诈,网络入侵检测、客户异动行为识别等等。

4.2 异常值的识别方法

异常值的识别方法主要有以下几种:

(1)极值检查

主要检查字段的取值是否超出了合理的值域范围。
① 方法一:最大值最小值
使用最大值、最小值进行判断。比如客户年龄的最大值为199岁,客户账单的最小费用为-20,这些都明显存在异常。
② 方法二:3σ原则
如果数据服从正态分布,在3σ原则下,异常值被定义为与平均值的偏差超过了3倍标准差的值。这是因为,在正态分布的假设下,具体平均值3倍标准差之外的值出现的概率低于0.003,属于极个别的小概率事件。
③ 方法三:箱线图分析
箱线图提供了识别异常的标准:异常值被定义为小于下四分位-1.5倍的四分位间距,或者大于上四分位+1.5倍的四分位间距的值。
箱线图分析不要求数据服从任何分布,因此对异常值的识别比较客观。

#计算相关统计指标
statDF = dataset2.describe()  #获取描述性统计量
statDF.loc['mean+3std'] = statDF.loc['mean'] + 3 * statDF.loc['std']  #计算平均值+3倍标准差
statDF.loc['mean-3std'] = statDF.loc['mean'] - 3 * statDF.loc['std']  #计算平均值-3倍标准差
statDF.loc['75%+1.5dist'] = statDF.loc['75%'] + 1.5 * (statDF.loc['75%'] - statDF.loc['25%'])  #计算上四分位+1.5倍的四分位间距
statDF.loc['25%-1.5dist'] = statDF.loc['25%'] - 1.5 * (statDF.loc['75%'] - statDF.loc['25%'])  #计算下四分位-1.5倍的四分位间距
#获取各字段最大值、最小值
statDF.loc[['max','min']]
#判断取值是否大于平均值+3倍标准差
dataset3 = dataset2 - statDF.loc['mean+3std']
dataset3[dataset3>0]
#判断取值是否小于平均值-3倍标准差
dataset4 = dataset2 - statDF.loc['mean-3std']
dataset4[dataset4<0]
#判断取值是否大于上四分位+1.5倍的四分位间距
dataset5 = dataset2 - statDF.loc['75%+1.5dist']
dataset5[dataset5>0]
#判断取值是否小于下四分位-1.5倍的四分位间距
dataset6 = dataset2 - statDF.loc['25%-1.5dist']
dataset6[dataset6<0]

(2)记录数分布检查

主要检查字段的记录数分布是否超出合理的分布范围,包括三个指标:零值记录数、正值记录数、负值记录数。

(3)波动检查

波动检查主要适用于有监督的数据,用于检查随着自变量的变化,因变量是否发生明显的波动情况。
以上异常值的识别方法主要针对连续型的字段,而对于离散型的字段的异常识别主要通过检查类别出现是否出现了合理阈值外的数据,比如苹果终端型号字段,出现了“P20”的取值。

4.3 异常值的处理

对于统计上的异常值的处理,主要采取两种方式:剔除或者替换。剔除是指直接将被标记为异常值的记录从数据集中删除掉,而替换是指将异常值用一个非异常值进行替换,比如边界值,或者有监督情况下的目标变量表征相似的某个值。
对于业务上的异常值的处理,原则就是进行深入探索分析,查找出现这一特殊情况的根本原因。


5.参考与感谢

[1] Python数据分析与数据化运营
[2] Python数据分析与数据挖掘实战





猜你喜欢

转载自www.cnblogs.com/hbsygfz/p/8909761.html
今日推荐