新聞中心
用樸素貝葉斯分類器解決現(xiàn)實(shí)世界里的機(jī)器學(xué)習(xí)問題。
樸素貝葉斯Na?ve Bayes是一種分類技術(shù),它是許多分類器建模算法的基礎(chǔ)。基于樸素貝葉斯的分類器是簡單、快速和易用的機(jī)器學(xué)習(xí)技術(shù)之一,而且在現(xiàn)實(shí)世界的應(yīng)用中很有效。
樸素貝葉斯是從 貝葉斯定理Bayes' theorem 發(fā)展來的。貝葉斯定理由 18 世紀(jì)的統(tǒng)計(jì)學(xué)家 托馬斯·貝葉斯 提出,它根據(jù)與一個(gè)事件相關(guān)聯(lián)的其他條件來計(jì)算該事件發(fā)生的概率。比如,帕金森氏病 患者通常嗓音會發(fā)生變化,因此嗓音變化就是與預(yù)測帕金森氏病相關(guān)聯(lián)的癥狀。貝葉斯定理提供了計(jì)算目標(biāo)事件發(fā)生概率的方法,而樸素貝葉斯是對該方法的推廣和簡化。
解決一個(gè)現(xiàn)實(shí)世界里的問題
這篇文章展示了樸素貝葉斯分類器解決現(xiàn)實(shí)世界問題(相對于完整的商業(yè)級應(yīng)用)的能力。我會假設(shè)你對機(jī)器學(xué)習(xí)有基本的了解,所以文章里會跳過一些與機(jī)器學(xué)習(xí)預(yù)測不大相關(guān)的步驟,比如 數(shù)據(jù)打亂date shuffling 和 數(shù)據(jù)切片data splitting。如果你是機(jī)器學(xué)習(xí)方面的新手或者需要一個(gè)進(jìn)修課程,請查看 《An introduction to machine learning today》 和 《Getting started with open source machine learning》。
樸素貝葉斯分類器是 有監(jiān)督的supervised、屬于 生成模型generative 的、非線性的、屬于 參數(shù)模型parametric 的和 基于概率的probabilistic。
在這篇文章里,我會演示如何用樸素貝葉斯預(yù)測帕金森氏病。需要用到的數(shù)據(jù)集來自 UCI 機(jī)器學(xué)習(xí)庫。這個(gè)數(shù)據(jù)集包含許多語音信號的指標(biāo),用于計(jì)算患帕金森氏病的可能性;在這個(gè)例子里我們將使用這些指標(biāo)中的前 8 個(gè):
- MDVP:Fo(Hz):平均聲帶基頻
- MDVP:Fhi(Hz):最高聲帶基頻
- MDVP:Flo(Hz):最低聲帶基頻
- MDVP:Jitter(%)、MDVP:Jitter(Abs)、MDVP:RAP、MDVP:PPQ 和 Jitter:DDP:5 個(gè)衡量聲帶基頻變化的指標(biāo)
這個(gè)例子里用到的數(shù)據(jù)集,可以在我的 GitHub 倉庫 里找到。數(shù)據(jù)集已經(jīng)事先做了打亂和切片。
用 Python 實(shí)現(xiàn)機(jī)器學(xué)習(xí)
接下來我會用 Python 來解決這個(gè)問題。我用的軟件是:
- Python 3.8.2
- Pandas 1.1.1
- scikit-learn 0.22.2.post1
Python 有多個(gè)樸素貝葉斯分類器的實(shí)現(xiàn),都是開源的,包括:
- NLTK Na?ve Bayes:基于標(biāo)準(zhǔn)的樸素貝葉斯算法,用于文本分類
- NLTK Positive Na?ve Bayes:NLTK Na?ve Bayes 的變體,用于對只標(biāo)注了一部分的訓(xùn)練集進(jìn)行二分類
- Scikit-learn Gaussian Na?ve Bayes:提供了部分?jǐn)M合方法來支持?jǐn)?shù)據(jù)流或很大的數(shù)據(jù)集(LCTT 譯注:它們可能無法一次性導(dǎo)入內(nèi)存,用部分?jǐn)M合可以動態(tài)地增加數(shù)據(jù))
- Scikit-learn Multinomial Na?ve Bayes:針對離散型特征、實(shí)例計(jì)數(shù)、頻率等作了優(yōu)化
- Scikit-learn Bernoulli Na?ve Bayes:用于各個(gè)特征都是二元變量/布爾特征的情況
在這個(gè)例子里我將使用 sklearn Gaussian Naive Bayes。
我的 Python 實(shí)現(xiàn)在 naive_bayes_parkinsons.py 里,如下所示:
import pandas as pd# x_rows 是我們所使用的 8 個(gè)特征的列名x_rows=['MDVP:Fo(Hz)','MDVP:Fhi(Hz)','MDVP:Flo(Hz)','MDVP:Jitter(%)','MDVP:Jitter(Abs)','MDVP:RAP','MDVP:PPQ','Jitter:DDP']y_rows=['status'] # y_rows 是類別的列名,若患病,值為 1,若不患病,值為 0# 訓(xùn)練# 讀取訓(xùn)練數(shù)據(jù)train_data = pd.read_csv('parkinsons/Data_Parkinsons_TRAIN.csv')train_x = train_data[x_rows]train_y = train_data[y_rows]print("train_x:\n", train_x)print("train_y:\n", train_y)# 導(dǎo)入 sklearn Gaussian Naive Bayes,然后進(jìn)行對訓(xùn)練數(shù)據(jù)進(jìn)行擬合from sklearn.naive_bayes import GaussianNBgnb = GaussianNB()gnb.fit(train_x, train_y)# 對訓(xùn)練數(shù)據(jù)進(jìn)行預(yù)測predict_train = gnb.predict(train_x)print('Prediction on train data:', predict_train)# 在訓(xùn)練數(shù)據(jù)上的準(zhǔn)確率from sklearn.metrics import accuracy_scoreaccuracy_train = accuracy_score(train_y, predict_train)print('Accuray score on train data:', accuracy_train)# 測試# 讀取測試數(shù)據(jù)test_data = pd.read_csv('parkinsons/Data_Parkinsons_TEST.csv')test_x = test_data[x_rows]test_y = test_data[y_rows]# 對測試數(shù)據(jù)進(jìn)行預(yù)測predict_test = gnb.predict(test_x)print('Prediction on test data:', predict_test)# 在測試數(shù)據(jù)上的準(zhǔn)確率accuracy_test = accuracy_score(test_y, predict_test)print('Accuray score on test data:', accuracy_train)
運(yùn)行這個(gè) Python 腳本:
$ python naive_bayes_parkinsons.pytrain_x:MDVP:Fo(Hz) MDVP:Fhi(Hz) ... MDVP:RAP MDVP:PPQ Jitter:DDP0 152.125 161.469 ... 0.00191 0.00226 0.005741 120.080 139.710 ... 0.00180 0.00220 0.005402 122.400 148.650 ... 0.00465 0.00696 0.013943 237.323 243.709 ... 0.00173 0.00159 0.00519.. ... ... ... ... ... ...155 138.190 203.522 ... 0.00406 0.00398 0.01218[156 rows x 8 columns]train_y:status0 11 12 13 0.. ...155 1[156 rows x 1 columns]Prediction on train data: [1 1 1 0 ... 1]Accuracy score on train data: 0.6666666666666666Prediction on test data: [1 1 1 1 ... 11 1]Accuracy score on test data: 0.6666666666666666
在訓(xùn)練集和測試集上的準(zhǔn)確率都是 67%。它的性能還可以進(jìn)一步優(yōu)化。你想嘗試一下嗎?你可以在下面的評論區(qū)給出你的方法。
背后原理
樸素貝葉斯分類器從貝葉斯定理發(fā)展來的。貝葉斯定理用于計(jì)算條件概率,或者說貝葉斯定理用于計(jì)算當(dāng)與一個(gè)事件相關(guān)聯(lián)的其他事件發(fā)生時(shí),該事件發(fā)生的概率。簡而言之,它解決了這個(gè)問題:如果我們已經(jīng)知道事件 x 發(fā)生在事件 y 之前的概率,那么當(dāng)事件 x 再次發(fā)生時(shí),事件 y 發(fā)生的概率是多少? 貝葉斯定理用一個(gè)先驗(yàn)的預(yù)測值來逐漸逼近一個(gè)最終的 后驗(yàn)概率。貝葉斯定理有一個(gè)基本假設(shè),就是所有的參數(shù)重要性相同(LCTT 譯注:即相互獨(dú)立)。
貝葉斯計(jì)算主要包括以下步驟:
- 計(jì)算總的先驗(yàn)概率:
P(患病)P(患病) 和 P(不患病)P(不患病) - 計(jì)算 8 種指標(biāo)各自是某個(gè)值時(shí)的后驗(yàn)概率 (value1,...,value8 分別是 MDVP:Fo(Hz),...,Jitter:DDP 的取值):
P(value1,\ldots,value8\ |\ 患病)P(value1,…,value8 ∣ 患病)
P(value1,\ldots,value8\ |\ 不患病)P(value1,…,value8 ∣ 不患病) - 將第 1 步和第 2 步的結(jié)果相乘,最終得到患病和不患病的后驗(yàn)概率:
P(患病\ |\ value1,\ldots,value8) \propto P(患病) \times P(value1,\ldots,value8\ |\ 患病)P(患病 ∣ value1,…,value8)∝P(患病)×P(value1,…,value8 ∣ 患病)
P(不患病\ |\ value1,\ldots,value8) \propto P(不患病) \times P(value1,\ldots,value8\ |\ 不患病)P(不患病 ∣ value1,…,value8)∝P(不患病)×P(value1,…,value8 ∣ 不患病)
上面第 2 步的計(jì)算非常復(fù)雜,樸素貝葉斯將它作了簡化:
- 計(jì)算總的先驗(yàn)概率:
P(患病)P(患病) 和 P(不患病)P(不患病) - 對 8 種指標(biāo)里的每個(gè)指標(biāo),計(jì)算其取某個(gè)值時(shí)的后驗(yàn)概率:
P(value1\ |\ 患病),\ldots,P(value8\ |\ 患病)P(value1 ∣ 患病),…,P(value8 ∣ 患病)
P(value1\ |\ 不患病),\ldots,P(value8\ |\ 不患病)P(value1 ∣ 不患病),…,P(value8 ∣ 不患病) - 將第 1 步和第 2 步的結(jié)果相乘,最終得到患病和不患病的后驗(yàn)概率:
P(患病\ |\ value1,\ldots,value8) \propto P(患病) \times P(value1\ |\ 患病) \times \ldots \times P(value8\ |\ 患病)P(患病 ∣ value1,…,value8)∝P(患病)×P(value1 ∣ 患病)×…×P(value8 ∣ 患病)
P(不患病\ |\ value1,\ldots,value8) \propto P(不患病) \times P(value1\ |\ 不患病) \times \ldots \times P(value8\ |\ 不患病)P(不患病 ∣ value1,…,value8)∝P(不患病)×P(value1 ∣ 不患病)×…×P(value8 ∣ 不患病)
這只是一個(gè)很初步的解釋,還有很多其他因素需要考慮,比如數(shù)據(jù)類型的差異,稀疏數(shù)據(jù),數(shù)據(jù)可能有缺失值等。
超參數(shù)
樸素貝葉斯作為一個(gè)簡單直接的算法,不需要超參數(shù)。然而,有的版本的樸素貝葉斯實(shí)現(xiàn)可能提供一些高級特性(比如超參數(shù))。比如,GaussianNB 就有 2 個(gè)超參數(shù):
- priors:先驗(yàn)概率,可以事先指定,這樣就不必讓算法從數(shù)據(jù)中計(jì)算才能得出。
- var_smoothing:考慮數(shù)據(jù)的分布情況,當(dāng)數(shù)據(jù)不滿足標(biāo)準(zhǔn)的高斯分布時(shí),這個(gè)超參數(shù)會發(fā)揮作用。
損失函數(shù)
為了堅(jiān)持簡單的原則,樸素貝葉斯使用 0-1 損失函數(shù)。如果預(yù)測結(jié)果與期望的輸出相匹配,損失值為 0,否則為 1。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):樸素貝葉斯是最簡單、最快速的算法之一。
優(yōu)點(diǎn):在數(shù)據(jù)量較少時(shí),用樸素貝葉斯仍可作出可靠的預(yù)測。
缺點(diǎn):樸素貝葉斯的預(yù)測只是估計(jì)值,并不準(zhǔn)確。它勝在速度而不是準(zhǔn)確度。
缺點(diǎn):樸素貝葉斯有一個(gè)基本假設(shè),就是所有特征相互獨(dú)立,但現(xiàn)實(shí)情況并不總是如此。
從本質(zhì)上說,樸素貝葉斯是貝葉斯定理的推廣。它是最簡單最快速的機(jī)器學(xué)習(xí)算法之一,用來進(jìn)行簡單和快速的訓(xùn)練和預(yù)測。樸素貝葉斯提供了足夠好、比較準(zhǔn)確的預(yù)測。樸素貝葉斯假設(shè)預(yù)測特征之間是相互獨(dú)立的。已經(jīng)有許多樸素貝葉斯的開源的實(shí)現(xiàn),它們的特性甚至超過了貝葉斯算法的實(shí)現(xiàn)。
當(dāng)前標(biāo)題:用Python輕松實(shí)現(xiàn)機(jī)器學(xué)習(xí)
鏈接地址:http://m.fisionsoft.com.cn/article/dhijeji.html


咨詢
建站咨詢

