sklearn中的数据预处理
2017-12-30 14:38
232 查看
1.介绍
klearn.preprocessing提供了各种公共函数,来将raw feature vetor转换成另外一种更适合评估器工作的格式。2.标准化(Standardization)、平均移除法(mean removal)和方差归一化(variance scaling)
数据集的标准化,在scikit中,对于众多机器学习评估器来说是必须的;如果各独立特征不进行标准化,结果标准正态分布数据差距很大:比如使用均值为0、方差为1的高斯分布.实际上,我们经常忽略分布的形状,只是简单地通过移除每个feature的均值,将数据转换成中间值,接着通过分割非常数项的feature进行归一化。
例如,在机器学习的目标函数(objective function),比如SVM中的RBF或者线性模型中的L1和L2正则项,其中使用的元素,前提是所有的feature都是以0为中心,且方差的阶(order)都一致。如果一个feature的方差,比其它feature的阶(order)都大,那么它将在目标函数中占支配地位,从而使得estimator从其它feature上学习不到任何东西。
scale函数提供了一个快速而简单的方式:
>>> from sklearn import preprocessing >>> import numpy as np >>> X = np.array([[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]]) >>> X_scaled = preprocessing.scale(X) >>> X_scaled array([[ 0. ..., -1.22..., 1.33...], [ 1.22..., 0. ..., -0.26...], [-1.22..., 1.22..., -1.06...]])
我们可以看到,归一化后的数据,均值为0,方差为1:
>>> X_scaled.mean(axis=0) array([ 0., 0., 0.]) >>> X_scaled.std(axis=0) array([ 1., 1., 1.])
preprocessing模块提供了另一个工具类:StandardScaler,它实现了Transformer API,来计算在一个训练集上的平均值和标准差(standard deviation),同样需要在测试集上使用相同的转换。该类也可以应用在sklearn.pipeline.Pipeline上。
>>> scaler = preprocessing.StandardScaler().fit(X) >>> scaler StandardScaler(copy=True, with_mean=True, with_std=True) >>> scaler.mean_ array([ 1. ..., 0. ..., 0.33...]) >>> scaler.scale_ array([ 0.81..., 0.81..., 1.24...]) >>> scaler.transform(X) array([[ 0. ..., -1.22..., 1.33...], [ 1.22..., 0. ..., -0.26...], [-1.22..., 1.22..., -1.06...]])
scaler实例,可以用在新数据上,并可以以相同的方式在训练集上转换:
>>> scaler.transform([[-1., 1., 0.]]) array([[-2.44..., 1.22..., -0.26...]])
通过在StandardScaler的构造函数中设置with_mean=False 或者 with_std=False,可以禁止均值中心化(centering)和归一化(scaling)。
2.1 将feature归一化到一个范围内
另一种标准化方式是,将feature归一化到给定的最大、最小值范围内,比如:[0,1]之间,这样,每个feature的最大绝对值为1. 可以使用:MinMaxScaler或者MaxAbsScaler。使用归一化的动机是,阻止sparse中的0元素,让含有小标准差的feature变得更健壮.
下例:归一化至[0, 1]
>>> X_train = np.array([[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]]) ... >>> min_max_scaler = preprocessing.MinMaxScaler() >>> X_train_minmax = min_max_scaler.fit_transform(X_train) >>> X_train_minmax array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]])
可以通过查看scaler的属性,来看下训练集上的转换是否合理.
>>> min_max_scaler.scale_ array([ 0.5 , 0.5 , 0.33...]) >>> min_max_scaler.min_ array([ 0. , 0.5 , 0.33...])
如果MinMaxScaler给出了显式的范围:feature_range=(min, max)。那么对应完整的公式为:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) X_scaled = X_std / (max - min) + min
MaxAbsScaler以相类似的方式运作,它的归一化会介于[-1, 1]之间,通过在每个feature上分隔最大值来实现。这意味着数据已经是以0为中心的,或者是稀疏数据。
这里我们使用一个示例数据:
>>> X_train = np.array([[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]]) ... >>> max_abs_scaler = preprocessing.MaxAbsScaler() >>> X_train_maxabs = max_abs_scaler.fit_transform(X_train) >>> X_train_maxabs # doctest +NORMALIZE_WHITESPACE^ array([[ 0.5, -1. , 1. ], [ 1. , 0. , 0. ], [ 0. , 1. , -0.5]]) >>> X_test = np.array([[ -3., -1., 4.]]) >>> X_test_maxabs = max_abs_scaler.transform(X_test) >>> X_test_maxabs array([[-1.5, -1. , 2. ]]) >>> max_abs_scaler.scale_ array([ 2., 1., 2.])
如果你不想创造对象,scale模块提供了另外的函数: minmax_scale 和 maxabs_scale。
2.2 归一化sparse矩阵
如果对sparse数据进行中心化,会摧毁数据的稀疏性,十分敏感。我们可以对sparse数据进行特殊的归一化,尤其各种feature以不同的归一化方式进行。MaxAbsScaler 和 maxabs_scale 是专门处理稀疏数据的,强烈推荐这种方式。然而,scale 和 StandardScaler 可以接受scipy.sparse的metrics作为输入,只要在构造函数中显示传入with_centering=False。否则会抛出ValueError,打破sparsity,并且在执行时由于分配大量内存而经常crash。 RobustScaler 不能对稀疏数据进行fit,但是你可以在稀疏数据输入上使用transform方法。
注意:scaler接受压缩式稀疏数据行(Compressed Sparse Rows),以及压缩式稀疏数据列(Compressed Sparse Columns),分别参见:scipy.sparse.csr_matrix 和 scipy.sparse.csc_matrix。其它稀疏输入可以转换成CSR表示。为了避免不必要的内存拷贝,推荐你使用CSR或者CSC表示法。
最后,如果该中心化后的数据如预期般足够小,可以通过sparse matricses的toarray方法转成一个数组。
2.3 归一化异常数据
如果你的数据包含许多异常项(outliers),使用均值和方差的效果不会很好。在这种情况下,我们可以使用robust_scale 和 RobustScaler作为替代。它可以在你给定的中心或者范围内给出健壮的估计。Scaling vs Whitening
对于独自进行中心化和归一化来说有时并不够好。因为下游的模型可能会基于feature的线性独立性做出一些假设。
你可以使用 sklearn.decomposition.PCA 或 sklearn.decomposition.RandomizedPCA,并设置whiten=True以便移除feature之间的线性相关性。
2.4 kernel matrics的中心化
如果你有一个kernel为K的kernel矩阵,通过定义函数phi计算在特征空间内的内积(点乘),KernelCenterer可以对kernel矩阵进行转换,以便它在移除空间的均值后,能包含通过phi函数定义的特征空间的内积。3.正态分布化(Normalization)
Normalization用来将各个样本归一化为norm为1的正态分布。如果你要使用二项式形式(比如点乘、或者其它kernel来确定样本相似性)该假设是向量空间模型(VSM)的基础,经常用于文本分类和内容聚类。
函数 normalize 提供了一个简单的方法来操作类似数组的数据集,使用l1或l2范式:
>>> X = [[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]] >>> X_normalized = preprocessing.normalize(X, norm='l2') >>> X_normalized array([[ 0.40..., -0.40..., 0.81...], [ 1. ..., 0. ..., 0. ...], [ 0. ..., 0.70..., -0.70...]])
preprocessing模块提供了一个工具类: Normalizer。
>>> normalizer = preprocessing.Normalizer().fit(X) # fit does nothing >>> normalizer Normalizer(copy=True, norm='l2')
normalizer实例可以作为转换器被用在样本向量上:
>>> normalizer.transform(X) array([[ 0.40..., -0.40..., 0.81...], [ 1. ..., 0. ..., 0. ...], [ 0. ..., 0.70..., -0.70...]]) >>> normalizer.transform([[-1., 1., 0.]]) array([[-0.70..., 0.70..., 0. ...]])
对于稀疏矩阵输入来说:
normalize和 Normalizer同时接受dense array、或者scipy.sparse输入。
对于sparse来说,数据被转换成CSR形式(scipy.sparse.csr_matrix)。
4.二值化(Binarization)
Feature二值化可以将数值形(numerical)的feature进行阀值化得到boolean型数据。这对于下游的概率估计来说可能很有用(比如:数据分布为Bernoulli分布时)。例如,sklearn.neural_network.BernoulliRBM的case也是。在文本处理社区中,使用二值feature也很常用(可以简化概率模型),如果归一化的count(比如:词频TF)或者TF-IDF值feature经常很有用。
对于 Normalizer来说,工具类 Binarizer可以在sklearn.pipeline.Pipeline的早期使用。
>>> X = [[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]] >>> binarizer = preprocessing.Binarizer().fit(X) # fit does nothing >>> binarizer Binarizer(copy=True, threshold=0.0) >>> binarizer.transform(X) array([[ 1., 0., 1.], [ 1., 0., 0.], [ 0., 1., 0.]])
我们有可能调整binarizer的threshold:
>>> binarizer = preprocessing.Binarizer(threshold=1.1) >>> binarizer.transform(X) array([[ 0., 0., 1.], [ 1., 0., 0.], [ 0., 0., 0.]])
对于StandardScaler 或 Normalizer来说,preprocessing模块提供了另一个函数binarize。
5.将类别特征进行编码
经常,有些特征并不是连续的,可能是类别化的。比如:性别:[“male”, “female”]
国家:[“from Europe”, “from US”, “from Asia”]
使用的浏览器:[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]
这样的feature可以用整型表示,例如:
[“male”, “from US”, “uses Internet Explorer”]表示为:[0, 1, 3]
[“female”, “from Asia”, “uses Chrome”]表示为:[1, 2, 1]
一些整型表示可以被直接用在sklearn的评估器上,当成连续输入,或者解释成类别。
将类别feature转换成sklearn评估器可用的feature的一种方式为:使用one-of-K,或者one-hot编码,它可以用 OneHotEncoder来实现。该评估器将m个可能的feature类别值转换成m个二元feature。
例如:
>>> enc = preprocessing.OneHotEncoder() >>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) OneHotEncoder(categorical_features='all', dtype=<... 'float'>, handle_unknown='error', n_values='auto', sparse=True) >>> enc.transform([[0, 1, 3]]).toarray() array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
缺省的,每个feature可以取多少值可以从数据集中自动判断。通过使用n_values参数可以显示指定。在我们的数据集中有两个性别(gender),三个可能的大洲(continents),还有4种浏览器(web browser)。我们去拟合该estimator,并进行数据转换。在结果中,头两个数表示性别的编码,接下去的3个数表示大洲的编码,最后4个则用于浏览器。
详见字典载入feature
6.补充缺失值
出于其他原因,现实世界中,有许多数据集中包含着缺失值(missing values),经常编码成空格,NaN或者其它占位符。这样的数据集对于sklearn来说是不兼容的,它认为的输入数据必须是全是数值型的。一个基本策略是,使用不完整的数据(抛弃掉那些带缺失值的行)。然而,缺失的数据中也有可能含有有价值的信息(尽管不完整)。另一个更好地策略是,插入缺失值,比如:从已经数据中去模拟它们。Imputer类提供了基本策略来补充缺失值,或者使用均值、中值、或者行中最常用的值、或者缺失值所在列中最常用的值。该类提供了不同的缺失值补充策略。
下面的代码段演示了如何使用np.nan替换缺失值,使用了包含了缺失值的列(axis 0)的均值:
>>> 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)) [[ 4. 2. ] [ 6. 3.666...] [ 7. 6. ]]
Imputer类提支持稀疏策略:
>>> import scipy.sparse as sp >>> X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]]) >>> imp = Imputer(missing_values=0, strategy='mean', axis=0) >>> imp.fit(X) Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0) >>> X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]]) >>> print(imp.transform(X_test)) [[ 4. 2. ] [ 6. 3.666...] [ 7. 6. ]]
注意,缺失值用0编码,并被显式地存于矩阵中。如果缺失值的数目比观测值还要多时,这种格式很合适。
Imputer可以用在Pipeline上,来构建一个支持插值(imputation)的组合estimator。详见 Imputing missing values before building an estimator
7.生成多项式特征(polynomial features)
通常,由于考虑到输入数据的非线性feature的存在,你的模型变复杂。一个简单的方法是,使用多项式feature,它可以给出feature的高阶表示以及交叉项(interaction terms)。通过PolynomialFeatures实现:>>> import numpy as np >>> from sklearn.preprocessing import PolynomialFeatures >>> X = np.arange(6).reshape(3, 2) >>> X array([[0, 1], [2, 3], [4, 5]]) >>> poly = PolynomialFeatures(2) >>> poly.fit_transform(X) array([[ 1., 0., 1., 0., 0., 1.], [ 1., 2., 3., 4., 6., 9.], [ 1., 4., 5., 16., 20., 25.]])
X的feature可以通过(X1, X2) 转换成
在一些情况下,只有feature间的交叉项是必须的(忽略高阶项),可以通过interaction_only=True来实现:
>>> X = np.arange(9).reshape(3, 3) >>> X array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> poly = PolynomialFeatures(degree=3, interaction_only=True) >>> poly.fit_transform(X) array([[ 1., 0., 1., 2., 0., 0., 2., 0.], [ 1., 3., 4., 5., 12., 15., 20., 60.], [ 1., 6., 7., 8., 42., 48., 56., 336.]])
X的feature可以从(X1,X2,X3)转换成
注意:多项式feature只能显示地用在核方法(比如: sklearn.svm.SVC, sklearn.decomposition.KernelPCA)上的多项式核函数(polynomial Kernel functions)上。
Ridge regression的多项式内插(Polynomial interpolation)用它来创建多项式feature。
8.定制转换器
通常,你需要将一个存在的python函数转换成一个transformer来进行数据清洗和处理。你可以使用一个专用函数来实现一个转换器: FunctionTransformer。例如,我们可以在一个pipeline上使用一个log函数来进行转换:>>> import numpy as np >>> from sklearn.preprocessing import FunctionTransformer >>> transformer = FunctionTransformer(np.log1p) >>> X = np.array([[0, 1], [2, 3]]) >>> transformer.transform(X) array([[ 0. , 0.69314718], [ 1.09861229, 1.38629436]])
详见原文.
参考:
1.http://scikit-learn.org/stable/modules/preprocessing.html#preprocessing
相关文章推荐
- 【原】关于使用Sklearn进行数据预处理 —— 缺失值(Missing Value)处理
- Sklearn用户手册(三): 文本数据的处理
- sklearn-数据预处理scale
- sklearn中的数据预处理
- 使用sklearn来处理类别数据
- 数据预处理(2)—— One-hot coding 独热编码#分别使用 pandans.dummies 和 sklearn.feature_extraction.DictVectorizer 进行处理
- Python下的机器学习工具sklearn--数据预处理
- DataFrame通过sklearn做数据预处理
- sklearn学习记录二:数据预处理
- sklearn的数据预处理
- 关于使用Sklearn进行数据预处理 —— 缺失值(Missing Value)处理
- sklearn的preprocessing模块--数据预处理
- sklearn包中的分析算法对 数据进行处理
- 数据归一化和其在sklearn中的处理
- 数据挖掘sklearn中的的特征工程处理
- shell处理—文件汇总到一个文件里,用sqlldr装入数据库这些文件数据都少一个字段而字段内容为这个文件的名字
- awk:好用的数据处理工具
- 处理大规模数据的基础知识
- 处理百万级的数据
- C#16位MD5加密算法的一个错误测试数据处理