Make grid search functions in sklearn to ignore empty models

人盡茶涼 提交于 2019-12-10 18:24:07

问题


Using python and scikit-learn, I'd like to do a grid search. But some of my models end up being empty. How can I make the grid search function to ignore those models?

I guess I can have a scoring function which returns 0 if the models is empty, but I'm not sure how.

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)

My data's in a way that this learner object will choose a C corresponding to an empty model. Any idea how I can make sure the model's not empty?

EDIT: by an "empty model" I mean a model that has selected 0 features to use. Specially with an l1 regularized model, this can easily happen. So in this case, if the C in the SVM is small enough, the optimization problem will find the 0 vector as the optimal solution for the coefficients. Therefore predictor.coef_ will be a vector of 0s.


回答1:


Try to implement custom scorer, something similar to:

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_)



回答2:


I don't think there is such a built-in function; it's easy, however, to make a custom gridsearcher:

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     


来源:https://stackoverflow.com/questions/32417268/make-grid-search-functions-in-sklearn-to-ignore-empty-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!