数据预处理的工具有许多,在我看来主要有两种:pandas数据预处理和scikit-learn中的sklearn.preprocessing数据预处理。
前面更新的博客中,我已有具体的根据pandas来对数据进行预处理,原文请点击这里。其中主要知识点包括一下几个方面:
这里,本文主要针对与在scikit-learn中的sklearn.preprocessing数据预处理。
首先,sklearn.preprocessing包提供了几个常用的实用函数和转换器类(这里主要介绍类的使用),以将原始特征向量转换为更适合下游估计器的表示。
preprocessing中有很多的类,但主要有以下几种常用的数据处理类:
标准化相信大家接触的也多所以这里就不过多介绍,这里只是顺带提一下。
1. MinMaxScaler
最小-最大规范化对原始数据进行线性变换,变换到[0,1]区间(也可以是其他固定最小最大值的区间)每个特征中的最小值变成了0,最大值变成了1.
import numpy as np
from sklearn.preprocessing import MinMaxScaler
X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])
#实现归一化
scaler = MinMaxScaler() #实例化
scaler = scaler.fit(X) #fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(X) #通过接口导出结果
#也可以训练和导出结果一步达成
result_ = scaler.fit_transform(data)
此外,使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中。
scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化
result = scaler.fit_transform(X)
将归一化后的结果逆转::
scaler.inverse_transform(result)
2. StandardScaler
Standardization标准化:将特征数据的分布调整成标准正太分布,也叫高斯分布,也就是使得数据的均值维0,方差为1.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler() #实例化
scaler.fit(data) #fit,本质是生成均值和方差
scaler.mean_ #查看均值的属性mean_
scaler.var_ #查看方差的属性var_
x_std = scaler.transform(data) #通过接口导出结果
x_std.mean() #导出的结果是一个数组,用mean()查看均值
x_std.std() #用std()查看方差
scaler.fit_transform(data) #使用fit_transform(data)一步达成结果
scaler.inverse_transform(x_std) #使用inverse_transform逆转标准化
补充:
3. MaxAbsScaler
原理与上面的很像,只是数据会被规模化到[-1,1]之间。也就是特征中,所有数据都会除以最大值。这个方法对那些已经中心化均值维0或者稀疏的数据有意义,后者不会改变矩阵的稀疏性,是0的还是0,而前者会改变。
4. RobustScaler
根据四分位数来缩放数据。对于数据有较多异常值的情况,使用均值和方差来标准化显然不合适,按中位数,一、四分位数缩放效果要好。
1. QuantileTransformer
使用百分位教转换特征,通过缩小边缘异常值和非异常值之间的距离来提供特征的非线性变换。可以使用参数output_distribution = "normal"
来将数据映射到标准正态分布。
以下是QuantileTransformer参数:
sklearn.preprocessing.QuantileTransformer(n_quantiles=1000, output_distribution=’uniform’,
ignore_implicit_zeros=False, subsample=100000, random_state=None, copy=True)
2. PowerTransformer
映射到高斯分布。在许多建模场景中,数据集中的特性是正常的。幂变换是一类参数的单调变换,其目的是将数据从任意分布映射到尽可能接近高斯分布,以稳定方差和最小化偏度。
PowerTransformer目前提供了两个这样的幂变换,Yeo-Johnson变换和Box-Cox变换,利用极大似然估计了稳定方差和最小偏度的最优参数。并且,box-Cox要求输入数据严格为正数据,而Yeo-Johnson支持正负数据。参数如下:
sklearn.preprocessing.PowerTransformer(method=’yeo-johnson’, standardize=True, copy=True)
注意:PowerTransformer只有在0.20.0以后的版本才有,不然会报错。 你可以使用conda update scikit-learn来进行更新。
归一化是缩放单个样本以具有单位范数的过程,这里的”范数”,可以使用L1或L2范数。如果你计划使用二次形式(如点积或任何其他核函数)来量化任何样本间的相似度,则此过程将非常有用。
这个观点基于 向量空间模型(Vector Space Model) ,经常在文本分类和内容聚类中使用。
sklearn.preprocessing.Normalizer(norm=’l2’, copy=True)
其中,norm : ‘l1’, ‘l2’, or ‘max’, optional (‘l2’ by default)
在机器学习中,大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,不能处理文字,在sklearn当中,除了专用来处理文字的算法,其他算法在fit的时候全部要求输入数组或矩阵,也不能够导入文字型数据(其实手写决策树和朴素贝叶斯可以处理文字,但是sklearn中规定必须导入数值型)。然而在现实中,许多标签和特征在数据收集完毕的时候,都不是以数字来表现的。比如说,学历的取值可以是[“小学”,“初中”,“高中”,“大学”],付费方式可能包含[“支付宝”,“现金”,“微信”]等等。在这种情况下,为了让数据适应算法和库,我们必须将数据进行编码,即是说,将文字型数据转换为数值型。
1.LabelEncoder
标签专用,能够将分类转换为分类数值。
import pandas as pd
from sklearn.preprocessing import LabelEncoder
y = pd.DataFrame(['yes','yes','yes','no','no','no'],columns=['target'])
label = LabelEncoder().fit_transform(y)
label
2. OrdinalEncoder
特征专用,能够将分类特征转换为分类数值。
import pandas as pd
from sklearn.preprocessing import OrdinalEncoder
X = pd.DataFrame([['male','high'],
['female','high'],
['male','low'],
['female','medium'],
['female','medium'],
['female','low']],
columns=['sex','income'])
X = OrdinalEncoder().fit_transform(X)
3. OneHotEncoder
类别OrdinalEncoder可以用来处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量
向算法传达最准确的信息。
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
X = pd.DataFrame(['male','female','male','female','female','female'],columns=['sex'])
X = OneHotEncoder().fit_transform(X).toarray()
补充
数据类型 | 数据名称 | 数学含义 | 描述 | 举例 | 可用操作 |
---|---|---|---|---|---|
离散变量,定性 | 名义 | =,≠ | 名义变量就是不同的名字,是用来告诉我们,这两个数据是否相同的 | 邮编、性别、职工号,颜色等 | 取众数、信息熵、情形分析表或列联表、相关性分析、卡方检验 |
离散变量,定性 | 有序 | <,> | 有序变量为数据的相对大小提供信息,告诉我们数据的顺序,但数据之间大小的间隔不是具有固定意义的,因此有序变量不能加减 | 收入高低、学历、硬度、强度等 | 中位数、分位数、非参数相关性分析、测量系统分析、符号检验 |
连续变量,定量 | 有距 | +,- | 有距变量之间的间隔是有固定意义的,可以加减,不能乘除 | 日期、以摄氏度或华氏度为量纲的温度 | 均值、标准差、皮尔逊相关系数、t检验和F检验 |
连续变量,定量 | 比率 | +,-,*,/ | 可以加减乘除 | 收入、年龄、质量、长度、数量等 | 平均、百分数、变化量等 |
离散化(也称为量化或绑定)提供了一种将连续特征划分为离散值的方法。某些具有连续特征的数据集可能受益于离散化,因为离散化可以将连续属性的数据集转换为仅具有名义属性的数据集。
1. KBinsDiscretizer
k个等宽箱的离散化特征,默认情况下,输出是one-hot编码成稀疏矩阵,并且可以使用encode参数。对于每个特性,在fit再加上分箱的数量,他们会定义间隔。
sklearn.preprocessing.KBinsDiscretizer(n_bins=5, encode=’onehot’, strategy=’quantile’)
2. Binarizer
根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。默认阈值为0时,特征中所有的正值都映射到1。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。
sklearn.preprocessing.Binarizer(threshold=0.0, copy=True)
当k=2时,当bin边处于值阈值时,Binarizer类似于KBinsDiscreizer。
针对于最新的0.20.0版本的scikit-learn中,Imputer好象是被取代了换成了sklearn.impute
这里面包含两个类:
sklearn.impute.SimpleImputer(missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True)
sklearn.impute.MissingIndicator(missing_values=nan, features=’missing-only’, sparse=’auto’, error_on_new=True)
由于用的较多的是SimpleImputer,下面给出一般参数:
在机器学习中,通过增加一些输入数据的非线性特征来增加模型的复杂度通常是有效的。一个简单通用的办法是使用多项式特征,这可以获得特征的更高维度和互相间关系的项。多项式特征经常用于使用多项式核函数的核方法(比如SVC和KernelPCA)。这在 PolynomialFeatures 中实现:
sklearn.preprocessing.PolynomialFeatures(degree=2, interaction_only=False, include_bias=True)
我们经常希望将一个Python的函数转变为transformer,用于数据清洗和预处理。可以使用FunctionTransformer方法将任意函数转化为一个Transformer。
sklearn.preprocessing.FunctionTransformer(func=None, inverse_func=None, validate=None,
accept_sparse=False, pass_y=’deprecated’, check_inverse=True, kw_args=None, inv_kw_args=None)
自0.20.0版本的scikit-learn中,变化还是挺大的,其中有些类增加了,有些类减少了(其他模块中去了)。所以对于新的知识个人建议去scikit-learn官网中进行查找阅读。