python3 - sklearn metrics
Realice funciones de búsqueda de grillas en sklearn para ignorar modelos vacíos (2)
Usando python y scikit-learn, me gustaría hacer una búsqueda en grilla. Pero algunos de mis modelos terminan vacíos. ¿Cómo puedo hacer que la función de búsqueda de cuadrícula ignore esos modelos?
Supongo que puedo tener una función de puntuación que devuelve 0 si los modelos están vacíos, pero no estoy seguro de cómo.
predictor = sklearn.svm.LinearSVC(penalty=''l1'', dual=False, class_weight=''auto'')
param_dist = {''C'': pow(2.0, np.arange(-10, 11))}
learner = sklearn.grid_search.GridSearchCV(estimator=predictor,
param_grid=param_dist,
n_jobs=self.n_jobs, cv=5,
verbose=0)
learner.fit(X, y)
Mis datos son de tal manera que este objeto de learner
elegirá una C
correspondiente a un modelo vacío. ¿Alguna idea de cómo puedo asegurarme de que el modelo no esté vacío?
EDITAR : por un "modelo vacío" me refiero a un modelo que ha seleccionado 0 características para usar. Especialmente con un modelo regularizado l1
, esto puede suceder fácilmente. Entonces, en este caso, si la C
en SVM es lo suficientemente pequeña, el problema de optimización encontrará el vector 0 como la solución óptima para los coeficientes. Por lo tanto, predictor.coef_
será un vector de 0
s.
Intente implementar un marcador personalizado, algo similar a:
import numpy as np
def scorer_(estimator, X, y):
# Your criterion here
if np.allclose(estimator.coef_, np.zeros_like(estimator.coef_)):
return 0
else:
return estimator.score(X, y)
learner = sklearn.grid_search.GridSearchCV(...
scoring=scorer_)
No creo que haya una función tan incorporada; Sin embargo, es fácil hacer un gridsearcher personalizado:
from sklearn.cross_validation import KFold
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import cross_val_score
import itertools
from sklearn import metrics
import operator
def model_eval(X, y, model, cv):
scores = []
for train_idx, test_idx in cv:
X_train, y_train = X[train_idx], y[train_idx]
X_test, y_test = X[test_idx], y[test_idx]
model.fit(X_train, y_train)
nonzero_coefs = len(np.nonzero(model.coef_)[0]) #check for nonzero coefs
if nonzero_coefs == 0: #if they''re all zero, don''t evaluate any further; move to next hyperparameter combo
return 0
predictions = model.predict(X_test)
score = metrics.accuracy_score(y_test, predictions)
scores.append(score)
return np.array(scores).mean()
X, y = make_classification(n_samples=1000,
n_features=10,
n_informative=3,
n_redundant=0,
n_repeated=0,
n_classes=2,
random_state=0,
shuffle=False)
C = pow(2.0, np.arange(-20, 11))
penalty = {''l1'', ''l2''}
parameter_grid = itertools.product(C, penalty)
kf = KFold(X.shape[0], n_folds=5) #use the same folds to evaluate each hyperparameter combo
hyperparameter_scores = {}
for C, penalty in parameter_grid:
model = svm.LinearSVC(dual=False, C=C, penalty=penalty)
result = model_eval(X, y, model, kf)
hyperparameter_scores[(C, penalty)] = result
sorted_scores = sorted(hyperparameter_scores.items(), key=operator.itemgetter(1))
best_parameters, best_score = sorted_scores[-1]
print best_parameters
print best_score