【Python機器學習】110:簡單貝氏分類器介紹及其應用

Naive Bayes Classifier

--

Photo by JOHN TOWNER on Unsplash

接下來要介紹的分類器叫簡單(單純)貝氏分類器,那什麼是貝氏呢?

貝氏定理是機率中的一個定理,描述在已知一些條件下,某事件的發生機率。 通常,事件A在事件B已發生的條件下發生的機率,與事件B在事件A已發生的條件下發生的機率是不一樣的。

貝氏定理的公式

那貝氏定理又和分類器有什麼關聯呢?首先我們要先知道分類器模型其實是把連續型的輸出 𝑋𝑤 轉換到離散型的輸出 𝑦̂,中間會經過兩個函數的運算,第一個函數用𝜎,第二個則用 𝐻 表示。

其中 𝜎 俗稱為激勵函數(Activation function),𝐻 稱為階躍函數(Step function)

激勵函數將連續型輸出轉換為機率(0~1)

階躍函數將機率輸出轉換為離散值

而貝氏分類器只在意第一個函數(機率的計算),也就是說,該分類器的輸出可以用機率表示:給定 𝑥則其類別為 𝐶𝑖 的機率為多少

其中,𝑃(𝐶𝑖|𝑥)即我們俗稱的後驗機率(Posterior Probability)

我們一樣使用鐵達尼號的範例,使用簡單貝氏分類器分類乘客的生存與否:

先使用 pd.crosstab() 製作 Frequency Table,以方便我們計算機率:

我們將乘客分割成6個類別(Pclass3個,Survived2個),用這6個區塊的數字就可以分別計算後驗機率:

左邊的機率是我們屆時分類的依據,當一個Pclass=1的樣本進來時,究竟要猜他是存活還是死亡,就是根據計算得到的後驗機率,如果進來的Pclass=2,就看Pclass為2的後驗機率,以此類推。

為方便計算,先把所需要的數字都先準備好:

注意:以上程式嗎使用loc函數,括號裡放的是標籤的名字而不是索引值,所以程式嗎中的123是標籤名字,而不是相對位置

分別去計算分母以及分子的機率:

計算3個 Pclass的後驗機率:

如上圖,3個後驗機率分別求出來了後,假如現在得到一個樣本,他的Pclass=1,那我就有63%的機率去猜該乘客是存活的,相反,有37%的機率猜他是死的。果然與上一章提到的專家意見的建議差不多,倉等越高的顧客存活率越高,make sense!!

我們現在算出來的機率並不是training data 的機率,只是把整個data拿來算

如何操作簡單貝氏分類器來預測乘客的生存與否:

注意:傳資料回資料框時,記得先使用ravel()函數轉回一維陣列

製作訓練資料的Frequency Table:

如此一來,training data就會跟先前的titanic subset差不多,只是樣本數較少

計算訓練資料的後驗機率:

如上圖,我們一樣輕鬆的把後驗機率算出來,雖然值和剛才略有不一樣,但還是和專家意見預期的差不多,越高倉等的就要用越高的機率去猜他存活。但是在有了後驗機率之後,到底要怎麼把它應用到我們的X_validation上面來預測 y_validation 呢?

將後驗機率應用至 X_validation,得到𝑦̂:

我們使用 choice 函數,給一個陣列(0,1)從裡面隨機挑選,之前在不給p參數的情況下就是各50%。現在我們把後驗機率放進去:假如它的Pclass為1,則預測該乘客死亡(0)的機率為(1 - 0.24),存活(1)的機率為(0.24)

我們印出前十筆預測結果和正確答案(y_validation)做比較,假如上下是一樣的,就表示我們的預測是對的,假如不一樣,那預測就是錯的。

使用準確率檢查該分類器的表現

如果簡單貝氏分類器希望納入多個類別變數呢?

在專家意見中,除了艙等以外,性別也是影響生存率的,女性較男性易生存。如果要把性別加入該分類模型,應該要如何操作呢?

一樣先製作訓練資料的Frequency Table:

如上圖,如果再加入一個類別變數,則 Frequency Table 外觀就會變得比較麻煩,且其索引會成一個巢狀外觀,每一個Pclass對應到兩種性別,所以要抓的樣本個數就會變得更多,計算也會更多,最後才會得到6個後驗機率。

計算有n個特徵的後驗機率(泛化形式):

在泛化的公式中有個假設:特徵和特徵之間是獨立的,互相不影響,為什麼要有這個假設呢?這樣它的機率才可以互相相乘,而這也是為什麼該分類器叫“簡單”貝氏分類器的原因。

但在現實中,如果該模型含有多個類別變數,則特徵之間一般是不會互相獨立的。舉鐵達尼號的例子,Pclass通常跟年紀有關,年紀越大,會有比較大的機率坐到頭等艙。

計算訓練資料的後驗機率:

有了這6個後驗機率之後,就可以去判斷validation的資料。將後驗機率應用至X_validation,得到𝑦̂:

那如果簡單貝氏分類器希望納入數值變數呢?(ex:年齡)

回顧一下貝氏定理的公式,會發現根本應用不了數值變數,光是創一個 Frequency Table 檯面就會炸掉了。那應該要怎麼辦才好呢?

假如你碰到數值變數,但還是堅持使用簡單貝氏分類器的話,常用方法有兩種:

將數值變數分組為類別變數(能有效的將outlier剔除)

定義分組規則並向量化映射(可採用map, apply np.vectorize())

使用 pd.cut()函數

使用sklearn.preprocessing.LabelEncoder Transformer

運用機率密度函數(Probability Density Function)

運用機率密度函數(Probability Density Function),假定數值變數符合常態分佈,因此又稱為Gaussian Naive Bayes Classifier:

感謝你閱讀完這篇文章,如果你覺得這些文章對你有幫助請在底下幫我拍個手(長按最多可以拍50下手)。

上一章:【Python機器學習】109:當數據集含有遺漏值的處理方法與未經過訓練的分類預測器

下一章:【Python機器學習】111:羅吉斯回歸分類器介紹及應用

--

--

張育晟 Eason Chang
展開數據人生

在不斷變動中努力思索自己的定位,想做的事情很多,但最希望的是不要變成無趣的人。 Linkedin: https://www.linkedin.com/in/stareason1997