我是新手。
我在Sklearn工具包中使用朴素贝叶斯分类器(NBC)构建了一组弱分类器。
我的问题是如何将每个NBC的输出结合起来做出最终决定。我希望我的决定是概率而不是标签。
我在python中创建了以下程序。我假设来自sklean的iris-dataset有2个类问题。对于演示/学习说我按照以下方式制作了4 NBC。
#checkbox {
width: 10px;
}
正如您将注意到的那样,我只是简单地将每个NBC的概率添加为最终得分。我想知道这是否正确?
如果我没有错,请你提出一些想法,以便我自己纠正。
答案 0 :(得分:3)
首先 - 你为什么这样做?你应该在这里有一个朴素贝叶斯,而不是每个功能一个。看起来你不理解分类器的想法。你所做的实际上是Naive Bayes在内部做的事情 - 它独立地对待每个特征,但是因为这些是概率你应该乘以,或者添加对数,所以:
gnb.fit(iris.data, target)
如果你坚持要有很多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_prob2
(var_smoothing=0
有助于减少误差)。