如何结合多个朴素贝叶斯分类器的输出?

时间:2015-11-02 12:35:57

标签: python machine-learning scikit-learn artificial-intelligence bayesian

我是新手。

我在Sklearn工具包中使用朴素贝叶斯分类器(NBC)构建了一组弱分类器。

我的问题是如何将每个NBC的输出结合起来做出最终决定。我希望我的决定是概率而不是标签。

我在python中创建了以下程序。我假设来自sklean的iris-dataset有2个类问题。对于演示/学习说我按照以下方式制作了4 NB​​C。

#checkbox {
    width: 10px;
}

正如您将注意到的那样,我只是简单地将每个NBC的概率添加为最终得分。我想知道这是否正确?

如果我没有错,请你提出一些想法,以便我自己纠正。

2 个答案:

答案 0 :(得分:3)

首先 - 你为什么这样做?你应该在这里有一个朴素贝叶斯,而不是每个功能一个。看起来你不理解分类器的想法。你所做的实际上是Naive Bayes在内部做的事情 - 它独立地对待每个特征,但是因为这些是概率你应该乘以,或者添加对数,所以:

  1. 您应该只有一个NB,gnb.fit(iris.data, target)
  2. 如果你坚持要有很多NB,你应该通过乘法或加数对数来合并它们(从数学角度来看是相同的,但乘法在数值意义上不太稳定)

    pos = y_prob1[:,1] * y_prob2[:,1] * y_prob3[:,1] * y_prob4[:,1]

    pos = np.exp(np.log(y_prob1[:,1]) + np.log(y_prob2[:,1]) + np.log(y_prob3[:,1]) + np.log(y_prob4[:,1]))

    您也可以通过gnb.predict_log_proba而不是gbn.predict_proba直接预测对数。

    但是,这种方法有一个错误 - 朴素贝叶斯还会在每个问题中包含先验,因此你会有非常偏斜的分布。所以你必须手动标准化

    pos_prior = gnb1.class_prior_[1]#所有型号都有相同的先验,所以我们可以使用gnb1中的那个

    pos = pos_prior_ * (y_prob1[:,1]/pos_prior_) * (y_prob2[:,1]/pos_prior_) * (y_prob3[:,1]/pos_prior_) * (y_prob4[:,1]/pos_prior_)

    简化为

    pos = y_prob1[:,1] * y_prob2[:,1] * y_prob3[:,1] * y_prob4[:,1] / pos_prior_**3

    和登录

    pos = ... - 3 * np.log(pos_prior_)

    再一次 - 你应该使用" 1"选项。

答案 1 :(得分:0)

answer by lejlot几乎是正确的。缺少的一件事是,您需要通过两个类的pos结果之和来归一化他的pos结果(概率乘积除以先验值)。否则,所有类别的概率之和将不等于1。

以下是示例代码,用于测试具有6个功能的数据集的此过程的结果:

# Use one Naive Bayes for all 6 features:

gaus = GaussianNB(var_smoothing=0)
gaus.fit(X, y)
y_prob1 = gaus.predict_proba(X)

# Use one Naive Bayes on each half of the features and multiply the results:

gaus1 = GaussianNB(var_smoothing=0)
gaus1.fit(X[:, :3], y)
y_log_prob1 = gaus1.predict_log_proba(X[:, :3])

gaus2 = GaussianNB(var_smoothing=0)
gaus2.fit(X[:, 3:], y)
y_log_prob2 = gaus2.predict_log_proba(X[:, 3:])

pos = np.exp(y_log_prob1 + y_log_prob2 - np.log(gaus1.class_prior_))
y_prob2 = pos / pos.sum(axis=1)[:,None]

y_prob1除数字误差外,应等于y_prob2var_smoothing=0有助于减少误差)。