【机器学习入门】机器学习基础核心算法:贝叶斯分类!(附西瓜书案例及代码实现)...
?Datawhale?
作者:尹曉丹,Datawhale優秀學習者
寄語:首先,簡單介紹了生成模型和判別模型,對條件概率、先驗概率和后驗概率進行了總結;其次,對樸素貝葉斯的原理及公式推導做了詳細解讀;再次,對三種可能遇到的問題進行了解析,給出了合理的解決辦法;最后,對樸素貝葉斯的sklearn參數和代碼進行了詳解。
貝葉斯分類是一類分類算法的總稱,這類算法均以貝葉斯定理為基礎,故統稱為貝葉斯分類。而樸素貝葉斯分類是貝葉斯分類中最簡單,也是應用最為廣泛的分類算法之一。樸素貝葉斯方法是在貝葉斯算法的基礎上進行了相應的簡化,即假定給定目標值時屬性之間相互條件獨立。
知識框架
相關概念
生成模型
概率統計理論中, 生成模型是指能夠隨機生成觀測數據的模型,尤其是在給定某些隱含參數的條件下。它給觀測值和標注數據序列指定一個聯合概率分布。
在機器學習中,生成模型可以用來直接對數據建模(例如根據某個變量的概率密度函數進行數據采樣),也可以用來建立變量間的條件概率分布。條件概率分布可以由生成模型根據貝葉斯定理形成。
常見的基于生成模型算法有高斯混合模型和其他混合模型、隱馬爾可夫模型、隨機上下文無關文法、樸素貝葉斯分類器、AODE分類器、潛在狄利克雷分配模型、受限玻爾茲曼機等。
舉個栗子:要確定一個瓜是好瓜還是壞瓜,用判別模型的方法使從歷史數據中學習到模型,然后通過提取這個瓜的特征來預測出這只瓜是好瓜的概率,是壞瓜的概率。
判別模型
在機器學習領域判別模型是一種對未知數據 y 與已知數據 x 之間關系進行建模的方法。
判別模型是一種基于概率理論的方法。已知輸入變量 x ,判別模型通過構建條件概率分布 P(y|x) 預測 y 。
常見的基于判別模型算法有邏輯回歸、線性回歸、支持向量機、提升方法、條件隨機場、人工神經網絡、隨機森林、感知器。
舉個栗子:利用生成模型是根據好瓜的特征首先學習出一個好瓜的模型,然后根據壞瓜的特征學習得到一個壞瓜的模型,然后從需要預測的瓜中提取特征,放到生成好的好瓜的模型中看概率是多少,在放到生產的壞瓜模型中看概率是多少,哪個概率大就預測其為哪個。
生成模型與判別模型的區別
生成模型是所有變量的全概率模型,而判別模型是在給定觀測變量值前提下目標變量條件概率模型。
因此,生成模型能夠用于模擬(即生成)模型中任意變量的分布情況,而判別模型只能根據觀測變量得到目標變量的采樣。判別模型不對觀測變量的分布建模,因此它不能夠表達觀測變量與目標變量之間更復雜的關系。因此,生成模型更適用于無監督的任務,如分類和聚類。
先驗概率、條件概率
條件概率
就是事件A在事件B發生的條件下發生的概率。條件概率表示為P(A|B),讀作“A在B發生的條件下發生的概率”。
先驗概率
在貝葉斯統計中,某一不確定量 p 的先驗概率分布是在考慮"觀測數據"前,能表達 p 不確定性的概率分布。它旨在描述這個不確定量的不確定程度,而不是這個不確定量的隨機性。這個不確定量可以是一個參數,或者是一個隱含變量。
后驗概率
在貝葉斯統計中,一個隨機事件或者一個不確定事件的后驗概率是在考慮和給出相關證據或數據后所得到的條件概率。
同樣,后驗概率分布是一個未知量(視為隨機變量)基于試驗和調查后得到的概率分布。“后驗”在本文中代表考慮了被測試事件的相關證據。
貝葉斯決策理論
貝葉斯決策論是概率框架下實施決策的基本方法,對分類任務來說,在所有相關概率都已知的理想情形下,貝葉斯決策論考慮如何基于這些概率和誤判損失來選擇最優的類別標記。
假設有N種可能標記,是將類誤分類為所產生的損失,基于后驗概率可以獲得樣本x分類為所產生的期望損失 ,即在樣本x上的條件風險:
我們的任務是尋找一個判定準則 以最小化總體風險
顯然,對每個樣本,若能最小化條件風險,則總體風險也將被最小化。這就產生了貝葉斯判定準則:最小化總體風險,只需要在每個樣本上選擇那個能使條件風險最小的類別標記,即:
此時,稱作貝葉斯最優分類器,與之對應的總體風險稱為貝葉斯風險,反映了分類器能達到的最好性能,即機器學習所產生的模型精度的上限。具體來說,若目標是最小化分類錯誤率(對應0/1損失),則可以用損失改寫,得到條件風險和最小化分類錯誤率的最優分類器分別為:
即對每個樣本x,選擇能使后驗概率P(c|x)最大的類別標識。
獲得后驗概率的兩種方法:
判別式模型 : 給定x, 可以通過直接建模P(c|x)來預測c。
生成模型 : 先對聯合分布p(x,c)模,然后再有此獲得P(c|x)。
貝葉斯公式
對生成模型來說,必然考慮:
其中P(c)是“先驗概率”;P(x|c)是樣本x對于類標記c的類條件概率,或稱為“似然”;P(x)是用于歸一化的“證據”因子。上式即為貝葉斯公式,可以將其看做:
對類條件概率P(x|c)來說,直接根據樣本出現的頻率來估計將會遇到嚴重的困難,所以引入了極大似然估計。
極大似然估計
估計類條件概率有一種常用的策略就是先假定其具有某種確定的概率分布形式,再基于訓練樣本對概率分布的參數進行估計。
假設P(x|c)具有某種確定的形式并且被參數唯一確定,則我們的任務就是利用訓練結D估計參數。為了明確期間,我們將P(x|c)記為。
舉個通俗的例子:假設一個袋子裝有白球與紅球,比例未知,現在抽取10次(每次抽完都放回,保證事件獨立性),假設抽到了7次白球和3次紅球,在此數據樣本條件下,可以采用最大似然估計法求解袋子中白球的比例(最大似然估計是一種“模型已定,參數未知”的方法)。
當然,這種數據情況下很明顯,白球的比例是70%,但如何通過理論的方法得到這個答案呢?一些復雜的條件下,是很難通過直觀的方式獲得答案的,這時候理論分析就尤為重要了,這也是學者們為何要提出最大似然估計的原因。我們可以定義從袋子中抽取白球和紅球的概率如下:
x1為第一次采樣,x2為第二次采樣,f為模型, theta為模型參數。其中θ是未知的,因此,我們定義似然L為:
兩邊取ln,取ln是為了將右邊的乘號變為加號,方便求導。
兩邊取ln的結果,左邊的通常稱之為對數似然。
這是平均對數似然。最大似然估計的過程,就是找一個合適的theta,使得平均對數似然的值為最大。因此,可以得到以下公式:
最大似然估計的公式。這里討論的是2次采樣的情況,
當然也可以拓展到多次采樣的情況:最大似然估計的公式(n次采樣)。我們定義M為模型(也就是之前公式中的f),表示抽到白球的概率為θ,而抽到紅球的概率為(1-θ),因此10次抽取抽到白球7次的概率可以表示為:
將其描述為平均似然可得:
10次抽取抽到白球7次的平均對數似然,抽球的情況比較簡單,可以直接用平均似然來求解。那么最大似然就是找到一個合適的theta,獲得最大的平均似然。因此我們可以對平均似然的公式對theta求導,并另導數為0。
求得,θ=0.7。求導過程 由此可得,當抽取白球的概率為0.7時,最可能產生10次抽取抽到白球7次的事件。以上就用到了最大似然估計的思想。
令Dc表示訓練集D中第c類樣本組成的集合,假設這些集合是獨立同分布的,則對參數θc、對于數據集Dc的似然是:
對θc進行激發似然估計買就是去尋找能最大化似然函數的參數值θc直觀上,極大似然估計是在試圖在θc的所有可能的去職中,找到一個能使數據出現最大“可能性”的最大值上面的式子中的連乘操作容易造成下溢,通常使用對數似然:
此時,參數的極大似然估計為
例如,在連續屬性的情形下,假設概率密度函數,則參數和。
也就是說通過極大似然發得到的額正態分布均值就是樣本均值,方差就是的均值。這顯然是一個符合只覺得結果,在離散屬性情形下,也可以通過類似的方法來估計類條件概率。
需要注意的是這種方法雖然能夠使類條件概率估計變得簡單,但是估計結果準確性嚴重依賴于所假設的概率分布形式是否符合潛在的真實數據分布。在顯示生活中往往需要應用任務本身的經驗知識,“猜測”則會導致誤導性的結果。
貝葉斯分類器的訓練過程就是參數估計。總結最大似然法估計參數的過程,一般分為以下四個步驟:
寫出似然函數;
對似然函數取對數,并整理;
求導數,令偏導數為0,得到似然方程組;
解似然方程組,得到所有參數即為所求。
樸素貝葉斯分類器
基于貝葉斯公式來估計后驗概率P(c|x)主要困難在于類條件概率P(x|c)是所有屬性上的聯合概率,難以從有限的訓練樣本直接估計而得。
基于有限訓練樣本直接計算聯合概率,在計算上將會遭遇組合爆炸問題;在數據上將會遭遇樣本稀疏問題;屬性越多,問題越嚴重。
為了避開這個障礙,樸素貝葉斯分類器采用了“屬性條件獨立性假設”:對已知類別,假設所有屬性相互獨立。換言之,假設每個屬性獨立的對分類結果發生影響相互獨立。
回答西瓜的例子就可以認為{色澤 根蒂 敲聲 紋理 臍部 觸感}這些屬性對西瓜是好還是壞的結果所產生的影響相互獨立。
基于條件獨立性假設,對于多個屬性的后驗概率可以寫成:
d為屬性數目,是在第個屬性上取值。對于所有的類別來說相同,基于極大似然的貝葉斯判定準則有樸素貝葉斯的表達式:
極值問題情況下每個類的分類概率
很多時候遇到求出各種目標函數(object function)的最值問題(最大值或者最小值)。關于函數最值問題,其實在高中的時候我們就已經了解不少,最經典的方法就是:直接求出極值點。
這些極值點的梯度為0。若極值點唯一,則這個點就是代入函數得出的就是最值;若極值點不唯一,那么這些點中,必定存在最小值或者最大值(去除函數的左右的最端點),所以把極值代入函數,經對比后可得到結果。
請注意:并不一定所有函數的極值都可以通過設置導數為0的方式求出。也就是說,有些問題中當我們設定導數為0時,未必能直接計算出滿足導數為0的點(比如邏輯回歸模型),這時候就需要利用數值計算相關的技術(最典型為梯度下降法,牛頓法……)。
下溢問題如何解決
數值下溢問題:是指計算機浮點數計算的結果小于可以表示的最小數,因為計算機的能力有限,當數值小于一定數時,其無法精確保存,會造成數值的精度丟失,由上述公式可以看到,求概率時多個概率值相乘,得到的結果往往非常小;因此通常采用取對數的方式,將連乘轉化為連加,以避免數值下溢。
零概率問題如何解決?
零概率問題,就是在計算實例的概率時,如果某個量x,在觀察樣本庫(訓練集)中沒有出現過,會導致整個實例的概率結果是0。
在實際的模型訓練過程中,可能會出現零概率問題(因為先驗概率和反條件概率是根據訓練樣本算的,但訓練樣本數量不是無限的,所以可能出現有的情況在實際中存在,但在訓練樣本中沒有,導致為0的概率值,影響后面后驗概率的計算)。
即便可以繼續增加訓練數據量,但對于有些問題來說,數據怎么增多也是不夠的。這時我們說模型是不平滑的,我們要使之平滑,一種方法就是將訓練(學習)的方法換成貝葉斯估計。
現在看一個示例,及P(敲聲=清脆∣好瓜=是)=8/0=0。不論樣本的其他屬性如何,分類結果都會為“好瓜=否”,這樣顯然不太合理。
樸素貝葉斯算法的先天缺陷
其他屬性攜帶的信息被訓練集中某個分類下未出現的屬性值“抹去”,造成預測出來的概率絕對為0。為了彌補這一缺陷,前輩們引入了拉普拉斯平滑的方法:對先驗概率的分子(劃分的計數)加1,分母加上類別數;對條件概率分子加1,分母加上對應特征的可能取值數量。這樣在解決零概率問題的同時,也保證了概率和依然為1:
其中,N表示數據集中分類標簽,表示第個屬性的取值類別數,樣本容量,表示類別的記錄數量,表示類別中第個屬性取值為的記錄數量。
將這兩個式子應用到上面的計算過程中,就可以彌補樸素貝葉斯算法的這一缺陷問題。
用西瓜的數據來看,當我們計算 P(好瓜=是) 時,樣本有17個,所以|D| = 17,N,好瓜標簽可以分為{是,否}兩類,所以N=2,(好瓜=是)的樣本個數有8個,所以這里。
綜上,根據拉普拉斯平滑后有
P(色澤=青綠|好瓜=是)時,色澤青綠的樣本有8個,所以|D_c| = 8,色澤標簽可以分為{青綠,淺白,烏黑}三類,所以N=3,(好瓜=是)的樣本個數有3個,所以這里=3。綜上,根據拉普拉斯平滑后有
同理,分析可知,之前不合理的P(敲聲=清脆∣好瓜=是)=80=0P(敲聲=清脆|好瓜=是)=\frac{8}{0}=0P(敲聲=清脆∣好瓜=是)=?8/0?=0在進行拉普拉斯平滑后為:
顯然結果不是0,使結果變得合理。
優缺點
優點
1. 樸素貝葉斯模型有穩定的分類效率。
2. 對小規模的數據表現很好,能處理多分類任務,適合增量式訓練,尤其是數據量超出內存時,可以一批批的去增量訓練。
3. 對缺失數據不太敏感,算法也比較簡單,常用于文本分類。
缺點
1. 理論上,樸素貝葉斯模型與其他分類方法相比具有最小的誤差率。但是實際上并非總是如此,這是因為樸素貝葉斯模型給定輸出類別的情況下,假設屬性之間相互獨立,這個假設在實際應用中往往是不成立的,在屬性個數比較多或者屬性之間相關性較大時,分類效果不好。而在屬性相關性較小時,樸素貝葉斯性能最為良好。對于這一點,有半樸素貝葉斯之類的算法通過考慮部分關聯性適度改進。
2. 需要知道先驗概率,且先驗概率很多時候取決于假設,假設的模型可以有很多種,因此在某些時候會由于假設的先驗模型的原因導致預測效果不佳。
3. 由于我們是通過先驗和數據來決定后驗的概率從而決定分類,所以分類決策存在一定的錯誤率。
4. 對輸入數據的表達形式很敏感。
sklearn參數詳解
高斯樸素貝葉斯算法是假設特征的可能性(即概率)為高斯分布。
class sklearn.naive_bayes.GaussianNB(priors=None)
參數:
1. priors : 先驗概率大小,如果沒有給定,模型則根據樣本數據自己計算(利用極大似然法)。
2. var_smoothing:可選參數,所有特征的最大方差
屬性:
3. class_prior_ : 每個樣本的概率
4. class_count : 每個類別的樣本數量
5. classes_ : 分類器已知的標簽類型
6. theta_ : 每個類別中每個特征的均值
7. sigma_ : 每個類別中每個特征的方差
8. epsilon_ : 方差的絕對加值方法
貝葉斯的方法和其他模型的方法一致
1. fit(X,Y) : 在數據集(X,Y)上擬合模型。
2. get_params() : 獲取模型參數。
3. predict(X) : 對數據集X進行預測。
4. predict_log_proba(X) : 對數據集X預測,得到每個類別的概率對數值。
5. predict_proba(X) : 對數據集X預測,得到每個類別的概率。
6. score(X,Y) : 得到模型在數據集(X,Y)的得分情況。
構建樸素貝葉斯模型
這里采用GaussianNB 高斯樸素貝葉斯,概率密度函數為:
import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inlinefrom sklearn.datasets import load_iris from sklearn.model_selection import train_test_splitfrom collections import Counter import math import?math # data def create_data():iris = load_iris()df = pd.DataFrame(iris.data, columns=iris.feature_names)df['label'] = iris.targetdf.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']data = np.array(df.iloc[:100, :])# print(data)return?data[:,:-1],?data[:,-1] import math class NaiveBayes:def __init__(self):self.model = None# 數學期望@staticmethoddef mean(X):"""計算均值Param: X : list or np.ndarrayReturn:avg : float"""avg = 0.0# ========= show me your code ==================avg = sum(X) / float(len(X))# ========= show me your code ==================return avg# 標準差(方差)def stdev(self, X):"""計算標準差Param: X : list or np.ndarrayReturn:res : float"""res = 0.0# ========= show me your code ==================avg = self.mean(X)res = math.sqrt(sum([pow(x - avg, 2) for x in X]) / float(len(X)))# ========= show me your code ==================return res# 概率密度函數def gaussian_probability(self, x, mean, stdev):"""根據均值和標注差計算x符號該高斯分布的概率Parameters:----------x : 輸入mean : 均值stdev : 標準差Return:res : float, x符合的概率值"""res = 0.0# ========= show me your code ==================exponent = math.exp(-(math.pow(x - mean, 2) /(2 * math.pow(stdev, 2))))res = (1 / (math.sqrt(2 * math.pi) * stdev)) * exponent# ========= show me your code ==================return res# 處理X_traindef summarize(self, train_data):"""計算每個類目下對應數據的均值和標準差Param: train_data : listReturn : [mean, stdev]"""summaries = [0.0, 0.0]# ========= show me your code ==================summaries = [(self.mean(i), self.stdev(i)) for i in zip(*train_data)]# ========= show me your code ==================return summaries# 分類別求出數學期望和標準差def fit(self, X, y):labels = list(set(y))data = {label: [] for label in labels}for f, label in zip(X, y):data[label].append(f)self.model = {label: self.summarize(value) for label, value in data.items()}return 'gaussianNB train done!'# 計算概率def calculate_probabilities(self, input_data):"""計算數據在各個高斯分布下的概率Paramter:input_data : 輸入數據Return:probabilities : {label : p}"""# summaries:{0.0: [(5.0, 0.37),(3.42, 0.40)], 1.0: [(5.8, 0.449),(2.7, 0.27)]}# input_data:[1.1, 2.2]probabilities = {}# ========= show me your code ==================for label, value in self.model.items():probabilities[label] = 1for i in range(len(value)):mean, stdev = value[i]probabilities[label] *= self.gaussian_probability(input_data[i], mean, stdev)# ========= show me your code ==================return probabilities# 類別def predict(self, X_test):# {0.0: 2.9680340789325763e-27, 1.0: 3.5749783019849535e-26}label = sorted(self.calculate_probabilities(X_test).items(), key=lambda x: x[-1])[-1][0]return label# 計算得分def score(self, X_test, y_test):right = 0for X, y in zip(X_test, y_test):label = self.predict(X)if label == y:right += 1return?right?/?float(len(X_test)) model = NaiveBayes() model.fit(X_train,?y_train) print(model.predict([3.4, 6.2, 2.0, 0.3])) model.score(X_test,?y_test)往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習在線手冊AI基礎下載(pdf更新到25集)本站qq群1003271085,加入微信群請回復“加群”獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/yFQV7am喜歡文章,點個在看
總結
以上是生活随笔為你收集整理的【机器学习入门】机器学习基础核心算法:贝叶斯分类!(附西瓜书案例及代码实现)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 四个好用却可能不为人所熟知的Pandas
- 下一篇: 【Python入门】Python字符串的