作者 | 我是韩小琦

链接 | https://zhuanlan.zhihu.com/p/51768750

7.1 试使用极大似然法估算回瓜数据集 3.0 中前 3 个属性的类条件概率.

答:

以第一个属性色泽为例,其值计数如下:

  • 色泽 乌黑 浅白 青绿

  • 好瓜

  • 否 2 4 3

  • 是 4 1 3

令  表示好瓜中色泽为“乌黑”的概率,  为好瓜中“浅白”的概率,  ,  ,  表示好瓜的样本,其他类同,于是色泽属性的似然概率则可表示为 ,其对数似然为:  ,分别对  求偏导并使其为零,即可得  的极大似然估计:  ,同理可得  的似然概率,进而求得类为“否”时各取值条件概率的极大似然估计。

其他两个属性同理。

7.2* 试证明:条件独立性假设不成立时,朴素贝叶斯分类器仍有可能产生最优贝叶斯分类器.

答:

令一组数据中有  三中属性,其目标值为Bool型变量,即取值  且其概率相同,即  。给定一个样本  ,令  表示  ,  表示  中属性  的取值。假设 完全独立,而  即两者完全相关,因此理论上对于最优贝叶斯分类器来说,属性  应该被忽略,那么基于最优贝叶斯分类器时,其决策准则(书中P7.15式)可描述为:若  时,则将样本  归为  类;而另一方面,考虑朴素贝叶斯分类器,在分类决策时会将属性  也考虑在内,此时相当于将  计算了两次,此时决策准则则描述为:  时,将  归为  类。

根据贝叶斯理论,  ,且由于  ,则最优贝叶斯分类可表示为:  ;而朴素贝叶斯则表示为:  。取  ,于是最优贝叶斯分类器为:  ,朴素贝叶斯为  ,两者决策边界如下图:

只有在两者决策边界之间(浅黄色区域),其分类情况是不同的,在其他区域,朴素贝叶斯分类结果和最优贝叶斯的分类结果是相同的,因此即便属性之间独立性假设不成立,朴素贝叶斯在某些条件(本例中就是属性概率分布在两者相交区域之外)下任然是最优贝叶斯分类器。

参考:

《On the Optimality of the Simple Bayesian Classifier under Zero-One Loss》

ps.这个例子就是来自该论文,只做了一点翻译工作。论文中给出了更全面的理论证明,和朴素贝叶斯产生最优贝叶斯分类的充分必要条件。本打算看完把理论证明也尝试复述一遍,但能力有限,一方面没有理解很透彻,另一方面证明过程有点长感觉表达能力有点不大够用...

7.3 试编程实现拉普拉斯修正的朴素贝叶斯分类器,并以西瓜数据集 3.0 为训练集,对 p.151 "测1" 样本进行判别.

答:

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:  # 连续值时,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:  # 离散值时直接计算各类别的条件概率unique_value = xi.unique()  # 取值情况nvalue = len(unique_value)  # 取值个数xi1_value_count = pd.value_counts(xi1)[unique_value].fillna(0) + 1  # 计算正样本中,该属性每个取值的数量,并且加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 其实就是第一个数据print(predict_nb(x_test, p1, p1_list, p0_list))

这里代码很简单。不怎么规范。

7.4 实践中使用式 (7.15)决定分类类别时,若数据的维数非常高,则概率连乘  的结果通常会非常接近于 0 从试述防止下溢的可能方案.而导致下溢.

答:

这在p153中已经给出答案了。即取对数将连乘转化为“连加”防止下溢。

即将式(7.15)改为:  。

7.5 试证明:二分类任务中两类数据满足高斯分布且方差相同时,线性判别分析产生贝叶斯最优分类器.

答:

首先看一下贝叶斯最优分类器:在书中p148中解释了对于最小化分类错误率的贝叶斯最优分类器可表示为:

 ,

由贝叶斯定理即转换为:

 。

那么在数据满足高斯分布时有:

在二分类任务中,贝叶斯决策边界可表示为

再看看线性判别分析:

书中p62给出式3.39,其投影界面可等效于

 ,

注意为了和上面的推导一致,这里和书中给出的差了一个负号,但  位置没有改变,只是改变了方向而已。在两类别方差相同时有:

 ,

两类别在投影面连线的中点可为

  ,

那么线性判别分析的决策边界可表示为

 。

推导到这里发现贝叶斯最优分类器和线性判别分析的决策边界只相差

 ,

在题目左边小字中有提及,“假设同先验”,所以

 ,

于是得证。

7.6 试编程实现 AODE 分类器,并以西瓜数据集 3.0 为训练集,对 p.151的"测1" 样本进行判别.

答:

代码在:

han1057578619/MachineLearning_Zhouzhihua_ProblemSets

'''
目前仅拿西瓜数据集测试过,运行正常,其他数据未测试
'''
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# 这里转为list, 是因为貌似type_of_target 有bug, 只有在pd.Series类型的时候才能解析为'continuous',# 在这里转为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# 获取可以作为父节点的属性索引,这里在论文中取值为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  # 当前属性的取值数量pc_xi_denominator = self.m + self.n_class * nunique_xi  # 计算 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)和先验概率p(c, xi)c_xi = (X[:, xi_index] == xi) & (y == c)X_c_xi = X[c_xi, :]  # y 取值 为c, Xi 取值为xi 的所有数据pc_xi = (X_c_xi.shape[0] + 1) / pc_xi_denominator  # p(c, xi)# 实际上这里在j = i时, 个人理解应该是可以跳过不计算的,因为p(xi|c, xi) = 1, 在计算中都是一样的但这里为了方便实现,就没有跳过了。for j in range(self.n):if self.is_continuous[j]:  # 字段为连续值, 假设服从高斯分布, 保存均值和方差# 这里因为样本太少。有时候会出现X_c_xi为空或者只有一个数据的情况, 如何是离散值,依然可以计算;# 但是连续值的情况下,np.mean会报warning, 只有一个数据时,方差为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:# 计算 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)  # 储存每个样本为不同类别的对数概率值for value in p.index:  # 为了可以使用pandas的索引功能, 对于要预测的X值, 每一次循环求同一取值下样本的条件概率和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):  # 遍历所有的条件概率, 将对应的条件概率相加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):'''基于属性下各取值的样本数量,决定哪些属性可以作为父属性。关于连续值的处理,在《机器学习》书中也没有提及,AODE的原论文也没有提及如何处理连续值,考虑到若将连续值x_j作为父属性时,如何求解p(x_i|c, x_j)条件概率会比较麻烦(可以通过贝叶斯公式求解),此外AODE本身就是要将取值样本数量低于m的属性去除的,从这个角度来说,连续值就不能作为父属性了。所以这里连续值不作为父属性: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], :]))

提一下关于连续值处理的问题。这个书中和原论文(好像)都没有提交,所以按照自己的理解来处理了。考虑到以下,实现过程中不将连续值作为父属性。

此外AODE本身就是要将取值样本数量低于一定阈值(论文中给出的是30)的属性去除的,从这个角度来说,连续值就不能作为父属性了,当前其实可以按照区间划分将连续值离散化。

另外,虽然在样本这么小的情况下,看预测结果实际意义不大,但相比于朴素贝叶斯,AODE对于西瓜数据集的拟合更好(错误率更低)。

ps.书中给出的式(7.24)有错误的,分母的 改正为  ,在第十次印刷的时候纠正了,看旧版书的同学要注意了。

7.7 给定 d 个二值属性的二分类任务,假设对于任何先验概率项的估算至少需 30 个样例,则在朴素贝叶斯分类器式 (7.15) 中估算先验概率项  需 30 x 2 = 60 个样例.试估计在 AODE 式 (7.23) 中估算先验概率项  所需的样例数(分别考虑最好和最坏情形) .

答:

这里“假设对于任何先验概率项的估算至少需 30 个样例”意味着在所有样本中, 任意 的组合至少出现30次。

当  时,即只有一个特征  ,因为是二值属性,假设取值为  ,那为了估计  至少需要30个样本,同样  需要额外30个样本,另外两种情况同理,所以在  时,最好和最坏情况都需要120个样本。

再考虑  ,多加个特征  同样取值  ,为了满足求  已经有了120个样本,且60个正样本和60个负样本;在最好的情况下,在60个正样本中,正好有30个样本  ,30个  ,负样本同理,此时这120个样本也同样满足计算  的条件,所有  时,最好的情况也只需要120个样本,  时同理;在最坏的情况下,120个样子中,  都取相同的值  ,那么为了估算  需要额外60个样本,总计180个样本,同理计算出  时的样本数,即每多一个特征,最坏情况需要多加额外60个样本,  时,需要  个样本。

那么  个二值属性下,最好情况需要120个样本,最好情况需要  个样本。

这个问题主要基于书中式7.26,就很容易理解了

首先考虑同父结构,根据式7.26,其联合分布可以表示为:

 ,

在给定  时,

即同父结构中  关于  条件独立;

在  取值未知时有:

是推不出  的,所以同父结构中  关于  边际独立不成立。

再考虑顺序结构,其联合分布有:

给定  时,

即顺序结构中  关于  条件独立;

在  取值未知时有:

 ,

同样推不出  ,所以顺序结构中,同样  关于  边际独立不成立。


好久没更新...罪过,堕落了...前面八题一个月之前就写好了,一直在看7.7(主要还是懒.)阅读材料给出的贝叶斯网相关论文(主要是《A Tutorial on Learning With Bayesian Networks》),下面两题应该还是需要写代码实现的,回头有时间再补把。

7.9 以西瓜数据集 2.0 为训练集,试基于 BIC 准则构建一个贝叶斯网.

答:

关于贝叶斯网结构的构建,书中p160只稍微提了一下,不过还是挺好理解的,《A Tutorial on Learning With Bayesian Networks》11节给出了更详细的描述。比较简单是方法就是贪心法:

  • 1) 初始化一个网络结构;

  • 2) 使用E表示当前合法的改变一条边的操作集合,比如若两个节点已经有连接,那么合法操作可以删除或者逆转,如没有连接则可以增加一条边,当前必须是在保证不会形成回路的情况;

  • 3) 从中选择一个使得BIC下降最大的一个作为实际操作;

  • 4) 循环2,3直到BIC不再下降。

论文中也给出了其他算法。

有时间再补代码吧。

系列文章:

1. 周志华机器学习课后习题解析【第二章】

2. 周志华《机器学习》课后习题(第三章):线性模型

3. 周志华《机器学习》课后习题解析(第四章):决策树

4. 周志华《机器学习》课后习题(第五章):神经网络

5. 周志华《机器学习》课后习题(第六章):支持向量机


推荐阅读

(点击标题可跳转阅读)

干货 | 公众号历史文章精选

我的深度学习入门路线

我的机器学习入门路线图

重磅

AI有道年度技术文章电子版PDF来啦!

扫描下方二维码,添加 AI有道小助手微信,可申请入群,并获得2020完整技术文章合集PDF(一定要备注:入群 + 地点 + 学校/公司。例如:入群+上海+复旦

长按扫码,申请入群

(添加人数较多,请耐心等待)

最新 AI 干货,我在看 

周志华《机器学习》课后习题(第七章):贝叶斯分类相关推荐

  1. 周志华机器学习课后习题解析【第二章】

    作者 | 我是韩小琦 链接 | https://zhuanlan.zhihu.com/p/42435889 2.1 数据集包含 1000 个样本,其中 500 个正例. 500 个反例,将其划分为包含 ...

  2. bp神经网络代码_机器学习(周志华)课后习题——第五章——神经网络

    5.1 试述将线性函数 用作神经元激活函数的缺陷. 答: 使用线性函数作为激活函数时,无论是在隐藏层还是在输出层(无论传递几层),其单元值(在使用激活函数之前)都还是输入 的线性组合,这个时候的神经网 ...

  3. 【吃瓜教程】周志华机器学习西瓜书第三章答案

    线性模型结构梳理 3.1 试析在什么情形下式3.2中不必考虑偏置项b 答案一: 偏置项b在数值上代表了自变量取0时,因变量的取值: 1.当讨论变量x对结果y的影响,不用考虑b: 2.可以用变量归一化( ...

  4. 周志华-机器学习西瓜书-第三章习题3.3 编程实现对率回归

    本文为周志华机器学习西瓜书第三章课后习题3.3答案,编程实现对率回归,数据集为书本第89页的数据 使用tensorflow实现过程 # coding=utf-8 import tensorflow a ...

  5. 西瓜书(周志华)课后习题答案

    目录 第一章 绪论 http://blog.csdn.net/icefire_tyh/article/details/52065224 第二章 模型评估与选择 http://blog.csdn.net ...

  6. 【机器学习-周志华】学习笔记-第七章

    记录第一遍没看懂的 记录觉得有用的 其他章节:         第一章         第三章         第五章         第六章         第七章         第八章      ...

  7. 机器学习(周志华著)习题 第03章 线性模型

    3.1 试析在什么情形下式(3.2)中不必考虑偏置项b 有网友说可以让所有的数据减去第一个样本,但是在实际应用中这样做偶然性太大.可以先对数据进行"中心化"处理,也就是对每一个x ...

  8. 周志华机器学习:决策树

    决策树 文章目录 决策树 参考 基本流程 划分选择 信息增益 决策树的生成--ID3,及其问题 增益率 决策树生成 --C4.5,及其问题 剪枝处理 预剪枝和后剪枝 统计学习方法中的剪枝 CART算法 ...

  9. 周志华机器学习(西瓜书)学习笔记(持续更新)

    <周志华机器学习>笔记 第1章 绪论 1.1 引言 1.2 基本术语 1.3 假设空间 1.4 归纳偏好 1.5 发展历程 1.6 应用现状 第2章 模型评估与选择 2.1 经验误差与过拟 ...

  10. 机器学习(周志华) 参考答案 第十四章 概率图模型 14.9

    机器学习(周志华西瓜书) 参考答案 总目录 http://blog.csdn.net/icefire_tyh/article/details/52064910 机器学习(周志华) 参考答案 第十四章 ...

最新文章

  1. HTTP访问控制(CORS)
  2. python 笔记:函数
  3. 基于Android Studio的内存泄漏检测与解决全攻略
  4. Springboo零配置原理
  5. iOS 学习之NSPredicate
  6. objectC 数据类型转换
  7. php携程语比,PHP 协程
  8. Uber七折流血融资,软银拿下15%股份,滴滴笑了
  9. Flask渲染Jinja2模板
  10. 端口映射不能访问80端口
  11. U - 计算长方体、四棱锥的表面积和体积
  12. 【一文搞懂】FD_SET的使用
  13. Unity3D 场景切换
  14. application/octet-stream里的octet是什么意思
  15. Marvell 88E1111 百兆工程 (FPGA)
  16. 多人协作开发Axure教程(附Axure RP9的密钥)
  17. banner自适应屏幕代码
  18. Java架构师必备知识体系
  19. 正则匹配空字符串 /(^\s)/
  20. Linux下history查看历史操作记录,并显示操作时间

热门文章

  1. 【小松教你手游开发】【面试必读(编程基础)】堆和栈的区别(转过无数次的文章)...
  2. Ganglia:分布式监控系统
  3. 内存分配与数据格式化(malloc与new)
  4. 《Adobe Illustrator CS4中文版经典教程》目录—导读
  5. SQL Server 2005 Integration Services (SSIS) (2) - 导入/导出向导
  6. hdu 5616 Jam's balance(简单dp)
  7. hdu 1024(滚动数组优化)
  8. php组合设计模式(composite pattern)
  9. Android的Fragment中onActivityResult不被调用
  10. 20180525小测