目录
0、前言
数据处理之特征缩放和特征编码,特征缩放主要是归一化和正则化,用于消除量纲关系的影响,特征编码包括了序号编码、独热编码等,主要是处理类别型、文本型以及连续型特征。
1、特征缩放
特征缩放主要有两种方法:归一化和正则化。
1.1 归一化
归一化(Normalization),也称为标准化,不仅仅是对特征,实际上对于原始数据也可以进行归一化处理,它是将特征(或者数据)都缩放到一个指定的大致相同的数值区间内。
归一化的两个原因:
- 某些算法要求样本数据或特征的数值具有零均值和单位方差;
- 为了消除样本数据或者特征之间的量纲影响,即消除数量级的影响。
1.1.1 Min-Max Scaling
它对原始数据进行线性变换,使得结果映射到[0,1]的范围,实现对原始数据的等比缩放,公式如下:
x* = (x-x.min)/(x.max-x.min)
其中 X 是原始数据,x.max,x.min分别表示数据最大值和最小值。
1.1.2 Z-Score Normalization
它会将原始数据映射到均值为 0,标准差为 1 的分布上。假设原始特征的均值是μ、标准差是σ,则公式如下:
x* = (x-μ)/σ
1.1.3 归一化总结
如果数据集分为训练集、验证集、测试集,那么三个数据集都采用相同的归一化参数,数值都是通过训练集计算得到,即上述两种方法中分别需要的数据最大值、最小值,方差和均值都是通过训练集计算得到
归一化不是万能的,实际应用中,通过梯度下降法求解的模型是需要归一化的,这包括线性回归、逻辑回归、支持向量机、神经网络等模型。但决策树模型不需要,以 C4.5 算法为例,决策树在分裂结点时候主要依据数据集 D 关于特征 x 的信息增益比,而信息增益比和特征是否经过归一化是无关的,归一化不会改变样本在特征 x 上的信息增益。
1.2 正则化
正则化是将样本或者特征的某个范数(如 L1、L2 范数)缩放到单位 1。
对样本首先计算 Lp 范数,正则化后的结果是:每个属性值除以其 Lp 范数
1.3 归一化与正则化比较
正则化的过程是针对单个样本的,对每个样本将它缩放到单位范数;归一化是针对单个属性的,需要用到所有样本在该属性上的值。
通常如果使用二次型(如点积)或者其他核方法计算两个样本之间的相似性时,正则化的方法会很有用。
2、特征编码
2.1 类别数据处理
2.1.1 序号编码
定义:序号编码,可以理解为打标签,一般用于处理类别间具有大小关系的数据。
比如成绩,可以分为高、中、低三个档次,并且存在“高>中>低”的大小关系,那么序号编码可以对这三个档次进行如下编码:高表示为 3,中表示为 2,低表示为 1,这样转换后依然保留了大小关系。但如果特征实际上并不存在大小的关系,这里会给模型一个误导,所以此时标签编码更适合只有两个取值的情况。
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
x_le = le.fit_transform(data['species'])
x_le
2.1.2 独热编码(one-hot)
定义:独热编码通常用于处理类别间不具有大小关系的特征。
独热编码是采用 N 位状态位来对 N 个可能的取值进行编码。
from sklearn import preprocessing
x = np.array([[1,2,3],[3,4,6],[1,5,6]])
l = preprocessing.OneHotEncoder()
l.fit(x)
y = np.array([3,2,6])
print(l.transform(y.reshape(1,-1)).toarray())
实现 One-hot 编码有以下 3 种方法:
- Pandas 的 get_dummies
- Sklearn 的 DictVectorizer
- Sklearn 的 LabelEncoder+OneHotEncoder
独热编码的优点有以下几个:
- 能够处理非数值属性。比如血型、性别等
- 一定程度上扩充了特征。
- 编码后的向量是稀疏向量,只有一位是 1,其他都是 0,可以利用向量的稀疏来节省存储空间。
- 能够处理缺失值。当所有位都是 0,表示发生了缺失。此时可以采用处理缺失值提到的高维映射方法,用第 N+1 位来表示缺失值。
当然,独热编码也存在一些缺点:
1.高维度特征会带来以下几个方面问题:
- KNN 算法中,高维空间下两点之间的距离很难得到有效的衡量;
- 逻辑回归模型中,参数的数量会随着维度的增高而增加,导致模型复杂,出现过拟合问题;
- 通常只有部分维度是对分类、预测有帮助,需要借助特征选择来降低维度。
2.决策树模型不推荐对离散特征进行独热编码,有以下两个主要原因:
- 产生样本切分不平衡问题,此时切分增益会非常小。
- 影响决策树的学习。
2.2 连续变量离散化
需要离散化的原因:
- 算法需要,如决策树,朴素贝叶斯是基于离散型数据
- 离散化数据较连续型更容易被理解
- 强鲁棒性,克服数据缺陷
- 离散化后数据稳定性强,可以进行特征交叉,对于逻辑回归来说离散后每个特征具有权重,相当于为模型引入非线性
2.2.1 二值化
定义:特征二值化就是将数值型的属性转换为布尔型的属性。通常用于假设属性取值分布是伯努利分布的情形。
特征二值化的算法比较简单,即设定阈值,大于阈值为1,反之为0
from sklearn.preprocessing import Binarizer
# 阈值自定义为 3.0
# 大于阈值映射为 1,反之为 0
b = Binarizer(threshold=3.0)
x_binarizer = b.fit_transform(df.iloc[:, :4])
x_binarizer[:5]
2.2.2 分桶
*等宽:按照特征值划分pd.cut
*等频:将样本数量等频数划分pd.qcut
2.2.3 聚类划分
KMeans无监督学习,定义k个簇不断增加样本值改变簇的位置,直到簇不再改变。
# 聚类划分
import seaborn as sns
import numpy as np
from sklearn.cluster import KMeans
data = sns.load_dataset('iris')
X = data.iloc[:,1]
kmeans = KMeans(n_clusters=4) # 离散为 4 等份
kmeans.fit_transform(np.array(X).reshape(-1, 1)) # 只取一个特征进行聚类离散化
3、总结
特征缩放是非常常用的方法,特别是归一化处理特征数据,对于利用梯度下降来训练学习模型参数的算法,有助于提高训练收敛的速度;而特征编码,特别是独热编码,也常用于对结构化数据的数据预处理。