特征工程--模型训练的核心
特征工程是指对数据进行一系列处理的活动,其目的是最大限度地从原始数据中提取特征以供算法和模型使用
特征工程是整个人工智能中最重要的工作,该流程直接决定特征工程的上限,也是在整个模型训练中耗时时间最长,最令数据科学家“最讨厌”的工作
特征工程的步骤通常如下
数据清洗
在获得原始数据时,首先要保证数据是合格的,这样就需要我们清洗原始数据中的异常数据
这个基本就有以下步骤:
去除重复数据
填补空白数据
由于数据来源不同,空白数据的填补方式也不同,比如:
如果是数值型数据,可以使用均值、中位数、众数等来填补
如果是分类型数据,可以使用众数来填补
如果是时间序列数据,可以使用前后时间点的数据来填补
在结构性数据中,使用pandas导入数据较多,通常使用pandas清洗数据
数据编码
对于特定的数据,需要对其进行编码以符合模型的输入规格。
或者需要对某些string类型的数据装换成特定形式的int/float类型的数据。
说白了就是转换成机器看得懂的样子
One-Hot编码
One-Hot编码用于将分类的结果转换为向量的形式
假设有三个结果,分别是红、绿、蓝,编码前为y=1,编码后为y=[1, 0, 0]
通常使用from sklearn.preprocessing import OneHotEncoder
去进行这个操作,下面是例子:
import numpy as np
from sklearn.preprocessing import OneHotEncoder
# 构造标签
Y = np.array([np.random.randint(0, 100) for _ in range(10)])
Y = Y.reshape(-1, 1)
print(Y)
# 标签输出结果
# [[35]
# [ 3]
# [55]
# [14]
# [99]
# [56]
# [47]
# [82]
# [15]
# [67]]
# 创建一个OneHotEncoder对象
encoder = OneHotEncoder()
# 拟合并转换数据
Ytrans = encoder.fit_transform(Y)
# 输出结果
print(Ytrans.toarray())
# 输出结果
# [[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
# [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
# [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
# [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
# [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
# [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
输入的结构必须要类似于张量的结构,即二维数组,且每一行代表一个样本,每一列代表一个特征。如果要编码的数据是一维数组,则必须使用reshape(-1, 1)
将其转化为二维数组,否则会报错。
输出时可以使用.toarray()
转化为数组,方便我们观察,原数据为稀疏矩阵的方式展示。
另外, 在模型训练结束后,我们需要回转结果到原来的形式,可以使用如下结构:
# 转换回原来的形式
Y = encoder.inverse_transform(Ytrans)
print(Y)
LabelEncoder
LabelEncoder用于将分类的结果转换为int类型的数据
假设有三个结果,分别是红、绿、蓝,编码前为y=['red', 'green', 'blue'],编码后为y=[2, 1, 0]
通常使用from sklearn.preprocessing import LabelEncoder
去进行这个操作,下面是例子:
import numpy as np
from sklearn.preprocessing import LabelEncoder
# 构造标签
Y = np.array(['red', 'green', 'blue', 'red', 'green', 'blue'])
print(Y)
# 标签输出结果
# ['red' 'green' 'blue' 'red' 'green' 'blue']
# 创建一个LabelEncoder对象
encoder = LabelEncoder()
# 拟合并转换数据
Ytrans = encoder.fit_transform(Y)
# 输出结果
print(Ytrans)
# 输出结果
# [2 1 0 2 1 0]
另外, 在模型训练结束后,我们需要回转结果到原来的形式,可以使用如下结构:
# 转换回原来的形式
Y = encoder.inverse_transform(Ytrans)
print(Y)
特征缩放(无量纲化)
特征缩放确保所有特征在同一尺度上,避免某些特征因尺度较大(特征的规格不一样)而主导模型的学习过程。
特征缩放也叫无量纲化,常见的缩放方法有如下
标准化(Standardization)
标准化将数据转换为均值为0,标准差为1的标准正态分布
当算法假设数据符合正态分布时,或者当量级和分布对结果影响较大时,如线性回归、逻辑回归、支持向量机等。就适合使用标准化对特征进行缩放
通常使用from sklearn.preprocessing import StandardScaler
进行缩放
import numpy as np
from sklearn.preprocessing import StandardScaler
# 构造数据
X = np.array([[1., -1., 2.],
[2., 0., 0.],
[0., 1., -1.]])
# 创建一个StandardScaler对象
scaler = StandardScaler()
# 拟合并转换数据
Xtrans = scaler.fit_transform(X)
# 输出结果
print(Xtrans)
# [[ 0. -1.22474487 1.33630621]
# [ 1.22474487 0. -0.26726124]
# [-1.22474487 1.22474487 -1.06904497]]
在模型训练结束后,可以通过如下方法回转结果到原来的形式:
# 回转数据
X = scaler.inverse_transform(Xtrans)
print(X)
归一化/区间缩放法(Normalization)
将数据缩放到一个固定的范围,通常是[0, 1]或者[-1, 1]之间
归一化/区间缩放法在当数据量级不一,且算法对量级敏感时使用,比如神经网络、K近邻算法等
通常使用from sklearn.preprocessing import MinMaxScaler
进行缩放
import numpy as np
from sklearn.preprocessing import MinMaxScaler
# 构造数据
X = np.array([[121., -332., 421.],
[212., 302., 101.],
[603., 121., -314.]])
# 创建一个MinMaxScaler对象
scaler = MinMaxScaler((-1, 1)) # 指定缩放区间,输入类型必须是tuple
# 拟合并转换数据
Xtrans = scaler.fit_transform(X)
# 输出结果
print(Xtrans)
# [[-1. -1. 1. ]
# [-0.62240664 1. 0.1292517 ]
# [ 1. 0.42902208 -1. ]]
在模型训练结束后,可以通过如下方法回转结果到原来的形式:
# 回转数据
X = scaler.inverse_transform(Xtrans)
print(X)