Scikit-Learn RandomizedSearchCV不适用于MultinomialNB中的class_prior

时间:2017-09-27 13:52:41

标签: scikit-learn naivebayes grid-search

我正在尝试在MultinomialNB上进行随机参数优化(1)。现在我的参数有3而不是一个值,因为它是'class_prior'而且我有3个类。

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)

但错误日志如下所示:

...
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()

还尝试删除.rvs - >

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

RandomizeSearch是不可能有一个包含3个组件的变量,即3个class_priors?

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

1 个答案:

答案 0 :(得分:2)

是的,可能。这样做:

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

注意值周围的额外方括号。 原因是RandomizedSearchCV(或GridSearchCV)要调整的参数应该包含在一个列表中,每次都会尝试使用一个元素。将保留产生最高分数(或损失情况下最低分数)的元素组合。

例如,请参阅SVC参数调整的简单代码:

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

这将扩展为总共4个值的排列,如下所示:

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

这意味着估算器将适合4次(每次使用上面的不同选项),然后将保留最佳估算器。

在您的情况下,根据documentation of MultinomialNB class_prior,是类的概率数组。

理想情况下,它应该像这样扩展:

选项1:'class_prior':[uniform.rvs(0,3),uniform.rvs(0,3),uniform.rvs(0,3)]

但是在RandomizedSearhCV(没有关于class_prior类型的信息)中,它将被扩展为:

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

然后会将其呈现给MultinomialNB,因为uniform.rvs()的输出是浮点数而不是列表,所以它不会有len()因此错误。

为此,您需要使用双方括号,以便正确扩展,如下所示:

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

但现在也有问题。由于扩展产生了一个选项,所以很明显,无论得分如何都会被选中(因为我们没有任何其他选择)。

此外,RandomizedSearchCV会抛出错误,因为您指定了n_iter=10,并且选择的数量应该多于(在我们的例子中,它是一个选择)。

所以你需要改变你的tuned_parameters

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)],
                                    ...
                                    ...
                                    ... ]}

至少n_iter次。