数据预处理主要内容包括数据清洗,数据集成,数据变换和数据规约。

数据清洗主要删除原始数据中的缺失数据,异常值,重复值,与分析目标无关的数据。

处理缺失数据

处理缺失数据处理缺失数据有三种方法,删除记录,数据插补和不处理。这里主要详细说明缺失值的删除。

删除

处理缺失值要事先知道数据缺失的原因,比如用户调查问卷里的缺失值是因为被调查者回答问题时漏掉了一个问题选项,那么这个缺失值就代表了该用户没有回答该问题,而信用卡激活日期的缺失,不能表明是丢失了信用卡的激活日期,按照系统的计算逻辑来看,凡是还没有激活的信用卡,其激活日期都记为缺失的,即NULL,还有的缺失是因为系统本身的计算错误造成的,比如某个字段除以零,某个负数取对数等错误的数学运算直接删除带有缺失值的某行数据,这种方法删除方法的好处就是删除后得数据都是完整的数据,不存在缺失数据,但是最大的不足之处就是如果缺失数据存在很大的比例,删除后会导致后面用于挖掘的数据过少,不足于进行有效的分析,其次直接删除可能会误删掉重要的信息。直接删除带有大量缺失值的变量,这种方法只针对那些缺失值占比超过20%或更多的变量,另外是否删除要结合其商业应用价值,比如删除信用卡未激活日期的这个变量,这个变量代表该用户属于未激活卡的用户群体,是带有一定商业价值的,那么如果删除会因此得不偿失。

缺失值替换

分类型变量:用众数或者一个新的类别去代替缺失值对于次序型变量和区间型变量而言,用中间值,众数,最大值,最小值,平均值,新定义的其他值来代替缺失值,这样做的好处在于简单直观,有依据,比如用众数代替,众数本身说明该值出现的几率最大。

对缺失值进行赋值

这种方法将通过例如回归模型,决策树模型,贝叶斯定理等去预测缺失值的最近替代值,也就是把缺失数据所对应的变量当做目标变量,把其他的输入变量当做自变量。为每个缺失值赋值的字段分别建立预测模型。从理论上看,该种方法最严谨,但是成本较高。是否采用该方法要与业务背景相结合。

数据转换由于原始数据,在此主要是指区间型变量的分布不光滑(或有噪声),不对称分布,也使得数据转化成为一种必需的技术手段数据转换主要分为以下四大类:

1. 产生新变量

2. 改善数据分布特征,主要针对不对称分布的转换

3. 区间型变量的分箱转换

4. 数据标准化,主要是0,1均值化产生新变量:根据原始数据,通过数学公式推导,产生更加具有商业意义的新变量。

比如对用户的出生年月日进行处理,把当前的年月日减去用户出生年月日,得到一个新的字段’用户年龄’常用的衍生变量有:用户月均,年均消费金额和消费次数家庭人均年收入用户在线交易终止的次数占用户在线交易成功次数的比例用户下单付费的次数占用户下单次数的比例用户在制定商品类目的消费金额占其他全部消费金额的比例。

改善数据分布特征

通过取对数,开平方根,取倒数,开平方,取指数的方法使得不对称分布的数据呈现(或近似)正态分布,并形成倒钟形曲线。

分箱转换

分箱转换就是把区间型变量转换成次序型变量,转换目的如下:降低变量的复杂性,简化数据,比如一组用户的年龄,原始数据是区间型的,从20-80岁,每1岁的都是一个年龄段,如果通过分箱转换,每10岁构成一个年龄组,就可以有效简化数据,尤其是当自变量与因变量之间有比较明显的非线性关系时,分箱操作可用于探索和发现这些相关系性。

数据的标准化

数据标准化的目的就是将数据按照比例进行缩放,使之落入一个小的区间范围之内,使得不同的变量经过标准化处理后可以有平等分析和比较的基础。标准化转换主要俩种方式:

1.离差标准化

2.0-1均值化

在数据清洗的时候:

1. 缺失值

在我们经常填充缺失值的时候,我们会在使用Pandas会经常使用到fillna函数:

填充固定值:

data.fillna(0, inplace=True) # 填充 0

填充均值:

data.fillna(data.mean(),inplace=True) # 填充均值

填充中位数:

data.fillna(data.median(),inplace=True) # 填充中位数

填充众数:

data.fillna(data.mode(),inplace=True) # 填充众数

填充上下条数据:

data.fillna(method=’pad’, inplace=True) # 填充前一条数据的值,但是前一条也不一定有值

填充 knn 数据

from fancyimpute import KNN

2. 噪声数据

剔除噪声在数据预处理当中也非常重要,在kaggle最近在比的ieee中,剔除噪声数据非常重要。对于模型预测非常重要

主要是因为被这些离群点大大降低了模型预测的泛化能力。

剔除噪声数据经常的方法为:1.分箱;2.回归

3. 格式内容清洗

这部分主要是将不符合模型预测的数据数据进行预处理:

如时间,日期,str格式的数据不能直接用户模型预测,需要将他们进行编码label encoder等

4. 逻辑清洗

逻辑清洗:

(1)去重

(2)删掉极端值

图像数据的预处理一般包括缩放、裁剪、翻转和旋转、模糊、色彩增强、随机噪声和遮挡、mixup、归一化等几个方面。

下面还是以以基于虚拟仿真环境下的自动驾驶交通标志识别https://www.datafountain.cn/competitions/339这个比赛为例,讲一下计算机视觉类比赛的数据预处理。

缩放

这个处理在图像比赛中一般都会用到,交通标志的比赛也不例外,即使没显式的调用resize语句,在detectron或者mmdetection中指定训练尺寸的时候,实际也是进行了resize的。它的一个最大的用处是进行多尺度训练和多尺度测试,看到这个你就知道它的重要性了,在图像类比赛中,就如同空气和水,重要到必不可少的时候,反而有时候被忽略了,实际上它仍无处不在。

裁剪

这个处理对也非常重要,如果能够裁剪的话,通常都会起到非常好的效果。对于交通标志这个比赛裁剪简直可以称得上取胜关键之一了。裁剪可以很大的增加样本的多样性,通常效果都比较明显,而且一个优点是起副作用的时候非常少,不像色彩方面的增强,有的时候基本不起作用,甚至有反作用。

下面是交通标志比赛中在线随机裁剪的主要代码,可能写的比较乱,见谅。

ori_h,ori_w,_=img.shape
x_min=np.min(boxes[:,0])
y_min=np.min(boxes[:,1])
x_max=np.max(boxes[:,2])
y_max=np.max(boxes[:,3])
x_rand_range_min=x_max-self.long_size if x_max-self.long_size>0 else 0
x_rand_range_max=x_min if x_min<=ori_w-self.long_size else ori_w-self.long_size y_rand_range_min=y_max-self.short_size if y_max-self.short_size>0 else 0
y_rand_range_max=y_min if y_min<=ori_h-self.short_size else ori_h-self.short_size crop_x=x_rand_range_min if x_rand_range_min>=x_rand_range_max elsenp.random.randint(x_rand_range_min,x_rand_range_max)
crop_y=y_rand_range_min if y_rand_range_min>=y_rand_range_max elsenp.random.randint(y_rand_range_min,y_rand_range_max)
crop_image=img[crop_y:crop_y+self.short_size,crop_x:crop_x+self.long_size,:]
boxes -= np.tile((crop_x, crop_y), 2)

其中self.short_size、self.short_size为裁剪后的尺寸。

翻转和旋转

翻转一般来说包括水平翻转、垂直翻转,其中水平翻转在detectron、mmdetection等框架都内置了实现,直接设置即可,垂直翻转参照水平翻转的实现,实现起来也很简单。另外交换xy轴(img=img.swapaxes(0,1))也可以算是翻转的一种。

旋转在目标检测比赛中常用的是旋转90度、180度、270度,因为这几个角度的旋转可以保持bbox的大小不变,而旋转随机角度会引起bbox大小的变化,所以在目标检测中并不常用,当然如果有目标的mask信息的话,也是可以使用随机角度的旋转的。

回到交通标志检测这个比赛,在这个比赛中我并没有使用翻转和旋转,因为检测目标中包含有左侧行驶、右侧行驶这类左右对称的目标,所以不能使用默认的左右翻转了,其它的翻转和旋转也存在类似的问题。不过如果自己加上一些特殊的处理的话,这个比赛也是可以使用的,就是在翻转的同时,相应的改一下目标的类别。

模糊

有时在测试集中会包含有一些比较模糊的图片,遇到这种情况,为了能让模型更好的识别,可以在训练的时候对一定比例的图片使用高斯模糊,高斯模糊在一定程度上也可以丰富样本的多样性,当然效果如何还得通过实际测试,在交通标志的比赛中并未使用。

颜色增强

颜色增强一般包括亮度、对比度、饱和度、颜色通道的随机调整,不过颜色增强在目标检测中通常起到的作用并不大,所以还是需要根据实际情况选用。在交通标志的比赛中并未使用图像颜色增强。

Mixup

关于mixup的内容大家可以参考相关论文和代码实现。个人觉得这是一种非常好的数据增强方式,而且使用起来也可以很灵活,比如可以只mixup不带目标的背景,这样目标处理起来就比较简单,有时一样也可以起到不错的效果;扩展开来的话,向背景里粘贴目标什么的也可以算是mixup的一种延申吧。

归一化

这个其实没什么好说的,总之如果是自己写代码话别忘了加上就行了,如果使用已有的框架的话就不用操心了,一般不会少的。