机器学习之数据预处理python代码

数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限。而特征工程就是使机器学习算法达到最佳性能的特征处理的过程,一般包含了Data数据清洗、数据预处理、特征提取、特征构造、特征选择等内容,本篇主要讨论数据预处理的方法及实现。

而数据预处理主要包含数据标准化、数据特征编码、统计变换等内容,那数据预处理的意义是什么呢?

1. 标准化处理,消除量纲对数据的影响

在实际应用中,样本不同特征的单位不同,会在求距离时造成很大的影响。比如:在两个样本中年龄大小分别为20和25,发现时间分别为180天和360天,那么在求距离时,时间差为180、大小差为5,那么其结果会被时间所主导,因为年龄大小的差距太小了。但是如果我们把时间用年做单位,0.5年与1年的差距又远小于年龄大小的差距,结果又会被年龄大小所主导。

为了避免上述问题对结果造成影响,我们需要对数据做无量纲化处理(标准化)。无量纲化不是说把天数变成年数,而是说,无论是天数还是年数,最后都会变成1,也就是没有了单位。常见的无量纲化方法有标准化和归一化两种。

2. 数据分布更稳定

现实中很多数据的分布是倾斜的,数据分布与均值关系密切,方差不稳定,通过统计变换使原本密集的区间的值尽可能的分散,原本分散的区间的值尽量的聚合,帮助稳定方差等

3.模型算法的需要

大部分算法是基于向量空间中的度量来进行计算的,所以需要数值变量进行距离的计算,所以需要对对不连续的数字或者文本进行编码

1.1 Z-Score标准化
基于原始数据的均值(mean)和标准差(standarddeviation)进行数据标准化,标准化后,其转换成均值为0,方差为1的标准正态分布。

# z-score标准化方法
# 1.多列同时处理
def scale_encoder(col_x):
    x = preprocessing.scale(col_x)
    print(x, '\n', np.mean(x), np.std(x))
    return x
scale_encoder(i_x)


# 2.单列处理
def zscore_encoder(col_x):
    average = float(sum(col_x)) / len(col_x)
    new_x = [(x - average) / np.std(col_x) for x in col_x]
    print(new_x, '\n', np.mean(new_x), np.std(new_x))
    return new_x
zscore_encoder(i_x[:, 0])

在这里插入图片描述

优点:

  • 需要消除样本不同属性具有不同量级(大小)时的影响,特别是依赖于样本距离的算法对于数据的数量级非常敏感。
  • 标准化有可能提高精度。数量级的差异将导致量级较大的属性占据主导地位,从而与实际情况相悖(比如这时实际情况是值域范围小的特征更重要)。
  • 数量级的差异将导致迭代收敛速度减慢。当使用梯度下降法寻求最优解时,很有可能走“之字型”路线(垂直等高线走),从而导致需要迭代很多次才能收敛。
  • 适应某些算法的要求,他们要求样本具有零均值和单位方差。

缺点:

  • 对于数据分布有一定要求,近似正态分布的数据是最好的。
  • 标准化处理需要总体的平均值与方差,但是在真实的分析与挖掘中很难获取,多用样本的均值与标准差替代。
  • 消除了数据的实际意义,如年龄和收入与他们各自的标准化后分数不再有关系,因此Z-Score的结果只能用于比较数据间的结果,数据的真实意义还需要还原到原值。

1.2 MinMax归一化
也叫离差标准化或极差标准化,利用了边界值信息,将属性缩放到[0,1]区间

# min-max标准化(Min-Max Normalization)
def min_max_norm(col_x):
    print(col_x)
    preprocessing_min_max = preprocessing.MinMaxScaler()
    x = preprocessing_min_max.fit_transform(col_x)
    return x
min_max_norm(i_x)


def min_max_encoder(col_x):
    print(col_x)
    new_x = [(x - min(col_x))/(max(col_x) - min(col_x)) for x in col_x]
    return new_x
min_max_encoder(i_x[:, 0])

在这里插入图片描述

优点:

  • 归一化消除了量纲对数据的影响,有可能提高精度
  • 归一化后加快梯度下降的速度,算法收敛速度更快

缺点:

  • 当有新数据加入时,可能导致max和min的变化,需要重新定义
  • 对异常值的存在非常敏感。

标准化与归一化却别对比

相同点:

它们的相同点在于都能取消由于量纲不同引起的误差,都是一种线性变换,都是对向量X按照比例压缩再进行平移。

不同点:

  • 归一化是为了消除纲量,数据被压缩到[0,1]区间。 标准化只是调整特征整体的分布,调整成均值为0方差为1的标准正态分布
  • 归一化与最大,最小值有关。 标准化与均值,标准差有关。
  • 归一化输出在[0,1]之间。 标准化无限制。

适用场景:

  • 如果数据存在异常值和较多噪音,用标准化,可以间接通过中心化避免异常值和极端值的影响。在SVM、KNN等分类、聚类算法中,需要使用距离来度量相似性的时候,也是用标准化Z-score表现更好。
  • 如果对输出结果范围有要求、数据较为稳定,不存在极端的最大最小值、数据不符合正太分布或不涉及距离计算时,用归一化。
  • 如基于参数的模型或者基于距离的模型,因为需要对参数或者距离进行计算,都需要进行归一化。
  • 而决策树、随机森林,bagging与boosting等基于树的方法不需要进行特征的归一化。

1.3 正态分布化(Normalization)

# 规范化(Normalization)
def normalize_encoder(col_x):
    print(col_x)
    x1 = preprocessing.normalize(col_x, norm='l1')
    x2 = preprocessing.normalize(col_x, norm='l2')
    return x1, x2
normalize_encoder(i_x)

在这里插入图片描述

  • 正则化的过程是将每个样本缩放到单位范数(每个样本的范数为1)。Normalization主要思想是对每个样本计算其p-范数,然后对该样本中每个元素除以该范数,这样处理的结果是使得每个处理后样本的p-范数(l1-norm,l2-norm)等于1。
  • 如果要使用如二次型(点积)或者其它核方法计算两个样本之间的相似性这个方法会很有用。该方法是文本分类和聚类分析中经常使用的向量空间模型(VectorSpace Model)的基础。

2 统计变换

  • 如利用Log变换来减轻数据分布倾斜的影响,使原本密集的区间的值尽可能的分散,原本分散的区间的值尽量的聚合,稳定方差,始终保持分布接近于正态分布并使得数据与分布的平均值无关。
# 对数变换
def log_encoder(col, logn):
    print(col)
    if logn == 2:
        new_x = [math.log2(x) for x in col]
    elif logn == 10:
        new_x = [math.log10(x) for x in col]
    else:
        print('暂不支持')
    return new_x
log_encoder(i_x[:, 0], logn=10)

在这里插入图片描述

3.1 标签编码(LabelEncode)

  • 对不连续的数字或者文本进行编号,编码值介于0和n_classes-1之间的标签。但也隐含了一个不同的类别之间的默认顺序关系
def label_encoder(data):
    print(data)
    le = preprocessing.LabelEncoder()
    le.fit(data)
    t = le.transform(data)
    return t
label_encoder(i_x[:, 0])

在这里插入图片描述

3.2 标签二值化(LabelBinarizer)

  • 与OneHotEncoder一样,但是OneHotEncode只能对数值型变量二值化,无法直接对字符串型的类别变量编码,而LabelBinarizer可以直接对字符型变量二值化。
# 标签二值化(Label binarization)
def label_encoder(col_y):
    lb = preprocessing.LabelBinarizer()
    y = lb.fit_transform(col_y)
    return y

label_encoder(['a','b','c'])

在这里插入图片描述

3.3 独热编码(OneHotEncode)

  • 用于将表示分类的数据扩维,设置一个个数与类型数量相同的全0数组,每一位对应一个类型,如该位为1,该数字表示该类型。OneHotEncode只能对数值型变量二值化,无法直接对字符串型的类别变量编码。
# 独热编码
def onehot_encoder(data):
    print(data)
    enc = preprocessing.OneHotEncoder(sparse=False, categories='auto')
    t = enc.fit_transform(data)
    return t

onehot_encoder(i_x)

在这里插入图片描述

优点:

  • 将离散型特征使用one-hot编码,会让特征之间的距离计算更加合理,解决了分类器不好处理离散数据的问题,它的值只有0和1,不同的类型存储在垂直的空间。

缺点:

  • 当类别的数量很多时,特征空间会变得非常大。在这种情况下,一般可以用PCA来减少维度。而且one hotencoding+PCA这种组合在实际中也非常有用。

3.4 二值化(Binarization)

  • 二值化可以将数值型(numerical)的特征进行阀值化得到boolean型数据。这对于下游的概率估计来说可能很有用(比如:数据分布为Bernoulli分布时)。
  • 定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0。
# 特征二值化(Binarization)
def binary_encoder(data):
    print(data)
    binarizer = preprocessing.Binarizer(threshold=4)
    x = binarizer.transform(data)
    return x

binary_encoder(i_x)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值