Python · 樸素貝葉斯(三)· GaussianNB
(這裡是本章會用到的 GitHub 地址)
(話說居然一個月沒寫了啊……)(然而你一個月沒寫之後寫的東西還這麼水對得起觀眾老爺嗎)
(剛發現演算法敘述居然在這篇文章中說過了…… ( σω)σ)
本章主要介紹連續型樸素貝葉斯—— GaussianNB 的實現。在有了實現離散型樸素貝葉斯的經驗後,實現連續型樸素貝葉斯模型其實只是個觸類旁通的活了。演算法的敘述已經在這篇文章中進行過說明,下面就直接看看如何進行實現
由 GaussianNB 的演算法可知,在實現 GaussianNB 之前、我們需要先實現一個能夠計算正態分布密度和進行正態分布極大似然估計的類:
import numpy as npnfrom math import pi, expnn# 記錄常量以避免重複運算nsqrt_pi = (2 * pi) ** 0.5nnclass NBFunctions:n # 定義正態分布的密度函數n @staticmethodn def gaussian(x, mu, sigma):ntreturn np.exp(n -(x - mu) ** 2 / (2 * sigma)) / (sqrt_pi * sigma ** 0.5)nn # 定義進行極大似然估計的函數n # 它能返回一個存儲著計算條件概率密度的函數的列表n @staticmethodn def gaussian_maximum_likelihood(labelled_x, n_category, dim):n mu = [np.sum(n labelled_x[c][dim]) / n len(labelled_x[c][dim]) for c in range(n_category)]n sigma = [np.sum(n (labelled_x[c][dim]-mu[c])**2) / n len(labelled_x[c][dim]) for c in range(n_category)]n # 利用極大似然估計得到的和、定義生成計算條件概率密度的函數的函數 funcn def func(_c):n def sub(xx):n return NBFunctions.gaussian(xx, mu[_c], sigma[_c])n return subn # 利用 func 返回目標列表n return [func(_c=c) for c in range(n_category)]n
nnnnnnnnnnnnnnn對於 GaussianNB 本身,由於演算法中只有條件概率相關的定義變了、所以只需要將相關的函數重新定義即可。此外,由於輸入數據肯定是數值數據、所以數據預處理會簡單不少(至少不用因為要對輸入進行特殊的數值化處理而記錄其轉換字典了)。考慮到上一章說明 MultinomialNB 的實現時已經基本把我們框架的思想都說明清楚了,在接下來的 GaussianNB 的代碼實現中、我們會適當地減少注釋以提高閱讀流暢度(其實主要還是為了偷懶)(喂):
from b_NaiveBayes.Original.Basic import *nnclass GaussianNB(NaiveBayes):n def feed_data(self, x, y, sample_weight=None):n # 簡單地調用 Python 自帶的 float 方法將輸入數據數值化n x = np.array([list(map(n lambda c: float(c), sample)) for sample in x])n # 數值化類別向量n labels = list(set(y))n label_dic = {label: i for i, label in enumerate(labels)}n y = np.array([label_dic[yy] for yy in y])n cat_counter = np.bincount(y)n labels = [y == value for value in range(len(cat_counter))]n labelled_x = [x[label].T for label in labels]n # 更新模型的各個屬性n self._x, self._y = x.T, yn self._labelled_x, self._label_zip = labelled_x, labelsn self._cat_counter, self.label_dic = (n cat_counter, {i: _l for _l, i in label_dic.items()}n self.feed_sample_weight(sample_weight)n
nnnnnnnnnnnnnnn可以看到,數據預處理這一步確實要輕鬆很多。接下來只需要再定義訓練用的代碼就行,它們和 MultinomialNB 中的實現也大同小異:
# 定義處理樣本權重的函數n def feed_sample_weight(self, sample_weight=None):n if sample_weight is not None:n local_weights = sample_weight * len(sample_weight)n for i, label in enumerate(self._label_zip):n self._labelled_x[i] *= local_weights[label]nn def _fit(self, lb):n n_category = len(self._cat_counter)n p_category = self.get_prior_probability(lb)n # 利用極大似然估計獲得計算條件概率的函數、使用數組變數 data 進行存儲n data = [n NBFunctions.gaussian_maximum_likelihood(n self._labelled_x, n_category, dim)n for dim in range(len(self._x))]n self._data = datan def func(input_x, tar_category):n # 將輸入轉換成二維數組(矩陣)n input_x = np.atleast_2d(input_x).Tn rs = np.ones(input_x.shape[1])n for d, xx in enumerate(input_x):n rs *= data[d][tar_category](xx)n return rs * p_category[tar_category]n n # 由於數據本身就是數值的,所以數據轉換函數只需直接返回輸入值即可n @staticmethodn def _transfer_x(x):n return xn
nnnnnnnnnnnnnnn至此,連續型樸素貝葉斯模型就搭建完畢了
nn連續型樸素貝葉斯同樣能夠進行和離散型樸素貝葉斯類似的可視化,不過由於我們接下來就要實現適用範圍最廣的樸素貝葉斯模型:混合型樸素貝葉斯了,所以我們這裡不打算進行 GaussianNB 合理的評估、而打算把它歸結到對混合型樸素貝葉斯的評估中
希望觀眾老爺們能夠喜歡~
(猛戳我進入下一章! ( σω)σ )
推薦閱讀:
※Python數據處理 II:數據的清洗(預處理)
※如何回答同學知道我在學 Python 時問我「會盜 QQ 號嗎」?
※Python 抓取網頁亂碼原因分析
※用爬蟲抓取崑崙決所有選手信息並保存為PDF檔案!(淺談搏擊運動數據分析)
※Python數據分析模塊 | pandas做數據分析(一):基本數據對象