Подтвердить что ты не робот

Как применить стандартизацию к 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?

4b9b3361

Ответ 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)