2017-08-26 121 views
3

我想要做什么?GaussianNB: - ValueError:先验的总和应该是1

我想培养具有使用GaussianNB分类10个标签的数据集,但同时tunning我gaussianNB参数之前我得到这个错误: -

文件“/home/mg/anaconda2/lib/python2.7 /site-packages/sklearn/naive_bayes.py”,线路367,在_partial_fit 加注ValueError异常(‘先验的总和应为1’) ValueError异常:先验的总和应为1。

代码为此: - clf = GaussianNB(priors = [0.08,0.14,0.03,0.16,0.11,0.16,0.07,0.14,0.11,0.0])

你可以看到总和显然是1,但它向我显示了这个错误,你能指出错误吗?

+0

除了上面提到的行之外,你可以分享完整的代码吗?也许这个问题是别的。我尝试用你的先验初始化分类器,它工作正常。 –

回答

5

这看起来像sklearn内一个非常糟糕的设计决定他们正在做平常不比较浮点数东西(what every computer scientist should know about floating-point arithmetic),这令我感到奇怪(如sklearn通常是高质量的代码)!

(我没有看到你到底有什么错的使用,尽管使用的列表。该文档要求一个数组,数组没有类似像其他许多情况下,他们的代码是做数组转换尽管如此)

Their code

if self.priors is not None: 
    priors = np.asarray(self.priors) 
    # Check that the provide prior match the number of classes 
    if len(priors) != n_classes: 
     raise ValueError('Number of priors must match number of' 
         ' classes.') 
    # Check that the sum is 1 
    if priors.sum() != 1.0: 
     raise ValueError('The sum of the priors should be 1.') 
    # Check that the prior are non-negative 
    if (priors < 0).any(): 
     raise ValueError('Priors must be non-negative.') 
    self.class_prior_ = priors 
else: 
    # Initialize the priors to zeros for each class 
    self.class_prior_ = np.zeros(len(self.classes_), 
           dtype=np.float64) 

所以:

  • 你给一个列表,但他们的代码将创建一个numpy的阵列
  • 因此np.sum()将用于总结
  • 有可能是FP-数学有关的数值,错误在你的情况总结
    • 你和技术上= 1.0!;但非常接近它!
  • fp-comparison x == 1.0被认为是不好!
    • numpy的带来np.isclose()是这样

演示的通常的做法:

import numpy as np 

priors = np.array([0.08, 0.14, 0.03, 0.16, 0.11, 0.16, 0.07, 0.14, 0.11, 0.0]) 
my_sum = np.sum(priors) 
print('my_sum: ', my_sum) 
print('naive: ', my_sum == 1.0) 
print('safe: ', np.isclose(my_sum, 1.0)) 

输出:

('my_sum: ', 1.0000000000000002) 
('naive: ', False) 
('safe: ', True) 

编辑:

因为我认为这段代码不好,我发布了一个问题here,你可以按照它来看看它们是否符合。

numpy.random.sample(),这也需要这样的载体,实际上是做一个FP-安全的方法太(数值更稳定的总和+的ε-检查;但不使用np.isclose())所看到here