python - español - ¿Cómo aplicar la estandarización a SVMs en scikit-learn?
sklearn python install (2)
Estoy usando la versión estable actual 0.13 de scikit-learn. Estoy aplicando un clasificador de vectores de soporte lineal a algunos datos utilizando la clase sklearn.svm.LinearSVC
.
En el capítulo sobre el preprocesamiento en la documentación de scikit-learn, he leído lo siguiente:
Muchos elementos utilizados en la función objetivo de un algoritmo de aprendizaje (como el kernel RBF de Support Vector Machines o los regularizadores l1 y l2 de modelos lineales) asumen que todas las características están centradas alrededor de cero y tienen varianza en el mismo orden. Si una característica tiene una variación que es órdenes de magnitud mayor que otras, podría dominar la función objetivo y hacer que el estimador no pueda aprender de otras características correctamente como se esperaba.
Pregunta 1: ¿Es la estandarización útil para SVM en general, también para aquellos con una función de kernel lineal como en mi caso?
Pregunta 2: Según tengo entendido, tengo que calcular la media y la desviación estándar en los datos de entrenamiento y aplicar esta misma transformación en los datos de prueba utilizando la clase sklearn.preprocessing.StandardScaler
. Sin embargo, lo que no entiendo es si tengo que transformar los datos de entrenamiento también o solo los datos de prueba antes de enviarlos al clasificador SVM.
Es decir, tengo que hacer esto:
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)
O tengo que hacer esto:
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 resumen, ¿tengo que usar scaler.fit(X_train)
o scaler.fit_transform(X_train)
en los datos de entrenamiento para obtener resultados razonables con LinearSVC
?
¿Por qué no usar un Pipeline
para encadenar (o combinar) transformadores y estimadores de una sola vez? Le ahorra la molestia de ajustar y transformar sus datos por separado y luego usar el estimador. También ahorraría algo de espacio.
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)
Ninguno.
scaler.transform(X_train)
no tiene ningún efecto. La operación de transform
no está en el lugar. Tu tienes que hacer
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
o
X_train = scaler.fit(X_train).transform(X_train)
Siempre debe hacer el mismo preprocesamiento en los datos de entrenamiento o de prueba. Y sí, la estandarización siempre es buena si refleja su creencia para los datos. En particular para kernel-svms es a menudo crucial.