【火爐煉AI】機器學習010-用樸素貝葉斯分類器解決多分類問題

【火爐煉AI】機器學習010-用樸素貝葉斯分類器解決多分類問題

(本文所使用的Python庫和版本號: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

前面講到了使用邏輯回歸分類器解決多分類問題(【火爐煉AI】機器學習009-用邏輯回歸分類器解決多分類問題 ),但是解決多分類問題并不是只有邏輯回歸一種方法,此處我們講解用樸素貝葉斯分類器來解決多分類問題。

樸素貝葉斯的“樸素”,并不是簡單的意思,而是指樣本的特征之間是相互獨立的。在所有的機器學習分類算法中,樸素貝葉斯和其他絕大部分分類算法都不同,其他分類算法基本都是判別方法,即直接學習出特征輸出Y和特征向量X之間的關系,要么是決策函數Y=f(X),要么是條件分布P(Y|X),但是樸素貝葉斯卻是生成方法,也就是直接找出特征輸出Y和特征向量X之間的聯合分布P(X,Y),然后用P(Y|X)=P(X,Y)/P(X)得出。

樸素貝葉斯的優點在于:1,有穩定的分類效率,2,對小規模數據表現很好,能處理多分類任務,適合增量式訓練,尤其是數據量超出內存時,可以一批一批的去增量訓練。3,對缺失數據不太敏感,算法比較簡單,常用于文本分類。

但樸素貝葉斯的缺點是:1,樸素貝葉斯算法有一個重要的使用前提:樣本的特征屬性之間是相互獨立的,這使得樸素貝葉斯算法在滿足這一條件的數據集上效果非常好,而不滿足獨立性條件的數據集上,效果欠佳。理論上,樸素貝葉斯模型與其他分類方法相比,有最小的誤差率,但是這一結果僅限于滿足獨立性條件的數據集上。在實際應用中,屬性之間不太可能完全獨立,特別是在特征屬性個數非常多,且屬性之間相關性較大時,樸素貝葉斯分類效果不太好。2,需要知道先驗概率,且先驗概率很多時候取決于假設,假設的模型可以有很多種,因此在某些時候會由于假設的先驗模型的原因導致預測效果不佳。3,由于通過先驗和數據來決定后驗的概率從而決定分類,所以分類決策存在一定的錯誤率。4,對輸入數據的表達形式很敏感。

關于樸素貝葉斯模型的數學推導,可以參考:https://blog.csdn.net/malele4th/article/details/79348473


1. 準備數據集

本項目所使用的數據集參考《Python機器學習經典實例》中第二章提供的data_multivar數據集,下面是加載并分析該數據集的代碼。

# 準備數據集
data_path='D:\PyProjects\DataSet/NaiveBayers/data_multivar.txt'
df=pd.read_csv(data_path,header=None)
# print(df.head())
# print(df.info()) # 查看數據信息,確保沒有錯誤
dataset_X,dataset_y=df.iloc[:,:-1],df.iloc[:,-1] # 拆分為X和Y
# print(dataset_X.head())
# print(dataset_X.info())
# print('-'*100)
# print(dataset_y.head())
dataset_X=dataset_X.values
dataset_y=dataset_y.values
# print(dataset_X.shape) # (400, 2)
# print(dataset_y.shape) # (400,)
classes=list(set(dataset_y)) 
print('class Num: {}, class: {}'.format(len(classes), classes))
# 上面檢查加載沒有問題,一共有四個不同類別,類別名稱為:0,1,2,3

-------------------------------------輸---------出--------------------------------

class Num: 4, class: [0, 1, 2, 3]

--------------------------------------------完-------------------------------------

上面從txt文件中加載了數據集,可以看出,該數據集含有400個樣本,被平均分成4個不同類別(0,1,2,3)。下面將這不同類別的數據集繪制到散點圖中,以觀察每個類別的大概聚集位置。

# 數據集可視化
def visual_2D_dataset(dataset_X,dataset_y):
    '''將二維數據集dataset_X和對應的類別dataset_y顯示在散點圖中'''
    assert dataset_X.shape[1]==2,'only support dataset with 2 features'
    plt.figure()
    classes=list(set(dataset_y)) 
    markers=['.',',','o','v','^','<','>','1','2','3','4','8'
             ,'s','p','*','h','H','+','x','D','d','|']
    colors=['b','c','g','k','m','w','r','y']
    for class_id in classes:
        one_class=np.array([feature for (feature,label) in 
                   zip(dataset_X,dataset_y) if label==class_id])
        plt.scatter(one_class[:,0],one_class[:,1],marker=np.random.choice(markers,1)[0],
                    c=np.random.choice(colors,1)[0],label='class_'+str(class_id))
    plt.legend()

visual_2D_dataset(dataset_X,dataset_y)
該數據集的類別分布圖

########################小**********結###############################

1,數據集的準備,分析,可視化等常常是機器學習的第一步,也是非常重要的一個部分,更是非常耗時的一個部分。

2,此處定義了一個數據集可視化函數,用于將具有兩個特征屬性的數據集按照不同類別繪制到散點圖中。

#################################################################


2. 構建樸素貝葉斯分類器模型

在sklearn模塊中,一共有三個樸素貝葉斯分類方法,分別是GaussianNB, MultinomialNB和BernouliNB,其中,GaussianNB是先驗為高斯分布的樸素貝葉斯,適用于樣本特征的分布大部分是連續值的情況;MultinomialNB是先驗為多項式分布的樸素貝葉斯,適用于樣本特征的分布大部分是多元離散值的情況;BernouliNB是先驗為伯努利分布的樸素貝葉斯,適用于樣本特征是二元離散值或者很稀疏的多元離散值的情況。下面我分別用這三個分類方法來解決本項目的分類問題。

2.1 使用GaussianNB分類器構建樸素貝葉斯模型

直接上代碼,構建模型后還測試了一下該模型在整個數據集上的表現:

# 使用GaussianNB分類器構建樸素貝葉斯模型
from sklearn.naive_bayes import GaussianNB
gaussianNB=GaussianNB()
gaussianNB.fit(dataset_X,dataset_y)

# 評估本模型在整個數據集上的表現
dataset_predict_y=gaussianNB.predict(dataset_X)
correct_predicts=(dataset_predict_y==dataset_y).sum()
accuracy=100*correct_predicts/dataset_y.shape[0]
print('GaussianNB, correct prediction num: {}, accuracy: {:.2f}%'
      .format(correct_predicts,accuracy))

plot_classifier(gaussianNB,dataset_X,dataset_y)

-------------------------------------輸---------出--------------------------------

GaussianNB, correct prediction num: 398, accuracy: 99.50%

--------------------------------------------完-------------------------------------

GaussianNB分類器分類結果

2.2 使用MultinomialNB分類器構建樸素貝葉斯模型

很可惜,貌似MultinomialNB分類器要求數據集的所有特征屬性都是非負數,否則沒法訓練。故而下面的代碼報錯。

# 使用MultinomialNB分類器構建樸素貝葉斯模型
from sklearn.naive_bayes import MultinomialNB
multinomialNB=MultinomialNB()
multinomialNB.fit(dataset_X,dataset_y) 
# 此處報錯,multinomialNB的數據集的特征屬性必須是非負數

# 評估本模型在整個數據集上的表現
dataset_predict_y_multi=multinomialNB.predict(dataset_X)
correct_predicts_multi=(dataset_predict_y_multi==dataset_y).sum()
accuracy=100*correct_predicts_multi/dataset_y.shape[0]
print('MultinomialNB, correct prediction num: {}, accuracy: {:.2f}%'
      .format(correct_predicts,accuracy))

-------------------------------------輸---------出--------------------------------

ValueError: Input X must be non-negative

--------------------------------------------完-------------------------------------

2.3 使用BernouliNB分類器構建樸素貝葉斯模型

構建和測試方法與GaussianNB幾乎一樣,代碼為:


# 使用BernouliNB分類器構建樸素貝葉斯模型
from sklearn.naive_bayes import BernoulliNB
bernoulliNB=BernoulliNB()
bernoulliNB.fit(dataset_X,dataset_y) 

# 評估本模型在整個數據集上的表現
dataset_predict_y_bern=bernoulliNB.predict(dataset_X)
correct_predicts_bern=(dataset_predict_y_bern==dataset_y).sum()
accuracy=100*correct_predicts_bern/dataset_y.shape[0]
print('BernoulliNB, correct prediction num: {}, accuracy: {:.2f}%'
      .format(correct_predicts_bern,accuracy))

plot_classifier(bernoulliNB,dataset_X,dataset_y)

-------------------------------------輸---------出--------------------------------

BernoulliNB, correct prediction num: 195, accuracy: 48.75%

--------------------------------------------完-------------------------------------

使用BernouliNB分類器得到的分類結果

########################小**********結###############################

1,雖然sklearn模塊中有三種樸素貝葉斯方法,但在同一個數據集上的表現卻大不相同,只有GaussianNB表現最好,能夠正確的將四個數據集區分開來。

2,此處定義了一個數據集可視化函數,用于將具有兩個特征屬性的數據集按照不同類別繪制到散點圖中,對于其他項目這個函數也可以直接使用。

3,這三種樸素貝葉斯方法中,MultinomialNB要求數據集中的特征向量數值必須為非負數,否則直接報錯。BernoulliNB雖然沒有報錯,但是從分類結果圖中可以看到,結果非常不理想,可以說完全沒有起到分類的效果。

#################################################################


注:本部分代碼已經全部上傳到(我的github)上,歡迎下載。

參考資料:

1, Python機器學習經典實例,Prateek Joshi著,陶俊杰,陳小莉譯

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,283評論 6 530
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 97,947評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,094評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,485評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,268評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,817評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,906評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,039評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,551評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,502評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,662評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,188評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,907評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,304評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,563評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,255評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,637評論 2 370

推薦閱讀更多精彩內容