描述
机器学习的一些算法(如神经网络、SVM)对数据缩放非常敏感。通常的做法是对特征进行调节,使数据表示更适合与这些算法。
scikit-learn中提供了4中数据缩放方法:
- StandardScaler:确保每个特征平均值为0,方差为1,使所有特征都位于同一量级
- RobusScaler:工作原理与StandardScaler类似,确保每个特性的统计属性都位于同一范围
- MinMaxScaler:移动数据,使所有数据都刚好位于0到1之间。
- Normalizer:对每个个数据点进行缩放,使得特征向量的欧式长于等于1。(它将数据点投射到半径为1的圆上,这意味这每个数据点的缩放比都不相同。如果只有数据方向重要,而特征向量的长度无关紧要,那么通常用这种所方式归一化)
数据变换
import mglearn
mglearn.plots.plot_scaling()
应用数据变换
将核SVM(SVC)应用到cancer数据集上,并使用MinMaxScaler来预处理数据。
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
cancer = load_breast_cancer()
X_train,X_test,Y_train,Y_test = train_test_split(cancer.data,cancer.target,random_state=1)
print(X_train.shape)
print(X_test.shape)
导入MinMaxScaler,然后实例化,调用fit方法拟合缩放器。最后使用缩放器transform方法,对训练数据进行缩放
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
## 可以使用fit_transform代替fit、transform,一步到位
# X_train_scaled = scaler.fit_transform(X_train)
变换后的数据形状与原始数据相同,特征只是发生了移动和缩放。可以看到,现在所有特征都位于 0 到 1 之间。
对测试数据进行相同的缩放
为了让监督模型能够在测试集上运行,对训练集和测试集应用完全相同的变换是很重要。
例子1:训练使用缩放后的数据、测试使用原始数据
svc = SVC()
svc.fit(X_train_scaled,Y_train)
print(svc.score(X_train_scaled,Y_train),svc.score(X_test,Y_test))
例子2:训练、测试都使用缩放后的数据
svc = SVC()
svc.fit(X_train_scaled,Y_train)
X_test_scaled = scaler.transform(X_test)
print(svc.score(X_train_scaled,Y_train),svc.score(X_test_scaled,Y_test))
对比上面两个个例子,可以看到,测试集没有缩放的情况下(例子1),模型明显是一个过拟合的状态。
对训练集和测试集应用完全相同的变换后(例子3),模型训练、测试都拿到一个很不错的得分。(还可以针对SVC的参数进行调优,这里只是验证数据缩放对模型的影响)
预处理对监督学习的作用
通过上例的例子,可以看到数据缩放的作用非常显著。虽然数据缩放不涉及任何复杂的数学,但良好的做法仍然是使用 scikit-learn 提供的缩放机制,而不是自己重新实现它们。(在支持核向量机中手动实现了数据缩放)
可以通过改变使用的类将一种预处理算法轻松替换成另一种,因为所有的预处理类都具有相同的接口,都包含 fit 和 transform 方法:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
svc = SVC()
svc.fit(X_train_scaled,Y_train)
print(svc.score(X_train_scaled,Y_train),svc.score(X_test_scaled,Y_test))