python機器學(xué)習(xí)——樸素貝葉斯算法
背景與原理:
樸素貝葉斯算法是機器學(xué)習(xí)領(lǐng)域最經(jīng)典的算法之一,仍然是用來解決分類問題的。
那么對于分類問題,我們的模型始終是:用$m$組數(shù)據(jù),每條數(shù)據(jù)形如$(x_{1},...,x_{n},y)$,表示數(shù)據(jù)共有$n$個特征維度,而$y$表示該數(shù)據(jù)所屬的類別,不妨設(shè)有$k$個取值$C_{1},...,C_{k}$
我們想一想,當我們談?wù)摲诸悊栴}的時候,我們究竟在談?wù)撌裁矗?/p>
從一個角度來理解,我們實際上是在研究:當給定了$X=x$的條件下,求概率$P(y=C_{i})$,而我們對分類的預(yù)測實際上就是使得$P(y=C_{i})$最大的$C_{i}$!
那么我們實際想求出的是$P(y=C_{i}|X=x)$這樣的一個條件概率。
我們需要一些數(shù)學(xué)原理:
貝葉斯公式:$P(X|Y)=\dfrac{P(Y|X)P(X)}{P(Y)}$
這個公式的邏輯是很簡單的:$P(X\cap Y)=P(X|Y)P(Y)=P(Y|X)P(X)$,即兩個事件同時發(fā)生的概率始終等于一個事件在另一個事件發(fā)生條件下的概率乘以另一個事件發(fā)生的概率。
而基于這個邏輯,我們有:
$P(y=C_{i}|X=x)=\dfrac{P(X=x|y=C_{i})P(y=C_{i})}{P(X=x)}$
而我們再要求$X$的各個特征是彼此獨立的,那么我們有:
$P(X=x|y=C_{i})=\prod_{j=1}^{n}P(X_{j}=x_{j}|y=C_{i})$
于是我們有最終的表達式:
$P(y=C_{i}|X=x)=\dfrac{\prod_{j=1}^{n}P(X_{j}=x_{j}|y=C_{i}) P(y=C_{i})}{P(X=x)}$
而我們想要的是:
$argmax_{C_{i}}\dfrac{\prod_{j=1}^{n}P(X_{j}=x_{j}|y=C_{i}) P(y=C_{i})}{P(X=x)}$
可以看到,對不同的$C_{i}$,上式的分母是相同的,那么我們將其省略,就得到了:
$argmax_{C_{i}}P(y=C_{i})\prod_{j=1}^{n}P(X_{j}=x_{j}|y=C_{i}) $
這就是我們真正想求的東西
那么$P(y=C_{i})$是多少呢?它是一個無關(guān)條件的先驗概率,那么我們可以估計其為數(shù)據(jù)集中類別為$C_{i}$的數(shù)據(jù)出現(xiàn)的頻率,即出現(xiàn)次數(shù)與數(shù)據(jù)集大小之比。那么我們設(shè)數(shù)據(jù)集中類別為$C_{i}$的數(shù)據(jù)有$c_{i}$條,那么我們有:
$P(y=C_{i})=\dfrac{c_{i}}{m}$(其中$m$為數(shù)據(jù)集大小)
但是如果我們數(shù)據(jù)集選取的很不好,某一個類別雖然我們的先驗知識告訴我們有,但數(shù)據(jù)集中卻沒有這一個分類,這只能說明這個類別出現(xiàn)概率可能比較小,但并不意味著一定不會出現(xiàn),所以我們需要給一個補償項,我們選取一個常數(shù)$\lambda$,有:
$P(y=C_{i})=\dfrac{c_{i}+\lambda}{m+k\lambda}$(其中$k$為類別數(shù),相當于對每一類我們都人工添加了$\lambda$個屬于這一類的數(shù)據(jù))
這樣兜兜轉(zhuǎn)轉(zhuǎn),我們發(fā)現(xiàn)不太好求出的實際上是$P(X_{j}=x_{j}|y=C_{i})$
那么怎么求呢?如果$X_{j}$是一個離散的量,那么我們只需再次引入貝葉斯公式:
$P(X_{j}=x_{j}|y=C_{i})=\dfrac{P(X_{j}=x_{j},y=C_{i})}{P(y=C_{i})}$
這樣我們只需統(tǒng)計在原數(shù)據(jù)集中$X_{j}=x_{j}$且$y=C_{i}$的數(shù)據(jù)集出現(xiàn)的頻率近似為概率再除以$y=C_{i}$出現(xiàn)的概率就好了。
當然,和上面的情況一樣,我們同樣可能會遇到倒霉的情況,即這種數(shù)據(jù)沒有出現(xiàn)在數(shù)據(jù)集中,那我們當然也不能直接認為這種概率是零,那么和上述處理類似地引入拉普拉斯平滑,選取一個常數(shù)$\lambda$(通常為1),此時有:
$P(X_{j}=x_{j}|y=C_{i})=\dfrac{\sum_{p=1}^{m}[X_{j}=x_{j},y=C_{i}]+\lambda}{\sum_{p=1}^{m}[y=C_{i}]+O_{j}\lambda}$
這里的記號$[...]$表示如果中括號里內(nèi)容為真取值為1,否則取值為0,而$O_{j}$是特征$j$的取值個數(shù)
但是...如果特征是連續(xù)的呢?
那么我們會認為這樣的分布服從正態(tài)分布,即這個條件概率為:
$P(X_{j}=x_{j}|y=C_{i})=\dfrac{1}{\sqrt{2\pi \sigma_{i}^{2}}}e^{-\frac{(x_{j}-\mu_{i})^{2}}{2\sigma_{i}^{2}}}$
即我們認為在$y=C_{i}$的條件下,所有的$X_{j}$的分布服從均值為$\mu_{i}$,方差為$\sigma_{i}^{2}$的正態(tài)分布,而這個均值與方差可以通過極大似然估計求得。
這樣我們就解決了所有的問題。
代碼實現(xiàn):
import numpy as np from sklearn import datasets from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.svm import LinearSVC import matplotlib.pyplot as plt import pylab as plt from sklearn.naive_bayes import GaussianNB from sklearn.model_selection import train_test_split X,y=datasets.make_classification(n_samples=10000,n_features=20,n_informative=2,n_redundant=2) X_train,X_test,Y_train,Y_test=train_test_split(X,y,test_size=0.25) lr=LogisticRegression() svc=LinearSVC(C=1.0) rfc=RandomForestClassifier(n_estimators=100)#森林中樹的個數(shù) lr=lr.fit(X_train,Y_train) score1=lr.score(X_test,Y_test) print(score1) svc=svc.fit(X_train,Y_train) score2=svc.score(X_test,Y_test) print(score2) rfc=rfc.fit(X_train,Y_train) score3=rfc.score(X_test,Y_test) print(score3) gnb=GaussianNB() gnb=gnb.fit(X_train,Y_train) score4=gnb.score(X_test,Y_test) print(score4) y_pred=gnb.predict_proba(X_test) print(y_pred[:10])
這是在上一篇博客基礎(chǔ)上對四種分類器的對比,在sklearn中樸素貝葉斯分類器主要有三種:高斯樸素貝葉斯GaussianNB,多項式樸素貝葉斯MultinomialNB和伯努利樸素貝葉斯BernoulliNB,高斯樸素貝葉斯用于處理特征是連續(xù)值的情況,而多項式樸素貝葉斯用于處理特征是離散值的情況,而伯努利樸素貝葉斯則用于處理特征只有0/1的情況。
這里我們使用sklearn自帶的高斯樸素貝葉斯對與前文類似生成的數(shù)據(jù)集進行分類并對比分類效果,可以看到由于樸素貝葉斯對特征的分布有嚴格的要求(獨立、正態(tài)等),因此分類效果相較別的分類器相對較差,但是樸素貝葉斯的訓(xùn)練效率比較高,而且可解釋性也比較好,這是樸素貝葉斯的優(yōu)點所在。
小結(jié)與優(yōu)化:
樸素貝葉斯由于基礎(chǔ)要求太高,導(dǎo)致很多情況下分類效果并不好,那么為了解決這個問題,人們作出了一些優(yōu)化。比如針對要求各個維度相互獨立的要求,一種方法是在樸素貝葉斯基礎(chǔ)上增加屬性間可能存在的依賴關(guān)系,另一種則是重新構(gòu)建數(shù)據(jù)集,通過變換等手段將原來相關(guān)的屬性變?yōu)楠毩⒌膶傩浴W钪膬?yōu)化方法是TAN算法,通過發(fā)現(xiàn)屬性間的依賴關(guān)系來降低獨立性假設(shè)。

浙公網(wǎng)安備 33010602011771號