sklearn学习之--预处理数据
1.标准化,也成为曲俊致和方差按比例缩放
说明:什么是标准化 :数值减去均值,再除以标准差
什么是中心化:变量减去他们的均值
意义:数据中心化和标准化在回归分析中是取消由于量纲不同,自身变异或者数值相差较大一起的误差。
目的:通过中心化和标准化处理,得到均值为0,标准差为1的服从标准正态分布的数据。
数据集的标准化对scikit-learn中实现的大多是机器学习算法来说是常见的要求。如果个别特征或多或少看起来不是很像标准正态分布(具有0均值和单位方差),那么它的他们的表现可能会比较差。
在实际情况中,我们经常忽略特征的分布形状,直接经过去均值来对某个特征进行中心化,在通过初一非常亮特征的标准差进行缩放。
例如,在机器学习算法的目标函数例如(SVM的RBF内核或者线性模型的l1和l2正则化),许多学习算法目标函数的额基础都是假设所有的特征都是零均值并且具有同一阶数上的方差。如果某个特征的方差比其他特征的大几个数量级,那么他就会在学习算法中占主导位置,导致学习器并不能如我们所期望的那样,从其他特征中学习。
函数scale为数组形状的数据集的标准化提供了一个快捷的实现
from sklearn import preprocessing
import numpy as np
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
X_scaled = preprocessing.scale(X_train)
#结果
array([[ 0. ..., -1.22..., 1.33...],
[ 1.22..., 0. ..., -0.26...],
[-1.22..., 1.22..., -1.06...]])
经过缩放后的数据具有零均值以及标准方差
X_scaled.mean(axis=0)
#结果
array([ 0., 0., 0.])
X_scaled.std(axis=0)
#结果
array([ 1., 1., 1.])
预处理模块还提供了一个实用类StandardScaler,它实现了转化器的API来计算训练集上的平均值和标准偏差,一遍以后能够在测试集上重新引用相同的变换。因此,这个 类适合用于sklearn,pipe.Plieline的早期步骤。计算平均值和标准差
from sklearn import preprocessing
import numpy as np
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
scaler=preprocessing.StandarScaler().fit(X_train)
scaler.mean_ #均值结果 array([ 1. ..., 0. ..., 0.33...])
scaler.scale_ #缩放系数
1.1 将特征缩放至特定的范围内
一种标准化是将特征缩放到给定的最小值和最大值之间,通常在零和一之间,或者也可以将每个特征的最大绝对值转换至单位大小。可以分别使用MInMaxScaler和MaxAbsScaler
说过这种缩放的目的包括实现特征极小方差的鲁棒性以及在系数矩阵中保留零元素
以下是将简单数据的矩阵苏佛昂的奥0,1的例子
X_train = np.array([[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]])
#此处默认属性是[0,1] feature_range : tuple (min, max), default=(0, 1)
min_max_scaler=preprocessing.MinMaxScaler()
X_train_minmax=min_max_scaler.fit_transform(X_train)
#训练结果
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
同样的转换实例也可以被用在于训练过程中不可见的测试数据:实现和训练数据一致新的缩放和位移操作
1.2 缩放稀疏(矩阵)数据
中心化稀疏(矩阵)数据会破坏数据的系数结构,因此很少有一个比较明智的实现方式。但是缩放稀疏是有意义的,尤其当几个特征不在同一个量级范围时
中心化稀疏(矩阵)数据会破坏数据的稀疏结构,因此很少有一个比较明智的实现方式。但是缩放稀疏输入是有意义的,尤其是当几个特征在不同的量级范围时。
MaxAbsScaler
以及 maxabs_scale
是专为缩放数据而设计的,并且是缩放数据的推荐方法。但是, scale
和StandardScaler
也能够接受 scipy.sparse
作为输入,只要参数 with_mean=False
被准确传入它的构造器。否则会出现ValueError
的错误,因为默认的中心化会破坏稀疏性,并且经常会因为分配过多的内存而使执行崩溃。 RobustScaler
不能适应稀疏输入,但你可以在稀疏输入使用 transform
方法。
注意,缩放器同时接受压缩的稀疏行和稀疏列(参见 scipy.sparse.csr_matrix
以及 scipy.sparse.csc_matrix
)。任何其他稀疏输入将会 转化为压缩稀疏行表示 。为了避免不必要的内存复制,建议在上游(早期)选择CSR或CSC表示。
最后,最后,如果已经中心化的数据并不是很大,使用 toarray
方法将输入的稀疏矩阵显式转换为数组是另一种选择。
1.3 缩放有离群值的数据
如果你的数据包含许多异常值,使用均值和方差缩放可能并不是一个很好的选择。这种情况下,你可以使用 robust_scale
以及 RobustScaler
作为替代品。它们对你的数据的中心和范围使用更有鲁棒性的估计
2.非线性转换
类似于缩放,QuantitleTransformer类的每个特征缩放在同样的范围或者分布情况下。但是,通过执行一个秩转换能够使异常的分布平滑化,并且能够比缩放更少的收到离群值的影响。但是它的确是特征之间以及特征内的管理和距离失真了。
QuantileTransformer类以及quantile_transform函数提供了一个机遇分位数函数的无参数转化,将数据映射到了零道义的均值分布上
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris=load_iris
X,y=iris.data,iris.target
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0)
quantile_transformer=preprocessing.QuantileTransformer(random_state=0)
X_train_trans = quantile_transformer.fit_transform(X_train)
X_test_trans = quantile_transformer.transform(X_test)
np.percentile(X_train[:, 0], [0, 25, 50, 75, 100])
#结果 array([ 4.3, 5.1, 5.8, 6.5, 7.9])
这个特征是萼片的厘米单位长度。一旦应用费位数转换,这些元素就接近于之前定义的百分位数
通常情况会转我多多维。
3.归一化
归一化 是 缩放单个样本以具有单位范数 的过程。如果你计划使用二次形式(如点积或任何其他核函数)来量化任何样本间的相似度,则此过程将非常有用。
这个观点基于 向量空间模型(Vector Space Model) ,经常在文本分类和内容聚类中使用.
函数 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
工具类使用 Transformer
API 实现了相同的操作(即使在这种情况下, fit
方法是无用的:该类是无状态的,因为该操作独立对待样本).
因此这个类适用于 sklearn.pipeline.Pipeline
的早期步骤:
4.二值化
特征二值化是将数值特征用阈值过滤得到布尔值的过程。对于下游的概率性模型是有用的。他假设输入数据是多值分布
例如:
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
binarizer=preprocessing.Binarizer().fit(X)
binarzier.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.]])
5.分类特征编码
在机器学习中,特征经常不是数值型的而是分类型的。举个例子,一个人可能有 ["male", "female"]
,["from Europe", "from US", "from Asia"]
,["uses Firefox", "uses Chrome", "uses Safari", "uses Internet Explorer"]
等分类的特征。这些特征能够被有效地编码成整数,比如 ["male", "from US", "uses Internet Explorer"]
可以被表示为 [0, 1, 3]
,["female", "from Asia", "uses Chrome"]
表示为 [1, 2, 1]
。
这个的整数特征表示并不能在scikit-learn的估计器中直接使用,因为这样的连续输入,估计器会认为类别之间是有序的,但实际却是无序的。(例如:浏览器的类别数据则是任意排序的)
一种将分类特征转换为能够被scikit-learn中模型使用的编码是one-of-K或one-hot编码,在 OneHotEncoder
中实现。这个类使用 m
个可能值转换为 m
值化特征,将分类特征的每个元素转化为一个值。
考虑例子如下:
enc=preprocessing.OneHotEncoder()
enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
6.缺失值插补
因为各种各样的原因,真实世界中的许多数据集都包含缺失数据,这类数据经常被编码成空格、NaNs,或者是其他的占位符。但是这样的数据集并不能scikit-learn学习算法兼容,因为大多的学习算法都默认假设数组中的元素都是数值,因而所有的元素都有自己的意义。 使用不完整的数据集的一个基本策略就是舍弃掉整行或整列包含缺失值的数据。但是这样就付出了舍弃可能有价值数据(即使是不完整的 )的代价。 处理缺失数值的一个更好的策略就是从已有的数据推断出缺失的数值。
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]])
X = [[np.nan, 2], [6, np.nan], [7, 6]]
print(imp.transform(X))