Как применить стандартизацию к SVM в scikit-learn?
Я использую текущую стабильную версию 0.13 scikit-learn. Я применяю векторный классификатор линейной поддержки к некоторым данным, используя класс sklearn.svm.LinearSVC
.
В главе о предварительной обработке в документации scikit-learn я прочитал следующее:
Многие элементы, используемые в целевой функции алгоритма обучения (например, ядро RBF для поддерживающих векторных машин или регуляризаторов линейных моделей l1 и l2), предполагают, что все функции центрированы вокруг нуля и имеют дисперсию в том же порядке. Если функция имеет дисперсию, которая на несколько порядков больше, чем другие, она может доминировать над целевой функцией и сделать оценщик неспособным учиться на других функциях правильно, как ожидалось.
Вопрос 1: Является ли стандартизация полезной для SVM вообще, также для тех, у кого есть линейная функция ядра, как в моем случае?
Вопрос 2: Насколько я понимаю, мне приходится вычислять среднее и стандартное отклонение данных обучения и применять это же преобразование к тестовым данным, используя класс 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
?
Ответы
Ответ 1
Ни.
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-svms это очень важно.
Ответ 2
Почему бы не использовать 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)