1

我對此很陌生。如何組合多個樸素貝葉斯分類器的輸出?

我有一套在Sklearn工具包中使用樸素貝葉斯分類器(NBC)構建的弱分類器。

我的問題是如何結合每個NBC的輸出做出最終決定。我想我的決定是在概率而不是標籤。

我在python中做了下面的程序。我假設sklean中的虹膜數據集有2類問題。對於演示/學習,我說我做了一個4 NBC如下。

from sklearn import datasets 
from sklearn.naive_bayes import GaussianNB 

import numpy as np 
import cPickle 
import math 

iris = datasets.load_iris() 

gnb1 = GaussianNB() 
gnb2 = GaussianNB() 
gnb3 = GaussianNB() 
gnb4 = GaussianNB() 

#Actual dataset is of 3 class I just made it into 2 class for this demo 
target = np.where(iris.target, 2, 1) 

gnb1.fit(iris.data[:, 0].reshape(150,1), target) 
gnb2.fit(iris.data[:, 1].reshape(150,1), target) 
gnb3.fit(iris.data[:, 2].reshape(150,1), target) 
gnb4.fit(iris.data[:, 3].reshape(150,1), target) 

#y_pred = gnb.predict(iris.data) 
index = 0 
y_prob1 = gnb1.predict_proba(iris.data[index,0].reshape(1,1)) 
y_prob2 = gnb2.predict_proba(iris.data[index,1].reshape(1,1)) 
y_prob3 = gnb3.predict_proba(iris.data[index,2].reshape(1,1)) 
y_prob4 = gnb4.predict_proba(iris.data[index,3].reshape(1,1)) 

#print y_prob1, "\n", y_prob2, "\n", y_prob3, "\n", y_prob4 

# I just added it over all for each class 
pos = y_prob1[:,1] + y_prob2[:,1] + y_prob3[:,1] + y_prob4[:,1] 
neg = y_prob1[:,0] + y_prob2[:,0] + y_prob3[:,0] + y_prob4[:,0] 

print pos 
print neg 

正如您會注意到的,我只是簡單地將每個NBC的概率添加爲最終得分。我想知道這是否正確?

如果我沒有錯,你可以請建議一些想法,這樣我可以糾正自己。

回答

1

首先 - 你爲什麼這樣做?您應該有一個樸素貝葉斯在這裏,而不是一個每個功能。看起來你不明白分類器的想法。你所做的其實就是樸素貝葉斯在內部做的 - 它把各自獨立的功能,但因爲這些都是概率,你應該他們,或增加對數,所以:

  1. 你應該只擁有一個NB ,gnb.fit(iris.data, target)
  2. 如果你堅持有許多國家統計局數據,你應該通過乘法或加法的對數的合併它們(這是從數學的角度相同,但乘法是不太穩定的數值意義)

    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]))

    可以也直接predit通過對數代替gnb.predict_log_probagbn.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」選項。

+0

感謝您的回覆。實際上,我在我的程序中創建了多個GNB,因爲我很困惑,所以我決定檢查理解這個概念。感謝您指導正確的道路。除此之外,我很困惑,就像你說的我們可以添加日誌或多次響應一樣。我如何確定查詢矢量屬於哪個類?因爲我會添加或多個響應,我會得到標量值,所以如何獲得類信息。 –

+1

你可以用更大的概率對班級進行分類,這就是我所看到的全部 – lejlot

+0

。只是爲了檢查我是否有這個想法。正如你在解決方案中提到的兩點。如果我選擇使用(1)單個NB,而不是我不必添加或多個,而是我可以在sklearn中使用predict_log_proba()?我假設這個函數完成你在(2)中所說的內部。它是否正確?我很抱歉我缺乏理解。 –