sklearn - python multiclass classification
GridSearch para un estimador dentro de OneVsRestClassifier (1)
Cuando utiliza estimadores anidados con la búsqueda de grillas, puede determinar los parámetros con __
como separador. En este caso, el modelo SVC se almacena como un atributo denominado estimator
dentro del modelo OneVsRestClassifier
:
from sklearn.datasets import load_iris
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
from sklearn.grid_search import GridSearchCV
from sklearn.metrics import f1_score
iris = load_iris()
model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
parameters = {
"estimator__C": [1,2,4,8],
"estimator__kernel": ["poly","rbf"],
"estimator__degree":[1, 2, 3, 4],
}
model_tunning = GridSearchCV(model_to_set, param_grid=parameters,
score_func=f1_score)
model_tunning.fit(iris.data, iris.target)
print model_tunning.best_score_
print model_tunning.best_params_
Eso produce:
0.973290762737
{''estimator__kernel'': ''poly'', ''estimator__C'': 1, ''estimator__degree'': 2}
Quiero realizar GridSearchCV en un modelo de SVC, pero eso usa la estrategia de uno contra todos. Para la última parte, puedo hacer esto:
model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
Mi problema es con los parámetros. Digamos que quiero probar los siguientes valores:
parameters = {"C":[1,2,4,8], "kernel":["poly","rbf"],"degree":[1,2,3,4]}
Para realizar GridSearchCV, debería hacer algo como:
cv_generator = StratifiedKFold(y, k=10)
model_tunning = GridSearchCV(model_to_set, param_grid=parameters, score_func=f1_score, n_jobs=1, cv=cv_generator)
Sin embargo, luego lo ejecuto, obtengo:
Traceback (most recent call last):
File "/.../main.py", line 66, in <module>
argclass_sys.set_model_parameters(model_name="SVC", verbose=3, file_path=PATH_ROOT_MODELS)
File "/.../base.py", line 187, in set_model_parameters
model_tunning.fit(self.feature_encoder.transform(self.train_feats), self.label_encoder.transform(self.train_labels))
File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 354, in fit
return self._fit(X, y)
File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 392, in _fit
for clf_params in grid for train, test in cv)
File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 473, in __call__
self.dispatch(function, args, kwargs)
File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 296, in dispatch
job = ImmediateApply(func, args, kwargs)
File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 124, in __init__
self.results = func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 85, in fit_grid_point
clf.set_params(**clf_params)
File "/usr/local/lib/python2.7/dist-packages/sklearn/base.py", line 241, in set_params
% (key, self.__class__.__name__))
ValueError: Invalid parameter kernel for estimator OneVsRestClassifier
Básicamente, dado que el SVC está dentro de un OneVsRestClassifier y ese es el estimador que envío a GridSearchCV, no se puede acceder a los parámetros del SVC.
Para lograr lo que quiero, veo dos soluciones:
- Al crear el SVC, de alguna manera le dicen que no use la estrategia de uno contra uno, sino el uno contra todos.
- Indique de algún modo el GridSearchCV que los parámetros corresponden al estimador dentro del OneVsRestClassifier.
Todavía tengo que encontrar una manera de hacer cualquiera de las alternativas mencionadas. ¿Sabes si hay alguna manera de hacer alguno de ellos? ¿O tal vez podrías sugerir otra forma de obtener el mismo resultado?
¡Gracias!