当前位置: 首页 > news >正文

机器学习笔记 第八章集成学习

8.1  个体与集成

         集成学习就是通过构建并结合多个学习器来完成学习任务。如图所示,集成学习一般先产生一组“个体学习器”,再通过某种方法将它们结合起来。通过判断集成是否只包含同种类型的个体学习器可分为同质集成和异质集成。

        \circ同质集成:集成中只包含同种类型的个体学习器。同质集成中的个体学习器称为“基学习器”,相应的算法为“基学习算法”;

        \circ异质集成:集成中包含不同类型的个体学习器。

        优点:集成学习通过把多个个体学习器结合在一起,通常比单一学习器的泛化性能更有显著优势。

        通常情况下,如果把效果好坏不等的个体学习器掺杂在一起,那么得到结果通常会介于最好和最坏的个体学习器之间,那么,集成学习如何才能获得比最好的个体学习器更好的性能呢?结论是个体学习器要“好而不同”,即个体学习器要有一定的准确性,且每个个体学习器之间具有差异。接下来通过一个例子说明该结论,如下表所示,其中√表示分类正确,×表示分类错误,集成学习采用投票法,即“少数服从多数”,那么(a)中,每个分类器的精度为66.6%,但集成学习的精度达到100%;在(b)中,集成学习与每个分类器的精度无差别;在(c)中,每个分类器的精度为33.3%,而集成学习的精度却为0。以上例子恰好说明个体学习器应“好而不同”。

(a)集成提升性能                           (b)集成不起作用                   (c)集成起负作用
样例1样例2样例3样例1样例2样例3样例1样例2样例3
h_{1}×h_{1}×h_{1}××
h_{2}×h_{2}×h_{2}××
h_{3}×h_{3}×h_{3}××
集成集成×集成×××

        事实上,个体学习器的“准确性”和“多样性”本身存在一定的冲突,在确保准确性之后,则不得不牺牲其多样性;而在增加多样性的同时,有不得不牺牲其准确性。进而,如何产生并且结合准确度和多样性的个体学习器,恰好是集成学习的研究核心。

        集成学习大致可分为以下两大类:

        \square序列化方法:个体学习器之间存在强依赖关系、必须串行生成的方法,代表方法是Boosting;

        \square并行化方法:个体学习器之间不存在强依赖关系、可同时生成的方法,代表方法是Bagging和“随机森林”。

8.2  Boosting

        Boosting是一族可以将弱学习器提升为强学习器的算法。

        算法思想:从初始的训练集中训练出一个基学习器,再从基学习器的表现对训练集进行合理的调整,即先前基学习器做错的训练样本进行重点关注,然后用调整后的样本来训练下一个基学习器;重复进行前面步骤,直到基学习器数目达到事先指定的值T,最终对这T个基学习器进行加权结合。

        Boosting族算法的代表是AdaBoost,如图8.2所示,其中y_{i}\in \left \{ -1,+1 \right \}f是真是函数。采用基学习器的线性组合

H(x)=\sum_{t=1}^{T}\alpha _{t}h_{t}(x)

来最小化指数损失函数

\iota _{exp}(H|D)=E_{x\sim D}\left [ e^{-f(x)H(x)} \right ]

若指数损失函数能最小化,则可以对H(x)求偏导

\frac{\partial \iota _{exp}(H|D)}{\partial H(x)}=-e^{H(x)}P(f(x)=1|x)+e^{H(x)}P(f(x)=-1|x)

令上式等于零,可解得

H(x)=\frac{1}{2}ln\frac{P(f(x)=1|x)}{P(f(x)=-1|x)}

故有

                                sign(H(x))=sign(\frac{1}{2}ln\frac{P(f(x)=1|x)}{P(f(x)=-1|x)})

                                                      =\begin{cases} 1 & \text{ if } P(f(x)=1|x)>P(f(x)=-1|x) \\ -1& \text{ if } P(f(x)=1|x)<P(f(x)=-1|x) \end{cases}

                                                ​​​​​​​      =argmax_{y\in \left \{ -1,1 \right \}}P(f(x)=y|x)

        此时,sign(H(x))达到了贝叶斯最优错误解,也就是指数损失函数最小化,那么分类错误率也最小化。

图8.2  AdaBoost算法

        Boosting的特点是主要关注降低偏差,因此Boosting可以将泛化能力相当弱的学习器构建出很强的集成。

8.3  Bagging

        Bagging是并行式集成学习方法最著名的代表。给定包含个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过次随机采样操作,我们得到含个样本的采样集,初始训练集中有的样本在采样集里多次出现,有的则从未出现。我们可采样出个含个训练样本的采样集,然后基于每个采样集训练出一个基学习器,再将这些基学习器进行结合,这就是 Bagging 的基本流程。Bagging的算法描述如图8.5所示。

         D_{t}表示h_{t}实际使用的训练样本集,令H^{oob}(x)表示对样本的包外预测,即仅考虑那些未使用x训练的基学习器在x上的预测,有

H^{oob}(x)=argmax_{y\in \gamma }\sum_{t=1}^{T}\prod (h_{t}(x)=y)\cdot \prod (x\notin D_{t}),

则Bagging泛化误差的包外估计为

\epsilon^{oob}=\frac{1}{|D|}\sum_{(x,y)\in D}^{}\prod (H^{oob}(x)\neq y).

         从偏差方差分解的角度看,Bagging主要关注降低方差,因此它在不剪枝决策树、神经网络等易受样本扰动的学习器上效用更为明显。​​​​​​​      

8.4  多样性度量

        顾名思义,多样性度量就是估算个体学习器的多样化程度,做法就是考虑个体分类器两两是否相似。

        给定数据集D=\left \{ (x_{1},y_{1}),(x_{2},y_{2}),...,(x_{m},y_{m}) \right \}y_{i}\in \left \{ -1,+1 \right \},分类器h_{i}h_{j}的预测结果列联表为

h_{i}=+1h_{i}=-1
h_{j}=+1ac
h_{j}=-1bd

        其中,a表示h_{i}h_{j}均预测为正类的样本数目,b、c、d同理可得,a+b+c+d=m。基于上面的列联表,可以给出常见的多样性度量。

        \bullet不合度量

dis_{ij}=\frac{b+c}{m}

        \bullet相关系数

\rho _{ij}=\frac{ad-bc}{\sqrt{(a+b)(a+c)(c+d)(b +d)}}

        \rho _{ij}的值域为\left [ -1,1 \right ],若h_{i}h_{j}无关,则值为0;若h_{i}h_{j}正相关则值为正,否则为负。

        \bulletQ-统计量

Q_{ij}=\frac{ad-bc}{ad+bc}

        Q_{ij}与相关系数\rho _{ij}符号相同,且|Q_{ij}|\leqslant |\rho _{ij}|

        \bullet\kappa -统计量

\kappa =\frac{p_{1}-p_{2}}{1-p_{2}}

p_{1}=\frac{a+d}{m}

p_{2}=\frac{(a+b)(a+c)+(c+d)(b+d)}{m^{2}}

        若分类器h_{i}h_{j}在D上完全一致,则\kappa =1;若它们仅是偶然达成一致,则\kappa =0

8.5   实验

      下面是用Python实现AdaBoost算法的示例代码,使用了numpy和sklearn库。我们先手动实现一个简单的AdaBoost算法,然后使用sklearn中的实现进行比较。

import numpy as npclass WeakClassifier:"""简单的弱分类器"""def __init__(self):self.feature_index = Noneself.threshold = Noneself.polarity = Nonedef fit(self, X, y, weights):m, n = X.shapeself.feature_index = 0self.threshold = 0self.polarity = 1min_error = float('inf')for feature in range(n):thresholds = np.unique(X[:, feature])for threshold in thresholds:for polarity in [-1, 1]:predictions = np.ones(m)predictions[X[:, feature] < threshold] = -1predictions *= polarityerror = sum(weights[y != predictions])if error < min_error:min_error = errorself.threshold = thresholdself.feature_index = featureself.polarity = polaritydef predict(self, X):m = X.shape[0]predictions = np.ones(m)predictions[X[:, self.feature_index] < self.threshold] = -1return predictions * self.polarityclass AdaBoost:def __init__(self, n_classifiers=50):self.n_classifiers = n_classifiersself.classifiers = []self.alphas = []def fit(self, X, y):m = X.shape[0]weights = np.ones(m) / mfor _ in range(self.n_classifiers):classifier = WeakClassifier()classifier.fit(X, y, weights)predictions = classifier.predict(X)# Calculate the errorerror = sum(weights[y != predictions])# Calculate the alpha value (weight of the classifier)alpha = 0.5 * np.log((1 - error) / (error + 1e-10))# Update weightsweights *= np.exp(-alpha * y * predictions)weights /= sum(weights)  # Normalize# Store the classifier and its weightself.classifiers.append(classifier)self.alphas.append(alpha)def predict(self, X):m = X.shape[0]final_predictions = np.zeros(m)for alpha, classifier in zip(self.alphas, self.classifiers):final_predictions += alpha * classifier.predict(X)return np.sign(final_predictions)# 示例使用if __name__ == "__main__":from sklearn.datasets import make_classificationfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score# 创建数据X, y = make_classification(n_samples=100, n_features=20, n_informative=10, n_redundant=2, random_state=42)y = np.where(y == 0, -1, 1)  # 将类标签转换为-1和1# 划分训练集和测试集X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 训练和预测model = AdaBoost(n_classifiers=50)model.fit(X_train, y_train)y_pred = model.predict(X_test)# 输出准确率print("Accuracy:", accuracy_score(y_test, y_pred))  

参考文献:《机器学习》周志华

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 揭秘eBay店铺排名提升秘诀:测评自养号的好处
  • 数据库系列: 主流分库分表中间件介绍(图文总结)
  • 【C++】list介绍以及模拟实现(超级详细)
  • 前端性能优化-性能检测指标与工具
  • 【MySQL】慢sql优化全流程解析
  • 飞浆OCR模型训练详细教程
  • 短视频系统设计:支持三千万用户同时在线看视频
  • OD C卷 - 分配土地
  • 在 Django 模板中渲染并行数组
  • Es6常用的一些数组处理方法
  • JetBrains:Wrong tag。注释告警
  • 代码随想录算法训练营第三十天 | 贪心算法 part04
  • Python接口自动化测试框架(实战篇)-- Jenkins持续集成
  • PXE+Kickstart自动化安装操作系统
  • 荒原之梦考研:考研二战会很难吗?
  • [译] 怎样写一个基础的编译器
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • CEF与代理
  • create-react-app项目添加less配置
  • emacs初体验
  • Median of Two Sorted Arrays
  • Sublime Text 2/3 绑定Eclipse快捷键
  • 初识 beanstalkd
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前嗅ForeSpider中数据浏览界面介绍
  • 如何进阶一名有竞争力的程序员?
  • 深度解析利用ES6进行Promise封装总结
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​【已解决】npm install​卡主不动的情况
  • ​数据链路层——流量控制可靠传输机制 ​
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #职场发展#其他
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (11)MSP430F5529 定时器B
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (27)4.8 习题课
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (CPU/GPU)粒子继承贴图颜色发射
  • (第27天)Oracle 数据泵转换分区表
  • (二)linux使用docker容器运行mysql
  • (三)elasticsearch 源码之启动流程分析
  • (四)c52学习之旅-流水LED灯
  • (五)activiti-modeler 编辑器初步优化
  • (原)本想说脏话,奈何已放下
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)创业家杂志:UCWEB天使第一步
  • ******之网络***——物理***
  • .NET Micro Framework初体验(二)
  • .Net Web窗口页属性
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...