将特征缩放至特定范围内:
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)
# print(X_scaled)
# print(X_scaled.mean(axis=0))
# print(X_scaled.std(axis=0))
# scaler = preprocessing.StandardScaler().fit(X_train)
# print(scaler)
# print(scaler.scale_)
# print(scaler.transform(X_train))
#将特征缩放至特定范围内 简单的数据矩阵缩放到``[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)
# print(X_train_minmax)
# #同样的转换实例可以被用与在训练过程中不可见的测试数据:实现和训练数据一致的缩放和移位操作:
# X_test = np.array([[ -3., -1., 4.]])
# X_test_minmax = min_max_scaler.transform(X_test)
# print(X_test_minmax)
# #检查缩放器(scaler)属性
# print(min_max_scaler.scale_)
# print(min_max_scaler.min_)
# MaxAbsScaler通过除以每个特征的最大值将训练数据特征缩放至 [-1, 1] 范围内
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)
print(X_train_maxabs) # doctest +NORMALIZE_WHITESPACE^
输出:
[[ 0.5 -1. 1. ]
[ 1. 0. 0. ]
[ 0. 1. -0.5]]
缩放有离群值的数据
如果你的数据包含许多异常值,使用均值和方差缩放可能并不是一个很好的选择。这种情况下,你可以使用 robust_scale
以及 RobustScaler
作为替代品。它们对你的数据的中心和范围使用更有鲁棒性的估计。
非线性转换
类似于缩放, QuantileTransformer
类将每个特征缩放在同样的范围或分布情况下。但是,通过执行一个秩转换能够使异常的分布平滑化,并且能够比缩放更少地受到离群值的影响。但是它的确使特征间及特征内的关联和距离失真了
归一化
from sklearn import preprocessing
import numpy as np
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')
print(X_normalized)
normalizer = preprocessing.Normalizer().fit(X) # fit does nothing
print(normalizer.transform(X))
print(normalizer.transform([[-1., 1., 5.]]))
输出:
from sklearn import preprocessing
import numpy as np
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
X_normalized = preprocessing.normalize(X, norm='l2')
print(X_normalized)
normalizer = preprocessing.Normalizer().fit(X) # fit does nothing
print(normalizer.transform(X))
print(normalizer.transform([[-1., 1., 5.]]))
二值化
特征二值化 是 将数值特征用阈值过滤得到布尔值 的过程
X = [[ 1., -1., 2.],
[ 2., 0., 0.],
[ 0., 1., -1.]]
binarizer = preprocessing.Binarizer().fit(X) # fit does nothing
print(binarizer)
print(binarizer.transform(X))
binarizer = preprocessing.Binarizer(threshold=1.1)
print(binarizer.transform(X))
输出:
Binarizer(copy=True, threshold=0.0)
[[1. 0. 1.]
[1. 0. 0.]
[0. 1. 0.]]
[[0. 0. 1.]
[1. 0. 0.]
[0. 0. 0.]]
分类特征编码
一种将分类特征转换为能够被scikit-learn中模型使用的编码是one-of-K或one-hot编码,在 OneHotEncoder
中实现。这个类使用 m
个可能值转换为 m
值化特征,将分类特征的每个元素转化为一个值。
from sklearn import preprocessing
import numpy as np
#默认情况下,每个特征使用几维的数值由数据集自动推断。当然,你也可以通过使用参数``n_values``来精确指定
enc = preprocessing.OneHotEncoder()
print(enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]))
print(enc.transform([[0, 1, 3]]).toarray())
enc = preprocessing.OneHotEncoder(n_values=[2, 3, 4])
# 注意到第二、三个特征是不全的
# features
print(enc.fit([[1, 2, 3],
[0, 2, 0]]))
print(enc.transform([[1, 0, 3]]).toarray())
print(enc.transform([[1, 0, 2]]).toarray())
print(enc.transform([[1, 0, 1]]).toarray())
print(enc.transform([[1, 0, 0]]).toarray())
输出:
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
handle_unknown='error', n_values='auto', sparse=True)
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
handle_unknown='error', n_values=[2, 3, 4], sparse=True)
[[0. 1. 1. 0. 0. 0. 0. 0. 1.]]
[[0. 1. 1. 0. 0. 0. 0. 1. 0.]]
[[0. 1. 1. 0. 0. 0. 1. 0. 0.]]
[[0. 1. 1. 0. 0. 1. 0. 0. 0.]]
缺失值插补
因为各种各样的原因,真实世界中的许多数据集都包含缺失数据,这类数据经常被编码成空格、NaNs,或者是其他的占位符。但是这样的数据集并不能scikit-learn学习算法兼容,因为大多的学习算法都默认假设数组中的元素都是数值,因而所有的元素都有自己的意义。 使用不完整的数据集的一个基本策略就是舍弃掉整行或整列包含缺失值的数据。但是这样就付出了舍弃可能有价值数据(即使是不完整的 )的代价。 处理缺失数值的一个更好的策略就是从已有的数据推断出缺失的数值。
Imputer
类提供了估算缺失值的基本策略,使用缺失值所在的行/列中的平均值、中位数或者众数来填充。这个类也支持不同的缺失值编码。
以下代码段演示了如何使用包含缺失值的列(轴0)的平均值来替换编码为 np.nan
的缺失值:
import numpy as np
from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
print(imp.fit([[1, 2],
[np.nan, 3],
[7, 6]]))
X = [[np.nan, 2],
[6, np.nan],
[7, 6]]
print(imp.transform(X))
# 第一列缺失值 = (1 +7) /2 =4
# 第二列缺失值 = (2+3+6)/3 =3.666667
输出:
Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0)
[[4. 2. ]
[6. 3.66666667]
[7. 6. ]]
生成多项式特征
在机器学习中,通过增加一些输入数据的非线性特征来增加模型的复杂度通常是有效的。一个简单通用的办法是使用多项式特征,这可以获得特征的更高维度和互相间关系的项
import numpy as np
from sklearn.preprocessing import PolynomialFeatures
X = np.arange(6).reshape(3, 2)
print(X)
poly = PolynomialFeatures(2)
print(poly.fit_transform(X))
#X 的特征已经从 (X_1, X_2) 转换为 (1, X_1, X_2, X_1^2, X_1X_2, X_2^2)
X = np.arange(9).reshape(3, 3)
print(X)
poly = PolynomialFeatures(degree=3, interaction_only=True)
print(poly.fit_transform(X))
#X的特征已经从 (X_1, X_2, X_3) 转换为 (1, X_1, X_2, X_3, X_1X_2, X_1X_3, X_2X_3, X_1X_2X_3)
输出:
[[0 1]
[2 3]
[4 5]]
[[ 1. 0. 1. 0. 0. 1.]
[ 1. 2. 3. 4. 6. 9.]
[ 1. 4. 5. 16. 20. 25.]]
[[0 1 2]
[3 4 5]
[6 7 8]]
[[ 1. 0. 1. 2. 0. 0. 2. 0.]
[ 1. 3. 4. 5. 12. 15. 20. 60.]
[ 1. 6. 7. 8. 42. 48. 56. 336.]]
自定义转换器
在机器学习中,想要将一个已有的 Python 函数转化为一个转换器来协助数据清理或处理。可以使用 FunctionTransformer
从任意函数中实现一个转换器。例如,在一个管道中构建一个实现日志转换的转化器,这样做:
import numpy as np
from sklearn.preprocessing import FunctionTransformer
transformer = FunctionTransformer(np.log1p)# = log(1+p)
X = np.array([[0, 1], [2, 3]])
print(transformer.transform(X))
输出:
[[0. 0.69314718]
[1.09861229 1.38629436]]