【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)

引言

在前文中,我们对数据进行了初步处理,主要针对异常值和缺失值。

在本文中,我们将对数据做进一步处理,主要对特征进行分桶以及标准化。

数据分桶

️数据分桶的原因

离散化连续特征,例如将不同年龄段的人分成不同的类别。

是否使用特征离散化,其实是使用“海量离散特征+简单模型”,还是“少量连续特征+复杂模型”的问题。

对于线性模型,通常使用多特征。

  • 优点:模型简单
  • 缺点:特征工程比较困难。

对于非线性模型(如深度学习),通常使用“少量连续特征+复杂模型”。

  • 优点:不需要复杂的特征工程。
  • 缺点:模型较为复杂。

️无监督数据分桶的方法

等宽分桶

采用同等宽度的不同尺度进行分桶,适合分布比较均匀的特征。例如一个人的年龄可以分为老,中,青三个桶。

这部分可以使用pandas中的cut实现,下面使用二手车数据举例。首先我们观察该数据的分布情况:

train_data['power'].plot.hist()

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第1张图片
然后我们对其,进行等宽分桶,分成6部分。

cut = pd.cut(train_data['power'], 6, labels=False)
cut.plot.hist()

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第2张图片
分桶后分布如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第3张图片
同时也可以自己自定义分桶区间,根据业务逻辑定义分桶:

cut = pd.cut(train_data['power'], [0,100,200,300], labels=False, include_lowest=True)

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第4张图片

等频分桶

有时候数据的分布是不均匀的,所以我们需要首先分析数据的分布情况然后再根据不同的分布进行分桶。

# 分别查看0.1-1之间的分位数的数据个数
w = train_data['power'].describe (percentiles=[i for i in np.arange(0,1,0.1)])[4:]
# 直接传入cut进行分桶
pd.cut(train_data['power'],w,labels=range(10), include_lowest=True)

结果如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第5张图片
分布图如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第6张图片

一维聚类离散化

先聚类(如k-means),然后对每一类的连续值进行标记。把每一类的中心点求出来加上每一类的首尾点构成分箱点,然后使用cut函数进行分箱。

kmodel=sklearn.cluster.KMeans(n_clusters=5)
data = np.array(train_data.loc[:,'power':])
kmodel.fit(data)
c = pd.DataFrame(kmodel.cluster_centers_)
c = c.sort_values(by=0)
# 使用滑动窗口求中心点的中心
c = c.rolling(2).mean()
c = c[0].iloc[1:].append(pd.Series(train_data['power'].min()))
c = c.append(pd.Series(train_data['power'].max()))
c.sort_values()
print(c)
cut = pd.cut(train_data['power'],c.sort_values(), include_lowest=True, labels=False)
cut.plot.hist()

结果如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第7张图片
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第8张图片

️有监督数据分桶的方法

以下两部分,均来自

️卡方分桶

卡方分箱是自底向上的(即基于合并的)数据离散化方法。它依赖于卡方检验:具有最小卡方值的相邻区间合并在一起,直到满足确定的停止准则。

对于精确的离散化,相对类频率在一个区间内应当完全一致。因此,如果两个相邻的区间具有非常类似的类分布,则这两个区间可以合并;否则,它们应当保持分开。而低卡方值表明它们具有相似的类分布。

️best-ks分桶

KS(Kolmogorov-Smirnov)用于模型风险区分能力进行评估,指标衡量的是好坏样本累计部分之间的差距 。KS值越大,表示该变量越能将正,负客户的区分程度越大。

通常来说,KS>0.2即表示特征有较好的准确率。

数据标准化/归一化

️归一化/标准化的原因

  • 当模型的建立过程中用到了距离方面的内容以及使用了梯度下降算法的时候,就需要使用归一化/标准化。
  • 归一化能够加快梯度下降的速度,消除特征间单位和尺度的影响,加快模型学习速度。
  • 有很多模型的目标函数的基础都是假设所有特征都是零均值并且方差的值在同一阶数上的,所以进行标准化处理在一定程度上能够使得模型学习的更好。

虽然大部分机器学习模型都需要做标准化和归一化,也有不少模型可以不做做标准化和归一化,主要是基于概率分布的模型,比如决策树大家族的CART,随机森林等。当然此时使用标准化也是可以的,大多数情况下对模型的泛化能力也有改进。

️归一化/标准化的方法

z-score标准化

将训练集中的数值特征的值缩放成为均值为0,方差为1的状态,几乎所有的线性模型都会用到此标准化。

代码如下:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().fit(train_data)
train_data = scaler.transform(train_data)

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第9张图片

max-min标准化

将训练集中某一列数值特征的值缩放到0和1之间,如果数据的输出结果有要求,数据较为稳定且不存在极端的最大最小值,则使用归一化。

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
train_data = scaler.fit_transform(train_data)

结果如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第10张图片

Mean normalization

将训练集中的数值缩放到[-1,1]零均值之间。

def mean_norm(data, col):
    # data: DataFrame 需要处理的数据
    # col: 需要处理的列名
    # return: DataFrame mean_normed
    data_max = data[col].max()
    data_min = data[col].min()
    data_mean = data[col].mean()
    data[col] = data[col].apply(lambda x:(x - data_mean)/(data_max - data_min))
    return data

print(train_data['power'])
mean_norm(train_data, 'power')['power']
mean_norm(train_data, 'power')['power'].mean()

处理结果如下:
【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第11张图片

单位长度标准化

如果后续的模型构建中需要使用距离,则使得完整向量具有长度1。在一些应用中(例如直方图特征),使用特征向量的L1范数(即曼哈顿距离,城市块长度或出租车几何)可能更实际。

import sklearn
Normalizer = sklearn.preprocessing.Normalizer(norm='l2', copy=True)
Normalize = Normalizer.fit(train_data)
train_data = Normalize.transform(train_data)

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第12张图片

绝对值标准化

专为稀疏数据而生。将每个要素缩放到[-1,1]范围,它不会移动/居中数据,因此不会破坏任何稀疏性。该估计器单独地缩放每个特征,使得训练集中的每个特征的最大绝对值将是1.0。该缩放器也可以应用于稀疏CSR或CSC矩阵。

MaxAbsScaler = sklearn.preprocessing.MaxAbsScaler()
MaxAbsScaler = MaxAbsScaler.fit(train_data)
train_data = MaxAbsScaler.transform(train_data)

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第13张图片

鲁棒性标准化

如果你的数据包含许多异常值,使用均值和方差缩放可能并不是一个很好的选择。这种情况下,你可以使用 robust_scale 以及 RobustScaler 作为替代品。它们对你的数据的中心和范围使用更有鲁棒性的估计。

RobustScaler = sklearn.preprocessing.RobustScaler()
RobustScaler = RobustScaler.fit(train_data)
train_data = RobustScaler.transform(train_data)
train_data

【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)_第14张图片

对数/平方根缩放

对数缩放对于处理长尾分布且取值为正数的数值变量非常有效,它将大端长尾压缩为短尾,并将小端进行延伸,平方根或者对数变换是幂变换的特例,在统计学中都称为方差稳定的变换。

import numpy as np
train_data['fea'] = np.log(train_data['fea']

总结

本文总结了多种不同的数据分桶和标准化的方法,他们都有不同的应用场景,我们应该结合实践经验选择相对应的方法。

另外,从数据处理到构建高效模型系列已经全部更新完毕,感兴趣的朋友可以点击下列链接进行支持一下:

  • 【建议收藏】机器学习数据预处理(一)——缺失值处理方法(内附代码)
  • 【建议收藏】机器学习数据预处理(二)——异常值处理方法(内附代码)
  • 【建议收藏】机器学习数据预处理(三)——数据分桶及数据标准化(内附代码)
  • 【建议收藏】机器学习数据预处理(四)——特征构造(内附代码)
  • 【建议收藏】机器学习数据预处理(五)——特征选择(内附代码)
  • 【建议收藏】机器学习模型构建(一)——建模调参(内附代码)
  • 【建议收藏】机器学习模型构建(二)——模型融合(内附代码)

你可能感兴趣的:(机器学习,机器学习,python,人工智能)