Data Preprocessing -- 2.MLP
编辑说明
sklearn是Python语言中功能完善的机器学习库,其中包括Classification、Regression、Clustering、Dimensionality reduction、Model selection、Processing模块;
Classification:分类模型算法;
Regression:回归模型算法;
Clustering:聚类模型算法;
Dimensionality reduction:降维算法;
Model selection:比较、验证和选择参数和模型;
Processing:数据处理,特征提取和归一化。
本篇文章主要简介Processing中的常见用法。
若本篇文章中未解决您的问题,请参考API reference : https://scikit-learn.org/stable/index.html
1、sklearn.Preprocessing简介
一般而言,学习算法受益于数据集的标准化。如果数据集中存在一些异常值,则鲁棒标量或转换器更为合适。在比较不同的标量对异常值数据的影响时,突出显示了不同的标量、变形器和归一化器在包含边缘异常值数据集上的行为。
2、标准化
数据集的标准化是许多在scikit-learn中实现的机器学习估计器的共同需求;如果单个特征或多或少不像标准正态分布数据,即均值和单位方差为零的高斯分布数据,数据表现会比较差。
标准化是将数据转换成符合标准正态分布的数据并非一定是正态的。
2.1 中心化
标准化公式:
# 自己实现的话,可以基于上面的标准化公式:z=(x-mean)/variance
def my_scale(data):
mean = sum(data) / len(data) #先求均值
variance = ( sum([ (I-mean) ** 2 for I in data]) ) / len(data) #再求方差
normal = [(I - mean) / (variance ) ** 0.5 for I in data] #按照公式标准化
return normal
from sklearn.preprocessing import StandardScaler
import numpy as np
import joblib
X_train = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
#定义模型
scaler = StandardScaler()
#训练模型
scaler_model = scaler.fit(X_train)
#训练集中每个特征的均值。当fit()中参数with_mean=False时为None。
scaler.mean_
#每个特征对数据的相对缩放。这是使用np.sqrt(var_)计算的。当fit()中参数with_std=False时,等于None。
scaler.scale_
#预测
scaler_model.transform(X_train)
#joblib模型保存
joblib.dump(scaler_model, r'C:\scaler_model.clf')
2.2 区间缩放
2.2.1 (0,1)缩放
使用这个缩放的情况包括:增强极小方差的值还有保留稀疏样本中的零值
# 代码实现
import numpy as np
from sklearn import preprocessing
X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]])
min_max_sacler = preprocessing.MinMaxScaler()
min_max_sacler.fit(X_train)
print(min_max_sacler.transform(X_train))
2.2.2 (-1,1)区间缩放
可以实现将数据值缩放到[-1,1]区间,这种情况适合在均值在0附近的值,或者稀疏矩阵。
# 代码实现
import numpy as np
from sklearn import preprocessing
X_train = np.array([[ -4., -2., 2.],[ -5., 0., 0.],[ 0., 1., 6.],[10, 2, 3]])
max_abs_sacler = preprocessing.MaxAbsScaler()
max_abs_sacler.fit(X_train)
print(max_abs_sacler.transform(X_train))
用法详见API
2.3 正则化
归一化是将个体样本缩放到单位区间的过程。比较适合使用二次型(如点积法)或任何其他核来量化任何一对样本的相似性。
L1 公式:
L2 公式:
#将输入向量按单位范数(向量长度)分别缩放。
"""
sklearn.preprocessing.normalize(X, norm='l2', *, axis=1, copy=True, return_norm=False)
Args:
norm:‘l1’, ‘l2’, or ‘max’, optional (‘l2’ by default),用于规范化每个非零样本(或如果轴为0,则每个非零特征)的范数。
axis:0 or 1, optional (1 by default),用于沿数据规格化的轴。如果为1,则对每个样本分别进行归一化;如果为0,则对每个特征进行归一化。
"""
from sklearn.preprocessing import normalize
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
X_normalized = normalize(X, norm='l2')
X_normalized_model = qt.fit(X)
X_normalized_model.transform(X)
3、非线性转换
若数据集为非线性数据集,想要使用线性回归的模型进行预测,可以使用非线性转换的方式将数据集转换为线性数据集。
非线性转换的代价:
- 计算变复杂,需要的存储空间增大
- 模型复杂度增大
3.1 分数位转换
分位数转换的目的也是把特征数据转换到一定的范围内,或者让他们符合一定的分布。
分位数转换利用的是数据的分位数信息进行变换。它能够平滑那些异常分布,对于存在异常点的数据也很适合。但是它会破坏原来数据的相关性和距离信息。
# 代码实现:
# QuantileTransformer提供非参数转换,将数据映射到值在0到1之间的均匀分布,使用分位数信息变换特征。
import numpy as np
from sklearn.preprocessing import QuantileTransformer
rng = np.random.RandomState(0)
X = np.sort(rng.normal(loc=0.5, scale=0.25, size=(25, 1)), axis=0)
qt = QuantileTransformer(n_quantiles=10, random_state=0)
qt_model = qt.fit(X)
qt_model.transform(X)
3.2 幂变换
# 代码实现:
# PowerTransformer采用幂变换,幂变换是一组参数单调变换,旨在将数据从任意分布映射到尽可能接近高斯分布,以稳定方差和最小化偏态。PowerTransformer目前提供两种转换方式,Yeo-Johnson转换和Box-Cox转换。
"""
sklearn.preprocessing.PowerTransformer(method='yeo-johnson', *, standardize=True, copy=True)
Args:
method:
‘yeo-johnson’ [Rf3e1504535de-1], works with positive and negative values
‘box-cox’ [Rf3e1504535de-2], only works with strictly positive values
"""
import numpy as np
from sklearn.preprocessing import PowerTransformer
pt = PowerTransformer()
data = [[1, 2], [3, 2], [4, 5]]
pt_model = pt.fit(data)
pt_model.lambdas_
pt_model.transform(data)
4、类别特征编码
训练数据中很难避免不会出现例如[‘男’,‘女’]类别特征,需要将其转换为可供模型学习的数值型数据,则需运用到类别特征编码。
类别特征编码后再使用标准化方式进行数据标准化处理。
4.1 序列编码
#1、OrdinalEncoder:使用序号编码方式将分类特征转换为整数编码,该方式将每个分类特征转换为整数的一个新特征(0到样本的类别数量-1)
"""sklearn.preprocessing.OrdinalEncoder(*, categories='auto', dtype=<class 'numpy.float64'>)
Args:
Categories:
'auto' : 从训练数据中自动确定类别;
list : 类别[i]包括在i列中预期的类别。通过的类别不应该混合字符串和数字值,在数值的情况下进行排序;
Attrs:
categories_:list of arrays
拟合过程中确定的每个特征的类别(按照X中特征的顺序,对应变换的输出)
"""
from sklearn.preprocessing import OrdinalEncoder
enc = OrdinalEncoder()
X = [['Male', 1], ['Female', 3], ['Female', 2]]
#训练模型
enc.fit(X)
#输出训练类
enc.categories_
#预测
enc.transform([['Female', 3], ['Male', 1]])
#将预测输出数据转换回原始形态
enc.inverse_transform([[1, 0], [0, 1]])
4.2 标签编码
#这个的整数特征表示并不能在scikit-learn的估计器中直接使用,因为这样的连续输入,估计器会认为类别之间是有序的,但实际却是无序的。
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
LabelEncoder()
list(le.classes_)
['amsterdam', 'paris', 'tokyo']
le.transform(["tokyo", "tokyo", "paris"])
array([2, 2, 1]...)
list(le.inverse_transform([2, 2, 1]))
['tokyo', 'tokyo', 'paris']
4.3 One-Hot 编码
#2、OneHotEncoder:使用one-of-K编码,也称为one-hot编码或dummy编码。这种类型的编码将带有n_categories可能值的每个分类特征转换为n_categories二进制特征,其中一个为1,其他所有为0
"""sklearn.preprocessing.OneHotEncoder(*, categories='auto', drop=None, sparse=True, dtype=<class 'numpy.float64'>, handle_unknown='error')
Args:
Categories:
'auto' : 从训练数据中自动确定类别;
list : categories[i]保存第i列中期望的类别。传递的类别不应该在单个特性中混合字符串和数值,应该在数值情况下进行排序;
Attrs:
categories_:list of arrays
拟合过程中确定的每个特征的类别(按照X中特征的顺序,对应变换的输出)
"""
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
#训练
enc.fit(X)
#类别
enc.categories_
#预测
enc.transform([['Female', 1], ['Male', 4]]).toarray()
#将预测输出数据转换回原始形态
enc.inverse_transform([[0, 1, 1, 0, 0], [0, 0, 0, 1, 0]])
#返回输出特性的特性名称
enc.get_feature_names(['gender', 'group'])
4.4 二进制编码
# 基于LabelBinarizer()方法
# 主要分两步:1.先用序号编码给每个类别赋予一个类别ID;2.然后将类别ID对应的二进制编码作为结果。
#(其实就是用序号编码的结果做一个十进制转二进制的转换)
5、 二值化
特征二值化是将数值特征用阈值过滤得到布尔值 的过程,就是基于阈值进行判断。
# 代码呈现
X = [[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]
binarizer = preprocessing.Binarizer().fit(X)
binarizer
Binarizer(copy=True, threshold=0.0)
binarizer.transform(X)
array([[ 1., 0., 1.],
[ 1., 0., 0.],
[ 0., 1., 0.]])
# 手动指定阈值
binarizer = preprocessing.Binarizer(threshold=1.1)
binarizer.transform(X)
array([[ 0., 0., 1.],
[ 1., 0., 0.],
[ 0., 0., 0.]])
6、 缺失值增补
# 基于Imputer方法,可以用均值、最值等形式进行填充
import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit([[1, 2], [np.nan, 3], [7, 6]])
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
X = [[np.nan, 2], [6, np.nan], [7, 6]]
print(imp.transform(X))