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

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

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

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

樸素貝葉斯的「樸素」,並非簡單的意思,而是指樣本的特徵之間是相互獨立的。在全部的機器學習分類算法中,樸素貝葉斯和其餘絕大部分分類算法都不一樣,其餘分類算法基本都是判別方法,即直接學習出特徵輸出Y和特徵向量X之間的關係,要麼是決策函數Y=f(X),要麼是條件分佈P(Y|X),可是樸素貝葉斯倒是生成方法,也就是直接找出特徵輸出Y和特徵向量X之間的聯合分佈P(X,Y),而後用P(Y|X)=P(X,Y)/P(X)得出。算法

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

但樸素貝葉斯的缺點是:1,樸素貝葉斯算法有一個重要的使用前提:樣本的特徵屬性之間是相互獨立的,這使得樸素貝葉斯算法在知足這一條件的數據集上效果很是好,而不知足獨立性條件的數據集上,效果欠佳。理論上,樸素貝葉斯模型與其餘分類方法相比,有最小的偏差率,可是這一結果僅限於知足獨立性條件的數據集上。在實際應用中,屬性之間不太可能徹底獨立,特別是在特徵屬性個數很是多,且屬性之間相關性較大時,樸素貝葉斯分類效果不太好。2,須要知道先驗機率,且先驗機率不少時候取決於假設,假設的模型能夠有不少種,所以在某些時候會因爲假設的先驗模型的緣由致使預測效果不佳。3,因爲經過先驗和數據來決定後驗的機率從而決定分類,因此分類決策存在必定的錯誤率。4,對輸入數據的表達形式很敏感。機器學習

關於樸素貝葉斯模型的數學推導,能夠參考:https://blog.csdn.net/malele4th/article/details/79348473函數


1. 準備數據集

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

# 準備數據集
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]測試

--------------------------------------------完-------------------------------------spa

上面從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著,陶俊傑,陳小莉譯

相關文章
相關標籤/搜索