Sklearn(v3)——朴素贝叶斯(1)
真正的概率分類器
在許多分類算法應用中,特征和標簽之間的關系并非是決定性的。比如說,我們想預測一個人究竟是否會在泰坦尼克號海難中生存下來,那我們可以建一棵決策樹來學習我們的訓練集。在訓練中,其中一個人的特征為:30歲,男,普?通艙,他最后在泰坦尼克號海難中去世了。當我們測試的時候,我們發現有另一個人的特征也為:30歲,男,普通???艙。基于在訓練集中的學習,我們的決策樹必然會給這個人打上標簽:去世。然而這個人的真實情況一定是去世了嗎?并非如此。
也許這個人是心臟病患者,得到了上救生艇的優先權。又有可能,這個人就是擠上了救生艇,活了下來。對分類算法來說,基于訓練的經驗,這個人“很有可能”是沒有活下來,但算法永遠也無法確定”這個人一定沒有活下來“。即便這個人最后真的沒有活下來,算法也無法確定基于訓練數據給出的判斷,是否真的解釋了這個人沒有存活下來的真實情況。這就是說,算法得出的結論,永遠不是100%確定的,更多的是判斷出了一種“樣本的標簽更可能是某類的可能性”,而非一種“確定”。我們通過某些規定,比如說,在決策樹的葉子節點上占比較多的標簽,就是葉子節點上所有樣本的標簽,來強行讓算法為我們返回一個固定結果。但許多時候,我們也希望能夠理解算法判斷出的可能性本身。
每種算法使用不同的指標來衡量這種可能性。比如說,決策樹使用的就是葉子節點上占比較多的標簽所占的比例(接口predict_proba調用),邏輯回歸使用的是sigmoid函數壓縮后的似然(接口predict_proba調用),而SVM使用的是樣本點到決策邊界的距離(接口decision_function調用)。但這些指標的本質,其實都是一種“類概率”的表示,我們可以通過歸一化或sigmoid函數將這些指標壓縮到0~1之間,讓他們表示我們的模型對預測的結果究竟有多大的把握(置信度)。但無論如何,我們都希望使用真正的概率來衡量可能性,因此就有了真正的概率算法:樸素貝葉斯。
樸素貝葉斯是一種直接衡量標簽和特征之間的概率關系的有監督學習算法,是一種專注分類的算法。樸素貝葉斯的算法根源就是基于概率論和數理統計的貝葉斯理論,因此它是根正苗紅的概率模型。接下來,我們就來認識一下這個簡單快速的概率算法。
樸素貝葉斯是如何工作的
概率大于0.5標簽為1
概率小于0.5標簽為0
溫度和觀察到的瓢蟲數量不是獨立的,但是當控制了冬眠個變量時,溫度和觀察到了瓢蟲數量就不是獨立的了?
fit過程是在估計對應分布的參數,predict過程是在該參數下的分布中去進行概率預測
sklearn中的樸素貝葉斯 ?
?高斯樸素貝葉斯
import numpy as np import matplotlib.pyplot as plt from sklearn.naive_bayes import GaussianNB from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split#十分類問題 digits = load_digits() X, y = digits.data,digits.target Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.3,random_state=420)gnb = GaussianNB().fit(Xtrain,Ytrain) #查看分數 acc_score = gnb.score(Xtest,Ytest) acc_score結果:
0.8592592592592593 #查看預測結果 Y_pred = gnb.predict(Xtest) #查看預測的概率結果 prob = gnb.predict_proba(Xtest) prob #每一行和為1結果:?
from sklearn.metrics import confusion_matrix as CM CM(Ytest,Y_pred)結果:
?
貝葉斯——要求變量是相互獨立的,故通常而言不是第一選擇
不同樣本量是橫坐標,?準確率是縱坐標
import numpy as np import matplotlib.pyplot as plt from sklearn.naive_bayes import GaussianNB from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier as RFC from sklearn.tree import DecisionTreeClassifier as DTC from sklearn.linear_model import LogisticRegression as LR from sklearn.datasets import load_digits from sklearn.model_selection import learning_curve from sklearn.model_selection import ShuffleSplit from time import time import datetimedef plot_learning_curve(estimator,title, X, y,ax, #選擇子圖ylim=None, #設置縱坐標的取值范圍cv=None, #交叉驗證n_jobs=None #設定索要使用的線程):train_sizes,train_scores,test_scores = learning_curve(estimator,X,y,cv=cv,n_jobs=n_jobs)ax.set_title(title) #設置標題if ylim is not None:ax.set_ylim(*ylim) #縱坐標在一致的量綱下ax.set_xlabel("Training examples")ax.set_ylabel("Score")ax.grid() #顯示網格作為背景,不是必須ax.plot(train_sizes,np.mean(train_scores,axis=1),'o-', color="r",label="Training score")ax.plot(train_sizes,np.mean(test_scores,axis=1),'o-', color="g",label="Test score")ax.legend(loc="best")return axdigits = load_digits() X, y = digits.data, digits.targettitle = ["Naive Bayes" ,"DecisionTree" ,"SVM, RBF kernel" ,"RandomForest" ,"Logistic"] model = [GaussianNB(),DTC(),SVC(gamma=0.001),RFC(n_estimators=50),LR(C=.1,solver="lbfgs")] cv = ShuffleSplit(n_splits=50, test_size=0.2, random_state=0)fig, axes = plt.subplots(1,5,figsize=(30,6)) for ind,title_,estimator in zip(range(len(title)),title,model):times = time()plot_learning_curve(estimator, title_, X, y,ax=axes[ind], ylim = [0.7, 1.05],n_jobs=4, cv=cv) print("{}:{}".format(title_,datetime.datetime.fromtimestamp(time()-times).strftime("%M:%S:%f"))) plt.show()note:
?結果:
Naive Bayes:00:00:417101 DecisionTree:00:00:604189 SVM, RBF kernel:00:08:924170 RandomForest:00:05:252286 Logistic:00:05:541503三個模型表現出的狀態非常有意思。
我們首先返回的結果是各個算法的運行時間。可以看到,決策樹和貝葉斯不相伯仲(如果你沒有發現這個結果,那么可以多運行幾次,你會發現貝葉斯和決策樹的運行時間逐漸變得差不多)。決策樹之所以能夠運行非常快速是因為sklearn中的分類樹在選擇特征時有所“偷懶”,沒有計算全部特征的信息熵而是隨機選擇了一部分特征來進行計算,因此速度快可以理解,但我們知道決策樹的運算效率隨著樣本量逐漸增大會越來越慢,但樸素貝葉斯卻可以在很少的樣本上獲得不錯的結果,因此我們可以預料,隨著樣本量的逐漸增大貝葉斯會逐漸變得比決策樹更快。樸素貝葉斯計算速度遠遠勝過SVM,隨機森林這樣復雜的模型,邏輯回歸的運行受到最大迭代次數的強烈影響和輸入數據的影響(邏輯回歸一般在線性數據上運行都比較快,但在這里應該是受到了稀疏矩陣的影響)。因此在運算時間上,樸素貝葉斯還是十分有優勢的。
緊接著,我們來看一下每個算法在訓練集上的擬合。手寫數字數據集是一個較為簡單的數據集,決策樹,森林,SVC和邏輯回歸都成功擬合了100%的準確率,但貝葉斯的最高訓練準確率都沒有超過95%,這也應證了我們最開始說的,樸素貝葉斯的分類效果其實不如其他分類器,貝葉斯天生學習能力比較弱。并且我們注意到,隨著訓練樣本量的逐漸增大,其他模型的訓練擬合都保持在100%的水平,但貝葉斯的訓練準確率卻逐漸下降,這證明樣本量越大,貝葉斯需要學習的東西越多,對訓練集的擬合程度也越來越差。反而比較少量的樣本可以讓貝葉斯有較高的訓練準確率。
再來看看過擬合問題。首先一眼看到,所有模型在樣本量很少的時候都是出于過擬合狀態的(訓練集上表現好,測試集上表現糟糕),但隨著樣本的逐漸增多,過擬合問題都逐漸消失了,不過每個模型的處理手段不同。比較強大的分類器們,比如SVM,隨機森林和邏輯回歸,是依靠快速升高模型在測試集上的表現來減輕過擬合問題。相對的,決策樹雖然也是通過提高模型在測試集上的表現來減輕過擬合,但隨著訓練樣本的增加,模型在測試集上的表現善生卻非常緩慢。樸素貝葉斯獨樹一幟,是依賴訓練集上的準確率下降,測試集上的準確率上升來逐漸解決過擬合問題。
接下來,看看每個算法在測試集上的擬合結果,即泛化誤差的大小。隨著訓練樣本數量的上升,所有模型的測試表現都上升了,但貝葉斯和決策樹在測試集上的表現遠遠不如SVM,隨機森林和邏輯回歸。??SVM在訓練數據量增大到1500個樣本左右的時候,測試集上的表現已經非常接近100%,而隨機森林和邏輯回歸的表現也在95%以上,而決策樹和樸素貝葉斯還徘徊在85%左右。但這兩個模型所面臨的情況十分不同:決策樹雖然測試結果不高,但是卻依然具有潛力,因為它的過擬合現象非常嚴重,我們可以通過減枝來讓決策樹的測試結果逼近訓練結果。然而貝葉斯的過擬合現象在訓練樣本達到1500左右的時候已經幾乎不存在了,訓練集上的分數和測試集上的分數非常接近,只有在非常少的時候測試集上的分數才能夠比訓練集上的結果更高,所以我們基本可以判斷,85%左右就是貝葉斯在這個數據集上的極限了。可以預測到,如果我們進行調參,那決策樹最后應該可以達到90%左右的預測準確率,但貝葉斯卻幾乎沒有潛力了。
在這個對比之下,我們可以看出:貝葉斯是速度很快,但分類效果一般,并且初次訓練之后的結果就很接近算法極限的算法,幾乎沒有調參的余地。也就是說,如果我們追求對概率的預測,并且希望越準確越好,那我們應該先選擇邏輯回歸。如果數據十分復雜,或者是稀疏矩陣,那我們堅定地使用貝葉斯。如果我們分類的目標不是要追求對概率的預測,那我們完全可以先試試看高斯樸素貝葉斯的效果(反正它運算很快速,還不需要太多的樣本),如果效果很不錯,我們就很幸運地得到了一個表現優秀又快速的模型。如果我們沒有得到比較好的結果,那我們完全可以選擇再更換成更加復雜的模型。
總結
以上是生活随笔為你收集整理的Sklearn(v3)——朴素贝叶斯(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Sklearn(v3)——SVM理论(4
- 下一篇: Sklearn(v3)——朴素贝叶斯(2
