Comment appliquer la standardisation aux SVM dans scikit-learn?

j'utilise la version stable actuelle 0.13 de scikit-learn. J'applique un classificateur de vecteur de support linéaire à certaines données en utilisant la classe sklearn.svm.LinearSVC.

Dans le chapitre sur le préprocesseur dans la documentation de scikit-learn, j'ai lu ce qui suit:

de nombreux éléments utilisés dans la fonction objective d'un algorithme d'apprentissage (comme le noyau RBF des machines vectorielles de Support ou les régularisateurs l1 et l2 des modèles linéaires)) supposons que toutes les caractéristiques sont centrées autour de zéro et ont une variance dans le même ordre. Si une caractéristique a une variance qui est des ordres de grandeur plus grands que les autres, elle pourrait dominer la fonction objective et rendre l'estimateur incapable d'apprendre des autres caractéristiques correctement comme prévu.

Question 1: la standardisation est-elle utile pour les SVM en général, aussi pour ceux qui ont une fonction de noyau linéaire comme dans mon cas?

Question 2: Pour autant que je comprenne, je dois calculer la moyenne et l'écart-type sur les données d'entraînement et appliquer cette même transformation sur les données d'essai en utilisant la classe sklearn.preprocessing.StandardScaler. Cependant, ce que je ne comprends pas, c'est si je dois aussi transformer les données de formation ou simplement les données d'essai avant de les transmettre au classificateur SVM.

Qu'est ce que je dois faire ceci:

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)

Ou dois-je faire ceci:

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)

En bref, dois-je utilisez scaler.fit(X_train) ou scaler.fit_transform(X_train) sur les données d'apprentissage afin d'obtenir des résultats raisonnables avec <!--6?

20
demandé sur pemistahl 2013-02-04 18:03:14

2 réponses

ni l'un ni l'autre.

scaler.transform(X_train) n'a aucun effet. transform opération n'est pas en place. Que vous avez à faire

X_train = scaler.fit_transform(X_train)

X_test = scaler.transform(X_test)

ou

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

vous avez toujours besoin de faire le même prétraitement sur les données de formation ou d'essai. Et oui, la standardisation est toujours bonne si elle reflète votre foi pour les données. En particulier pour kernel-svms il est souvent crucial.

32
répondu Andreas Mueller 2013-02-04 19:39:33

Pourquoi ne pas utiliser un Pipeline pour enchaîner (ou combiner) les transformateurs et les estimateurs en une seule fois? Cela vous évite de devoir ajuster et transformer vos données séparément, puis d'utiliser l'estimateur. Cela permettrait d'économiser de l'espace, trop.

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)
5
répondu vosirus 2016-09-16 20:26:04