1.首先要明确有多少特征,哪些是连续的,哪些是类别的。
2.检查有没有缺失值,对确实的特征选择恰当方式进行弥补,使数据完整。
3.对连续的数值型特征进行标准化,使得均值为0,方差为1。
4.对类别型的特征进行one-hot编码。
5.将需要转换成类别型数据的连续型数据进行二值化。
6.为防止过拟合或者其他原因,选择是否要将数据进行正则化。
7.在对数据进行初探之后发现效果不佳,可以尝试使用多项式方法,寻找非线性的关系。
8.根据实际问题分析是否需要对特征进行相应的函数转换。
Standardization标准化:将特征数据的分布调整成标准正太分布,也叫高斯分布,也就是使得数据的均值维0,方差为。
标准化的原因在于如果有些特征的方差过大,则会主导目标函数从而使参数估计器无法正确地去学习其他特征。
标准化的过程为两步:去均值的中心化(均值变为0);方差的规模化(方差变为1)。
(1)在sklearn.preprocessing中提供了一个scale的方法,可以实现以上功能。
(2)preprocessing这个模块还提供了一个实用类StandarScaler,它可以在训练数据集上做了标准转换操作之后,把相同的转换应用到测试训练集中。
这是相当好的一个功能。可以对训练数据,测试数据应用相同的转换,以后有新的数据进来也可以直接调用,不用再重新把数据放在一起再计算一次了。
from sklearn.model_selection import train_test_split
from sklearn import datasets,preprocessing
import numpy as np
iris = datasets.load_iris()
x, y = iris.data, iris.target
# 标准化
# 将每一列特征标准化为标准正态分布,注意,标准化是针对每一列而言的
x_scale = preprocessing.scale(x)
print(x_scale.mean(),x_scale.std())
print(x_scale.mean(axis=0))# axis=1表示对每一行去做这个操作,axis=0表示对每一列做相同的这个操作
x_scale2 = preprocessing.StandardScaler().fit(x)
x_scale3 = x_scale2.transform(x)
print(x_scale3.mean(),x_scale3.std())
new_x = np.array([[1,1,1,1]])
x_scale4 = x_scale2.transform(new_x)
print(x_scale4.mean())
out:
-1.4684549872375404e-15 1.0
[-1.69031455e-15 -1.84297022e-15 -1.69864123e-15 -1.40924309e-15]
-1.4684549872375404e-15 1.0
-3.1086104294861445
也就是使得特征的分布是在一个给定最小值和最大值的范围内的。一般情况下是在[0,1]之间,或者是特征中绝对值最大的那个数为1,其他数以此维标准分布在[[-1,1]之间
以上两者分别可以通过MinMaxScaler 或者 MaxAbsScaler方法来实现。
之所以需要将特征规模化到一定的[0,1]范围内,是为了对付那些标准差相当小的特征并且保留下稀疏数据中的0值。
在MinMaxScaler中是给定了一个明确的最大值与最小值。它的计算公式如下:
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std / (max - min) + min
以下这个例子是将数据规于[0,1]之间,每个特征中的最小值变成了0,最大值变成了1。
from sklearn import datasets,preprocessing
iris = datasets.load_iris()
x, y = iris.data, iris.target
scaler = preprocessing.MinMaxScaler()
x_scale = scaler.fit_transform(x)
print(x_scale)
print(x_scale.mean(0), x_scale.std(0))
原理与上面的很像,只是数据会被规模化到[-1,1]之间。也就是特征中,所有数据都会除以最大值。这个方法对那些已经中心化均值维0或者稀疏的数据有意义。
from sklearn import datasets,preprocessing
iris = datasets.load_iris()
x, y = iris.data, iris.target
scaler = preprocessing.MaxAbsScaler()
x_scale = scaler.fit_transform(x)
print(x_scale)
print(x_scale.mean(0), x_scale.std(0))
如果对稀疏数据进行去均值的中心化就会破坏稀疏的数据结构。虽然如此,我们也可以找到方法去对稀疏的输入数据进行转换,特别是那些特征之间的数据规模不一样的数据。
MaxAbsScaler 和 maxabs_scale这两个方法是专门为稀疏数据的规模化所设计的。
如果你的数据有许多异常值,那么使用数据的均值与方差去做标准化就不行了。
在这里,你可以使用robust_scale 和 RobustScaler这两个方法。它会根据中位数或者四分位数去中心化数据。
from sklearn import datasets,preprocessing
iris = datasets.load_iris()
x, y = iris.data, iris.target
scaler = preprocessing.RobustScaler()
x_scale = scaler.fit_transform(x)
print(x_scale)
print(x_scale.mean(0), x_scale.std(0))
正则化是将样本在向量空间模型上的一个转换,经常被使用在分类与聚类中。
函数normalize 提供了一个快速有简单的方式在一个单向量上来实现这正则化的功能。正则化有l1,l2等。
from sklearn.model_selection import train_test_split
from sklearn import datasets,preprocessing
import numpy as np
iris = datasets.load_iris()
x, y = iris.data, iris.target
x_normalized = preprocessing.Normalizer(norm="l2").fit(x)
x_normalized = x_normalized.transform(x)
print(x_normalized.mean(0),x_normalized.std(0))
# 这两段代码都一样
scaler = preprocessing.Normalizer(norm="l2")
x_scale = scaler.fit_transform(x)
print(x_scale.mean(0), x_scale.std(0))
out:
[0.75140029 0.40517418 0.45478362 0.14107142] [0.04421945 0.10527109 0.15945216 0.07771647]
[0.75140029 0.40517418 0.45478362 0.14107142] [0.04421945 0.10527109 0.15945216 0.07771647]
特征的二值化是指将数值型的特征数据转换成布尔类型的值。可以使用实用类Binarizer。
默认是根据0来二值化,大于0的都标记为1,小于等于0的都标记为0。当然也可以自己设置这个阀值,只需传出参数threshold即可。
from sklearn import datasets,preprocessing
iris = datasets.load_iris()
x, y = iris.data, iris.target
x2 = preprocessing.Binarizer().fit(x)
x3 = x2.transform(x)
print(x3)
# 两段代码一样
scaler = preprocessing.Binarizer(threshold=0)
x_scale = scaler.fit_transform(x)
print(x_scale)
类别特征无法直接进入模型,它们需要被转换成整数来表征。要想使得类别型的变量能最终被模型直接使用,可以使用one-of-k编码或者one-hot编码。这些都可以通过OneHotEncoder实现。
from sklearn import datasets,preprocessing
enc = preprocessing.OneHotEncoder()
a = enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
b = enc.transform([[0,1,3]]).toarray()
print(b)
enc = preprocessing.OneHotEncoder(n_values=[2,3,4])
c = enc.fit([[1, 2, 3], [0, 2, 0]])
d = enc.transform([[1,0,0]]).toarray()
print(d)
enc = preprocessing.OneHotEncoder(n_values=3, sparse=False)
ans = enc.fit_transform([[0], [1], [2],[1]])
print(ans)
out:
[[1. 0. 0. 1. 0. 0. 0. 0. 1.]]
[[0. 1. 1. 0. 0. 1. 0. 0. 0.]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]
[0. 1. 0.]]
在scikit-learn的模型中都是假设输入的数据是数值型的,并且都是有意义的,如果有缺失数据是通过NAN,或者空值表示的话,就无法识别与计算了。
要弥补缺失值,可以使用均值,中位数,众数等等。Imputer这个类可以实现。
imp = preprocessing.Imputer(missing_values='NaN', strategy='mean', axis=0)
y_imp = imp.fit_transform([[np.nan, 2], [6, np.nan], [7, 6]])
print(y_imp)
# 通过学习填值
imp.fit([[1, 2], [np.nan, 3], [7, 6]])
y_imp = imp.transform([[np.nan, 2], [6, np.nan], [7, 6]])
print(y_imp)
out:
[[6.5 2. ]
[6. 4. ]
[7. 6. ]]
[[4. 2. ]
[6. 3.66666667]
[7. 6. ]]# (1+7+4)/3=4 (2+3+6)/3=11/3
有的时候线性的特征并不能做出美的模型,于是我们会去尝试非线性。非线性是建立在将特征进行多项式地展开上的。
比如将两个特征 (X_1, X_2),它的平方展开式便转换成5个特征(1, X_1, X_2, X_1^2, X_1X_2, X_2^2).
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
# 自建一组3*2的样本
x = np.arange(6).reshape(3, 2)
print(x)
# 创建2次方的多项式
poly = PolynomialFeatures(2)
x = poly.fit_transform(x)
print(x)
out:
[[0 1]
[2 3]
[4 5]]
[[ 1. 0. 1. 0. 0. 1.]
[ 1. 2. 3. 4. 6. 9.]
[ 1. 4. 5. 16. 20. 25.]]# 里面有5个特征,加上第一列的是Bias.
参数说明:
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
x = np.arange(9).reshape(3, 3)
poly = PolynomialFeatures(degree=3, interaction_only=True)
x = poly.fit_transform(x)
print(x)
out:
[[ 1. 0. 1. 2. 0. 0. 2. 0.]
[ 1. 3. 4. 5. 12. 15. 20. 60.]
[ 1. 6. 7. 8. 42. 48. 56. 336.]]
通俗的讲,就是把原始的特征放进一个函数中做转换,这个函数出来的值作为新的特征。比如说将特征数据做log转换,做倒数转换等等。FunctionTransformer 可以实现这个功能
import numpy as np
from sklearn.preprocessing import FunctionTransformer
transformer = FunctionTransformer(np.log1p)
#log1p 的使用就像是一个数据压缩到了一个区间,与数据的标准类似。其逆运算就是expm1的函数
x = np.array([[0, 1], [2, 3]])
y = transformer.transform(x)
print(y)
out:
[[0. 0.69314718]
[1.09861229 1.38629436]]