Scikit-Learn RandomizedSearchCV 不适用于 MultinomialNB 中的 class_prior
Scikit-Learn RandomizedSearchCV not working for class_prior in MultinomialNB
我正在尝试对 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()
是否无法随机搜索具有 3 个分量的变量,即 3 class_priors?
是的,这是可能的。这样做:
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
次。
我正在尝试对 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()
是否无法随机搜索具有 3 个分量的变量,即 3 class_priors?
是的,这是可能的。这样做:
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
次。