26

我正在使用 scikit-learn 的当前稳定版本 0.13。我正在使用类对一些数据应用线性支持向量分类器sklearn.svm.LinearSVC

在scikit-learn 文档中关于预处理的章节中,我阅读了以下内容:

学习算法的目标函数中使用的许多元素(例如支持向量机的 RBF 内核或线性模型的 l1 和 l2 正则化器)假设所有特征都以零为中心并且具有相同顺序的方差。如果一个特征的方差比其他特征大几个数量级,它可能会主导目标函数并使估计器无法按预期正确地从其他特征中学习。

问题 1:标准化对于一般的 SVM 有用吗,也适用于像我这样具有线性核函数的那些?

问题 2:据我了解,我必须计算训练数据的均值和标准差,并使用 class 对测试数据应用相同的转换sklearn.preprocessing.StandardScaler。但是,我不明白的是,在将训练数据输入 SVM 分类器之前,我是否必须同时转换训练数据或仅转换测试数据。

也就是说,我是否必须这样做:

scaler = StandardScaler()
scaler.fit(X_train)                # only compute mean and std here
X_test = scaler.transform(X_test)  # perform standardization by centering and scaling

clf = LinearSVC()
clf.fit(X_train, y_train)
clf.predict(X_test)

还是我必须这样做:

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)  # compute mean, std and transform training data as well
X_test = scaler.transform(X_test)  # same as above

clf = LinearSVC()
clf.fit(X_train, y_train)
clf.predict(X_test)

简而言之,我是否必须使用scaler.fit(X_train)scaler.fit_transform(X_train)在训练数据上才能获得合理的结果LinearSVC

4

2 回答 2

38

两者都不。

scaler.transform(X_train)没有任何效果。transform操作不到位。你所要做的

X_train = scaler.fit_transform(X_train)

X_test = scaler.transform(X_test)

或者

X_train = scaler.fit(X_train).transform(X_train)

您总是需要对训练或测试数据进行相同的预处理。是的,标准化总是好的,如果它反映了你对数据的信念。特别是对于 kernel-svm,它通常是至关重要的。

于 2013-02-04T18:45:05.273 回答
8

为什么不一次性使用Pipeline链接(或组合)转换器和估算器?为您省去分别拟合和转换数据然后使用估算器的麻烦。它也会节省一些空间。

from sklearn.pipeline import Pipeline

pipe_lrSVC = Pipeline([('scaler', StandardScaler()), ('clf', LinearSVC())])
pipe_lrSVC.fit(X_train, y_train)
y_pred = pipe_lrSVC.predict(X_test)
于 2016-09-16T20:26:04.677 回答