周志华《机器学习》课后习题(第七章):贝叶斯分类
作者 |?我是韓小琦
鏈接 |?https://zhuanlan.zhihu.com/p/51768750
7.1 試使用極大似然法估算回瓜數(shù)據(jù)集 3.0 中前 3 個屬性的類條件概率.
答:
以第一個屬性色澤為例,其值計(jì)數(shù)如下:
色澤 烏黑 淺白 青綠
好瓜
否 2 4 3
是 4 1 3
令??表示好瓜中色澤為“烏黑”的概率,??為好瓜中“淺白”的概率,??,??,??表示好瓜的樣本,其他類同,于是色澤屬性的似然概率則可表示為?,其對數(shù)似然為:??,分別對??求偏導(dǎo)并使其為零,即可得??的極大似然估計(jì):??,同理可得??的似然概率,進(jìn)而求得類為“否”時各取值條件概率的極大似然估計(jì)。
其他兩個屬性同理。
7.2* 試證明:條件獨(dú)立性假設(shè)不成立時,樸素貝葉斯分類器仍有可能產(chǎn)生最優(yōu)貝葉斯分類器.
答:
令一組數(shù)據(jù)中有??三中屬性,其目標(biāo)值為Bool型變量,即取值??且其概率相同,即??。給定一個樣本??,令??表示??,??表示??中屬性??的取值。假設(shè)?完全獨(dú)立,而??即兩者完全相關(guān),因此理論上對于最優(yōu)貝葉斯分類器來說,屬性??應(yīng)該被忽略,那么基于最優(yōu)貝葉斯分類器時,其決策準(zhǔn)則(書中P7.15式)可描述為:若??時,則將樣本??歸為??類;而另一方面,考慮樸素貝葉斯分類器,在分類決策時會將屬性??也考慮在內(nèi),此時相當(dāng)于將??計(jì)算了兩次,此時決策準(zhǔn)則則描述為:??時,將??歸為??類。
根據(jù)貝葉斯理論,??,且由于??,則最優(yōu)貝葉斯分類可表示為:??;而樸素貝葉斯則表示為:??。取??,于是最優(yōu)貝葉斯分類器為:??,樸素貝葉斯為??,兩者決策邊界如下圖:
只有在兩者決策邊界之間(淺黃色區(qū)域),其分類情況是不同的,在其他區(qū)域,樸素貝葉斯分類結(jié)果和最優(yōu)貝葉斯的分類結(jié)果是相同的,因此即便屬性之間獨(dú)立性假設(shè)不成立,樸素貝葉斯在某些條件(本例中就是屬性概率分布在兩者相交區(qū)域之外)下任然是最優(yōu)貝葉斯分類器。
參考:
《On the Optimality of the Simple Bayesian Classifier under Zero-One Loss》
ps.這個例子就是來自該論文,只做了一點(diǎn)翻譯工作。論文中給出了更全面的理論證明,和樸素貝葉斯產(chǎn)生最優(yōu)貝葉斯分類的充分必要條件。本打算看完把理論證明也嘗試復(fù)述一遍,但能力有限,一方面沒有理解很透徹,另一方面證明過程有點(diǎn)長感覺表達(dá)能力有點(diǎn)不大夠用...
7.3 試編程實(shí)現(xiàn)拉普拉斯修正的樸素貝葉斯分類器,并以西瓜數(shù)據(jù)集 3.0 為訓(xùn)練集,對 p.151 "測1" 樣本進(jìn)行判別.
答:
han1057578619/MachineLearning_Zhouzhihua_ProblemSets
import numpy as np import pandas as pd from sklearn.utils.multiclass import type_of_target from collections import namedtupledef train_nb(X, y):m, n = X.shapep1 = (len(y[y == '是']) + 1) / (m + 2) # 拉普拉斯平滑p1_list = [] # 用于保存正例下各屬性的條件概率p0_list = []X1 = X[y == '是']X0 = X[y == '否']m1, _ = X1.shapem0, _ = X0.shapefor i in range(n):xi = X.iloc[:, i]p_xi = namedtuple(X.columns[i], ['is_continuous', 'conditional_pro']) # 用于儲存每個變量的情況is_continuous = type_of_target(xi) == 'continuous'xi1 = X1.iloc[:, i]xi0 = X0.iloc[:, i]if is_continuous: # 連續(xù)值時,conditional_pro 儲存的就是 [mean, var] 即均值和方差xi1_mean = np.mean(xi1)xi1_var = np.var(xi1)xi0_mean = np.mean(xi0)xi0_var = np.var(xi0)p1_list.append(p_xi(is_continuous, [xi1_mean, xi1_var]))p0_list.append(p_xi(is_continuous, [xi0_mean, xi0_var]))else: # 離散值時直接計(jì)算各類別的條件概率unique_value = xi.unique() # 取值情況nvalue = len(unique_value) # 取值個數(shù)xi1_value_count = pd.value_counts(xi1)[unique_value].fillna(0) + 1 # 計(jì)算正樣本中,該屬性每個取值的數(shù)量,并且加1,即拉普拉斯平滑xi0_value_count = pd.value_counts(xi0)[unique_value].fillna(0) + 1p1_list.append(p_xi(is_continuous, np.log(xi1_value_count / (m1 + nvalue))))p0_list.append(p_xi(is_continuous, np.log(xi0_value_count / (m0 + nvalue))))return p1, p1_list, p0_listdef predict_nb(x, p1, p1_list, p0_list):n = len(x)x_p1 = np.log(p1)x_p0 = np.log(1 - p1)for i in range(n):p1_xi = p1_list[i]p0_xi = p0_list[i]if p1_xi.is_continuous:mean1, var1 = p1_xi.conditional_promean0, var0 = p0_xi.conditional_prox_p1 += np.log(1 / (np.sqrt(2 * np.pi) * var1) * np.exp(- (x[i] - mean1) ** 2 / (2 * var1 ** 2)))x_p0 += np.log(1 / (np.sqrt(2 * np.pi) * var0) * np.exp(- (x[i] - mean0) ** 2 / (2 * var0 ** 2)))else:x_p1 += p1_xi.conditional_pro[x[i]]x_p0 += p0_xi.conditional_pro[x[i]]if x_p1 > x_p0:return '是'else:return '否'if __name__ == '__main__':data_path = r'C:\Users\hanmi\Documents\xiguabook\watermelon3_0_Ch.csv'data = pd.read_csv(data_path, index_col=0)X = data.iloc[:, :-1]y = data.iloc[:, -1]p1, p1_list, p0_list = train_nb(X, y)x_test = X.iloc[0, :] # 書中測1 其實(shí)就是第一個數(shù)據(jù)print(predict_nb(x_test, p1, p1_list, p0_list))這里代碼很簡單。不怎么規(guī)范。
7.4 實(shí)踐中使用式 (7.15)決定分類類別時,若數(shù)據(jù)的維數(shù)非常高,則概率連乘??的結(jié)果通常會非常接近于 0 從試述防止下溢的可能方案.而導(dǎo)致下溢.
答:
這在p153中已經(jīng)給出答案了。即取對數(shù)將連乘轉(zhuǎn)化為“連加”防止下溢。
即將式(7.15)改為:??。
7.5 試證明:二分類任務(wù)中兩類數(shù)據(jù)滿足高斯分布且方差相同時,線性判別分析產(chǎn)生貝葉斯最優(yōu)分類器.
答:
首先看一下貝葉斯最優(yōu)分類器:在書中p148中解釋了對于最小化分類錯誤率的貝葉斯最優(yōu)分類器可表示為:
?,
由貝葉斯定理即轉(zhuǎn)換為:
?。
那么在數(shù)據(jù)滿足高斯分布時有:?
在二分類任務(wù)中,貝葉斯決策邊界可表示為?
再看看線性判別分析:
書中p62給出式3.39,其投影界面可等效于
?,
注意為了和上面的推導(dǎo)一致,這里和書中給出的差了一個負(fù)號,但??位置沒有改變,只是改變了方向而已。在兩類別方差相同時有:?
?,
兩類別在投影面連線的中點(diǎn)可為?
??,
那么線性判別分析的決策邊界可表示為
??。
推導(dǎo)到這里發(fā)現(xiàn)貝葉斯最優(yōu)分類器和線性判別分析的決策邊界只相差?
?,
在題目左邊小字中有提及,“假設(shè)同先驗(yàn)”,所以?
?,
于是得證。
7.6 試編程實(shí)現(xiàn) AODE 分類器,并以西瓜數(shù)據(jù)集 3.0 為訓(xùn)練集,對 p.151的"測1" 樣本進(jìn)行判別.
答:
代碼在:
han1057578619/MachineLearning_Zhouzhihua_ProblemSets
''' 目前僅拿西瓜數(shù)據(jù)集測試過,運(yùn)行正常,其他數(shù)據(jù)未測試 ''' import numpy as np import pandas as pd from sklearn.utils.multiclass import type_of_targetclass AODE(object):def __init__(self, m):self.m_hat = mself.m = Noneself.n = Noneself.unique_y = Noneself.n_class = Noneself.is_continuous = Noneself.unique_values = Noneself.total_p = Nonedef predict(self, X):X = np.array(X)if self.total_p == None:raise Exception('you have to fit first before predict.')result = pd.DataFrame(np.zeros((X.shape[0], self.unique_y.shape[0])), columns=self.unique_y)for i in self.total_p.keys():result += self._spode_predict(X, self.total_p[i], i)return self.unique_y[np.argmax(result.values, axis=1)]def fit(self, X, y):X = np.array(X)self.m, self.n = X.shapeself.unique_y = np.unique(y)self.n_class = self.unique_y.size# 這里轉(zhuǎn)為list, 是因?yàn)槊菜苩ype_of_target 有bug, 只有在pd.Series類型的時候才能解析為'continuous',# 在這里轉(zhuǎn)為array類型后解析為 'unknown'了is_continuous = pd.DataFrame(X).apply(lambda x: (type_of_target(x.tolist()) == 'continuous'))self.is_continuous = is_continuousunique_values = {} # 離散型字段的各取值for i in is_continuous[~is_continuous].index:unique_values[i] = np.unique(X[:, i])self.unique_values = unique_values# 獲取可以作為父節(jié)點(diǎn)的屬性索引,這里在論文中取值為30; 但在西瓜書中由于樣本很少, 所有直接取0就好parent_attribute_index = self._get_parent_attribute(X)total_p = {}for i in parent_attribute_index:p = self._spode_fit(X, y, i)total_p[i] = pself.total_p = total_preturn selfdef _spode_fit(self, X, y, xi_index):p = pd.DataFrame(columns=self.unique_y, index=self.unique_values[xi_index]) # 儲存各取值下的條件概率nunique_xi = self.unique_values[xi_index].size # 當(dāng)前屬性的取值數(shù)量pc_xi_denominator = self.m + self.n_class * nunique_xi # 計(jì)算 p(c, xi) 的分母 |D| + N * N_ifor c in self.unique_y:for xi in self.unique_values[xi_index]:p_list = [] # 儲存y取值為c, Xi取值為xi下各個條件概率p(xj|c, xi)和先驗(yàn)概率p(c, xi)c_xi = (X[:, xi_index] == xi) & (y == c)X_c_xi = X[c_xi, :] # y 取值 為c, Xi 取值為xi 的所有數(shù)據(jù)pc_xi = (X_c_xi.shape[0] + 1) / pc_xi_denominator # p(c, xi)# 實(shí)際上這里在j = i時, 個人理解應(yīng)該是可以跳過不計(jì)算的,因?yàn)閜(xi|c, xi) = 1, 在計(jì)算中都是一樣的但這里為了方便實(shí)現(xiàn),就沒有跳過了。for j in range(self.n):if self.is_continuous[j]: # 字段為連續(xù)值, 假設(shè)服從高斯分布, 保存均值和方差# 這里因?yàn)闃颖咎佟S袝r候會出現(xiàn)X_c_xi為空或者只有一個數(shù)據(jù)的情況, 如何是離散值,依然可以計(jì)算;# 但是連續(xù)值的情況下,np.mean會報(bào)warning, 只有一個數(shù)據(jù)時,方差為0# 所有這時, 均值和方差以類別樣本來替代。if X_c_xi.shape[0] <= 1:p_list.append([np.mean(X[y == c, j]), np.var(X[y == c, j])])else:p_list.append([np.mean(X_c_xi[:, j]), np.var(X_c_xi[:, j])])else:# 計(jì)算 p(xj|c, xi)condi_proba_of_xj = (pd.value_counts(X_c_xi[:, j])[self.unique_values[j]].fillna(0) + 1) / (X_c_xi.shape[0] + self.unique_values[j].size)p_list.append(np.log(condi_proba_of_xj))p_list.append(np.log(pc_xi)) # p(c, xi)在最后的位置p.loc[xi, c] = p_listreturn pdef _spode_predict(self, X, p, xi_index):assert X.shape[1] == self.nxi = X[:, xi_index]result = pd.DataFrame(np.zeros((X.shape[0], p.shape[1])), columns=self.unique_y) # 儲存每個樣本為不同類別的對數(shù)概率值for value in p.index: # 為了可以使用pandas的索引功能, 對于要預(yù)測的X值, 每一次循環(huán)求同一取值下樣本的條件概率和xi_value = xi == valueX_split = X[xi_value, :]for c in p.columns:p_list = p.loc[value, c] # 儲存p(xj|c, xi) 和 p(c, xi)的列表for j in range(self.n): # 遍歷所有的條件概率, 將對應(yīng)的條件概率相加if self.is_continuous[j]:mean_, var_ = p_list[j]result.loc[xi_value, c] += (-np.log(np.sqrt(2 * np.pi) * var_) - (X_split[:, j] - mean_) ** 2 / (2 * var_ ** 2))else:result.loc[xi_value, c] += p_list[j][X_split[:, j]].valuesresult.loc[xi_value, c] += p_list[-1] # 最后加上p(c, xi)return resultdef _get_parent_attribute(self, X):'''基于屬性下各取值的樣本數(shù)量,決定哪些屬性可以作為父屬性。關(guān)于連續(xù)值的處理,在《機(jī)器學(xué)習(xí)》書中也沒有提及,AODE的原論文也沒有提及如何處理連續(xù)值,考慮到若將連續(xù)值x_j作為父屬性時,如何求解p(x_i|c, x_j)條件概率會比較麻煩(可以通過貝葉斯公式求解),此外AODE本身就是要將取值樣本數(shù)量低于m的屬性去除的,從這個角度來說,連續(xù)值就不能作為父屬性了。所以這里連續(xù)值不作為父屬性:param X::return:'''enough_quantity = pd.DataFrame(X).apply(lambda x: (type_of_target(x.tolist()) != 'continuous') & (pd.value_counts(x) > self.m_hat).all())return enough_quantity[enough_quantity].index.tolist()if __name__ == '__main__':data_path = r'C:\Users\hanmi\Documents\xiguabook\watermelon3_0_Ch.csv'data = pd.read_csv(data_path, index_col=0)X = data.iloc[:, :-1]y = data.iloc[:, -1]aode = AODE(0)print(aode.fit(X, y).predict(X.iloc[[0], :]))提一下關(guān)于連續(xù)值處理的問題。這個書中和原論文(好像)都沒有提交,所以按照自己的理解來處理了。考慮到以下,實(shí)現(xiàn)過程中不將連續(xù)值作為父屬性。
此外AODE本身就是要將取值樣本數(shù)量低于一定閾值(論文中給出的是30)的屬性去除的,從這個角度來說,連續(xù)值就不能作為父屬性了,當(dāng)前其實(shí)可以按照區(qū)間劃分將連續(xù)值離散化。
另外,雖然在樣本這么小的情況下,看預(yù)測結(jié)果實(shí)際意義不大,但相比于樸素貝葉斯,AODE對于西瓜數(shù)據(jù)集的擬合更好(錯誤率更低)。
ps.書中給出的式(7.24)有錯誤的,分母的?改正為??,在第十次印刷的時候糾正了,看舊版書的同學(xué)要注意了。
7.7 給定 d 個二值屬性的二分類任務(wù),假設(shè)對于任何先驗(yàn)概率項(xiàng)的估算至少需 30 個樣例,則在樸素貝葉斯分類器式 (7.15) 中估算先驗(yàn)概率項(xiàng)??需 30 x 2 = 60 個樣例.試估計(jì)在 AODE 式 (7.23) 中估算先驗(yàn)概率項(xiàng)??所需的樣例數(shù)(分別考慮最好和最壞情形) .
答:
這里“假設(shè)對于任何先驗(yàn)概率項(xiàng)的估算至少需 30 個樣例”意味著在所有樣本中, 任意?的組合至少出現(xiàn)30次。
當(dāng)??時,即只有一個特征??,因?yàn)槭嵌祵傩?#xff0c;假設(shè)取值為??,那為了估計(jì)??至少需要30個樣本,同樣??需要額外30個樣本,另外兩種情況同理,所以在??時,最好和最壞情況都需要120個樣本。
再考慮??,多加個特征??同樣取值??,為了滿足求??已經(jīng)有了120個樣本,且60個正樣本和60個負(fù)樣本;在最好的情況下,在60個正樣本中,正好有30個樣本??,30個??,負(fù)樣本同理,此時這120個樣本也同樣滿足計(jì)算??的條件,所有??時,最好的情況也只需要120個樣本,??時同理;在最壞的情況下,120個樣子中,??都取相同的值??,那么為了估算??需要額外60個樣本,總計(jì)180個樣本,同理計(jì)算出??時的樣本數(shù),即每多一個特征,最壞情況需要多加額外60個樣本,??時,需要??個樣本。
那么??個二值屬性下,最好情況需要120個樣本,最好情況需要??個樣本。
答
這個問題主要基于書中式7.26,就很容易理解了
首先考慮同父結(jié)構(gòu),根據(jù)式7.26,其聯(lián)合分布可以表示為:
?,
在給定??時,
即同父結(jié)構(gòu)中??關(guān)于??條件獨(dú)立;
在??取值未知時有:
?
是推不出??的,所以同父結(jié)構(gòu)中??關(guān)于??邊際獨(dú)立不成立。
再考慮順序結(jié)構(gòu),其聯(lián)合分布有:
給定??時,
,
即順序結(jié)構(gòu)中??關(guān)于??條件獨(dú)立;
在??取值未知時有:
?,
同樣推不出??,所以順序結(jié)構(gòu)中,同樣??關(guān)于??邊際獨(dú)立不成立。
好久沒更新...罪過,墮落了...前面八題一個月之前就寫好了,一直在看7.7(主要還是懶.)閱讀材料給出的貝葉斯網(wǎng)相關(guān)論文(主要是《A Tutorial on Learning With Bayesian Networks》),下面兩題應(yīng)該還是需要寫代碼實(shí)現(xiàn)的,回頭有時間再補(bǔ)把。
7.9 以西瓜數(shù)據(jù)集 2.0 為訓(xùn)練集,試基于 BIC 準(zhǔn)則構(gòu)建一個貝葉斯網(wǎng).
答:
關(guān)于貝葉斯網(wǎng)結(jié)構(gòu)的構(gòu)建,書中p160只稍微提了一下,不過還是挺好理解的,《A Tutorial on Learning With Bayesian Networks》11節(jié)給出了更詳細(xì)的描述。比較簡單是方法就是貪心法:
1) 初始化一個網(wǎng)絡(luò)結(jié)構(gòu);
2) 使用E表示當(dāng)前合法的改變一條邊的操作集合,比如若兩個節(jié)點(diǎn)已經(jīng)有連接,那么合法操作可以刪除或者逆轉(zhuǎn),如沒有連接則可以增加一條邊,當(dāng)前必須是在保證不會形成回路的情況;
3) 從中選擇一個使得BIC下降最大的一個作為實(shí)際操作;
4) 循環(huán)2,3直到BIC不再下降。
論文中也給出了其他算法。
有時間再補(bǔ)代碼吧。
系列文章:
1.?周志華機(jī)器學(xué)習(xí)課后習(xí)題解析【第二章】
2.?周志華《機(jī)器學(xué)習(xí)》課后習(xí)題(第三章):線性模型
3.?周志華《機(jī)器學(xué)習(xí)》課后習(xí)題解析(第四章):決策樹
4.?周志華《機(jī)器學(xué)習(xí)》課后習(xí)題(第五章):神經(jīng)網(wǎng)絡(luò)
5.?周志華《機(jī)器學(xué)習(xí)》課后習(xí)題(第六章):支持向量機(jī)
推薦閱讀
(點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)
干貨 | 公眾號歷史文章精選
我的深度學(xué)習(xí)入門路線
我的機(jī)器學(xué)習(xí)入門路線圖
重磅!
AI有道年度技術(shù)文章電子版PDF來啦!
掃描下方二維碼,添加?AI有道小助手微信,可申請入群,并獲得2020完整技術(shù)文章合集PDF(一定要備注:入群?+ 地點(diǎn) + 學(xué)校/公司。例如:入群+上海+復(fù)旦。?
長按掃碼,申請入群
(添加人數(shù)較多,請耐心等待)
?
最新 AI 干貨,我在看?
總結(jié)
以上是生活随笔為你收集整理的周志华《机器学习》课后习题(第七章):贝叶斯分类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程必备:c/c++的编程经验技巧!
- 下一篇: MFC对话框程序中添加工具栏及工具栏上的