Python 不同貝葉斯在樣本不均衡時的處理

關注微信公共號:小程在線

關注CSDN博客:程志偉的博客

from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_blobs
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.metrics import brier_score_loss as BS,recall_score,roc_auc_score as AUC
import numpy as np

 

創建一個新的數據集

class_1 = 50000 #多數類爲50000個樣本
class_2 = 500 #少數類爲500個樣本
centers = [[0.0, 0.0], [5.0, 5.0]] #設定兩個類別的中心
clusters_std = [3, 1] #設定兩個類別的方差
X, y = make_blobs(n_samples=[class_1, class_2],
                  centers=centers,
                  cluster_std=clusters_std,
                  random_state=0, shuffle=False)

X.shape
Out[52]: (50500, 2)

np.unique(y)
Out[53]: array([0, 1])

 

#多項式、高斯和伯努利三種貝葉斯在樣本不均衡下的表現

name = ["Multinomial","Gaussian","Bernoulli"]
models = [MultinomialNB(),GaussianNB(),BernoulliNB()]
for name,clf in zip(name,models):
    Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y
                                                    ,test_size=0.3
                                                    ,random_state=420)
    if name != "Gaussian":
        kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)
        Xtrain = kbs.transform(Xtrain)
        Xtest = kbs.transform(Xtest)
    
    clf.fit(Xtrain,Ytrain)
    y_pred = clf.predict(Xtest)
    proba = clf.predict_proba(Xtest)[:,1]
    score = clf.score(Xtest,Ytest)
    print(name)
    print("\tBrier:{:.3f}".format(BS(Ytest,proba,pos_label=1)))
    print("\tAccuracy:{:.3f}".format(score))
    print("\tRecall:{:.3f}".format(recall_score(Ytest,y_pred)))
    print("\tAUC:{:.3f}".format(AUC(Ytest,proba)))
Multinomial
        Brier:0.007
        Accuracy:0.990
        Recall:0.000
        AUC:0.991
Gaussian
        Brier:0.006
        Accuracy:0.990
        Recall:0.438
        AUC:0.993
Bernoulli
        Brier:0.009
        Accuracy:0.987
        Recall:0.771
        AUC:0.987

從結果上來看,多項式樸素貝葉斯判斷出了所有的多數類樣本,但放棄了全部的少數類樣本,受到樣本不均衡問題影
響最嚴重。高斯比多項式在少數類的判斷上更加成功一些,至少得到了43.8%的recall。伯努利貝葉斯雖然整體的準
確度和布里爾分數不如多項式和高斯樸素貝葉斯和,但至少成功捕捉出了77.1%的少數類。可見,伯努利貝葉斯最能
夠忍受樣本不均衡問題。
可是,伯努利貝葉斯只能用於處理二項分佈數據,在現實中,強行將所有的數據都二值化不會永遠得到好結果,在我
們有多個特徵的時候,我們更需要一個個去判斷究竟二值化的閾值該取多少才能夠讓算法的效果優秀。這樣做無疑是
非常低效的。那如果我們的目標是捕捉少數類,我們應該怎麼辦呢?高斯樸素貝葉斯的效果雖然比多項式好,但是也
沒有好到可以用來幫助我們捕捉少數類的程度——43.8%,還不如拋硬幣的結果。因此,孜孜不倦的統計學家們改進
了樸素貝葉斯算法,修正了包括無法處理樣本不平衡在內的傳統樸素貝葉斯的衆多缺點,得到了新興貝葉斯算法:補
集樸素貝葉斯。
 

改進多項式樸素貝葉斯:補集樸素貝葉斯
from sklearn.naive_bayes import ComplementNB
from time import time
import datetime

name = ["Multinomial","Gaussian","Bernoulli","Complement"]
models = [MultinomialNB(),GaussianNB(),BernoulliNB(),ComplementNB()]
for name,clf in zip(name,models):
    times = time()
    Xtrain, Xtest, Ytrain, Ytest = train_test_split(X,y
                                                    ,test_size=0.3
                                                    ,random_state=420)
    #預處理
    if name != "Gaussian":
        kbs = KBinsDiscretizer(n_bins=10, encode='onehot').fit(Xtrain)
        Xtrain = kbs.transform(Xtrain)
        Xtest = kbs.transform(Xtest)
    clf.fit(Xtrain,Ytrain)
    y_pred = clf.predict(Xtest)
    proba = clf.predict_proba(Xtest)[:,1]
    score = clf.score(Xtest,Ytest)
    print(name)
    print("\tBrier:{:.3f}".format(BS(Ytest,proba,pos_label=1)))
    print("\tAccuracy:{:.3f}".format(score))
    print("\tRecall:{:.3f}".format(recall_score(Ytest,y_pred)))
    print("\tAUC:{:.3f}".format(AUC(Ytest,proba)))
    print(datetime.datetime.fromtimestamp(time()-times).strftime("%M:%S:%f"))
Multinomial
        Brier:0.007
        Accuracy:0.990
        Recall:0.000
        AUC:0.991
00:00:054023
Gaussian
        Brier:0.006
        Accuracy:0.990
        Recall:0.438
        AUC:0.993
00:00:030061
Bernoulli
        Brier:0.009
        Accuracy:0.987
        Recall:0.771
        AUC:0.987
00:00:055022
Complement
        Brier:0.038
        Accuracy:0.953
        Recall:0.987
        AUC:0.991
00:00:051082

補集樸素貝葉斯犧牲了部分整體的精確度和布里爾指數,但是得到了十分高的召回率Recall,捕捉出了
98.7%的少數類,並且在此基礎上維持了和原本的多項式樸素貝葉斯一致的AUC分數。和其他的貝葉斯算法比起來,
我們的補集樸素貝葉斯的運行速度也十分優秀。如果我們的目標是捕捉少數類,那我們毫無疑問會希望選擇補集樸素
貝葉斯作爲我們的算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章