目录

数据预处理

# 数据无量纲化

在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到相同分布的需求,这种需求统称为将数据“无量纲化”,比方说希望数据都在0~10之间亦或是数据都满足标准正态分布。在比如逻辑回归、支持向量机、神经网络中,无量纲化能够加快求解速度。而在距离类模型,警如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。(一个特例是决策树和树的集成算法们,对决策树我们不需要无量纲化,决策树可以把任意数据都处理得很好。)

数据的无量纲化可以是线性的,也可以是非线性的。线性的无量纲化包括中心化 (Zero-centered或者Mean-subtraction)处理和缩放处理(Scale)。中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。缩放的本质是通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。

# preprocessing.MinMaxScaler

当数据 (X) 按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间,而这个过程,就叫做数据归一化(Normalization,又称Min-Max Scaling)。注意,Normalization是归一化,不是正则化,真正的正则化是Regularization,不是数据预处理的一种手段。归一化之后的数据服从正态分布,公式为 new_x = (x - min(x)) / max(x) - min(x)

在sklearn中,我们使用preprocessing.MinMaxScaler实现该功能。MinMaxScalar中有个重要参数feature_range,用于空置我们希望把数据压缩到的范围,默认为[0,1]

from sklearn.preprocessing import MinMaxScaler

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = [[-1,2],[-0.5,6],[0,10],[1,18]]

pd.DataFrame(data)
scaler = MinMaxScaler()
result = scaler.fit_transform(data)
result

'''
array([[0.  , 0.  ],
       [0.25, 0.25],
       [0.5 , 0.5 ],
       [1.  , 1.  ]])
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# preprocessing.StandardScaler

当数据(x)按均值(μ)中心化后,再按标准差θ缩放,数据就会服从为均值为0,方差为1的正态分布,这个过程叫做数据标准化(Standardization),公式为new_x = (x - μ)/θ

from sklearn.preprocessing import StandardScaler
data = [[-1,2],[-0.5,6],[0,10],[1,18]]

scaler = StandardScaler()
scaler.fit(data)
scaler.mean_ #均值
scaler.var_ #方差
result = scaler.transform(data)
result

'''
array([[-1.18321596, -1.18321596],
       [-0.50709255, -0.50709255],
       [ 0.16903085,  0.16903085],
       [ 1.52127766,  1.52127766]])
'''

result.mean() #均值为0
result.std() #标准差为1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 我该选择哪一种?

这要视乎情况决定,大多数机器学习算法中,我们会选择StandardScaler进行特征缩放,因为MinMaxScaler对异常值极度敏感!假设数据普遍在0~10之间,而出现一个1000的异常值,该异常值会被捕获成为最大值,这将极大地影响最终结果。

MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比方说数字图像处理中的量化像素强度时,都会使用该方法将数据压缩到0~1之间

总而言之,我们会优先选择StandardScaler,效果不好时再选MinMaxScaler。

此外,还有别的缩放选择,例如MaxAbsScaler,当你希望压缩数据时,不影响矩阵中取值为0的个数时,可以考虑该缩放器

# 处理分类型数据

# preprocessing.LabelEncoder

该编码器用于将文本分类转化为分类数值

from sklearn.preprocessing import LabelEncoder
y = data["OWN_OCCUPIED"]
le = LabelEncoder()
label = le.fit_transform(y)
label

'''
data["OWN_OCCUPIED"]
0    Y
1    N
2    N
3    C
4    Y
5    Y
6    Y
7    Y
8    Y

label:
array([2, 1, 1, 0, 2, 2, 2, 2, 2])
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

上述是基于一维特征进行编码,如果是多维特征需要用到OrdinalEncoder

# OneHotEncoder

分类数据的性质可能不同,例如舱门(S,C,Q)彼此毫无联系,而体重(>45kg , >90kg , >135kg)则不同,各个取值之间是有联系的,且是可以互相计算的,例如120-45 = 90,这是有距变量

然而在对特征进行编码的时候,这三种分类数据都会被我们转换为[0,1,2],这三个数字在算法看来,是连续且可以计算的,这三个数字相互不等,有大小,并且有着可以相加相乘的联系。所以算法会把舱门,学历这样的分类特征,都误会成是体重这样的分类特征。这是说,我们把分类转换成数字的时候,忽略了数字中自带的数学性质,所以给算法传达了一些不准确的信息,而这会影响我们的建模

在此,我们要引入一个新概念 - 哑变量 即原本,"S","Q","C" => [0,1,2] 但现在, "S","Q","C" => [[1,0,0],[0,1,0],[0,0,1]] 通过这种高维形式能让三种类别相互独立存在

from sklearn.preprocessing import OneHotEncoder
y = data["OWN_OCCUPIED"].values.reshape(-1,1)
ohe = OneHotEncoder()
ohe = ohe.fit(y)
ohe.get_feature_names_out() # 查看对应的标签
pd.DataFrame(ohe.transform(y).toarray())
1
2
3
4
5
6

# 处理连续性数据

# skleran.preprocessing.Binarizer

根据阈值将数据二值化(将特征值设置为0或者1),用于处理连续型变量,大于阈值的值映射为1,反之为0。默认阈值为0时,特征中所有正值豆映射到1。

from sklearn.preprocessing import Binarizer
data_2 = data.copy()

x = data_2.iloc[:,1].values.reshape(-1,1)
b = Binarizer(threshold=200)
b = b.fit_transform(x)

1
2
3
4
5
6
7
最近更新
01
基本知识
07-18
02
卷积神经网络识别图像
07-18
03
损失函数
07-18
更多文章>