2017-09-27 4 views
0

J'essaie de faire Randomized Parameter Optimization sur un MultinomialNB (1). Maintenant, mon paramètre a 3 et pas une valeur, car il est 'class_prior' et j'ai 3 classes.Scikit-Learn RandomizedSearchCV ne fonctionne pas pour class_prior dans MultinomialNB

from sklearn.naive_bayes import MultinomialNB 
from sklearn.grid_search import RandomizedSearchCV 
from scipy.stats import uniform 

tuned_parameters = {'class_prior': [uniform.rvs(0,3), uniform.rvs(0,3), 
uniform.rvs(0,3)]} 
clf = RandomizedSearchCV(MultinomialNB(), tuned_parameters, cv=3, 
scoring='f1_micro', n_iter=10) 

Cependant, le journal des erreurs ressemble:

... 
File "/home/mark/Virtualenvs/python3env2/lib/python3.5/site- 
packages/sklearn/naive_bayes.py", line 607, in fit 
self._update_class_log_prior(class_prior=class_prior) 
File "/home/mark/Virtualenvs/python3env2/lib/python3.5/site- 
packages/sklearn/naive_bayes.py", line 455, in _update_class_log_prior 
if len(class_prior) != n_classes: 
TypeError: object of type 'numpy.float64' has no len() 

également essayé d'enlever les .rvs ->

TypeError: object of type 'rv_frozen' has no len() 

Est-il impossible de RandomizeSearch une variable qui a 3 composantes, à savoir les 3 class_priors?

(1) http://scikit-learn.org/stable/modules/grid_search.html

Répondre

2

Oui son possible. Procédez comme suit:

tuned_parameters = {'class_prior': [[uniform.rvs(0,3), uniform.rvs(0,3), 
uniform.rvs(0,3)]]} 

Notez les crochets entourant les valeurs. La raison en est que les paramètres à être réglés par RandomizedSearchCV (ou GridSearchCV d'ailleurs) devraient être enveloppés dans une liste, à partir de laquelle un seul élément sera essayé à chaque fois. La combinaison sur les éléments qui produit le score le plus élevé (ou le plus bas en cas de perte) sera conservée.

Par exemple, voir ce code simple pour le réglage des paramètres de SVC:

parameters = {'kernel':['linear', 'rbf'], 'C':[1, 10]} 

Ce sera étendu dans une permutation de 4 au total des valeurs comme ci-dessous:

Option1:- 'kernel':'linear', 'C':1 
Option2:- 'kernel':'linear', 'C':10 
Option3:- 'kernel':'rbf', 'C':1 
Option4:- 'kernel':'rbf', 'C':10 

Cela signifie que l'estimateur être ajusté 4 fois (chaque fois en utilisant une option différente de ci-dessus) et ensuite le meilleur estimateur sera conservé.

Dans votre cas, selon le documentation of MultinomialNBclass_prior est le tableau des probabilités des classes.

Donc, idéalement, il devrait être élargi dans la manière suivante:

Option1: 'class_prior': [uniform.rvs (0,3), (0,3) uniform.rvs, uniform.rvs (0,3)]

Mais RandomizedSearhCV (qui ont aucune information sur le type de class_prior), il sera étendu comme:

Option1: 'class_prior': uniform.rvs(0,3) 
Option2: 'class_prior': uniform.rvs(0,3) 
Option3: 'class_prior': uniform.rvs(0,3) 

qui sera ensuite présenté à MultinomialNB et depuis la sortie de uniform.rvs() est un flotteur et pas une liste, il n'aura pas le len() et d'où l'erreur.

Pour cela, vous devez utiliser doubles crochets pour que l'expansion correcte se fait comme ci-dessous:

Option1: 'class_prior': [uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)] 

Mais maintenant il y a un problème. Depuis l'expansion a abouti à une seule option, de toute évidence qui sera sélectionné quel que soit le score (parce que nous n'avons pas d'autre choix).

En outre, RandomizedSearchCV va lancer une erreur parce que vous avez spécifié n_iter=10 et le nombre de choix devrait être plus que cela (dans notre cas, c'est un choix unique).

Vous avez donc besoin de modifier votre tuned_parameters comme ceci:

tuned_parameters = {'class_prior': [[uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)], 
            [uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)], 
            [uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)], 
            [uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)], 
            [uniform.rvs(0,3), uniform.rvs(0,3), uniform.rvs(0,3)], 
            ... 
            ... 
            ... ]} 

au moins n_iter fois.