图解机器学习算法-ShowMeAI--全-
图解机器学*算法(ShowMeAI)(全)
图解机器学*算法 | 从入门到精通系列教程

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
声明:版权所有,转载请联系平台与作者并注明出处
引言
本篇内容是 ShowMeAI 组织的「图解机器学*算法」系列教程入口,本教程尽量以生动可视化的方式,帮助大家理解机器学*的核心知识和重要的系列模型,并配以相关的代码实现帮助大家了解应用方法。(对机器学*实战感兴趣的同学,可以关注 ShowMeAI 的另外一个系列[机器学*应用实践])
内容覆盖:机器学*基础、评估方法准则、KNN、逻辑回归、朴素贝叶斯、决策树、回归树、随机森林、GBDT、xgboost、lightgbm、支持向量机、聚类、kmeans、降维算法、PCA。
教程地址
点击查看完整教程学*路径
内容章节
1. 机器学*基础知识

2. 模型评估方法与准则

3. KNN 算法及其应用

4. 逻辑回归算法详解

5. 朴素贝叶斯算法详解

6. 决策树模型详解

7. 随机森林分类模型详解

8. 回归树模型详解

9. GBDT 模型详解

10. XGBoost 模型最全解析

11. LightGBM 模型详解

12. 支持向量机模型详解

13. 聚类算法详解

14. PCA 降维算法详解

ShowMeAI系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程
- 机器学*实战:手把手教你玩转机器学*系列
- 深度学*教程 | 吴恩达专项课程 · 全套笔记解读

图解机器学* | 机器学*基础知识

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/185
声明:版权所有,转载请联系平台与作者并注明出处
1. 机器学*概述
1)什么是机器学*
人工智能(Artificial intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。它是一个笼统而宽泛的概念,人工智能的最终目标是使计算机能够模拟人的思维方式和行为。大概在上世纪 50 年代开始兴起,但是受限于数据和硬件设备等限制,当时发展缓慢。

机器学*(Machine learning)是人工智能的子集,是实现人工智能的一种途径,但并不是唯一的途径。它是一门专门研究计算机怎样模拟或实现人类的学*行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科。大概在上世纪 80 年代开始蓬勃发展,诞生了一大批数学统计相关的机器学*模型。
深度学*(Deep learning)是机器学*的子集,灵感来自人脑,由人工神经网络(ANN)组成,它模仿人脑中存在的相似结构。在深度学*中,学*是通过相互关联的「神经元」的一个深层的、多层的「网络」来进行的。「深度」一词通常指的是神经网络中隐藏层的数量。大概在 2012 年以后爆炸式增长,广泛应用在很多的场景中。
让我们看看国外知名学者对机器学*的定义:

机器学*研究的是计算机怎样模拟人类的学*行为,以获取新的知识或技能,并重新组织已有的知识结构,使之不断改善自身。从实践的意义上来说,机器学*是在大数据的支撑下,通过各种算法让机器对数据进行深层次的统计分析以进行「自学」,使得人工智能系统获得了归纳推理和决策能力

通过经典的「垃圾邮件过滤」应用,我们再来理解下机器学*的原理,以及定义中的 T、E、P 分别指代什么。

2)机器学*三要素
机器学*三要素包括数据、模型、算法。这三要素之间的关系,可以用下面这幅图来表示:

(1)数据
数据驱动:数据驱动指的是我们基于客观的量化数据,通过主动数据的采集分析以支持决策。与之相对的是经验驱动,比如我们常说的「拍脑袋」。

(2)模型&算法
模型:在 AI 数据驱动的范畴内,模型指的是基于数据 X 做决策 Y 的假设函数,可以有不同的形态,计算型和规则型等。
算法:指学*模型的具体计算方法。统计学*基于训练数据集,根据学*策略,从假设空间中选择最优模型,最后需要考虑用什么样的计算方法求解最优模型。通常是一个最优化的问题。

3)机器学*发展历程
人工智能一词最早出现于 1956 年,用于探索一些问题的有效解决方案。1960 年,美国国防部借助「神经网络」这一概念,训练计算机模仿人类的推理过程。
2010 年之前,谷歌、微软等科技巨头改进了机器学*算法,将查询的准确度提升到了新的高度。而后,随着数据量的增加、先进的算法、计算和存储容量的提高,机器学*得到了更进一步的发展。

4)机器学*核心技术

-
分类:应用以分类数据进行模型训练,根据模型对新样本进行精准分类与预测。
-
聚类:从海量数据中识别数据的相似性与差异性,并按照最大共同点聚合为多个类别。
-
异常检测:对数据点的分布规律进行分析,识别与正常数据及差异较大的离群点。
-
回归:根据对已知属性值数据的训练,为模型寻找最佳拟合参数,基于模型预测新样本的输出值。
5)机器学*基本流程
机器学*工作流(WorkFlow)包含数据预处理(Processing)、模型学*(Learning)、模型评估(Evaluation)、新样本预测(Prediction)几个步骤。

-
数据预处理:输入(未处理的数据 + 标签)→处理过程(特征处理+幅度缩放、特征选择、维度约减、采样)→输出(测试集 + 训练集)。
-
模型学*:模型选择、交叉验证、结果评估、超参选择。
-
模型评估:了解模型对于数据集测试的得分。
-
新样本预测:预测测试集。
6)机器学*应用场景
作为一套数据驱动的方法,机器学*已广泛应用于数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA 序列测序、语音和手写识别和机器人等领域。

-
智能医疗:智能假肢、外骨骼、医疗保健机器人、手术机器人、智能健康管理等。
-
人脸识别:门禁系统、考勤系统、人脸识别防盗门、电子护照及身份证,还可以利用人脸识别系统和网络,在全国范围内搜捕逃犯。
-
机器人的控制领域:工业机器人、机械臂、多足机器人、扫地机器人、无人机等。
2.机器学*基本名词

-
监督学*(Supervised Learning):训练集有标记信息,学*方式有分类和回归。
-
无监督学*(Unsupervised Learning):训练集没有标记信息,学*方式有聚类和降维。
-
强化学*(Reinforcement Learning):有延迟和稀疏的反馈标签的学*方式。

-
示例/样本:上面一条数据集中的一条数据。
-
属性/特征:「色泽」「根蒂」等。
-
属性空间/样本空间/输入空间 X:由全部属性张成的空间。
-
特征向量:空间中每个点对应的一个坐标向量。
-
标记:关于示例结果的信息,如((色泽=青绿,根蒂=蜷缩,敲声=浊响),好瓜),其中「好瓜」称为标记。
-
分类:若要预测的是离散值,如「好瓜」,「坏瓜」,此类学*任务称为分类。
-
假设:学得模型对应了关于数据的某种潜在规律。
-
真相:潜在规律自身。
-
学*过程:是为了找出或逼*真相。
-
泛化能力:学得模型适用于新样本的能力。一般来说,训练样本越大,越有可能通过学*来获得具有强泛化能力的模型。
3.机器学*算法分类
1)机器学*算法依托的问题场景
机器学*在* 30 多年已发展为一门多领域交叉学科,涉及概率论、统计学、逼*论、凸分析、计算复杂性理论等多门学科。机器学*理论主要是设计和分析一些让计算机可以自动「学*」的算法。
机器学*算法从数据中自动分析获得规律,并利用规律对未知数据进行预测。机器学*理论关注可以实现的、行之有效的学*算法。很多推论问题属于无程序可循难度,所以部分的机器学*研究是开发容易处理的*似算法。

机器学*最主要的类别有:监督学*、无监督学*和强化学*。

监督学*:从给定的训练数据集中学*出一个函数,当新的数据到来时,可以根据这个函数预测结果。监督学*的训练集要求是包括输入和输出,也可以说是特征和目标。训练集中的目标是由人标注的。常见的监督学*算法包括回归分析和统计分类。
- 更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
无监督学*:与监督学*相比,训练集没有人为标注的结果。常见的无监督学*算法有生成对抗网络(GAN)、聚类。
- 更多无监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-无监督学*。
强化学*:通过观察来学*做成如何的动作。每个动作都会对环境有所影响,学*对象根据观察到的周围环境的反馈来做出判断。
2)分类问题
分类问题是机器学*非常重要的一个组成部分。它的目标是根据已知样本的某些特征,判断一个新的样本属于哪种已知的样本类。分类问题可以细分如下:
-
二分类问题:表示分类任务中有两个类别新的样本属于哪种已知的样本类。
-
多类分类(Multiclass classification)问题:表示分类任务中有多类别。
-
多标签分类(Multilabel classification)问题:给每个样本一系列的目标标签。
了解更多机器学*分类算法:KNN 算法、逻辑回归算法、朴素贝叶斯算法、决策树模型、随机森林分类模型、GBDT 模型、XGBoost 模型、支持向量机模型等。

3)回归问题
了解更多机器学*回归算法:决策树模型、随机森林分类模型、GBDT 模型、回归树模型、支持向量机模型等。

4)聚类问题
了解更多机器学*聚类算法:聚类算法。

5)降维问题
了解更多机器学*降维算法:PCA 降维算法。

4.机器学*模型评估与选择
1)机器学*与数据拟合
机器学*最典型的监督学*为分类与回归问题。分类问题中,我们学*出来一条「决策边界」完成数据区分;在回归问题中,我们学*出拟合样本分布的曲线。

2)训练集与数据集
我们以房价预估为例,讲述一下涉及的概念。
-
训练集(Training Set):帮助训练模型,简单的说就是通过训练集的数据让确定拟合曲线的参数。
-
测试集(Test Set):为了测试已经训练好的模型的精确度。

当然,test set 这并不能保证模型的正确性,只是说相似的数据用此模型会得出相似的结果。因为在训练模型的时候,参数全是根据现有训练集里的数据进行修正、拟合,有可能会出现过拟合的情况,即这个参数仅对训练集里的数据拟合比较准确,这个时候再有一个数据需要利用模型预测结果,准确率可能就会很差。
3)经验误差
在训练集的数据上进行学*。模型在训练集上的误差称为「经验误差」(Empirical Error)。但是经验误差并不是越小越好,因为我们希望在新的没有见过的数据上,也能有好的预估结果。

4)过拟合
过拟合,指的是模型在训练集上表现的很好,但是在交叉验证集合测试集上表现一般,也就是说模型对未知样本的预测表现一般,泛化(Generalization)能力较差。

如何防止过拟合呢?一般的方法有 Early Stopping、数据集扩增(Data Augmentation)、正则化、Dropout 等。
-
正则化:指的是在目标函数后面添加一个正则化项,一般有 L1 正则化与 L2 正则化。L1 正则是基于 L1 范数,即在目标函数后面加上参数的 L1 范数和项,即参数绝对值和与参数的积项。
-
数据集扩增:即需要得到更多的符合要求的数据,即和已有的数据是独立同分布的,或者*似独立同分布的。一般方法有:从数据源头采集更多数据、复制原有数据并加上随机噪声、重采样、根据当前数据集估计数据分布参数,使用该分布产生更多数据等。
-
DropOut:通过修改神经网络本身结构来实现的。
5)偏差
偏差(Bias),它通常指的是模型拟合的偏差程度。给定无数套训练集而期望拟合出来的模型就是平均模型。偏差就是真实模型和平均模型的差异。
简单模型是一组直线,平均之后得到的平均模型是一条直的虚线,与真实模型曲线的差别较大(灰色阴影部分较大)。因此,简单模型通常高偏差 。

复杂模型是一组起伏很大波浪线,平均之后最大值和最小组都会相互抵消,和真实模型的曲线差别较小,因此复杂模型通常低偏差(见黄色曲线和绿色虚线几乎重合)。

6)方差
方差(Variance),它通常指的是模型的平稳程度(简单程度)。简单模型的对应的函数如出一辙,都是水平直线,而且平均模型的函数也是一条水平直线,因此简单模型的方差很小,并且对数据的变动不敏感。

复杂模型的对应的函数千奇百怪,毫无任何规则,但平均模型的函数也是一条平滑的曲线,因此复杂模型的方差很大,并且对数据的变动很敏感。

7)偏差与方差的平衡

8)性能度量指标
性能度量是衡量模型泛化能力的数值评价标准,反映了当前问题(任务需求)。使用不同的性能度量可能会导致不同的评判结果。更详细的内容可见 模型评估方法与准则
(1)回归问题
关于模型「好坏」的判断,不仅取决于算法和数据,还取决于当前任务需求。回归问题常用的性能度量指标有:平均绝对误差、均方误差、均方根误差、R 平方等。

-
平均绝对误差(Mean Absolute Error,MAE),又叫平均绝对离差,是所有标签值与回归模型预测值的偏差的绝对值的平均。
-
平均绝对百分误差(Mean Absolute Percentage Error,MAPE)是对 MAE 的一种改进,考虑了绝对误差相对真实值的比例。
-
均方误差(Mean Square Error,MSE)相对于平均绝对误差而言,均方误差求的是所有标签值与回归模型预测值的偏差的平方的平均。
-
均方根误差(Root-Mean-Square Error,RMSE),也称标准误差,是在均方误差的基础上进行开方运算。RMSE 会被用来衡量观测值同真值之间的偏差。
-
R 平方,决定系数,反映因变量的全部变异能通过目前的回归模型被模型中的自变量解释的比例。比例越接*于 1,表示当前的回归模型对数据的解释越好,越能精确描述数据的真实分布。
(2)分类问题
分类问题常用的性能度量指标包括错误率(Error Rate)、精确率(Accuracy)、查准率(Precision)、查全率(Recall)、F1、ROC 曲线、AUC 曲线和 R 平方等。更详细的内容可见 模型评估方法与准则

-
错误率:分类错误的样本数占样本总数的比例。
-
精确率:分类正确的样本数占样本总数的比例。
-
查准率(也称准确率),即在检索后返回的结果中,真正正确的个数占你认为是正确的结果的比例。
-
查全率(也称召回率),即在检索结果中真正正确的个数,占整个数据集(检索到的和未检索到的)中真正正确个数的比例。
-
F1是一个综合考虑查准率与查全率的度量,其基于查准率与查全率的调和平均定义:即:F1 度量的一般形式-Fβ,能让我们表达出对查准率、查全率的不同偏好。
ROC 曲线(Receiver Operating Characteristic Curve)全称是「受试者工作特性曲线」。综合考虑了概率预测排序的质量,体现了学*器在不同任务下的「期望泛化性能」的好坏。ROC 曲线的纵轴是「真正例率」(TPR),横轴是「假正例率」(FPR)。
AUC(Area Under ROC Curve)是 ROC 曲线下面积,代表了样本预测的排序质量。

从一个比较高的角度来认识 AUC:仍然以异常用户的识别为例,高的 AUC 值意味着,模型在能够尽可能多地识别异常用户的情况下,仍然对正常用户有着一个较低的误判率(不会因为为了识别异常用户,而将大量的正常用户给误判为异常。
9)评估方法
我们手上没有未知的样本,如何可靠地评估?关键是要获得可靠的「测试集数据」(Test Set),即测试集(用于评估)应该与训练集(用于模型学*)「互斥」。

常见的评估方法有:留出法(Hold-out)、交叉验证法( Cross Validation)、自助法(Bootstrap)。更详细的内容可见 模型评估方法与准则
留出法(Hold-out)是机器学*中最常见的评估方法之一,它会从训练数据中保留出验证样本集,这部分数据不用于训练,而用于模型评估。

机器学*中,另外一种比较常见的评估方法是交叉验证法( Cross Validation)。k 折交叉验证对 k 个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感,对数据的使用也会更充分,模型评估结果更加稳定。

自助法(Bootstrap)是一种用小样本估计总体值的一种非参数方法,在进化和生态学研究中应用十分广泛。
Bootstrap 通过有放回抽样生成大量的伪样本,通过对伪样本进行计算,获得统计量的分布,从而估计数据的整体分布。

10)模型调优与选择准则
我们希望找到对当前问题表达能力好,且模型复杂度较低的模型:

-
表达力好的模型,可以较好地对训练数据中的规律和模式进行学*;
-
复杂度低的模型,方差较小,不容易过拟合,有较好的泛化表达。
11)如何选择最优的模型
(1)验证集评估选择
-
切分数据为训练集和验证集。
-
对于准备好的候选超参数,在训练集上进行模型,在验证集上评估。
(2)网格搜索/随机搜索交叉验证
-
通过网格搜索/随机搜索产出候选的超参数组。
-
对参数组的每一组超参数,使用交叉验证评估效果。
-
选出效果最好的超参数。
(3)贝叶斯优化
- 基于贝叶斯优化的超参数调优。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=935770612
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 模型评估方法与准则

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/186
声明:版权所有,转载请联系平台与作者并注明出处
引言
科学家门捷列夫说「没有测量,就没有科学」,在 AI 场景下我们同样需要定量的数值化指标来指导我们更好地应用模型对数据进行学*和建模。
事实上,在机器学*领域,对模型的测量和评估至关重要。选择与问题相匹配的评估方法,能帮助我们快速准确地发现在模型选择和训练过程中出现的问题,进而对模型进行优化和迭代。本文我们系统地讲解一下机器学*模型评估相关知识。
(本篇内容会涉及到不少机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识。
1.模型评估的目标
模型评估的目标是选出泛化能力强的模型完成机器学*任务。实际的机器学*任务往往需要进行大量的实验,经过反复调参、使用多种模型算法(甚至多模型融合策略)来完成自己的机器学*问题,并观察哪种模型算法在什么样的参数下能够最好地完成任务。

泛化能力强的模型能很好地适用于未知的样本,模型的错误率低、精度高。机器学*任务中,我们希望最终能得到准确预测未知标签的样本、泛化能力强的模型。

但是我们无法提前获取「未知的样本」,因此我们会基于已有的数据进行切分来完成模型训练和评估,借助于切分出的数据进行评估,可以很好地判定模型状态(过拟合 or 欠拟合),进而迭代优化。
在建模过程中,为了获得泛化能力强的模型,我们需要一整套方法及评价指标。
-
评估方法:为保证客观地评估模型,对数据集进行的有效划分实验方法。
-
性能指标:量化地度量模型效果的指标。
2.离线与在线实验方法
进行评估的实验方法可以分为「离线」和「在线」两种。

1)离线实验方法
模型评估通常指离线试验。原型设计(Prototyping)阶段及离线试验方法,包含以下几个过程:
-
使用历史数据训练一个适合解决目标任务的一个或多个机器学*模型。
-
对模型进行验证(Validation)与离线评估(Offline Evaluation)。
-
通过评估指标选择一个较好的模型。
2)在线实验方法
除了离线评估之外,其实还有一种在线评估的实验方法。由于模型是在老的模型产生的数据上学*和验证的,而线上的数据与之前是不同的,因此离线评估并不完全代表线上的模型结果。因此我们需要在线评估,来验证模型的有效性。
在线实验有一个杰出代表,那就是 A/B Test。

A/B Test 是目前在线测试中最主要的方法。A/B Test 是为同一个目标制定两个方案让一部分用户使用 A 方案,另一部分用户使用 B 方案,记录下用户的使用情况,看哪个方案更符合设计目标。如果不做 AB 实验直接上线新方案,新方案甚至可能会毁掉你的产品。

3)评估指标
在离线评估中,经常使用准确率(Accuracy)、查准率(Precision)、召回率(Recall)、ROC、AUC、PRC等指标来评估模型。
在线评估与离线评估所用的评价指标不同,一般使用一些商业评价指标,如用户生命周期值(Customer Lifetime value)、广告点击率(Click Through Rate)、用户流失率(Customer Churn Rate)等标。
我们将常见的评估指标汇总如下:

3.常见模型评估方法介绍
下面我们来了解一下模型评估方法,主要涉及到对完整数据集不同的有效划分方法,保证我们后续计算得到的评估指标是可靠有效的,进而进行模型选择和优化。
1)留出法(Hold-out)
留出法是机器学*中最常见的评估方法之一,它会从训练数据中保留出验证样本集,这部分数据不用于训练,而用于模型评估。
完整的数学定义如下:
对于一个机器学*问题,通常有数据集 D(用于训练模型),但还需要评估模型,因此不能把整个 D 用于训练,因为拿训练过的数据再去评估必然无效。那么最基本的方法就是留出法:把 D 划分为两部分,训练集 S 和测试集 T,其中 SUT=D,S∩T=Φ。

下面是留出法数据划分的注意点:
-
随机划分不一定能保证有效性,因为如果 T 中正好只取到某一种特殊类型数据,从而带来了额外的误差。此时处理方法要视具体情况而定,如当数据明显的分为有限类时,可以采用分层抽样方式选择测试数据,保证数据分布比例的平衡。
-
单次划分不一定能得到合适的测试集,一般多次重复「划分 - 训练 - 测试求误差」的步骤,取误差的平均值。
-
划分的验证集,太大或者太小都不合适,常用做法是选择 1/5 - 1/3 左右数据当作验证集用于评估。
2)交叉验证法(Cross Validation)
留出法的数据划分,可能会带来偏差。在机器学*中,另外一种比较常见的评估方法是交叉验证法——K 折交叉验证对 K 个不同分组训练的结果进行平均来减少方差。
因此模型的性能对数据的划分就不那么敏感,对数据的使用也会更充分,模型评估结果更加稳定,可以很好地避免上述问题。

3)自助法(Bootstrap)
部分场景下,数据量较少,很难通过已有的数据来估计数据的整体分布(因为数据量不足时,计算的统计量反映不了数据分布),这时可以使用 Bootstrap 自助法。
Bootstrap 是一种用小样本估计总体值的一种非参数方法,在进化和生态学研究中应用十分广泛。Bootstrap 通过有放回抽样生成大量的伪样本,通过对伪样本进行计算,获得统计量的分布,从而估计数据的整体分布。

有了有效的模型评估方法,我们还需要量化的度量标准来精准评估与判断。下文归纳了分类与回归问题的各类评估指标。
4.回归问题常用的评估指标
回归类问题场景下,我们会得到连续值的预测结果,比对标准答案,我们有 MAE、MSE、RMSE 等评估指标(准则)可以衡量预测结果相对实际情况的偏离程度,它们的取值越小说明回归模型的预测越准,模型性能越好。如下图所示:

1)平均绝对误差 MAE
平均绝对误差(Mean Absolute Error,MAE),又叫平均绝对离差,是所有标签值与回归模型预测值的偏差的绝对值的平均。
-
优点:直观地反映回归模型的预测值与实际值之间的偏差。准确地反映实际预测误差的大小。不会出现平均误差中误差符号不同而导致的正负相互抵消。
-
缺点:不能反映预测的无偏性(估算的偏差就是估计值的期望与真实值的差值。无偏就要求估计值的期望就是真实值)。
M A E = 1 m ∑ i = 1 m ∣ f ( x i ) − y i ∣ MAE=\frac{1}{m} \sum_{i=1}^{m}\left|f\left(x_{i}\right)-y_{i}\right| MAE=m1i=1∑m∣f(xi)−yi∣

2)平均绝对百分误差 MAPE
虽然平均绝对误差能够获得一个评价值,但是你并不知道这个值代表模型拟合是优还是劣,只有通过对比才能达到效果。当需要以相对的观点来衡量误差时,则使用 MAPE。
平均绝对百分误差(Mean Absolute Percentage Error,MAPE)是对 MAE 的一种改进,考虑了绝对误差相对真实值的比例。
- 优点:考虑了预测值与真实值的误差。考虑了误差与真实值之间的比例。
M A P E = 100 m ∑ i = 1 m ∣ y i − f ( x i ) y i ∣ MAPE=\frac{100}{m} \sum_{i=1}^{m} \left | \frac{y_{i}-f\left(x_{i}\right)}{y_{i}} \right | MAPE=m100i=1∑m∣∣∣∣yiyi−f(xi)∣∣∣∣
在某些场景下,如房价从 5K 到 50K 之间,5K 预测成 10K 与 50K 预测成 45K 的差别是非常大的,而平均绝对百分误差考虑到了这点。
3)均方误差 MSE
MAE 虽能较好衡量回归模型的好坏,但是绝对值的存在导致函数不光滑,在某些点上不能求导。可以考虑将绝对值改为残差的平方,就得到了均方误差。
均方误差(Mean Square Error,MSE)相对于平均绝对误差而言,均方误差求的是所有标签值与回归模型预测值的偏差的平方的平均。
-
优点:准确地反映实际预测误差的大小。放大预测偏差较大的值。比较不同预测模型的稳定性。
-
缺点:不能反映预测的无偏性。
M S E = 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 MSE=\frac{1}{m} \sum_{i=1}{m}\left(f\left(x_{i}\right)-y_{i}\right) MSE=m1i=1∑m(f(xi)−yi)2

4)均方根误差 RMSE
均方根误差(Root-Mean-Square Error,RMSE),也称标准误差,是在均方误差的基础上进行开方运算。RMSE 会被用来衡量观测值同真值之间的偏差。
R M S E = M S E = 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 RMSE=\sqrt{MSE} =\sqrt{\frac{1}{m} \sum_{i=1}{m}\left(f\left(x_{i}\right)-y_{i}\right){2}} RMSE=MSE =m1i=1∑m(f(xi)−yi)2
5)决定系数
决定系数 R 平方与之前介绍的三个指标有所不同,它表征的是因变量 y 的变化中有多少可以用自变量 x 来解释,是回归方程对观测值拟合程度的一种体现。
R 平方越接* 1,说明回归模型的性能越好,即能够解释大部分的因变量变化。
-
优点:用于定量描述回归模型的解释能力。
-
缺点:没有考虑特征数量变化的影响。无法比较特征数目不同的回归模型。
R 2 = S S R S S T R^{2}=\frac{SSR}{SST} R2=SSTSSR

-
SSR:Sum of Squares of the Regression,即预测数据与原始数据均值之差的平方和,反映的是模型相对原始数据均值的离散程度。
-
SST:Total Sum of Squares,即原始数据和均值之差的平方和,反映的是原始数据相对均值的离散程度。
-
SSE:Sum of Squares for Error,残差平方和,原始数据和预测数据之差的平方和。

6)校正决定系数
在利用 R 平方来评价回归方程的优劣时,随着自变量个数的不断增加,R 平方将不断增大。而校正决定系数则可以消除样本数量和特征数量的影响。
- 优点:在决定系数 R 平方的基础上考虑了特征个数的影响。比较变量数不同的模型。
R − 2 adjusted = 1 − ( 1 − R 2 ) ( m − 1 ) m − n − 1 R^{2}_{-} \text {adjusted }=1-\frac{\left(1-R^{2}\right)(m-1)}{m-n-1} R−2adjusted =1−m−n−1(1−R2)(m−1)
5.回归评估指标适用场景分析
在熟悉了回归问题的各种评价指标后,再来看看各自适用的具体场景以及优缺点。

MAE、MSE、RMSE 均存在求平均的操作(包括 R 的平方也可以认为有此操作,只是因为分子分母的约分导致求平均的操作不明显),而取均值是为了消除样本数量的影响,使得评估指标的大小不会太依赖于样本数量,而是更多地反映模型的误差。
校正之后的决定系数在此基础上消除了样本数量和特征数量的影响,自变量越多,校正决定系数就会对自变量进行处罚,所以一般校正决定系数小于决定系数,它能更好地反映模型的质量,可以用来选择不同特征数量的回归模型。

6.分类问题常用的评估指标
分类问题是机器学*领域最常见的大类问题,有很多场景可以划归到分类问题的解决范畴。下面我们梳理一下分类问题的主要评估指标(Evaluation Metrics)。
1)混淆矩阵
在人工智能中,混淆矩阵(Confusion Matrix)是非常有效的评估模式,特别用于监督学*(在无监督学*中一般叫做匹配矩阵)。典型的混淆矩阵构成如下图所示:
-
每一列代表了预测类别,每一列的总数表示预测为该类别的数据的数目。
-
每一行代表了数据的真实归属类别,每一行的数据总数表示该类别的数据实例的数目。

-
True Positive(TP):真实值为 Positive,预测值为 Positive。
-
False positive(FP):真实值为 Negative,预测值为 Negative。
-
False Negative(FN):真实值为 Negative,预测值为 Positive。
-
True Negative(TN):真实值为 Positive,预测值为 Negative。
很多评估指标可以基于混淆矩阵计算得到,如下图所示:

2)Accuracy 精确率
对于分类问题,精确率(Accuracy)指分类正确的样本数占样本总数的比例,是最常用的指标,可以总体上衡量一个预测的性能。一般情况(数据类别均衡)下,模型的精度越高,说明模型的效果越好。
A c c u r a c y = T P + T N F P + F N + F P + T N Accuracy =\frac{TP+TN}{FP+FN+FP+TN} Accuracy=FP+FN+FP+TNTP+TN

但是在数据类别严重不均衡的情况下,这个评估指标并不合理,比如发病率 0.1%的医疗场景下,如果只追求 Accuracy,模型可以把所有人判定为没有病的正常人,Accuracy 高达 99.9%,但这个模型实际是不可用的。为了更好地应对上述问题,衍生出了一系列其他评估指标。例如:
-
宁愿漏掉,不可错杀:在识别垃圾邮件的场景中可能偏向这一种思路,因为不希望很多的正常邮件被误杀,这样会造成严重的困扰。因此,查准率(Precision)将是一个被侧重关心的指标。
-
宁愿错杀,不可漏掉:在金融风控领域大多偏向这种思路,希望系统能够筛选出所有有风险的行为或用户,然后交给人工鉴别,漏掉一个可能造成灾难性后果。因此,查全率(Recall)将是一个被侧重关心的指标。
3)Precision 查准率
Precision(查准率),又称正确率、准确率,表示在模型识别为正类的样本中,真正为正类的样本所占的比例。一般情况下,查准率越高,说明模型的效果越好。
P r e c i s i o n = T P F P + F P Precision =\frac{TP}{FP+FP} Precision=FP+FPTP

4)Recall 查全率
Recall(查全率),又称召回率,表示的是,模型正确识别出为正类的样本的数量占总的正类样本数量的比值。一般情况下,Recall 越高,说明有更多的正类样本被模型预测正确,模型的效果越好。
R e c a l l = T P T P + F N Recall =\frac{TP}{TP+FN} Recall=TP+FNTP

5)Fβ-Score 和 F1-Score
理论上来说,Precision 和 Recall 都是越高越好,但更多时候它们两个是矛盾的,经常无法保证二者都很高。此时,引入一个新指标 F β − S c o r e F \beta - Score Fβ−Score,用来综合考虑 Precision 与 Recall。
F β = ( 1 + β 2 ) × Precision × Recall β 2 × Precision + Recall F_{\beta}=\left(1+\beta^{2}\right) \times \frac{\text { Precision } \times \text { Recall }}{\beta^{2} \times \text { Precision }+\text { Recall }} Fβ=(1+β2)×β2× Precision + Recall Precision × Recall
需要根据不同的业务场景来调整 β \beta β 值:

- β = 1 \beta = 1 β=1 时, F β − S c o r e F \beta - Score Fβ−Score 就是 F 1 − S c o r e F 1 - Score F1−Score,综合平等考虑 Precision 和 Recall 的评估指标,当 F1 值较高时则说明模型性能较好。
F 1 = 2 Precision × Recall Precision + Recall F_{1}=\frac{2 \text { Precision } \times \text { Recall }}{\text { Precision }+\text { Recall }} F1= Precision + Recall 2 Precision × Recall
-
β < 1 \beta < 1 β<1 时,更关注 Precision。
-
β > 1 \beta > 1 β>1 时,更关注 Recall。
6)ROC
除了前面介绍的 Accuracy、Precision 与 Recall,还有一些其他的度量标准,如使用 True Positive Rate(TPR,真正例率)和 False Positive Rate(FPR,假正例率)两个指标来绘制 ROC 曲线。


T P R = T P T P + F N TPR =\frac{TP}{TP+FN} TPR=TP+FNTP
F P R = F P F P + T N FPR =\frac{FP}{FP+TN} FPR=FP+TNFP
算法对样本进行分类时,都会有置信度,即表示该样本是正样本的概率。
比如,99%的概率认为样本A是正例,1%的概率认为样本 B 是正例。通过选择合适的阈值,比如 50%,对样本进行划分,概率大于 50%的就认为是正例,小于 50%的就是负例。
通过置信度可以对所有样本进行降序排序,再逐个样本地选择阈值,比如排在某个样本之前的都属于正例,该样本之后的都属于负例。每一个样本作为划分阈值时,都可以计算对应的 TPR 和 FPR,那么就可以绘制 ROC 曲线。

ROC 曲线(Receiver Operating Characteristic Curve)全称是「受试者工作特性曲线」。综合考虑了概率预测排序的质量,体现了学*器在不同任务下的「期望泛化性能」的好坏,反映了 TPR 和 FPR 随阈值的变化情况。

ROC 曲线越接*左上角,表示该分类器的性能越好。也就是说模型在保证能够尽可能地准确识别小众样本的基础上,还保持一个较低的误判率,即不会因为要找出小众样本而将很多大众样本给误判。
一般来说,如果 ROC 是光滑的,那么基本可以判断没有太大的 overfitting。
7)AUC
ROC 曲线的确能在一定程度上反映模型的性能,但它并不是那么方便,因为曲线靠*左上方这个说法还比较主观,不够定量化,因此还是需要一个定量化的标量指标来反映这个事情。ROC 曲线的 AUC 值恰好就做到了这一点。

AUC(Area Under ROC Curve)是 ROC 曲线下面积,其物理意义是,正样本的预测结果大于负样本的预测结果的概率,本质是 AUC 反应的是分类器对样本的排序能力。
AUC 值越大,就能够保证 ROC 曲线越靠*左上方。
8)PRC
与 ROC 曲线的思想类似,根据 Precision 和 Recall,也提出了一种 Precision-Recall 曲线。

同样是通过置信度就可以对所有样本进行降序排序,再逐个样本地选择阈值,比如排在某个样本之前的都属于正例,该样本之后的都属于负例。每一个样本作为划分阈值时,都可以计算对应的 Precision 和 Recall,那么就可以绘制 PR 曲线。
9)小结

7.二分类评估指标适用场景
在不同的业务场景中,Precision 和 Recall 的侧重不一样:
-
对于癌症预测、地震预测这类业务场景,人们更关注模型对正类的预测能力和敏感度,因此模型要尽可能提升 Recall,甚至不惜降低 Precision。
-
而对于垃圾邮件识别等场景中,人们更难以接受 FP(把正常邮件识别为垃圾邮件,影响工作),因此模型可以适度降低 Recall 以便获得更高的 Precision。我们可以通过调节 F β − S c o r e F \beta - Score Fβ−Score 中 β \beta β的大小来控制 Precision 和 Recall 的侧重程度。
1)评价指标分析
对于这些评价指标的选择,有如下的一些经验:

-
Accuracy 适用于正负样本比例相差不大的情况的结果评估。
-
Precision 和 Recall 适用于正负样本差异很大的情况,Precision 不能用于抽样情况下的效果评估,Recall 不受抽样影响。
-
负样本的数量远远大于正样本的数据集里,PRC 更能有效衡量分类器的好坏。
-
AUC 计算主要与排序有关,所以它对排序敏感,而对预测分数没那么敏感。
2)垃圾邮件识别
垃圾邮件占用网络带宽、侵犯收件人的隐私权、骗人钱财等,已经对现实社会造成了危害。一般来说,凡是未经用户许可就强行发送到用户的邮箱中的任何电子邮件都可称作是垃圾邮件,这是一个典型的二分类问题。
「把垃圾文件识别为正常文件」和「把正常文件识别为垃圾文件」,二者相比,、我们显然更能容忍前者,因此模型可以适度降低 Recall 以便获得更高的 Precision。
3)金融风控
再来看个金融风控的例子,首先需要明确一点,正常客户的数量一般来说是远远大于风险客户的,这是个样本不均衡问题。互联网金融公司风控部门的主要工作是利用机器模型抓取坏客户。
根据前面对 Precision、Recall 以及 PR 曲线的介绍,知道,Precision 和 Recall 往往都是相互牵制的,很难同时达到一个很高的水平。所以在这个案例中,同样需要根据业务场景来衡量这两个指标的重要性。
-
互联网金融公司要扩大业务量,尽量多的吸引好客户,此时风控部门就会提高阈值,从而提高模型的查准率 Precision,同时,也会放进一部分坏客户,导致查全率 Recall 下降。
-
如果公司坏账扩大,公司缩紧业务,尽可能抓住更多的坏客户,此时风控部门需要不惜一切代价降低损失,守住风险底线,因此会降低阈值,从而提高模型的查全率 Recall,但是这样会导致一部分好客户误抓,从而降低模型的查准率 Precision。
可以通过调节 F β − S c o r e F \beta - Score Fβ−Score 中 β \beta β 的大小来控制 Precision 和 Recall 的侧重程度。 β < 1 \beta < 1 β<1,重视查准率; β > 1 \beta > 1 β>1,重视查全率。
8.样本均衡与采样
首先看看什么是分类任务中的样本不均衡问题,以及如何解决样本不均衡问题。
1)样本均衡问题
在学术研究与教学中,很多算法都有一个基本假设,那就是数据分布是均匀的。当把这些算法直接应用于实际数据时,大多数情况下都无法取得理想的结果,因为实际数据往往分布得很不均匀,都会存在「长尾现象」。

-
多数样本数量多,信息量大,容易被模型充分学*,模型容易识别这类样本
-
少数样本数量少,信息量少,模型没有充分学*到它们的特征,很难识别这类样本
解决这一问题的基本思路是,让正负样本在训练过程中拥有相同的话语权(比如利用采样与加权等方法)。样本类别不均衡的情况下,最常见的处理方式是「数据采样」与「样本加权」,详细介绍如下:
2)数据采样

(1)欠采样 / 下采样
欠采样技术是将数据从原始数据集中移除。
-
从多数类集合中筛选样本集 E。
-
将这些样本从多数类集合中移除。
(2)过采样 / 上采样
随机过采样:
-
首先在少数类集合中随机选中一些少数类样本。
-
然后通过复制所选样本生成样本集合 E。
-
将它们添加到少数类集合中来扩大原始数据集从而得到新的少数类集合。
我们也有一些少类别样本合成技术方法,比如机器学*中有 SMOTE 算法通过合成新样本完成过采样,缓解样本类别不均衡问题。
(3)不同采样方法的比较
下采样的缺点显而易见,那就是最终的训练集丢失了数据,模型只学到了总体模式的一部分。而 SMOTE 算法为每个小众样本合成相同数量的新样本,但这也带来一些潜在的问题:
-
一方面是增加了类之间重叠的可能性,即通过算法生成的小众样本并不一定是合理的小众样本。
-
另一方面是生成一些没有提供有益信息的样本。
3)加权
除了上采样和下采样这种采样方式以外,还可以通过加权的方式来解决数据不均衡问题,即对不同类别分错的代价不同,对于小众样本,如果分错了会造成更大的损失。这种方法的难点在于设置合理的权重,实际应用中一般让各个分类间的加权损失值*似相等。当然这并不是通用法则,还是需要具体问题具体分析。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=935770612&page=8
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
https://www.bilibili.com/video/BV1TT4y127Nf?p=8
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | KNN 算法及其应用

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/187
声明:版权所有,转载请联系平台与作者并注明出处
引言
K *邻算法(k-nearest neighbors,KNN,有些地方也译作「K *邻算法」)是一种很基本朴实的机器学*方法。
KNN 在我们日常生活中也有类似的思想应用,比如,我们判断一个人的人品,往往只需要观察他最密切的几个人的人品好坏就能得到结果了。这就是 KNN 的思想应用,KNN 方法既可以做分类,也可以做回归。在本篇内容中,我们来给大家展开讲解 KNN 相关的知识原理。
(本篇 KNN 部分内容涉及到机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识。
1.机器学*与分类问题
1)分类问题
分类问题是机器学*非常重要的一个组成部分,它的目标是根据已知样本的某些特征,判断一个样本属于哪个类别。分类问题可以细分如下:
-
二分类问题:表示分类任务中有两个类别新的样本属于哪种已知的样本类。
-
多类分类(Multiclass classification)问题:表示分类任务中有多类别。
-
多标签分类(Multilabel classification)问题:给每个样本一系列的目标标签。

2)分类问题的数学抽象
从算法的角度解决一个分类问题,我们的训练数据会被映射成 n 维空间的样本点(这里的 n 就是特征维度),我们需要做的事情是对 n 维样本空间的点进行类别区分,某些点会归属到某个类别。
下图所示的是二维平面中的两类样本点,我们的模型(分类器)在学*一种区分不同类别的方法,比如这里是使用一条直线去对 2 类不同的样本点进行切分。

常见的分类问题应用场景很多,我们选择几个进行举例说明:
-
垃圾邮件识别:可以作为二分类问题,将邮件分为你「垃圾邮件」或者「正常邮件」。
-
图像内容识别:因为图像的内容种类不止一个,图像内容可能是猫、狗、人等等,因此是多类分类问题。
-
文本情感分析:既可以作为二分类问题,将情感分为褒贬两种,还可以作为多类分类问题,将情感种类扩展,比如分为:十分消极、消极、积极、十分积极等。
2.K *邻算法核心思想
在模式识别领域中,K *邻算法(KNN 算法,又译 K-最*邻算法)是一种用于分类和回归的非参数统计方法。在这两种情况下,输入包含特征空间中的 K 个最接*的训练样本。
1)K *邻核心思想
在 KNN 分类中,输出是一个分类族群。一个对象的分类是由其邻居的「多数表决」确定的,K 个最*邻居(K 为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。
- 若 K=1,则该对象的类别直接由最*的一个节点赋予。
在 KNN 回归中,输出是该对象的属性值。该值是其 K 个最*邻居的值的平均值。

K *邻居法采用向量空间模型来分类,概念为相同类别的案例,彼此的相似度高。而可以借由计算与已知类别案例之相似度,来评估未知类别案例可能的分类。
KNN 是一种基于实例的学*,或者是局部*似和将所有计算推迟到分类之后的惰性学*。K-*邻算法是所有的机器学*算法中最简单的之一。
2)豆子分类例子
想一想:下图中只有三种豆,有三个豆的种类未知,如何判定他们的种类?

1968 年,Cover 和 Hart 提出了最初的*邻法,思路是——未知的豆离哪种豆最*,就认为未知豆和该豆是同一种类。

由此,引出最*邻算法的定义:为了判定未知样本的类别,以全部训练样本作为代表点计算未知样本与所有训练样本的距离,并以最*邻者的类别作为决策未知样本类别的唯一依据。
最*邻算法的缺陷是对噪声数据过于敏感。从图中可以得到,一个圈起来的蓝点和两个圈起来的红点到绿点的距离是相等的,根据最*邻算法,该点的形状无法判断。
为了解决这个问题,我们可以把位置样本周边的多个最*样本计算在内,扩大参与决策的样本量,以避免个别数据直接决定决策结果。

引进 K-*邻算法——选择未知样本一定范围内确定个数的 K 个样本,该 K 个样本大多数属于某一类型,则未知样本判定为该类型。K-*邻算法是最*邻算法的一个延伸。
根据 K *邻算法,离绿点最*的三个点中有两个是红点,一个是蓝点,红点的样本数量多于蓝点的样本数量,因此绿点的类别被判定为红点。
3.K *邻算法步骤与示例
下面的内容首先为大家梳理下 K *邻算法的步骤,之后通过示例为大家展示 K *邻算法的计算流程。

1)K *邻算法工作原理
-
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每个数据与所属分类的对应关系。
-
输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最*邻)的分类标签。
-
一般来说,只选择样本数据集中前 N 个最相似的数据。K 一般不大于 20,最后,选择 K 个中出现次数最多的分类,作为新数据的分类。
2)K *邻算法参数选择
-
如何选择一个最佳的 K 值取决于数据。一般情况下,在分类时较大的 K 值能够减小噪声的影响, 但会使类别之间的界限变得模糊。一个较好的 K 值能通过各种启发式技术(见超参数优化)来获取。
-
噪声和非相关性特征的存在,或特征尺度与它们的重要性不一致会使 K *邻算法的准确性严重降低。对于选取和缩放特征来改善分类已经做了很多研究。一个普遍的做法是利用进化算法优化功能扩展,还有一种较普遍的方法是利用训练样本的互信息进行选择特征。
-
在二元(两类)分类问题中,选取 K 为奇数有助于避免两个分类平票的情形。在此问题下,选取最佳经验 K 值的方法是自助法。
说明:KNN 没有显示的训练过程,它是「懒惰学*」的代表,它在训练阶段只是把数据保存下来,训练时间开销为 0,等收到测试样本后进行处理。
3)K *邻算法示例
举例:以电影分类作为例子,电影题材可分为爱情片,动作片等。那么爱情片有哪些特征?动作片有哪些特征呢?也就是说给定一部电影,怎么进行分类?
这里假定将电影分为爱情片和动作片两类,如果一部电影中接吻镜头很多,打斗镜头较少,显然是属于爱情片,反之为动作片。

有人曾根据电影中打斗动作和接吻动作数量进行评估,数据如图。给定一部电影数据(18,90)打斗镜头 18 个,接吻镜头 90 个,如何知道它是什么类型的呢?
现在我们按照距离的递增顺序排序,可以找到 k 个距离最*的电影。

假如 K=3,那么来看排序的前 3 个电影的类别,都是爱情片,根据 KNN 的投票机制,我们判定这部电影属于爱情片。(这里的 K 是超参数,可以调整,如果取 K=4,那可能投票的 4 部电影分别是 爱情片、爱情片、爱情片、动作片,但本例中判定结果依旧为爱情片)
4.K *邻算法的缺点与改进
1)K *邻算法的优缺点
不同类别的样本点,分布在空间的不同区域。K *邻是基于空间距离较*的样本类别来进行分类,本质上是对于特征空间的划分。

-
优点:精度高、对异常值不敏感、无数据输入假定。
-
缺点:计算复杂度高、空间复杂度高。
-
适用数据范围:数值型和标称型。
2)K *邻算法的核心要素:距离度量准则
*邻算法能用一种有效的方式隐含的计算决策边界。另外,它也可以显式的计算决策边界,以及有效率的这样做计算,使得计算复杂度是边界复杂度的函数。K *邻算法依赖于空间中相*的点做类别判断,判断距离远*的度量标准非常重要。
距离的度量标准,对很多算法来说都是核心要素(比如无监督学*的 聚类算法 也很大程度依赖距离度量),也对其结果有很大的影响。

Lp 距离(又称闵可夫斯基距离,Minkowski Distance)不是一种距离,而是一组距离的定义。
-
参数p=1时为曼哈顿距离(又称 L1 距离或程式区块距离),表示两个点在标准坐标系上的绝对轴距之和。
-
参数p=2时为欧氏距离(又称 L2 距离或欧几里得度量),是直线距离常见的两点之间或多点之间的距离表示法。
-
参数p→∞时,就是切比雪夫距离(各坐标数值差的最大值)。
3)K *邻算法的核心要素:K 的大小
对于 KNN 算法而言,K 的大小取值也至关重要,如果选择较小的 K 值,意味着整体模型变得复杂(模型容易发生过拟合),模型学*的*似误差(approximation error)会减小,但估计误差(estimation error)会增大。
如果选择较大的 K 值,就意味着整体的模型变得简单,减少学*的估计误差,但缺点是学*的*似误差会增大。
在实际的应用中,一般采用一个比较小的 K 值。并采用交叉验证的方法,选取一个最优的 K 值。
4)K *邻算法的缺点与改进
(1)缺点
观察下面的例子,我们看到,对于样本 X,通过 KNN 算法,我们显然可以得到 X 应属于红色类别。但对于样本 Y,KNN 算法判定的结果是 Y 应属于蓝色类别,然而从距离上看 Y 和红色的批次样本点更接*。因此,原始的 KNN 算法只考虑*邻不同类别的样本数量,而忽略掉了距离。

除了上述缺点,KNN 还存在如下缺点:
-
样本库容量依赖性较强对 KNN 算法在实际应用中的限制较大:有不少类别无法提供足够的训练样本,使得 KNN 算法所需要的相对均匀的特征空间条件无法得到满足,使得识别的误差较大。
-
K 值的确定:KNN 算法必须指定 K 值,K 值选择不当则分类精度不能保证。
(2)改进方法

加快 KNN 算法的分类速度。
-
浓缩训练样本当训练样本集中样本数量较大时,为了减小计算开销,可以对训练样本集进行编辑处理,即从原始训练样本集中选择最优的参考子集进行 K *邻寻找,从而减少训练样本的存储量和提高计算效率。
-
加快 K 个最*邻的搜索速度这类方法是通过快速搜索算法,在较短时间内找到待分类样本的 K 个最*邻。
对训练样本库的维护。
- 对训练样本库进行维护以满足 KNN 算法的需要,包括对训练样本库中的样本进行添加或删除,采用适当的办法来保证空间的大小,如符合某种条件的样本可以加入数据库中,同时可以对数据库库中已有符合某种条件的样本进行删除。从而保证训练样本库中的样本提供 KNN 算法所需要的相对均匀的特征空间。
5.案例介绍
假如一套房子打算出租,但不知道市场价格,可以根据房子的规格(面积、房间数量、厕所数量、容纳人数等),在已有数据集中查找相似(K *邻)规格的房子价格,看别人的相同或相似户型租了多少钱。

分类过程:已知的数据集中,每个已出租住房都有房间数量、厕所数量、容纳人数等字段,并有对应出租价格。将预计出租房子数据与数据集中每条记录比较计算欧式距离,取出距离最小的 5 条记录,将其价格取平均值,可以将其看做预计出租房子的市场平均价格。
注意:
-
最好不要将所有数据全部拿来测试,需要分出训练集和测试集,具体划分比例按数据集确定。
-
理想情况下,数据集中每个字段取值范围都相同。但实际上这是几乎不可能的,如果计算时直接用原数数据计算,则会造成较大训练误差。所以需要对各列数据进行标准化或归一化操作,尽量减少不必要的训练误差。
-
数据集中非数值类型的字段需要转换,替换掉美元$符号和千分位逗号。
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 逻辑回归算法详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/188
声明:版权所有,转载请联系平台与作者并注明出处
引言
本篇内容我们给大家介绍机器学*领域最常见的模型之一:逻辑回归。它也是目前工业界解决问题最广泛作为 baseline 的解决方案。逻辑回归之所以被广泛应用,因为其简单有效且可解释性强。
本文的结构如下:
-
第 1 部分:回顾机器学*与分类问题。回顾机器学*中最重要的问题之一分类问题,不同的分类问题及数学抽象。
-
第 2 部分:逻辑回归核心思想。介绍线性回归问题及逻辑回归解决方式,讲解逻辑回归核心思想。
-
第 3 部分:Sigmoid 函数与分类器决策边界。介绍逻辑回归模型中最重要的 Sigmoid 变换函数,以及不同分类器得到的决策边界。
-
第 4 部分:模型优化使用的梯度下降算法。介绍模型参数学*过程中最常使用到的优化算法:梯度下降。
-
第 5 部分:模型过拟合问题与正则化。介绍模型状态分析及过拟合问题,以及缓解过拟合问题可以使用的正则化手段。
-
第 6 部分:特征变换与非线性切分。介绍由线性分类器到非线性分类场景,对特征可以进行的变换如构建多项式特征,使得分类器得到分线性切分能力。
(本篇逻辑回归算法的部分内容涉及到机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识)。
1.机器学*与分类问题
1)分类问题
分类问题是机器学*非常重要的一个组成部分,它的目标是根据已知样本的某些特征,判断一个样本属于哪个类别。分类问题可以细分如下:
-
二分类问题:表示分类任务中有两个类别新的样本属于哪种已知的样本类。
-
多类分类(Multiclass Classification)问题:表示分类任务中有多类别。
-
多标签分类(Multilabel Classification)问题:给每个样本一系列的目标标签。

2)分类问题的数学抽象
从算法的角度解决一个分类问题,我们的训练数据会被映射成 n 维空间的样本点(这里的 n 就是特征维度),我们需要做的事情是对 n 维样本空间的点进行类别区分,某些点会归属到某个类别。
下图所示的是二维平面中的两类样本点,我们的模型(分类器)在学*一种区分不同类别的方法,比如这里是使用一条直线去对 2 类不同的样本点进行切分。

常见的分类问题应用场景很多,我们选择几个进行举例说明:
-
垃圾邮件识别:可以作为二分类问题,将邮件分为你「垃圾邮件」或者「正常邮件」。
-
图像内容识别:因为图像的内容种类不止一个,图像内容可能是猫、狗、人等等,因此是多类分类问题。
-
文本情感分析:既可以作为二分类问题,将情感分为褒贬两种,还可以作为多类分类问题,将情感种类扩展,比如分为:十分消极、消极、积极、十分积极等。
2.逻辑回归算法核心思想
下面介绍本次要讲解的算法——逻辑回归(Logistic Regression)。逻辑回归是线性回归的一种扩展,用来处理分类问题。
1)线性回归与分类
分类问题和回归问题有一定的相似性,都是通过对数据集的学*来对未知结果进行预测,区别在于输出值不同。
-
分类问题的输出值是离散值(如垃圾邮件和正常邮件)。
-
回归问题的输出值是连续值(例如房子的价格)。
既然分类问题和回归问题有一定的相似性,那么我们能不能在回归的基础上进行分类呢?
可以想到的一种尝试思路是,先用线性拟合,然后对线性拟合的预测结果值进行量化,即将连续值量化为离散值——即使用『线性回归+阈值』解决分类问题。
我们来看一个例子。假如现在有一个关于肿瘤大小的数据集,需要根据肿瘤的大小来判定是良性(用数字 0 表示)还是恶性(用数字 1 表示),这是一个很典型的二分类问题。

如上图,目前这个简单的场景我们得到 1 个直观的判定:肿瘤的大小大于 5,即为恶性肿瘤(输出为 1);肿瘤的大小等于 5,即为良性肿瘤(输出为 0)。
下面我们尝试之前提到的思路,使用一元线性函数 h ( x ) = θ 0 + θ 1 x h(x) = \theta_0+\theta_1x h(x)=θ0+θ1x 去进行拟合数据,函数体现在图片中就是这条黑色直线。

这样分类问题就可以转化为:对于这个线性拟合的假设函数,给定一个肿瘤的大小,只要将其带入假设函数,并将其输出值和 0.5 进行比较:
-
如果线性回归值大于 0.5,就输出 1(恶性肿瘤)。
-
如果线性回归值小于 0.5,就输出 0(良性肿瘤)。

上图的数据集中的分类问题被完美解决。但如果将数据集更改一下,如图所示,如果我们还是以 0.5 为判定阈值,那么就会把肿瘤大小为 6 的情况进行误判为良好。
所以,单纯地通过将线性拟合的输出值与某一个阈值进行比较,这种方法用于分类非常不稳定。
2)逻辑回归核心思想
因为「线性回归+阈值」的方式很难得到鲁棒性好的分类器,我们对其进行拓展得到鲁棒性更好的逻辑回归(Logistic Regression,有些地方也叫做「对数几率回归」)。逻辑回归将数据拟合到一个 logit 函数中,从而完成对事件发生概率的预测。
如果线性回归的结果输出是一个连续值,而值的范围是无法限定的,这种情况下我们无法得到稳定的判定阈值。那是否可以把这个结果映射到一个固定大小的区间内(比如 0 到 1),进而判断呢。
当然可以,这就是逻辑回归做的事情,而其中用于对连续值压缩变换的函数叫做Sigmoid 函数(也称 Logistic 函数,S 函数)。

Sigmoid 数学表达式为
S ( x ) = 1 1 + e − x S(x) = \dfrac{1}{1+e^{-x}} S(x)=1+e−x1
可以看到 S 函数的输出值在 0 到 1 之间。
3.Sigmoid 函数与决策边界
刚才大家见到了 Sigmoid 函数,下面我们来讲讲它和线性拟合的结合,如何能够完成分类问题,并且得到清晰可解释的分类器判定「决策边界」。
1)分类与决策边界
决策边界就是分类器对于样本进行区分的边界,主要有线性决策边界(linear decision boundaries)和非线性决策边界(non-linear decision boundaries),如下图所示。

2)线性决策边界生成
那么,逻辑回归是怎么得到决策边界的呢,它与 Sigmoid 函数又有什么关系呢?
如下图中的例子:
如果我们用函数 g 表示 Sigmoid 函数,逻辑回归的输出结果由假设函数 h θ ( x ) = g ( θ 0 + θ 1 x 1 + θ 2 x 2 ) h_{\theta}(x)=g\left(\theta_{0}+\theta_{1} x_{1}+\theta_{2} x_{2}\right) hθ(x)=g(θ0+θ1x1+θ2x2)得到。
对于图中的例子,我们暂时取参数 θ 0 、 θ 1 、 θ 2 \theta_{0}、\theta_{1} 、\theta_{2} θ0、θ1、θ2分别为-3、1 和 1,那么对于图上的两类样本点,我们代入一些坐标到 h θ ( x ) h_{\theta}(x) hθ(x),会得到什么结果值呢。

-
对于直线上方的点 ( x 1 , x 2 ) \left ( x_{1}, x_{2} \right ) (x1,x2)(例如 ( 100 , 100 ) \left ( 100, 100 \right ) (100,100)),代入 − 3 + x 1 + x 2 -3+ x_{1}+ x_{2} −3+x1+x2,得到大于 0 的取值,经过 Sigmoid 映射后得到的是大于 0.5 的取值。
-
对于直线下方的点 ( x 1 , x 2 ) \left ( x_{1}, x_{2} \right ) (x1,x2)(例如 ( 0 , 0 ) \left ( 0, 0 \right ) (0,0)),代入 − 3 + x 1 + x 2 -3+ x_{1}+ x_{2} −3+x1+x2,得到小于 0 的取值,经过 Sigmoid 映射后得到的是小于 0.5 的取值。
如果我们以 0.5 为判定边界,则线性拟合的直线 − 3 + x 1 + x 2 = 0 -3+ x_{1}+ x_{2} = 0 −3+x1+x2=0 变换成了一条决策边界(这里是线性决策边界)。
3)非线性决策边界生成
其实,我们不仅仅可以得到线性决策边界,当 h θ ( x ) h_{\theta}(x) hθ(x)更复杂的时候,我们甚至可以得到对样本非线性切分的非线性决策边界(这里的非线性指的是无法通过直线或者超平面把不同类别的样本很好地切分开)。
如下图中另外一个例子:如果我们用函数 g 表示 Sigmoid 函数,逻辑回归的输出结果由假设函数 h θ ( x ) = g ( θ 0 + θ 1 x 1 + θ 2 x 2 + θ 3 x 1 2 + θ 4 x 2 2 ) h_{\theta}(x)=g\left(\theta_{0}+\theta_{1} x_{1}+\theta_{2} x_{2}+\theta_{3} x_{1}^{2}+\theta_{4} x_{2}^{2}\right) hθ(x)=g(θ0+θ1x1+θ2x2+θ3x12+θ4x22)得到。
对于图中的例子,我们暂时取参数 θ 0 、 θ 1 、 θ 2 、 θ 3 、 θ 4 \theta_{0} 、\theta_{1} 、\theta_{2} 、\theta_{3} 、\theta_{4} θ0、θ1、θ2、θ3、θ4分别为-1、0、0、1 和 1,那么对于图上的两类样本点,我们代入一些坐标到
h θ ( x ) h_{\theta}(x) hθ(x),会得到什么结果值呢。

-
对于圆外部的点 ( x 1 , x 2 ) \left ( x_{1}, x_{2} \right ) (x1,x2)(例如 ( 100 , 100 ) \left ( 100, 100 \right ) (100,100)),代入 θ 0 + θ 1 x 1 + θ 2 x 2 + θ 3 x 1 2 + θ 4 x 2 2 \theta_{0}+\theta_{1} x_{1}+\theta_{2} x_{2}+\theta_{3} x_{1}^{2}+\theta_{4} x_{2}^{2} θ0+θ1x1+θ2x2+θ3x12+θ4x22,得到大于 0 的取值,经过 Sigmoid 映射后得到的是大于 0.5 的取值。
-
对于圆内部的点 ( x 1 , x 2 ) \left ( x_{1}, x_{2} \right ) (x1,x2)(例如 ( 0 , 0 ) \left ( 0, 0 \right ) (0,0)),代入 θ 0 + θ 1 x 1 + θ 2 x 2 + θ 3 x 1 2 + θ 4 x 2 2 \theta_{0}+\theta_{1} x_{1}+\theta_{2} x_{2}+\theta_{3} x_{1}^{2}+\theta_{4} x_{2}^{2} θ0+θ1x1+θ2x2+θ3x12+θ4x22,得到小于 0 的取值,经过 Sigmoid 映射后得到的是小于 0.5 的取值。
如果我们以 0.5 为判定边界,则线性拟合的圆曲线 − 1 + x 1 2 + x 2 2 = 0 -1+x_{1}²+x_{2}²=0 −1+x12+x22=0 变换成了一条决策边界(这里是非线性决策边界)。
4.梯度下降与优化
1)损失函数
前一部分的例子中,我们手动取了一些参数θ的取值,最后得到了决策边界。但大家显然可以看到,取不同的参数时,可以得到不同的决策边界。
哪一条决策边界是最好的呢?我们需要定义一个能量化衡量模型好坏的函数——损失函数(有时候也叫做「目标函数」或者「代价函数」)。我们的目标是使得损失函数最小化。
我们如何衡量预测值和标准答案之间的差异呢,最简单直接的方式是数学中的均方误差。它的计算方式很简单,对于所有的样本点 x i x_{i} xi,预测值 h θ ( x i ) h_{\theta}(x_{i}) hθ(xi)与标准答案 y i y_{i} yi作差后平方,求均值即可,这个取值越小代表差异度越小。
M S E = 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 MSE=\frac{1}{m} \sum_{i=1}{m}\left(f\left(x_{i}\right)-y_{i}\right) MSE=m1i=1∑m(f(xi)−yi)2
均方误差对应的损失函数:均方误差损失(MSE)在回归问题损失定义与优化中广泛应用,但是在逻辑回归问题中不太适用。sigmoid 函数的变换使得我们最终得到损失函数曲线如下图所示,是非常不光滑凹凸不平的,这种数学上叫做非凸的损失函数(关于损失函数与凸优化更多知识可以参考 ShowMeAI 的文章 图解 AI 数学基础 | 微积分与最优化),我们要找到最优参数(使得函数取值最小的参数)是很困难的。

解释:在逻辑回归模型场景下,使用 MSE 得到的损失函数是非凸的,数学特性不太好,我们希望损失函数如下的凸函数。凸优化问题中,局部最优解同时也是全局最优解,这一特性使得凸优化问题在一定意义上更易于解决,而一般的非凸最优化问题相比之下更难解决。
我们更希望我们的损失函数如下图所示,是凸函数,我们在数学上有很好优化方法可以对其进行优化。

在逻辑回归模型场景下,我们会改用对数损失函数(二元交叉熵损失),这个损失函数同样能很好地衡量参数好坏,又能保证凸函数的特性。对数损失函数的公式如下:
J ( θ ) = − 1 m [ ∑ i = 1 m y ( i ) log h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^{m} y^{(i)} \log h_{\theta}\left(x{(i)}\right)+\left(1-y\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right] J(θ)=−m1[i=1∑my(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i)))]
其中 y ( i ) y^{(i)} y(i)表示样本取值,在其为正样本时取值为 1,负样本时取值为 0,我们分这两种情况来看看:

Cost ( h θ ( x ) , y ) = { − log ( h θ ( x ) ) if y = 0 − log ( 1 − h θ ( x ) ) if y = 1 \operatorname{Cost}\left(h_{\theta}(x), y\right)=\left{\begin{array}{ll} -\log \left(h_{\theta}(x)\right) & \text { if } y=0 \ -\log \left(1-h_{\theta}(x)\right) & \text { if } y=1 \end{array}\right. Cost(hθ(x),y)={−log(hθ(x))−log(1−hθ(x)) if y=0 if y=1
-
y ( i ) = 0 y^{(i)}=0 y(i)=0:当一个样本为负样本时,若 h θ ( x ) h_{\theta}(x) hθ(x)的结果接* 1(即预测为正样本),那么 − log ( 1 − h θ ( x ) ) - \log \left(1-h_{\theta}\left(x\right)\right) −log(1−hθ(x))的值很大,那么得到的惩罚就大。
-
y ( i ) = 1 y^{(i)}=1 y(i)=1:当一个样本为正样本时,若 h θ ( x ) h_{\theta}(x) hθ(x)的结果接* 0(即预测为负样本),那么 − log ( h θ ( x ) ) - \log \left(h_{\theta}\left(x\right)\right) −log(hθ(x))的值很大,那么得到的惩罚就大。
2)梯度下降
损失函数可以用于衡量模型参数好坏,但我们还需要一些优化方法找到最佳的参数(使得当前的损失函数值最小)。最常见的算法之一是「梯度下降法」,逐步迭代减小损失函数(在凸函数场景下非常容易使用)。如同下山,找准方向(斜率),每次迈进一小步,直至山底。

梯度下降(Gradient Descent)法,是一个一阶最优化算法,通常也称为最速下降法。要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是*似梯度)的反方向的规定步长距离点进行迭代搜索。

上图中,α称为学*率(learning rate),直观的意义是,在函数向极小值方向前进时每步所走的步长。太大一般会错过极小值,太小会导致迭代次数过多。

(关于损失函数与凸优化更多知识可以参考 ShowMeAI 的文章 图解 AI 数学基础 | 微积分与最优化 http://www.showmeai.tech/article-detail/165,关于监督学*的更多总结可以查看 ShowMeAI 总结的速查表手册 AI 知识技能速查 | 机器学*-监督学*)
5.正则化与缓解过拟合
1)过拟合现象
在训练数据不够多,或者模型复杂又过度训练时,模型会陷入过拟合(Overfitting)状态。如下图所示,得到的不同拟合曲线(决策边界)代表不同的模型状态:
-
拟合曲线 1 能够将部分样本正确分类,但是仍有较大量的样本未能正确分类,分类精度低,是「欠拟合」状态。
-
拟合曲线 2 能够将大部分样本正确分类,并且有足够的泛化能力,是较优的拟合曲线。
-
拟合曲线 3 能够很好的将当前样本区分开来,但是当新来一个样本时,有很大的可能不能将其正确区分,原因是该决策边界太努力地学*当前的样本点,甚至把它们直接「记」下来了。

拟合曲线中的「抖动」,表示拟合曲线不规则、不光滑(上图中的拟合曲线 3),对数据的学*程度深,过拟合了。
2)正则化处理
过拟合的一种处理方式是正则化,我们通过对损失函数添加正则化项,可以约束参数的搜索空间,从而保证拟合的决策边界并不会抖动非常厉害。如下图为对数损失函数中加入正则化项(这里是一个 L2 正则化项)

J ( θ ) = 1 m ∑ i = 1 m [ − y ( i ) log ( h θ ( x ( i ) ) ) − ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta)=\frac{1}{m} \sum_{i=1}{m}\left[-y \log \left(h_{\theta}\left(x{(i)}\right)\right)-\left(1-y\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]+\frac{\lambda}{2 m} \sum_{j=1}^{n} \theta_{j}^{2} J(θ)=m1i=1∑m[−y(i)log(hθ(x(i)))−(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2
其中 λ \lambda λ表示正则化系数,表示惩罚程度, λ \lambda λ的值越大,为使 J ( θ ) J(\theta) J(θ)的值小,则参数 θ \theta θ的绝对值就得越小,通常对应于越光滑的函数,也就是更加简单的函数,因此不易发生过拟合的问题。我们依然可以采用梯度下降对加正则化项的损失函数进行优化。
6.特征变换与非线性表达
1)多项式特征
对于输入的特征,如果我们直接进行线性拟合再给到 Sigmoid 函数,得到的是线性决策边界。但添加多项式特征,可以对样本点进行多项式回归拟合,也能在后续得到更好的非线性决策边界。

多项式回归,回归函数是回归变量多项式。多项式回归模型是线性回归模型的一种,此时回归函数关于回归系数是线性的。
在实际应用中,通过增加一些输入数据的非线性特征来增加模型的复杂度通常是有效的。一个简单通用的办法是使用多项式特征,这可以获得特征的更高维度和互相间关系的项,进而获得更好的实验结果。
2)非线性切分
如下图所示,在逻辑回归中,拟合得到的决策边界,可以通过添加多项式特征,调整为非线性决策边界,具备非线性切分能力。
-
Z θ ( x ) Z_{\theta}(x) Zθ(x)中 θ \theta θ是参数,当 Z θ ( x ) = θ 0 + θ 1 x Z_{\theta}(x) = \theta_{0} + \theta_{1}x Zθ(x)=θ0+θ1x 时,此时得到的是线性决策边界;
-
Z θ ( x ) = θ 0 + θ 1 x + θ 2 x 2 Z_{\theta}(x) = \theta_{0} + \theta_{1}x + \theta_{2}x² Zθ(x)=θ0+θ1x+θ2x2 时,使用了多项式特征,得到的是非线性决策边界。

目的是低维线性不可分的数据转化到高维时,会变成线性可分。得到在高维空间下的线性分割参数映射回低维空间,形式上表现为低维的非线性切分。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=975327190&page=4
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 朴素贝叶斯算法详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/189
声明:版权所有,转载请联系平台与作者并注明出处
引言
在众多机器学*分类算法中,本篇我们提到的朴素贝叶斯模型,和其他绝大多数分类算法都不同,也是很重要的模型之一。
在机器学*中如 KNN、逻辑回归、决策树等模型都是判别方法,也就是直接学*出特征输出 Y Y Y 和特征 X X X 之间的关系(决策函数 Y = f ( X ) Y= f(X) Y=f(X)或者条件分布 P ( Y ∣ X ) P(Y|X) P(Y∣X))。但朴素贝叶斯是生成方法,它直接找出特征输出 Y Y Y 和特征 X X X 的联合分布 P ( X , Y ) P(X,Y) P(X,Y),进而通过 P ( Y ∣ X ) = P ( X , Y ) P ( X ) P(Y \mid X)= \frac{P(X,Y)}{P(X)} P(Y∣X)=P(X)P(X,Y)计算得出结果判定。
朴素贝叶斯是一个非常直观的模型,在很多领域有广泛的应用,比如早期的文本分类,很多时候会用它作为 baseline 模型,本篇内容我们对朴素贝叶斯算法原理做展开介绍。
1.朴素贝叶斯算法核心思想
贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素贝叶斯(Naive Bayes)分类是贝叶斯分类中最简单,也是常见的一种分类方法。
朴素贝叶斯算法的核心思想是通过考虑特征概率来预测分类,即对于给出的待分类样本,求解在此样本出现的条件下各个类别出现的概率,哪个最大,就认为此待分类样本属于哪个类别。

举个例子:眼前有 100 个西瓜,好瓜和坏瓜个数差不多,现在要用这些西瓜来训练一个「坏瓜识别器」,我们要怎么办呢?
一般挑西瓜时通常要「敲一敲」,听听声音,是清脆声、浊响声、还是沉闷声。所以,我们先简单点考虑这个问题,只用敲击的声音来辨别西瓜的好坏。根据经验,敲击声「清脆」说明西瓜还不够熟,敲击声「沉闷」说明西瓜成熟度好,更甜更好吃。

所以,坏西瓜的敲击声是「清脆」的概率更大,好西瓜的敲击声是「沉闷」的概率更大。当然这并不绝对——我们千挑万选地「沉闷」瓜也可能并没熟,这就是噪声了。当然,在实际生活中,除了敲击声,我们还有其他可能特征来帮助判断,例如色泽、跟蒂、品类等。
朴素贝叶斯把类似「敲击声」这样的特征概率化,构成一个「西瓜的品质向量」以及对应的「好瓜/坏瓜标签」,训练出一个标准的「基于统计概率的好坏瓜模型」,这些模型都是各个特征概率构成的。

这样,在面对未知品质的西瓜时,我们迅速获取了特征,分别输入「好瓜模型」和「坏瓜模型」,得到两个概率值。如果「坏瓜模型」输出的概率值大一些,那这个瓜很有可能就是个坏瓜。
2.贝叶斯公式与条件独立假设
贝叶斯定理中很重要的概念是先验概率、后验概率和条件概率。(关于这部分依赖的数学知识,大家可以查看 ShowMeAI 的文章 图解 AI 数学基础 | 概率与统计,也可以下载我们的速查手册 AI 知识技能速查 | 数学基础-概率统计知识)
1)先验概率与后验概率
先验概率:事件发生前的预判概率。可以是基于历史数据的统计,可以由背景常识得出,也可以是人的主观观点给出。一般都是单独事件概率。
举个例子:如果我们对西瓜的色泽、根蒂和纹理等特征一无所知,按照常理来说,西瓜是好瓜的概率是 60%。那么这个概率 P(好瓜)就被称为先验概率。
后验概率:事件发生后求的反向条件概率。或者说,基于先验概率求得的反向条件概率。概率形式与条件概率相同。
举个例子:假如我们了解到判断西瓜是否好瓜的一个指标是纹理。一般来说,纹理清晰的西瓜是好瓜的概率大一些,大概是 75%。如果把纹理清晰当作一种结果,然后去推测好瓜的概率,那么这个概率 P(好瓜|纹理清晰)就被称为后验概率。
条件概率:一个事件发生后另一个事件发生的概率。一般的形式为 P ( B ∣ A ) P(B|A) P(B∣A)表示 A A A 发生的条件下 B B B 发生的概率。

2)贝叶斯公式
简单来说,贝叶斯定理(Bayes Theorem,也称贝叶斯公式)是基于假设的先验概率、给定假设下观察到不同数据的概率,提供了一种计算后验概率的方法。在人工智能领域,有一些概率型模型会依托于贝叶斯定理,比如我们今天的主角「朴素贝叶斯模型」。

-
P ( A ) P(A) P(A)是先验概率,一般都是人主观给出的。贝叶斯中的先验概率一般特指它。
-
P ( B ) P(B) P(B)是先验概率,在贝叶斯的很多应用中不重要(因为只要最大后验不求绝对值),需要时往往用全概率公式计算得到。
-
P ( B ∣ A ) P(B \mid A) P(B∣A)是条件概率,又叫似然概率,一般是通过历史数据统计得到。
-
P ( A ∣ B ) P(A \mid B) P(A∣B)是后验概率,一般是我们求解的目标。
3)条件独立假设与朴素贝叶斯
基于贝叶斯定理的贝叶斯模型是一类简单常用的分类算法。在「假设待分类项的各个属性相互独立」的情况下,构造出来的分类算法就称为朴素的,即朴素贝叶斯算法。
所谓「朴素」,是假定所有输入事件之间是相互独立。进行这个假设是因为独立事件间的概率计算更简单。
朴素贝叶斯模型的基本思想是:对于给定的待分类项 X { a 1 , a 2 , a 3 , ⋯ , a n } X \left{ a_1,a_2,a_3,⋯,a_n \right} X{a1,a2,a3,⋯,an},求解在此项出现的条件下各个类别 y i y_i yi出现的概率,哪个 P ( y i ∣ X ) P(y_i |X) P(yi∣X)最大,就把此待分类项归属于哪个类别。
朴素贝叶斯算法的定义为:设 X { a 1 , a 2 , a 3 , ⋯ , a n } X \left{ a_1,a_2,a_3,⋯,a_n \right} X{a1,a2,a3,⋯,an}为一个待分类项,每个 a i a_{i} ai为 x 的一个特征属性,且特征属性之间相互独立。设 C { y 1 , y 2 , y 3 , ⋯ , y n } C \left{ y_1,y_2,y_3,⋯,y_n\right} C{y1,y2,y3,⋯,yn}为一个类别集合,计算 P ( y 1 ∣ X ) , P ( y 2 ∣ X ) , P ( y 3 ∣ X ) , … , P ( y n ∣ X ) P\left(y_{1} \mid X\right), P\left(y_{2} \mid X\right), P\left(y_{3} \mid X\right), \ldots, P\left(y_{n} \mid X\right) P(y1∣X),P(y2∣X),P(y3∣X),…,P(yn∣X)。
P ( y k ∣ X ) = max { P ( y 1 ∣ X ) , P ( y 2 ∣ X ) , P ( y 3 ∣ X ) , … , P ( y n ∣ X ) } P\left(y_{k} \mid X\right)=\max \left{P\left(y_{1} \mid X\right), P\left(y_{2} \mid X\right), P\left(y_{3} \mid X\right), \ldots, P\left(y_{n} \mid X\right)\right} P(yk∣X)=max{P(y1∣X),P(y2∣X),P(y3∣X),…,P(yn∣X)}
则 X ∈ y k X \in y_{k} X∈yk

要求出第四项中的后验概率 P ( y k ∣ X ) P\left(y_{k} \mid X\right) P(yk∣X),就需要分别求出在第三项中的各个条件概率,其步骤是:
-
找到一个已知分类的待分类项集合,这个集合叫做训练样本集
-
统计得到在各类别下各个特征属性的条件概率估计。即
- P ( a 1 ∣ y 1 ) , P ( a 2 ∣ y 1 ) , ⋯ , P ( a n ∣ y 1 ) P\left(a_{1} \mid y_{1}\right), P\left(a_{2} \mid y_{1}\right), \cdots, P\left(a_{n} \mid y_{1}\right) P(a1∣y1),P(a2∣y1),⋯,P(an∣y1)
- P ( a 1 ∣ y 2 ) , P ( a 2 ∣ y 2 ) , ⋯ , P ( a n ∣ y 2 ) P\left(a_{1} \mid y_{2}\right), P\left(a_{2} \mid y_{2}\right), \cdots, P\left(a_{n} \mid y_{2}\right) P(a1∣y2),P(a2∣y2),⋯,P(an∣y2)
- ···
- P ( a 1 ∣ y n ) , P ( a 2 ∣ y n ) , ⋯ , P ( a n ∣ y n ) P\left(a_{1} \mid y_{n}\right), P\left(a_{2} \mid y_{n}\right), \cdots, P\left(a_{n} \mid y_{n}\right) P(a1∣yn),P(a2∣yn),⋯,P(an∣yn)

在朴素贝叶斯算法中,待分类项的每个特征属性都是条件独立的,由贝叶斯公式
P ( y i ∣ X ) = P ( X ∣ y i ) P ( y i ) P ( X ) P\left(y_{i} \mid X\right)=\frac{P\left(X \mid y_{i}\right) P\left(y_{i}\right)}{P(X)} P(yi∣X)=P(X)P(X∣yi)P(yi)
因为分母相当于在数据库中 X X X 存在的概率,所以对于任何一个待分类项来说 P ( X ) P\left(X \right) P(X)都是常数固定的。再求后验概率 P ( y i ∣ X ) P\left(y_{i} \mid X\right) P(yi∣X)的时候只用考虑分子即可。
因为各特征值是独立的所以有:
P ( X ∣ y i ) P ( y i ) = P ( a 1 ∣ y i ) P ( a 2 ∣ y i ) ⋯ P ( a n ∣ y i ) P ( y i ) = P ( y i ) ∏ j = 1 n P ( a j ∣ y i ) \begin{aligned} P\left(X \mid y_{i}\right) P\left(y_{i}\right) &=P\left(a_{1} \mid y_{i}\right) P\left(a_{2} \mid y_{i}\right) \cdots P\left(a_{n} \mid y_{i}\right) P\left(y_{i}\right) \ &=P\left(y_{i}\right) \prod_{j=1}^{n} P\left(a_{j} \mid y_{i}\right) \end{aligned} P(X∣yi)P(yi)=P(a1∣yi)P(a2∣yi)⋯P(an∣yi)P(yi)=P(yi)j=1∏nP(aj∣yi)
可以推出:
P ( X ∣ y i ) = ∏ k = 1 n P ( a k ∣ y i ) P\left(X \mid y_{i}\right)=\prod_{{k=1}}^{n} P\left(a_{k} \mid y_{i}\right) P(X∣yi)=k=1∏nP(ak∣yi)

对于 P ( y i ) P\left(y_{i}\right) P(yi)是指在训练样本中 y i y_{i} yi出现的概率,可以*似的求解为:
P ( y i ) = ∣ y i ∣ D P\left(y_{i}\right)=\frac{\left|y_{i}\right|}{D} P(yi)=D∣yi∣
对于先验概率 P ( a j ∣ y i ) P\left ( a_{j} \mid y_{i} \right ) P(aj∣yi),是指在类别 y i y_{i} yi中,特征元素 a j a_{j} aj出现的概率,可以求解为:
P ( a j ∣ y i ) = ∣ 在 训 练 样 本 为 y i 时 , a j 出 现 的 次 数 ∣ ∣ y i 训 练 样 本 数 ∣ P\left ( a_{j} \mid y_{i} \right ) = \frac{\left | 在训练样本为 y_{i} 时,a_{j} 出现的次数 \right | }{\left | y_{i} 训练样本数 \right | } P(aj∣yi)=∣yi训练样本数∣∣在训练样本为 yi时,aj出现的次数∣

总结一下,朴素贝叶斯模型的分类过程如下流程图所示:

3.伯努利与多项式朴素贝叶斯
1)多项式 vs 伯努利朴素贝叶斯
大家在一些资料中,会看到「多项式朴素贝叶斯」和「伯努利朴素贝叶斯」这样的细分名称,我们在这里基于文本分类来给大家解释一下:

在文本分类的场景下使用朴素贝叶斯,那对应的特征 a j a_j aj就是单词,对应的类别标签就是 y y y,这里有一个问题:每个单词会出现很多次,我们对于频次有哪些处理方法呢?
-
如果直接以单词的频次参与统计计算,那就是多项式朴素贝叶斯的形态。
-
如果以是否出现(0 和 1)参与统计计算,就是伯努利朴素贝叶斯的形态。

(1)多项式朴素贝叶斯
以文本分类为例,多项式模型如下。在多项式模型中,设某文档 d = ( t 1 , t 2 , … , t k ) d=\left(t_{1}, t_{2}, \ldots, t_{k}\right) d=(t1,t2,…,tk), t k t_{k} tk是该文档中出现过的单词,允许重复,则:
先验概率
P ( c ) = 类 c 下 单 词 总 数 整 个 训 练 样 本 的 单 词 总 数 P\left ( c \right ) = \frac{类 c 下单词总数}{整个训练样本的单词总数} P(c)=整个训练样本的单词总数类 c 下单词总数
类条件概率
P ( t k ∣ c ) = 类 c 下 单 词 t k 在 各 个 文 档 中 出 现 过 的 次 数 之 和 + 1 类 c 下 单 词 总 数 + ∣ V ∣ P\left ( t_{k} \mid c \right ) = \frac{类 c 下单词 t_{k}在各个文档中出现过的次数之和+1}{类 c 下单词总数+\left | V \right |} P(tk∣c)=类 c 下单词总数+∣V∣类 c 下单词 tk在各个文档中出现过的次数之和+1
-
V V V 是训练样本的单词表(即抽取单词,单词出现多次,只算一个), ∣ V ∣ \left | V \right | ∣V∣则表示训练样本包含多少种单词。
-
P ( t k ∣ c ) P\left ( t_{k} \mid c \right ) P(tk∣c)可以看作是单词 t k t_{k} tk在证明 d d d 属于类 c c c 上提供了多大的证据,而 P ( c ) P \left ( c \right ) P(c)则可以认为是类别 c c c 在整体上占多大比例(有多大可能性)。
(2)伯努利朴素贝叶斯
对应的,在伯努利朴素贝叶斯里,我们假设各个特征在各个类别下是服从 n 重伯努利分布(二项分布)的,因为伯努利试验仅有两个结果,因此,算法会首先对特征值进行二值化处理(假设二值化的结果为 1 与 0)。
对应的 P ( c ) P \left ( c \right ) P(c)和 P ( t k ∣ c ) P\left ( t_{k} \mid c \right ) P(tk∣c)计算方式如下(注意到分子分母的变化):
P ( c ) = 类 c 下 文 件 总 数 整 个 训 练 样 本 的 文 件 总 数 P \left ( c \right )=\frac{类 c 下文件总数}{整个训练样本的文件总数} P(c)=整个训练样本的文件总数类 c 下文件总数
P ( t k ∣ c ) = 类 c 下 单 词 t k 在 各 个 文 档 中 出 现 过 的 次 数 之 和 + 1 类 c 下 单 词 总 数 + 2 P\left ( t_{k} \mid c \right ) = \frac{类 c 下单词 t_{k}在各个文档中出现过的次数之和+1}{类 c 下单词总数+2} P(tk∣c)=类 c 下单词总数+2 类 c 下单词 tk在各个文档中出现过的次数之和+1
2)朴素贝叶斯与连续值特征
我们发现在之前的概率统计方式,都是基于离散值的。如果遇到连续型变量特征,怎么办呢?
以人的身高,物体的长度为例。一种处理方式是:把它转换成离散型的值。比如:
- 如果身高在 160cm 以下,特征值为 1;
- 在 160cm 和 170cm 之间,特征值为 2;
- 在 170cm 之上,特征值为 3。
当然有不同的转换方法,比如还可以:
- 将身高转换为 3 个特征,分别是 f1、f2、f3;
- 如果身高是 160cm 以下,这三个特征的值分别是 1、0、0;
- 若身高在 170cm 之上,这三个特征的值分别是 0、0、1。
但是,以上的划分方式,都比较粗糙,划分的规则也是人为拟定的,且在同一区间内的样本(比如第 1 套变换规则下,身高 150 和 155)难以区分,我们有高斯朴素贝叶斯模型可以解决这个问题。
如果特征 x i x_{i} xi是连续变量,如何去估计似然度 P ( x i ∣ y k ) P\left ( x_{i}\mid y_{k} \right ) P(xi∣yk)呢?高斯模型是这样做的:我们假设在 y i y_{i} yi的条件下, x x x 服从高斯分布(正态分布)。根据正态分布的概率密度函数即可计算出 P ( x ∣ y i ) P\left ( x \mid y_{i} \right ) P(x∣yi),公式如下:
P ( x i ∣ y k ) = 1 2 π σ y k , i 2 e − ( x i − μ y k , i ) 2 2 σ y k , i 2 P\left(x_{i} \mid y_{k}\right)=\frac{1}{\sqrt{2 \pi \sigma_{y k, i}^{2}}} e^{-\frac{\left(x_{i}-\mu_{y k, i}\right)^{2}}{2 \sigma_{y k, i}^{2}}} P(xi∣yk)=2πσyk,i2 1e−2σyk,i2(xi−μyk,i)2

回到上述例子,如果身高是我们判定人性别(男/女)的特征之一,我们可以假设男性和女性的身高服从正态分布,通过样本计算出身高均值和方差,对应上图中公式就得到正态分布的密度函数。有了密度函数,遇到新的身高值就可以直接代入,算出密度函数的值。
4.平滑处理
1)为什么需要平滑处理
使用朴素贝叶斯,有时候会面临零概率问题。零概率问题,指的是在计算实例的概率时,如果某个量 x x x,在观察样本库(训练集)中没有出现过,会导致整个实例的概率结果是 0。
在文本分类的问题中,当「一个词语没有在训练样本中出现」时,这个词基于公式统计计算得到的条件概率为 0,使用连乘计算文本出现概率时也为 0。这是不合理的,不能因为一个事件没有观察到就武断的认为该事件的概率是 0。
2)拉普拉斯平滑及依据
为了解决零概率的问题,法国数学家拉普拉斯最早提出用加 1 的方法估计没有出现过的现象的概率,所以加法平滑也叫做拉普拉斯平滑。
假定训练样本很大时,每个分量 x 的计数加 1 造成的估计概率变化可以忽略不计,但可以方便有效的避免零概率问题。
对应到文本分类的场景中,如果使用多项式朴素贝叶斯,假定特征 x i x_{i} xi表示某个词在样本中出现的次数(当然用 TF-IDF 表示也可以)。拉普拉斯平滑处理后的条件概率计算公式为:
P ( x i ∣ y ) = N y i + α N y + n α P\left(x_{i} \mid y\right) =\frac{N_{y i}+\alpha}{N_{y}+n \alpha} P(xi∣y)=Ny+nαNyi+α

-
N y i N_{yi} Nyi表示类 y y y 的所有样本中特征 x i x_{i} xi的特征值之和。
-
N y N_{y} Ny表示类 y y y 的所有样本中全部特征的特征值之和。
-
α \alpha α表示平滑值( α ∈ [ 0 , 1 ] \alpha \in \left [ 0, 1 \right ] α∈[0,1],主要为了防止训练样本中某个特征没出现而导致 N y i = 0 N_{yi} =0 Nyi=0,从而导致条件概率 P ( x i ∣ y ) = 0 P\left(x_{i} \mid y\right) = 0 P(xi∣y)=0 的情况,如果不加入平滑值,则计算联合概率时由于某一项为 0 导致后验概率为 0 的异常情况出现。
-
n n n 表示特征总数。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 决策树模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/190
声明:版权所有,转载请联系平台与作者并注明出处
引言
决策树(Decision Tree)是机器学*中一种经典的分类与回归算法。在本篇中我们讨论用于分类的决策树的原理知识。决策树模型呈树形结构,在分类问题中,一颗决策树可以视作 if-then 规则的集合。模型具有可读性,分类速度快的特点,在各种实际业务建模过程中广泛使用。
(本篇内容会涉及到不少机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识。
1.决策树算法核心思想
1)决策树结构与核心思想
决策树(Decision tree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。
决策树模型(Decision Tree model)模拟人类决策过程。以买衣服为例,一个顾客在商店买裤子,于是有了下面的对话:

决策树是一种预测模型,代表的是对象属性与对象值之间的映射关系。决策树是一种树形结构,其中:
- 每个内部结点表示一个属性的测试
- 每个分支表示一个测试输出
- 每个叶结点代表一种类别

如上图买衣服的例子,第一个「内部结点」对应于属性「材料」上的测试,两个分支分别是该属性取值为「牛仔」和「非牛仔」两种可能结果。当取值为「牛仔」时,则对下个属性「裤型」进行测试;若取值为「非牛仔」时,则对应于「叶结点」——「不买」。
决策树模型核心是下面几部分:
- 结点和有向边组成。
- 结点有内部结点和叶结点俩种类型。
- 内部结点表示一个特征,叶结点表示一个类。

2)决策树的发展史
决策树在发展过程中,有过很多不同类型的模型,典型的模型如 ID3、C4.5 和 CART 等,下面我们来简单介绍一下发展史中不同的模型。

2.决策树生长与最优属性的选择
上面介绍的决策树发展史里,大家对于不同的决策树模型有一个基础的理解了,下面一部分,我们来一起看一下决策树是如何生长构成的。
1)决策树生长流程
决策树的决策过程就是从根结点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子结点,将叶子结点的存放的类别作为决策结果。简单说来,决策树的总体流程是自根至叶的递归过程,在每个中间结点寻找一个「划分」(split or test)属性。
如下图的伪代码,是详细的决策树生长(构建)流程。大家可以特别注意图中 3 类终止条件和返回的结果,而整个流程中,有非常核心的一步是「最优划分属性的选择」。

决策树停止生长的三个条件:

2)最优属性选择
下面我们来看看,决策树的最优划分属性选择,是怎么做的。
(1)信息熵
要了解决策树的「最优属性」选择,我们需要先了解一个信息论的概念「信息熵(entropy)」(相关知识可以参考 ShowMeAI 文章 图解 AI 数学基础 | 信息论),它是消除不确定性所需信息量的度量,也是未知事件可能含有的信息量,可以度量样本集合「纯度」。
对应到机器学*中,假定当前数据集 D D D 中有 y y y 类,其中第 k k k 类样本占比为 p k p_{k} pk,则信息熵的计算公式如下:
E n t ( D ) = − ∑ K = 1 ∣ y ∣ p k log 2 p k Ent(D) = -\sum_{K=1}^{\left | y \right | } p_{k} \log_{2}{p_{k}} Ent(D)=−K=1∑∣y∣pklog2pk

但 p k p_{k} pk取值为 1 的时候,信息熵为 0(很显然这时候概率 1 表示确定事件,没有任何不确定性);而当 p k p_{k} pk是均匀分布的时候,信息熵取最大值 log ( ∣ y ∣ ) \log(|y|) log(∣y∣)(此时所有候选同等概率,不确定性最大)。
(2)信息增益
大家对信息熵有了解后,我们就可以进一步了解信息增益(Information Gain),它衡量的是我们选择某个属性进行划分时信息熵的变化(可以理解为基于这个规则划分,不确定性降低的程度)。
Gain ( D , a ) = Ent ( D ) − ∑ v = 1 v ∣ D v ∣ ∣ D ∣ Ent ( D v ) \operatorname{Gain}(D, a)=\operatorname{Ent}(D)-\sum_{v=1}^{v} \frac{\left|D^{v}\right|}{|D|} \operatorname{Ent}\left(D^{v}\right) Gain(D,a)=Ent(D)−v=1∑v∣D∣∣Dv∣Ent(Dv)

信息增益描述了一个特征带来的信息量的多少。在决策树分类问题中,信息增益就是决策树在进行属性选择划分前和划分后的信息差值。典型的决策树算法 ID3 就是基于信息增益来挑选每一节点分支用于划分的属性(特征)的。
这里以西瓜数据集为例。
- 数据集分为好瓜、坏瓜,所以 ∣ y ∣ = 2 |y|=2 ∣y∣=2。
- 根结点包含 17 个训练样例,其中好瓜共计 8 个样例,所占比例为 8/17。
- 坏瓜共计 9 个样例,所占比例为 9/17。
将数据带入信息熵公式,即可得到根结点的信息熵。

以属性「色泽」为例,其对应的 3 个数据子集:
-
D 1 ( 色 泽 = 青 绿 ) D1(色泽=青绿) D1(色泽=青绿),包含{1,4,6,10,13,17},6 个样例,其中好瓜样例为 { 1 , 4 , 6 } \left { 1,4,6 \right } {1,4,6},比例为 3/6,坏瓜样例为 { 10 , 13 , 17 } \left { 10,13,17 \right } {10,13,17},比例为 3/6。将数据带入信息熵计算公式即可得到该结点的信息熵。
-
D 2 ( 色 泽 = 乌 黑 ) D2(色泽=乌黑) D2(色泽=乌黑),包含 { 2 , 3 , 7 , 8 , 9 , 15 } \left { 2,3,7,8,9,15 \right } {2,3,7,8,9,15},6 个样例,其中好瓜样例为 { 2 , 3 , 7 , 8 } \left { 2,3,7,8 \right } {2,3,7,8},比例为 4/6,坏瓜样例为 { 9 , 15 } \left { 9,15 \right } {9,15},比例为 2/6。将数据带入信息熵计算公式即可得到该结点的信息熵。
-
D 3 ( 色 泽 = 浅 白 ) D3(色泽=浅白) D3(色泽=浅白),包含 { 5 , 11 , 12 , 14 , 16 } \left { 5,11,12,14,16 \right } {5,11,12,14,16},5 个样例,其中好瓜样例为 { 5 } \left { 5 \right } {5},比例为 1/5,坏瓜样例为 { 11 , 12 , 14 , 16 } \left { 11,12,14,16 \right } {11,12,14,16},比例为 4/5。将数据带入信息熵计算公式即可得到该结点的信息熵。

色泽属性的信息增益为:

同样的方法,计算其他属性的信息增益为:

对比不同属性,我们发现「纹理」信息增益最大,其被选为划分属性:清晰 { 1 , 2 , 3 , 4 , 5 , 6 , 8 , 10 , 15 } \left { 1,2,3,4,5,6,8,10,15 \right } {1,2,3,4,5,6,8,10,15}、稍糊 { 7 , 9 , 13 , 14 , 17 } \left { 7,9,13,14,17 \right } {7,9,13,14,17}、模糊 { 11 , 12 , 16 } \left { 11,12,16 \right } {11,12,16}。
再往下一步,我们看看「纹理」=「清晰」的节点分支,该节点包含的样例集合 D1 中有编号为 { 1 , 2 , 3 , 4 , 5 , 6 , 8 , 10 , 15 } \left { 1,2,3,4,5,6,8,10,15 \right } {1,2,3,4,5,6,8,10,15}共计 9 个样例,可用属性集合为 { 色 泽 , 根 蒂 , 敲 声 , 脐 部 , 触 感 } \left { 色泽,根蒂,敲声,脐部,触感 \right } {色泽,根蒂,敲声,脐部,触感}(此时「纹理」不再作为划分属性),我们同样的方式再计算各属性的信息增益为:

从上图可以看出「根蒂」、「脐部」、「触感」3 个属性均取得了最大的信息增益,可用任选其一作为划分属性。同理,对每个分支结点进行类似操作,即可得到最终的决策树。

(3)信息增益率(Gain Ratio)
大家已经了解了信息增益作为特征选择的方法,但信息增益有一个问题,它偏向取值较多的特征。原因是,当特征的取值较多时,根据此特征划分更容易得到纯度更高的子集,因此划分之后的熵更低,由于划分前的熵是一定的。因此信息增益更大,因此信息增益比较偏向取值较多的特征。
那有没有解决这个小问题的方法呢?有的,这就是我们要提到信息增益率(Gain Ratio),信息增益率相比信息增益,多了一个衡量本身属性的分散程度的部分作为分母,而著名的决策树算法 C4.5 就是使用它作为划分属性挑选的原则。
信息增益率的计算细节如下所示:
Gain − ratio ( D , a ) = Gain ( D , a ) IV ( a ) \operatorname{Gain}_{-} \operatorname{ratio}(D, a)=\frac{\operatorname{Gain}(D, a)}{\operatorname{IV}(a)} Gain−ratio(D,a)=IV(a)Gain(D,a)
I V ( a ) = − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ log 2 ∣ D v ∣ ∣ D ∣ IV(a)=-\sum_{v=1}^{V} \frac{\left|D^{v}\right|}{|D|} \log _{2} \frac{\left|D^{v}\right|}{|D|} IV(a)=−v=1∑V∣D∣∣Dv∣log2∣D∣∣Dv∣

数学上用于信息量(或者纯度)衡量的不止有上述的熵相关的定义,我们还可以使用基尼指数来表示数据集的不纯度。基尼指数越大,表示数据集越不纯。
基尼指数(Gini Index)的详细计算方式如下所示:
Gini ( D ) = ∑ k = 1 ∣ y ∣ ∑ k ′ ≠ k p k p k ′ = 1 − ∑ k = 1 ∣ y ∣ p k 2 \operatorname{Gini}(D)=\sum_{k=1}^{|y|} \sum_{k \prime \neq k} p_{k} p_{k{\prime}}=1-\sum_{k=1} p_{k}^{2} Gini(D)=k=1∑∣y∣k′=k∑pkpk′=1−k=1∑∣y∣pk2

其中, p k p_k pk表示第 k k k 类的数据占总数据的比例,著名的决策树算法 CART 就是使用基尼指数来进行划分属性的挑选(当然,CART 本身是二叉树结构,这一点和上述的 ID3 和 C4.5 不太一样)。
对于基尼指数的一种理解方式是,之所以它可以用作纯度的度量,大家可以想象在一个漆黑的袋里摸球,有不同颜色的球,其中第 k 类占比记作 p k p_k pk,那两次摸到的球都是第 k 类的概率就是 p k 2 p_k² pk2,那两次摸到的球颜色不一致的概率就是 1 − Σ p k 2 1-Σp_k² 1−Σpk2,它的取值越小,两次摸球颜色不一致的概率就越小,纯度就越高。
3.过拟合与剪枝
如果我们让决策树一直生长,最后得到的决策树可能很庞大,而且因为对原始数据学*得过于充分会有过拟合的问题。缓解决策树过拟合可以通过剪枝操作完成。而剪枝方式又可以分为:预剪枝和后剪枝。
1)决策树与剪枝操作
为了尽可能正确分类训练样本,有可能造成分支过多,造成过拟合。过拟合是指训练集上表现很好,但是在测试集上表现很差,泛化性能差。可以通过剪枝主动去掉一些分支来降低过拟合的风险,并使用「留出法」进行评估剪枝前后决策树的优劣。
基本策略包含「预剪枝」和「后剪枝」两个:
-
预剪枝(pre-pruning):在决策树生长过程中,对每个结点在划分前进行估计,若当前结点的划分不能带来决策树泛化性能的提升,则停止划分并将当前结点标记为叶结点。
-
后剪枝(post-pruning):先从训练集生成一颗完整的决策树,然后自底向上地对非叶结点进行考察,若将该结点对应的子树替换为叶结点能带来决策树泛化性能的提升,则将该子树替换为叶结点。
2)预剪枝与后剪枝案例
我们来看一个例子,下面的数据集,为了评价决策树模型的表现,会划分出一部分数据作为验证集。

在上述西瓜数据集上生成的一颗完整的决策树,如下图所示。

(1)预剪枝
「预剪枝」过程如下:将其标记为叶结点,类别标记为训练样例中最多的类别。
-
若选「好瓜」,验证集中{4,5,8}被分类正确,得到验证集精度为 3/7x100%=42.9%
-
根据结点②③④的训练样例,将这 3 个结点分别标记为「好瓜」、「好瓜」、「坏瓜」。此时,验证集中编号为{4,5,8,11,12}的样例被划分正确,验证集精度为 5/7x100%=71.4%
- 结点 2(好瓜):分类正确:{4,5},分类错误:
- 结点 3(好瓜):分类正确:{8},分类错误:
- 结点 4(坏瓜):分类正确:

若划分后的验证集精度下降,则拒绝划分。对结点②③④分别进行剪枝判断,结点②③都禁止划分,结点④本身为叶子结点。
根据预剪枝方法,此处生成了一层决策树。这种最终得到仅有一层划分的决策树,称为「决策树桩」(decision stump)。

(2)后剪枝
我们在生成的完整决策树上进行「后剪枝」:
-
用验证集的数据对该决策树进行评估,样例 { 4 , 11 , 12 } \left {4,11,12 \right } {4,11,12}分类正确,而样例 { 5 , 8 , 9 , 13 } \left {5,8,9,13 \right } {5,8,9,13}分类错误,此时的精度为 42.9%。
-
当对该决策树进行后剪枝,结点⑥的标记为好瓜,此时样例 { 4 , 8 , 11 , 12 } \left {4,8,11,12 \right } {4,8,11,12}分类正确,样例 { 5 , 9 , 13 } \left {5,9,13 \right } {5,9,13}分类错误,精度为 57.1%。
剪枝后的精度提升了,因此该决策树需要在结点⑥处进行剪枝。

考虑结点⑤,若将其替换为叶结点,根据落在其上的训练样例 { 6 , 7 , 15 } \left { 6,7,15 \right } {6,7,15}将其标记为「好瓜」,测得验证集精度仍为 57.1%,可以不剪枝。

考虑结点②,若将其替换为叶结点,根据落在其上的训练样例 { 1 , 2 , 3 , 14 } \left { 1,2,3,14 \right } {1,2,3,14}将其标记为「好瓜」,测得验证集精度提升至 71.4%,决定剪枝。

对结点③和①,若将其子树替换为叶结点,则所得决策树的验证集精度分布为 71.4%和 42.9%,均未提高,所以不剪枝。得到最终后剪枝之后的决策树。

3)预剪枝与后剪枝的特点
时间开销:
- 预剪枝:训练时间开销降低,测试时间开销降低。
- 后剪枝:训练时间开销增加,测试时间开销降低。
过/欠拟合风险:
- 预剪枝:过拟合风险降低,欠拟合风险增加。
- 后剪枝:过拟合风险降低,欠拟合风险基本不变。
泛化性能:后剪枝通常优于预剪枝。
4.连续值与缺失值的处理
1)连续值处理
我们用于学*的数据包含了连续值特征和离散值特征,之前的例子中使用的都是离散值属性(特征),决策树当然也能处理连续值属性,我们来看看它的处理方式。
对于离散取值的特征,决策树的划分方式是:选取一个最合适的特征属性,然后将集合按照这个特征属性的不同值划分为多个子集合,并且不断的重复这种操作的过程。
对于连续值属性,显然我们不能以这些离散值直接进行分散集合,否则每个连续值将会对应一种分类。那我们如何把连续值属性参与到决策树的建立中呢?
因为连续属性的可取值数目不再有限,因此需要连续属性离散化处理,常用的离散化策略是二分法,这个技术也是 C4.5 中采用的策略。
具体的二分法处理方式如下图所示:

注意:与离散属性不同,若当前结点划分属性为连续属性,该属性还可以作为其后代结点的划分属性。
2)缺失值处理
原始数据很多时候还会出现缺失值,决策树算法也能有效的处理含有缺失值的数据。使用决策树建模时,处理缺失值需要解决 2 个问题:
-
Q1:如何进行划分属性选择?
-
Q2:给定划分属性,若样本在该属性上的值缺失,如何进行划分?
缺失值处理的基本思路是:样本赋权,权重划分。我们来通过下图这份有缺失值的西瓜数据集,看看具体处理方式。
仅通过无缺失值的样例来判断划分属性的优劣,学*开始时,根结点包含样例集 D 中全部 17 个样例,权重均为 1。
-
根结点选择「色泽」属性时,有 3 个缺失值,因此样例总数为 14。
-
此时好瓜样例为 { 2 , 3 , 4 , 6 , 7 , 8 } \left {2,3,4,6,7,8\right } {2,3,4,6,7,8},比例为 6/14,坏瓜样例为 { 9 , 10 , 11 , 12 , 14 , 15 , 16 , 17 } \left { 9,10,11,12,14,15,16,17 \right } {9,10,11,12,14,15,16,17},比例为 8/14。
将数据带入信息熵计算公式即可得到该结点的信息熵。

令 D 1 ~ \tilde{D^{1}} D1~、 D 2 ~ \tilde{D^{2}} D2~、 D 3 ~ \tilde{D^{3}} D3~分别表示在属性「色泽」上取值为「青绿」「乌黑」以及「浅白」的样本子集:

-
D 1 ~ ( 色 泽 = 青 绿 ) \tilde{D^{1}} (色泽=青绿) D1~(色泽=青绿),包含 { 4 , 6 , 10 , 17 } \left { 4,6,10,17 \right } {4,6,10,17},4 个样例,其中好瓜样例为 { 4 , 6 } \left { 4,6 \right } {4,6},比例为 2/4,坏瓜样例为 { 10 , 17 } \left { 10,17 \right } {10,17},比例为 2/4。将数据带入信息熵计算公式即可得到该结点的信息熵。
-
D 2 ~ ( 色 泽 = 乌 黑 ) \tilde{D^{2}}(色泽=乌黑) D2~(色泽=乌黑),包含 { 2 , 3 , 7 , 8 , 9 , 15 } \left { 2,3,7,8,9,15 \right } {2,3,7,8,9,15},6 个样例,其中好瓜样例为 { 2 , 3 , 7 , 8 } \left { 2,3,7,8 \right } {2,3,7,8},比例为 4/6,坏瓜样例为 { 9 , 15 } \left { 9,15 \right } {9,15},比例为 2/6。将数据带入信息熵计算公式即可得到该结点的信息熵。
-
D 3 ~ ( 色 泽 = 浅 白 ) \tilde{D^{3}}(色泽=浅白) D3~(色泽=浅白),包含 { 11 , 12 , 14 , 16 } \left { 11,12,14,16 \right } {11,12,14,16},4 个样例,其中好瓜样例为 { ϕ } \left { \phi \right } {ϕ},比例为 0/5,坏瓜样例为 { 11 , 12 , 14 , 16 } \left { 11,12,14,16 \right } {11,12,14,16},比例为 4/4。将数据带入信息熵计算公式即可得到该结点的信息熵。
于是,样本集 D 上属性「色泽」的信息增益可以计算得出,Gain(D,纹理)=0.424 信息增益最大,选择「纹理」作为接下来的划分属性。

更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=975327190&page=12
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程
![]()
图解机器学* | 随机森林分类模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/191
声明:版权所有,转载请联系平台与作者并注明出处
引言
随机森林是一种由决策树构成的(并行)集成算法,属于 Bagging 类型,通过组合多个弱分类器,最终结果通过投票或取均值,使得整体模型的结果具有较高的精确度和泛化性能,同时也有很好的稳定性,广泛应用在各种业务场景中。
随机森林有如此优良的表现,主要归功于「随机」和「森林」,一个使它具有抗过拟合能力,一个使它更加精准。我们会在下文中做更详细的展开讲解。
(本篇部分内容涉及到机器学*基础知识、决策树、回归树算法,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识、决策树模型详解 及 回归树模型详解)。
1.集成学*
1)集成学*
学*随机森林,我们需要先了解一些概念,比如第 1 个大家要了解的概念是集成学*(ensemble learning):

对于训练数据集,我们训练一系列「个体学*器」,再通过「结合策略」将它们集成起来,形成一个更强的学*器,这就是「集成学*」在做的事情,内核思想类似「三个臭皮匠,顶个诸葛亮」。
2)个体学*器
个体学*器是相对于集成学*来说的,其实我们在之前了解到的很多模型,比如 C4.5 决策树算法、逻辑回归算法、朴素贝叶斯算法等,都是个体学*器。

-
若集成中只包含同种类型的个体学*器,叫做「同质」集成,个体学*器称作「基学*器」。例如随机森林中全是决策树集成。
-
若集成中包含不同类型的个体学*器,叫做「异质」集成,个体学*器称作「组件学*器」。例如同时包含决策树和神经网络进行集成。
个体学*器代表的是单个学*器,集成学*代表的是多个学*器的结合。
3)集成学*核心问题

(1)使用什么样的个体学*器?
- 个体学*器不能太「弱」,需要有一定的准确性。
- 个体学*器之间要具有「多样性」,即存在差异性。
(2)如何选择合适的结合策略构建强学*器?
- 并行组合方式,例如随机森林。
- 传统组合方式,例如 boosting 树模型。
2.Bagging
我们在这里讲到的随机森林是并行集成模型,而 Bagging 是并行式集成学*方法最著名的代表。
1)Bootstrap Sampling
要理解 bagging,首先要了解自助采样法(Bootstrap Sampling):

-
给定包含 m m m 个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中。
-
上述过程重复 m m m 轮,我们得到 m m m 个样本的采样集,初始训练集中有的样本在采样集中多次出现,有的则从未出现,约 63.2%的样本出现在采样集中,而未出现的约 36.8%的样本可用作验证集来对后续的泛化性能进行「包外估计」。
2)Bagging
Bagging 是 Bootstrap aggregating 的缩写,是在 Boostrap Sampling 基础上构建的,上述的采样过程我们可以重复 T T T 次,采样出 T T T 个含 m m m 个训练样本的采样集,然后基于每个采样集训练出一个基学*器,然后将这些基学*器进行结合。
在对预测输出进行结合时,Bagging 通常对分类任务使用简单投票法,对回归任务使用简单平均法,这就是 Bagging 的基本流程。

从「偏差-方差分解」的角度看,Bagging 主要关注降低方差,因此它在不剪枝的决策树、神经网络等易受到样本扰动的学*器上效用更明显。
3.随机森林算法
1)随机森林算法介绍
Random Forest(随机森林,简称 RF)是一种基于树模型的 Bagging 的优化版本。核心思想依旧是 Bagging,但是做了一些独特的改进——RF 使用了 CART 决策树作为基学*器。具体过程如下:
-
输入为样本集 D = { ( x , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) } D=\left{\left(x, y_{1}\right),\left(x_{2}, y_{2}\right), \ldots,\left(x_{m}, y_{m}\right)\right} D=
-
对于 t = 1 , 2 , . . . , T t=1,2,...,T t=1,2,...,T:
- 对训练集进行第 t t t 次随机采样,共采集 m m m 次,得到包含 m m m 个样本的采样集 D T D_T DT。
- 用采样集 D T D_T DT 训练第 T T T 个决策树模型 G T ( x ) G_{T} (x) GT(x) ,在训练决策树模型的节点的时候,在节点上所有的样本特征中选择一部分样本特征,在这些随机选择的部分样本特征中选择一个最优的特征来做决策树的左右子树划分。
-
分类场景,则 T T T 个基模型(决策树)投出最多票数的类别为最终类别。

2)随机森林核心特点
随机森林核心点是「随机」和「森林」,也是给它带来良好性能的最大支撑。
「随机」主要体现在两个方面:
-
样本扰动:直接基于自助采样法(Bootstrap Sampling),使得初始训练集中约 63.2%的样本出现在一个采样集中。并带来数据集的差异化。
-
属性扰动:在随机森林中,对基决策树的每个结点,先在该结点的特征属性集合中随机选择 k 个属性,然后再从这 k 个属性中选择一个最优属性进行划分。这一重随机性也会带来基模型的差异性。
「集成」体现在:根据多个(差异化)采样集,训练得到多个(差异化)决策树,采用简单投票或者平均法来提高模型稳定性和泛化能力。
3)随机森林决策边界可视化
下面是对于同一份数据集(iris 数据集),我们使用决策树和不同树棵树的随机森林做分类的结果,我们对其决策边界做了可视化。

可以很明显地看到,随着随机森林中决策树数量的增多,模型的泛化能力逐渐增强,决策边界越来越趋于平滑(受到噪声点的影响越来越小)。
4)随机森林算法优点
下面我们来总结一下随机森林的优缺点:
(1)随机森林优点
- 对于高维(特征很多)稠密型的数据适用,不用降维,无需做特征选择。
- 构建随机森林模型的过程,亦可帮助判断特征的重要程度。
- 可以借助模型构建组合特征。
- 并行集成,有效控制过拟合。
- 工程实现并行简单,训练速度快。
- 对于不平衡的数据集友好,可以平衡误差。
- 对于特征确实鲁棒性强,可以维持不错的准确度。
(2)随机森林缺点
- 在噪声过大的分类和回归数据集上还是可能会过拟合。
- 相比单一决策树,因其随机性,模型解释会更复杂一些。
4.影响随机森林的参数与调优
上面我们已经系统了解了随机森林的原理与机制,下面我们一起来看看工程应用实践中的一些重点,比如随机森林模型有众多可调参数,它们有什么影响,又如何调优。
1)核心影响参数

(1)生成单颗决策树时的特征数(max_features)
-
增加 max_features 一般能提高单个决策树模型的性能,但降低了树和树之间的差异性,且可能降低算法的速度。
-
太小的 max_features 会影响单颗树的性能,进而影响整体的集成效果。
-
需要适当地平衡和选择最佳的 max_features。
(2)决策树的棵树(n_estimators)
-
较多的子树可以让模型有更好的稳定性和泛化能力,但同时让模型的学*速度变慢。
-
我们会在计算资源能支撑的情况下,选择稍大的子树棵树。
(3)树深(max_depth)
-
太大的树深,因为每颗子树都过度学*,可能会有过拟合问题。
-
如果模型样本量多特征多,我们会限制最大树深,提高模型的泛化能力。
2)参数调优

(1)RF 划分时考虑的最大特征数(max_features)
- 总数的百分比,常见的选择区间是[0.5, 0.9]。
(2)决策树的棵树(n_estimators)
- 可能会设置为>50 的取值,可根据计算资源调整。
(3)决策树最大深度(max_depth)
- 常见的选择在 4-12 之间。
(4)内部节点再划分所需最小样本数(min_samples_split)
-
如果样本量不大,不需要调整这个值。
-
如果样本量数量级非常大,我们可能会设置这个值为 16,32,64 等。
(5)叶子节点最少样本数(min_samples_leaf)
- 为了提高泛化能力,我们可能会设置这个值>1。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=975327190&page=12
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 回归树模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/192
声明:版权所有,转载请联系平台与作者并注明出处
引言
大家在前面的部分学*到了使用决策树进行分类,实际决策树也可以用作回归任务,我们叫作回归树。而回归树的结构还是树形结构,但是属性选择与生长方式和分类的决策树有不同,我们一起来看看它的原理知识吧。
(本篇回归树模型部分内容涉及到机器学*基础知识、决策树算法,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识 及 决策树模型详解)。
1.决策树回归算法核心思想
1)决策树结构回顾
我们一起来回顾一下决策树的结构,决策树的典型结构如下图所示。

决策树的学*过程和预测过程如下图所示。详细内容可以参考 ShowMeAI 的文章 决策树模型详解。

主流的决策树算法有:
-
ID3:基于信息增益来选择分裂属性(每步选择信息增益最大的属性作为分裂节点,树可能是多叉的)。
-
C4.5:基于信息增益率来选择分裂属性(每步选择信息增益率最大的属性作为分裂节点,树可能是多叉的)。
-
CART:基于基尼系数来构建决策树(每步要求基尼系数最小,树是二叉的)。
其中:CART 树全称 Classification And Regression Tree,即可以用于分类,也可以用于回归,这里指的回归树就是 CART 树,ID3 和 C4.5 不能用于回归问题。
2)回归树的核心思想
要讲回归树,我们一定会提到 CART 树,CART 树全称 Classification And Regression Trees,包括分类树与回归树。
CART 的特点是:假设决策树是二叉树,内部结点特征的取值为「是」和「否」,右分支是取值为「是」的分支,左分支是取值为「否」的分支。这样的决策树等价于「递归地二分每个特征」,将输入空间(特征空间)划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。
设有数据集 D D D ,构建回归树的大体思路如下:
-
①考虑数据集 D D D 上的所有特征 j j j ,遍历每一个特征下所有可能的取值或者切分点 s s s ,将数据集 D D D 划分成两部分 D 1 D_1 D1 和 D 2 D_2 D2 。
-
②分别计算 D 1 D_1 D1 和 D 2 D_2 D2 的平方误差和,选择最小的平方误差对应的特征与分割点,生成两个子节点(将数据划分为两部分)。
-
③对上述两个子节点递归调用步骤①②,直到满足停止条件。
回归树构建完成后,就完成了对整个输入空间的划分(即完成了回归树的建立)。将整个输入空间划分为多个子区域,每个子区域输出为该区域内所有训练样本的平均值。


我们知道了回归树其实是将输入空间划分为 M 个单元,每个区域的输出值是该区域内所有点 y 值的平均数。但我们希望构建最有效的回归树:预测值与真实值差异度最小。下面部分我们展开讲讲,回归树是如何生长的。
2.启发式切分与最优属性选择
1)回归树模型示例
我们用一个经典的棒球案例来解释回归树:根据从业年限和表现,去预估棒球运动员的工资。如下所示,有 1987 个数据样本,包含 322 个棒球运动员。红黄表示高收入,蓝绿表示低收入。横坐标是年限,纵坐标是表现。

这个简单案例中,每个样本数据有两个特征:从业年限 years 和成绩表现 hits,回归树的决策过程由最终生成的回归树决定,如右图所示:
-
根决策节点为特征 Years,其划分阈值为 4.5,Years 小于 4.5 的样本划分到左边,大于或等于 4.5 的样本划分到右边;
-
第二个决策节点的特征为 Hits,其划分阈值为 117.5,Hits 小于 117.5 的样本划分到左边,大于或等于 117.5 的样本划分到右边。
-
一个样本顺着决策树的决策条件,走到叶子节点,即可获得预测工资,这里的预测工资总共就 3 种取值,分别为 5.11、6.00、6.74。

我们来深入拆解和对应一下,其实回归树构建完成后,实现了对整个空间的划分(如下图所示)。实际预测时,新样本会按照回归树的决策过程,被划分到下图 R 1 R_1 R1 、 R 2 R_2 R2 、 R 3 R_3 R3 之中的一个区域 R i R_i Ri ,而这个新样本的预测值(本案例中为棒球运动员的工资)就是它所在的区域。
- R i R_i Ri 中所有训练样本的工资平均值。

回归树背后的含义:对空间的划分。整个平面被划分成 3 部分:
- R 1 = X ∣ Y e a r s < 4.5 R1 = {X |Years < 4.5} R1=X∣Years<4.5
- R 2 = X ∣ Y e a r s ≥ 4.5 , H i t s < 117.5 R2 = {X |Years ≥ 4.5, Hits < 117.5} R2=X∣Years≥4.5,Hits<117.5
- R 3 = X ∣ Y e a r s ≥ 4.5 , H i t s ≥ 117.5 R3 = {X |Years ≥ 4.5, Hits ≥ 117.5} R3=X∣Years≥4.5,Hits≥117.5
2)回归树构建方法
下面切到回归树构建的核心:切分方式与属性选择。
假设一回归问题,预估结果 y ∈ R y \in R y∈R ,特征向量为 X = [ x 1 , x 2 , x 3 , … , x p ] X = [x_1,x_2,x_3, \dots , x_p ] X=[x1,x2,x3,…,xp] ,回归树 2 个步骤是:
-
①把整个特征空间 X X X 切分成 J J J 个没有重叠的区域 R 1 , R 2 , R 3 , … , R J R_1,R_2,R_3, \dots ,R_J R1,R2,R3,…,RJ
-
②其中区域 R J R_J RJ 中的每个样本我们都给一样的预测结果 y ~ R j = 1 n ∑ j ∈ R j y j \tilde{y}{R{j}}=\frac{1}{n} \sum j \in R j y_{j} y~Rj=n1∑j∈Rjyj ,其中 n n n 是 R J R_J RJ 中的总样本数。
仔细观察一下上面的过程,实际上我们希望能找到如下的 RSS 最小的化划分方式 R 1 , R 2 , R 3 , … , R J R_1,R_2,R_3, \dots ,R_J R1,R2,R3,…,RJ
R S S = ∑ j = 1 J ∑ i ∈ R j ( y i − y ~ R j ) 2 R S S=\sum_{j=1}^{J} \sum_{i \in R j}\left(y_{i}-\tilde{y}{R{j}}\right)^{2} RSS=j=1∑Ji∈Rj∑(yi−y~Rj)2

-
y y y :为每个训练样本的标签构成的标签向量,向量中的每个元素 $y_j $ 对应的是每个样本的标签。
-
X X X :为特征的集合, x 1 , x 2 , … , x p x_1,x_2, \dots , x_p x1,x2,…,xp 为第 1 个特征到第 p p p 个特征。
-
R 1 , R 2 , R 3 , … , R J R_1,R_2,R_3, \dots ,R_J R1,R2,R3,…,RJ 为整个特征空间划分得来的 J 个不重叠的区域(可以参考上页的右图)。
-
y ~ R j \tilde{y}{R{j}} y~Rj :为划分到第 j j j 个区域 $R_j $ 的样本的平均标签值,用这个值作为该区域的预测值,即如果有一个测试样本在测试时落入到该区域,就将该样本的标签值预测为 y ~ R j \tilde{y}{R{j}} y~Rj 。
但是这个最小化和探索的过程,计算量是非常非常大的。我们采用「探索式的递归二分」来尝试解决这个问题。
递归二分
回归树采用的是「自顶向下的贪婪式递归方案」。这里的贪婪,指的是每一次的划分,只考虑当前最优,而不回头考虑之前的划分。从数学上定义,即选择切分的维度(特征) x j x_j xj 以及切分点 s s s 使得划分后的树 RSS 结果最小,公式如下所示:
R 1 ( j , s ) = { x ∣ x j < s } R 2 ( j , s ) = { x ∣ x j ≥ s } R S S = ∑ x i ∈ R 1 ( j , s ) ( y i − y ~ R 1 ) 2 + ∑ x i ∈ R 2 ( j , s ) ( y i − y ~ R 2 ) 2 \begin{aligned} & R_{1}(j, s)=\left{x \mid x_{j}<s\right} \ & R_{2}(j, s)=\left{x \mid x_{j} \geq s\right} \ & RSS=\sum x_{i} \in R_{1}(j, s)\left(y_{i}-\tilde{y}{R 1}\right)^{2}+\sum x \in R_{2}(j, s)\left(y_{i}-\tilde{y}{R{2}}\right)^{2} \end{aligned} R1(j,s)={x∣xj<s}R2(j,s)={x∣xj≥s}RSS=∑xi∈R1(j,s)(yi−yR1)2+∑xi∈R2(j,s)(yi−yR2)2

我们再来看看「递归切分」。下方有两个对比图,其中左图是非递归方式切分得到的,而右图是二分递归的方式切分得到的空间划分结果(下一次划分一定是在之前的划分基础上将某个区域一份为二)。

两种方式的差别是:递归切分一定可以找到一个较优的解,非递归切分穷举不了所有情况,算法上无法实现,可能无法得到一个较好的解。

回归树总体流程类似于分类树:分枝时穷举每一个特征可能的划分阈值,来寻找最优切分特征和最优切分点阈值,衡量的方法是平方误差最小化。分枝直到达到预设的终止条件(如叶子个数上限)就停止。
但通常在处理具体问题时,单一的回归树模型能力有限且有可能陷入过拟合,我们经常会利用集成学*中的 Boosting 思想,对回归树进行增强,得到的新模型就是提升树(Boosting Decision Tree),进一步,可以得到梯度提升树(Gradient Boosting Decision Tree,GBDT),再进一步可以升级到XGBoost。通过多棵回归树拟合残差,不断减小预测值与标签值的偏差,从而达到精准预测的目的,ShowMeAI 会在后面介绍这些高级算法。
3.过拟合与正则化
1)过拟合问题
决策树模型存在过拟合风险,通常情况下,树的规模太小会导致模型效果不佳,而树的规模太大就会造成过拟合,非常难以控制。
2)过拟合问题处理
对于决策树,我们通常有如下一些策略可以用于环节过拟合:

(1)约束控制树的过度生长
- 限制树的深度:当达到设置好的最大深度时结束树的生长。
- 分类误差法:当树继续生长无法得到客观的分类误差减小,就停止生长。
- 叶子节点最小数据量限制:一个叶子节点的数据量过小,树停止生长。
(2)剪枝
约束树生长的缺点就是提前扼杀了其他可能性,过早地终止了树的生长,我们也可以等待树生长完成以后再进行剪枝,即所谓的后剪枝,而后剪枝算法主要有以下几种:
- Reduced-Error Pruning(REP,错误率降低剪枝)。
- Pesimistic-Error Pruning(PEP,悲观错误剪枝)。
- Cost-Complexity Pruning(CCP,代价复杂度剪枝)。
- Error-Based Pruning(EBP,基于错误的剪枝)。
3)正则化
对于回归树而言,在剪枝过程中我们会添加正则化项衡量。如下所示,考虑剪枝后得到的子树 { T a } \left {T_a \right } {Ta} ,其中 α \alpha α 是正则化项的系数。当固定住 α \alpha α 之后,最佳的 T a T_a Ta 就是使得下列式子值最小的子树。
∑ m = 1 ∣ T ∣ ∑ x i ∈ R m ( y i − y ~ R 2 ) 2 + α ∣ T ∣ \sum_{m=1}^{|T|} \sum_{x_{i} \in R_{m}}\left(y_{i}-\tilde{y}{R{2}}\right)^{2}+\alpha|T| m=1∑∣T∣xi∈Rm∑(yi−y~R2)2+α∣T∣
-
∣ T ∣ |T| ∣T∣ 是回归树叶子节点的个数。
-
α \alpha α 可以通过交叉验证去选择。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=975327190&page=12
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | GBDT 模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/193
声明:版权所有,转载请联系平台与作者并注明出处
1.GBDT 算法
GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学*器(树),并把多颗决策树的结果累加起来作为最终的预测输出。该算法将决策树与集成思想进行了有效的结合。

(本篇 GBDT 集成模型部分内容涉及到机器学*基础知识、决策树、回归树算法,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识 、决策树模型详解 及 回归树模型详解)。
1)Boosting 核心思想
Boosting 方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。

Bagging 与 Boosting 的串行训练方式不同,Bagging 方法在训练过程中,各基分类器之间无强依赖,可以进行并行训练。
2)GBDT 详解
GBDT 的原理很简单:
- 所有弱分类器的结果相加等于预测值。
- 每次都以当前预测为基准,下一个弱分类器去拟合误差函数对预测值的残差(预测值与真实值之间的误差)。
- GBDT 的弱分类器使用的是树模型。

如图是一个非常简单的帮助理解的示例,我们用 GBDT 去预测年龄:
- 第一个弱分类器(第一棵树)预测一个年龄(如 20 岁),计算发现误差有 10 岁;
- 第二棵树预测拟合残差,预测值 6,计算发现差距还有 4 岁;
- 第三棵树继续预测拟合残差,预测值 3,发现差距只有 1 岁了;
- 第四课树用 1 岁拟合剩下的残差,完成。
最终,四棵树的结论加起来,得到 30 岁这个标注答案(实际工程实现里,GBDT 是计算负梯度,用负梯度*似残差)。
(1)GBDT 与负梯度*似残差
回归任务下,GBDT 在每一轮的迭代时对每个样本都会有一个预测值,此时的损失函数为均方差损失函数:
l ( y i , y i ^ ) = 1 2 ( y i − y i ^ ) 2 l(y_{i}, \hat{y_{i}})=\frac{1}{2}(y_{i}-\hat{y_{i}})^{2} l(yi,yi)=21(yi−yi)2
损失函数的负梯度计算如下:
− [ ∂ l ( y i , y i ^ ) ∂ y i ^ ] = ( y i − y i ^ ) -[\frac{\partial l(y_{i}, \hat{y_{i}})}{\partial \hat{y_{i}}}]=(y_{i}-\hat{y_{i}}) −[∂yi∂l(yi,yi)]=(yi−yi^)

可以看出,当损失函数选用「均方误差损失」时,每一次拟合的值就是(真实值-预测值),即残差。
(2)GBDT 训练过程
我们来借助 1 个简单的例子理解一下 GBDT 的训练过程。假定训练集只有 4 个人 (A,B,C,D),他们的年龄分别是 (14,16,24,26)。其中,A、B 分别是高一和高三学生;C、D 分别是应届毕业生和工作两年的员工。
我们先看看用回归树来训练,得到的结果如下图所示:

接下来改用 GBDT 来训练。由于样本数据少,我们限定叶子节点最多为 2(即每棵树都只有一个分枝),并且限定树的棵树为 2。最终训练得到的结果如下图所示:

上图中的树很好理解:A、B 年龄较为相*,C、D 年龄较为相*,被分为左右两支,每支用平均年龄作为预测值。
-
我们计算残差(即「实际值」-「预测值」),所以 A 的残差 14-15=-1。
-
这里 A 的「预测值」是指前面所有树预测结果累加的和,在当前情形下前序只有一棵树,所以直接是 15,其他多树的复杂场景下需要累加计算作为 A 的预测值。

上图中的树就是残差学*的过程了:
-
把 A、B、C、D 的值换作残差-1、1、-1、1,再构建一棵树学*,这棵树只有两个值 1 和-1,直接分成两个节点:A、C 在左边,B、D 在右边。
-
这棵树学*残差,在我们当前这个简单的场景下,已经能保证预测值和实际值(上一轮残差)相等了。
-
我们把这棵树的预测值累加到第一棵树上的预测结果上,就能得到真实年龄,这个简单例子中每个人都完美匹配,得到了真实的预测值。

最终的预测过程是这样的:
- A:高一学生,购物较少,经常问学长问题,真实年龄 14 岁,预测年龄 A = 15 – 1 = 14
- B:高三学生,购物较少,经常被学弟提问,真实年龄 16 岁,预测年龄 B = 15 + 1 = 16
- C:应届毕业生,购物较多,经常问学长问题,真实年龄 24 岁,预测年龄 C = 25 – 1 = 24
- D:工作两年员工,购物较多,经常被学弟提问,真实年龄 26 岁,预测年龄 D = 25 + 1 = 26
综上,GBDT 需要将多棵树的得分累加得到最终的预测得分,且每轮迭代,都是在现有树的基础上,增加一棵新的树去拟合前面树的预测值与真实值之间的残差。
2.梯度提升 vs 梯度下降
下面我们来对比一下「梯度提升」与「梯度下降」。这两种迭代优化算法,都是在每 1 轮迭代中,利用损失函数负梯度方向的信息,更新当前模型,只不过:
-
梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新。
-
梯度提升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。
F = F t − 1 − ρ t ∇ F L ∣ F = F t − 1 F=F_{t-1}-\left.\rho_{t} \nabla_{F} L\right|{F=F{t-1}} F=Ft−1−ρt∇FL∣F=Ft−1
L = ∑ i l ( y i , F ( x i ) ) L=\sum_{i} l\left(y_{i}, F\left(x_{i}\right)\right) L=i∑l(yi,F(xi))
w t = w t − 1 − ρ t ∇ w L ∣ w = w t − 1 w_{t}=w_{t-1}-\left.\rho_{t} \nabla_{w} L\right|{w=w{t-1}} wt=wt−1−ρt∇wL∣w=wt−1
L = ∑ i l ( y i , f w ( w i ) ) L=\sum_{i} l\left(y_{i}, f_{w}\left(w_{i}\right)\right) L=i∑l(yi,fw(wi))

3.GBDT 优缺点
下面我们来总结一下 GBDT 模型的优缺点:

1)优点
-
预测阶段,因为每棵树的结构都已确定,可并行化计算,计算速度快。
-
适用稠密数据,泛化能力和表达能力都不错,数据科学竞赛榜首常见模型。
-
可解释性不错,鲁棒性亦可,能够自动发现特征间的高阶关系。
2)缺点
-
GBDT 在高维稀疏的数据集上,效率较差,且效果表现不如 SVM 或神经网络。
-
适合数值型特征,在 NLP 或文本特征上表现弱。
-
训练过程无法并行,工程加速只能体现在单颗树构建过程中。
4.随机森林 vs GBDT
对比 ShowMeAI 前面讲解的另外一个集成树模型算法随机森林,我们来看看 GBDT 和它的异同点。

1)相同点
-
都是集成模型,由多棵树组构成,最终的结果都是由多棵树一起决定。
-
RF 和 GBDT 在使用 CART 树时,可以是分类树或者回归树。
2)不同点
-
训练过程中,随机森林的树可以并行生成,而 GBDT 只能串行生成。
-
随机森林的结果是多数表决表决的,而 GBDT 则是多棵树累加之。
-
随机森林对异常值不敏感,而 GBDT 对异常值比较敏感。
-
随机森林降低模型的方差,而 GBDT 是降低模型的偏差。
5.Python 代码应用与模型可视化
下面是我们直接使用 python 机器学*工具库 sklearn 来对数据拟合和可视化的代码:
# 使用 Sklearn 调用 GBDT 模型拟合数据并可视化
import numpy as np
import pydotplus
from sklearn.ensemble import GradientBoostingRegressor
X = np.arange(1, 11).reshape(-1, 1)
y = np.array([5.16, 4.73, 5.95, 6.42, 6.88, 7.15, 8.95, 8.71, 9.50, 9.15])
gbdt = GradientBoostingRegressor(max_depth=4, criterion ='squared_error').fit(X, y)
from IPython.display import Image
from pydotplus import graph_from_dot_data
from sklearn.tree import export_graphviz
# 拟合训练 5 棵树
sub_tree = gbdt.estimators_[4, 0]
dot_data = export_graphviz(sub_tree, out_file=None, filled=True, rounded=True, special_characters=True, precision=2)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())

ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | XGBoost 模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/194
声明:版权所有,转载请联系平台与作者并注明出处
引言
XGBoost 是 eXtreme Gradient Boosting 的缩写称呼,它是一个非常强大的 Boosting 算法工具包,优秀的性能(效果与速度)让其在很长一段时间内霸屏数据科学比赛解决方案榜首,现在很多大厂的机器学*方案依旧会首选这个模型。
XGBoost 在并行计算效率、缺失值处理、控制过拟合、预测泛化能力上都变现非常优秀。本文我们给大家详细展开介绍 XGBoost,包含「算法原理」和「工程实现」两个方面。
关于 XGBoost 的工程应用实践,欢迎大家参考 ShowMeAI 的另外一篇实战文章 XGBoost 工具库建模应用详解。
(本篇 XGBoost 部分内容涉及到机器学*基础知识、决策树/回归树/GBDT 算法,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识 、决策树模型详解 、回归树模型详解)及图解机器学* | GBDT 模型详解)。
1.算法原理可视化解读
关于 XGBoost 的原理,其作者陈天奇本人有一个非常详尽的Slides做了系统性的介绍,我们在这里借助于这个资料给大家做展开讲解。
1)监督学*中的一些重要概念
在开始介绍 Boosted Tree 之前,我们先来回顾一下机器学*中的一些重要的概念。
(1)监督学*核心要素

符号(Notations): x i ∈ R d x_i \in R^d xi∈Rd 表示训练集中的第 i i i 个样本。
模型(Model):对于已知的 x i x_i xi如何预测 y ^ i \hat{y}_i y^i?
线性模型(Linear Model) y ^ i = Σ j w j x i j \hat{y}{i}=\Sigma w_{j} x_{ij} y^i=Σjwjxij(包括线性回归和逻辑回归),预测值 y ^ i \hat{y}_i y^i根据不同的任务有不同的解释:
-
线性回归(Linear Regression): y ^ i \hat{y}_i y^i表示预测的分数。
-
逻辑回归(Logistic Regression): 1 / ( 1 + e − y ^ i ) 1/(1+e^{-\hat{y}_i}) 1/(1+e−y^i)预测了实例为正的概率。
-
其他:例如在排名任务中 y ^ i \hat{y}_i y^i可以是排名分数。

参数(Parameters):需要从数据中学*的东西。
- 线性模型(Linear Model): Θ = { w j ∣ j = 1 , 2 , … , d } \Theta =\left{w_j|j=1,2,\dots,d\right} Θ=
目标函数(Objective function) O b j ( Θ ) = L ( Θ ) + Ω ( Θ ) Obj(\Theta )=L(\Theta )+\Omega (\Theta ) Obj(Θ)=L(Θ)+Ω(Θ)
-
L ( Θ ) L(\Theta ) L(Θ)代表训练损失函数(Training Loss),表示模型多好的拟合了训练数据。
-
Ω ( Θ ) \Omega (\Theta ) Ω(Θ)为正则化项(Regularization)衡量了模型的复杂程度。
训练数据损失函数(Training Loss) L = Σ i = 1 n l ( y i , y ^ i ) L=\Sigma_{i=1}^{n}l(y_i,\hat{y}_i) L=Σi=1nl(yi,y^i)
-
平方损失(Square Loss): l ( y i , y ^ i ) = ( y i − y ^ i ) 2 l(y_i,\hat{y}_i)=(y_i-\hat{y}_i)² l(yi,yi)=(yi−yi)2
-
逻辑损失(Logistic Loss): l ( y i , y ^ i ) = y i l n ( 1 + e − y ^ i ) + ( 1 − y i ) l n ( 1 + e y ^ i ) l(y_i,\hat{y}_i)=y_iln(1+e{-\hat{y}_i})+(1-y_i)ln(1+e_i}) l(yi,yi)=yiln(1+e−yi)+(1−yi)ln(1+ey^i)
正则化项(Regularization):描述了模型的复杂程度。
-
L1 Norm(lasso): Ω ( w ) = λ ∣ ∣ w ∣ ∣ 1 \Omega (w)=\lambda||w||_1 Ω(w)=λ∣∣w∣∣1
-
L2 Norm: Ω ( w ) = λ ∣ ∣ w ∣ ∣ 2 \Omega (w)=\lambda||w||² Ω(w)=λ∣∣w∣∣2
(2)监督学*进阶知识

Ridge 回归: Σ i = 1 n ( y i − w T x i ) 2 + λ ∣ ∣ w ∣ ∣ 2 \Sigma_{i=1}{n}(y_i-wTx_i)²+\lambda||w||² Σi=1n(yi−wTxi)2+λ∣∣w∣∣2
- Ridge 是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是 L2 Norm。
Lasso: Σ i = 1 n ( y i − w T x i ) 2 + λ ∣ ∣ w ∣ ∣ 1 \Sigma_{i=1}{n}(y_i-wTx_i)²+\lambda||w||_1 Σi=1n(yi−wTxi)2+λ∣∣w∣∣1
- Lasso 是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是 L1 Norm。
逻辑回归(Logistic Regression): Σ i = 1 n ( y i l n ( 1 + e − w T x i ) + ( 1 − y i ) l n ( 1 + e w T x i ) ) + λ ∣ ∣ w ∣ ∣ 2 \Sigma_{i=1}{n}(y_iln(1+e{-wTx_i})+(1-y_i)ln(1+e))+\lambda||w||² Σi=1n(yiln(1+e−wTxi)+(1−yi)ln(1+ewTxi))+λ∣∣w∣∣2
- 逻辑回归是线性模型(Linear Model),用的是逻辑损失(Logistic Loss),正则化项是 L2 Norm。
(3)目标函数及偏差方差权衡
回顾一下目标函数 O b j ( Θ ) = L ( Θ ) + Ω ( Θ ) Obj(\Theta )=L(\Theta )+\Omega (\Theta ) Obj(Θ)=L(Θ)+Ω(Θ),为什么目标函数需要两部分组成呢?

-
优化训练损失函数(Training Loss)有助于建立预测模型,很好地拟合训练数据至少能让你更接*潜在的训练数据的分布。
-
优化正则化项(Regularization)有助于建立简单的模型:模型越简单,未来预测的方差越小,预测越稳定。
2)回归树(Regression Tree)和集成(Ensemble)
(1)回归树(Regression Tree)
回归树,也就是分类回归树(Classification and Regression Tree)(详情请查看 ShowMeAI 文章回归树模型详解)
- 决策规则和决策树一样
- 每个叶子结点有一个值
(2)回归树集成(Regression Tree Ensemble)

从上图的左图可以看出,共有 5 个训练样本。
从上图的中图可以看出,每个叶子节点都有预测值:第一个叶子结点的预测值是 2,第二个叶子结点的预测值是 0.1,第三个叶子结点的预测值是-1。
- 小男孩被分到第一个叶子结点中,所以小男孩的预测值是 2;
- 小女儿被分到第二个叶子结点,她的预测值是 0.1;
- 剩余的三个人(样本)被分到第三个叶子结点中,他们的值都是-1。
最终的预测值就是样本在每颗树中所在的叶子结点的预测值的和。
(3)树集成方法
树集成的方法使用非常广泛,像 GBM、随机森林等(详见 ShowMeAI 文章 图解机器学* | GBDT 模型详解 和 图解机器学* | 随机森林分类模型详解)。多达半数的数据挖掘竞赛通过使用各种各样的树集成方法而获胜。
- 不受输入量纲的影响,因此不需要对特性进行细致的标准化。
- 学*特征之间的高阶交互(高阶交叉特征)。
- 可以扩展,用于不同的行业。
(4)Boosted Tree 的模型和参数

模型:假设我们有 K 棵树: y ^ i = Σ k = 1 K f k ( x i ) , f k ∈ F \hat{y}i=\Sigma^Kf_k(x_i), f_k\in F y^i=Σk=1Kfk(xi),fk∈F。其中,F 为包含所有回归树的函数空间。
- 回归树是一个将属性映射到分数的函数。
参数:包括每棵树的结构和叶子结点中的分数。或者使用函数当作参数: Θ = { f 1 , f 2 , … , f K } \Theta =\left{f_1,f_2,…,f_K\right} Θ={f1,f2,…,fK}。
- 这里我们不学* R d R^d Rd 的权重,我们在 Boosted Tree 中学*函数(树)。
(5)在单变量上学* Boosted Tree
单变量也就是单个特征,通过了解如何在单变量上学* Boosted Tree,我们可以对 Boosted Tree 的学*模式有个简单的概念。
举例:假设回归树只有一个输入变量 t(时间),希望预测小哥在 t 时刻有多喜欢浪漫音乐。

从上左图可以看到,这位小哥在单身的时候,对浪漫音乐的喜欢程度很低;但是当他遇到了女朋友,随着体内荷尔蒙的分布增加,他对浪漫音乐的喜欢程度增加了;但是有一天分手了,他对浪漫音乐的喜欢程度又变低了。当然,我们也可以发现,上右图的回归树很容易能表达上左图。
为了构建上右图的树,我们需要学*两个东西:
- 1、分裂的点;
- 2、每个分段上的高。

单变量回归树的目标(阶跃函数)
- 训练损失:函数如何拟合点?
- 正则化:如何定义函数的复杂度?(分裂点的个数和每段高度的 L2 Norm?)

- 图(1)是小哥在每个时间上对浪漫音乐的喜欢程度的散点图;
- 图(2)可以看到有太多的分割,模型的复杂度很高,所以模型的 Ω ( f ) { \Omega (f)} Ω(f)很高;
- 图(3)可以看到模型的拟合程度很差,所以 L ( f ) {L (f)} L(f)很高;
- 图(4)是最好的,无论是拟合程度和复杂程度都非常合适;
(6)一般情形的 Boosted Tree
首先回顾上面我们对 Boosted Tree 的定义:
模型:假设我们有 K 棵树: y ^ i = Σ k = 1 K f k ( x i ) , f k ∈ F \hat{y}i = \Sigma^{K} f_k(x_i), f_k\in F y^i=Σk=1Kfk(xi),fk∈F
目标函数: O b j = Σ i = 1 n l ( y i , y ^ i ) + Σ k = 1 K Ω ( f k ) Obj=\Sigma_{i=1}nl(y_i,\hat{y}_i)+\Sigma_{k=1}K\Omega (f_k) Obj=Σi=1nl(yi,y^i)+Σk=1KΩ(fk)
-
Σ i = 1 n l ( y i , y ^ i ) \Sigma_{i=1}^nl(y_i,\hat{y}_i) Σi=1nl(yi,y^i)是成本函数
-
Σ k = 1 K Ω ( f k ) \Sigma_{k=1}^K\Omega (f_k) Σk=1KΩ(fk)是正则化项,代表树的复杂程度,树越复杂正则化项的值越高(正则化项如何定义我们会在后面详细说)。
当我们讨论树的时候,通常是启发式的:

- 通过信息增益来做分裂
- 修剪树木
- 最大深度
- 平滑叶值
大多数启发式算法都能很好地映射到目标函数,采用形式(目标)视图让我们知道我们正在学*什么:

- 信息增益 → 训练损失
- 修剪 → 对节点的正则化
- 最大深度 - 函数空间上的约束
- 平滑叶片值 - L2 正则化对叶片的权重
回归树集成定义了如何得到预测值,它不仅仅可以做回归,同样还可以做分类和排序。具体做什么任务依赖于「目标函数」的定义:
-
使用平方误差:可以得到用于回归问题的 gradient boosted machine。
-
使用对数损失:可以得到 LogitBoost 用于分类。
3)Gradient Boosting(如何学*)
在这一节中我们将正式学* Gradient Boosting。这里,xgboost 的处理大家可以对比 GBDT 模型(可参考 ShowMeAI 文章 图解机器学* | GBDT 模型详解)来理解核心差异。
(1)解决方案
目标函数: O b j = Σ i = 1 n l ( y i , y ^ i ) + Σ k = 1 K Ω ( f k ) Obj=\Sigma_{i=1}nl(y_i,\hat{y}_i)+\Sigma_{k=1}K\Omega (f_k) Obj=Σi=1nl(yi,y^i)+Σk=1KΩ(fk)
在做 GBDT 的时候,我们没有办法使用 SGD,因为它们是树,而非数值向量——也就是说从原来我们熟悉的参数空间变成了函数空间。
-
参数空间:学*模型中的权重。
-
函数空间:学*函数 f f f,包括函数的结构和其中的权重。

解决方案:初始化一个预测值,每次迭代添加一个新函数( f f f):
y ^ i ( 0 ) = 0 y ^ i ( 1 ) = f 1 ( x i ) = y ^ i ( 0 ) + f 1 ( x i ) y ^ i ( 2 ) = f 1 ( x i ) + f 2 ( x i ) = y ^ i ( 1 ) + f 2 ( x i ) … y ^ i ( t ) = Σ k = 1 t f k ( x i ) = y ^ i ( t − 1 ) + f t ( x i ) \begin{aligned} \hat{y}_i^{(0)} & = 0 \ \hat{y}_i^{(1)} & = f_1(x_i)=\hat{y}_i^{(0)}+f_1(x_i) \ \hat{y}_i^{(2)} & = f_1(x_i)+f_2(x_i)=\hat{y}_i^{(1)}+f_2(x_i) \ \dots \ \hat{y}i^{(t)} & = \Sigmatf_k(x_i)=\hat{y}_i+f_t(x_i) \ \end{aligned} yi(0)yi(1)yi(2)…yi(t)=0=f1(xi)=yi(0)+f1(xi)=f1(xi)+f2(xi)=yi(1)+f2(xi)=Σk=1tfk(xi)=y^i(t−1)+ft(xi)
-
y ^ i ( t ) \hat{y}_i^{(t)} y^i(t)是第 t t t 次迭代的预测值。
-
y ^ i ( t − 1 ) \hat{y}_i^{(t-1)} y^i(t−1)是 t − 1 t-1 t−1 次迭代的预测值。
-
f t ( x i ) f_t(x_i) ft(xi)是第 t t t 颗树,也就是我们第 t t t 次迭代需要得到的树。
(2)目标函数变换
第一步:根据上面的公式,目标函数可以做如下变形
O b j ( t ) = Σ i = 1 n l ( y i , y ^ i ( t ) ) + Σ k = 1 t Ω ( f k ) = Σ i = 1 n l ( y i , y ^ i ( t − 1 ) + f t ( x i ) ) + Ω ( f t ) + c o n s t a n t \begin{aligned} Obj^{(t)} & =\Sigma_{i=1}nl(y_i,\hat{y}_i)+\Sigma_{k=1}^t\Omega (f_k)\ & =\Sigma_{i=1}nl(y_i,\hat{y}_i+f_t(x_i))+\Omega (f_t)+constant \end{aligned} Obj(t)=Σi=1nl(yi,yi(t))+Σk=1tΩ(fk)=Σi=1nl(yi,yi(t−1)+ft(xi))+Ω(ft)+constant
这里我们考虑平方损失,此时目标函数又可以变形为:
O b j ( t ) = Σ i = 1 n ( 2 ( y i − y ^ i ( t − 1 ) ) f t ( x i ) + f t ( x i ) 2 ) + Ω ( f t ) + c o n s t a n t Obj{(t)}=\Sigma_{i=1}n(2(y_i-\hat{y}_i^{(t-1)})f_t(x_i)+f_t(x_i)²)+\Omega (f_t)+constant Obj(t)=Σi=1n(2(yi−y^i(t−1))ft(xi)+ft(xi)2)+Ω(ft)+constant

第二步:所以我们的目的就是找到 f t f_t ft使得目标函数最低。然而,经过上面初次变形的目标函数仍然很复杂,目标函数会产生二次项。
在这里我们引入泰勒展开公式:
f ( x + Δ x ) ≃ f ( x ) + f ( x ) Δ x + 1 / 2 f ( x ) Δ x 2 f(x+\Delta x)\simeq f(x)+f(x)\Delta x+1/2f(x)\Delta x² f(x+Δx)≃f(x)+f(x)Δx+1/2f(x)Δx2
-
令 f ( x ) = Σ i = 1 n l ( y i , y ^ i ( t ) ) f(x)=\Sigma_{i=1}nl(y_i,\hat{y}_i) f(x)=Σi=1nl(yi,y^i(t))
-
令 Δ x = f t \Delta x=f_t Δx=ft
目标函数利用泰勒展开式就可以变成:
O b j ( t ) ≃ Σ i = 1 n ( l ( y i , y ^ i ( t − 1 ) ) + g i f t ( x i ) + 1 / 2 h i f t ( x i ) 2 ) + Ω ( f t ) + c o n s t a n t Obj^{(t)}\simeq \Sigma_{i=1}n(l(y_i,\hat{y}_i)+g_if_t(x_i)+1/2h_if_t(x_i)²)+\Omega (f_t)+constant Obj(t)≃Σi=1n(l(yi,y^i(t−1))+gift(xi)+1/2hift(xi)2)+Ω(ft)+constant
-
g i = ∂ y ^ ( t − 1 ) l ( y i , y ^ ( t − 1 ) ) g_i = \partial _{\hat{y}{(t-1)}}l(y_i,\hat{y}) gi=∂y(t−1)l(yi,y(t−1))
-
h i = ∂ y ^ ( t − 1 ) 2 l ( y i , y ^ ( t − 1 ) ) h_i = \partial _{\hat{y}{(t-1)}}²l(y_i,\hat{y}) hi=∂y(t−1)2l(yi,y(t−1))

第三部:把常数项提出来,目标函数可以简化为
O b j ( t ) ≃ Σ i = 1 n [ g i f t ( x i ) + 1 / 2 h i f t ( x i ) 2 ] + Ω ( f t ) + c o n s t a n t Obj^{(t)}\simeq \Sigma_{i=1}^n[g_if_t(x_i)+1/2h_if_t(x_i)²]+\Omega (f_t)+constant Obj(t)≃Σi=1n[gift(xi)+1/2hift(xi)2]+Ω(ft)+constant

思考:为什么要做这么多变化而不直接生成树?
-
理论好处:知道我们在学*什么,收敛。
-
工程好处:回顾监督学*的要素。
-
g i , h i g_i, h_i gi,hi都来自损失函数的定义。
-
函数的学*只通过 g i , h i g_i, h_i gi,hi依赖于目标函数。
-
当被要求为平方损失和逻辑损失实现 Bootsted Tree 时,可以考虑如何分离代码模块。
-
(3)重新定义树
在前面,我们使用 f t ( x ) f_t(x) ft(x)代表一颗树,在本小节,我们重新定义一下树:我们通过叶子结点中的分数向量和将实例映射到叶子结点的索引映射函数来定义树:(有点儿抽象,具体请看下图)
f t ( x ) = w q ( x ) , w ∈ R T , q : R d → { 1 , 2 , 3 , … , T } f_t(x)=w_q(x), w\in R^T, q:R^d\rightarrow \left{1,2,3,…,T\right} ft(x)=wq(x),w∈RT,q:Rd→{1,2,3,…,T}
-
w w w 代表树中叶子结点的权重
-
q q q 代表的是树的结构

从上图可以看出,共有 3 个叶子结点,第一个叶子结点的权重为+1,第二个叶子结点的权重为 0.1,第三个叶子结点的权重为-1;其中,小男孩属于第 1 个叶子结点,老奶奶属于第 3 个叶子结点。
(4)定义树的复杂程度
通过下面的式子定义树的复杂程度(定义并不是唯一的)
Ω ( f t ) = γ T + 1 2 λ Σ j = 1 T w j 2 \Omega (f_t)=\gamma T+\frac{1}{2}\lambda\Sigma_{j=1}^Tw_j² Ω(ft)=γT+21λΣj=1Twj2
-
γ T \gamma T γT 代表了叶子结点的个树
-
1 2 λ Σ j = 1 T w j 2 \frac{1}{2}\lambda\Sigma_{j=1}^Tw_j² 21λΣj=1Twj2叶子结点分数的 L2 Norm

(5)重新审视目标函数

定义在叶子结点 j j j 中的实例的集合为:
I j = { i ∣ q ( x i ) = j } I_j=\left{i|q(x_i)=j \right} Ij={i∣q(xi)=j}
根据每棵叶子重新定义目标函数:
O b j ( t ) ≃ Σ i = 1 n [ g i f t ( x i ) + 1 2 h i f t ( x i ) 2 ] + Ω ( f t ) + c o n s t a n t = Σ i = 1 n [ g i w q ( x i ) + 1 2 h i w q ( x i ) 2 ] + γ T + 1 2 λ Σ j = 1 T w j 2 + c o n s t a n t = Σ j = 1 T [ ( Σ i ϵ I j g i ) w j + 1 2 ( Σ i ϵ I j h i + λ ) w j 2 ] + γ T + c o n s t a n t \begin{aligned} Obj^{(t)}& \simeq \Sigma_{i=1}^n[g_if_t(x_i)+\frac{1}{2}h_if_t(x_i)²]+\Omega (f_t)+constant \ & = \Sigma_{i=1}^n[g_iw_q(x_i)+\frac{1}{2}h_iw_q(x_i)²]+\gamma T+\frac{1}{2}\lambda\Sigma_{j=1}^Tw_j²+constant \ & = \Sigma_{j=1}^T[(\Sigma_{i\epsilon I_j} g_i)w_j+\frac{1}{2}(\Sigma_{i\epsilon I_j} h_i+\lambda)w_j²]+\gamma T+constant \end{aligned} Obj(t)≃Σi=1n[gift(xi)+21hift(xi)2]+Ω(ft)+constant=Σi=1n[giwq(xi)+21hiwq(xi)2]+γT+21λΣj=1Twj2+constant=Σj=1T[(ΣiϵIjgi)wj+21(ΣiϵIjhi+λ)wj2]+γT+constant
- 上式是 T 个独立二次函数的和
(6)计算叶子结点的值
一些知识需要先了解。对于一元二次函数: G x + 1 2 H x 2 Gx+\frac{1}{2}Hx² Gx+21Hx2,我们很容易得到这个函数的最小值和最小值对应的 x x x。

-
最小值对应的 x x x 相当于求 G x + 1 2 H x 2 Gx+\frac{1}{2}Hx² Gx+21Hx2 的导数,使导数等于 0 时的值,即 G x + H x = 0 Gx+Hx=0 Gx+Hx=0,所以 x = − G / H x=-G/H x=−G/H。
-
当 x = − G / H x=-G/H x=−G/H,对应的 G x + 1 2 H x 2 Gx+\frac{1}{2}Hx² Gx+21Hx2 的值为: − 1 2 ∗ G 2 / H -\frac{1}{2}*G²/H −21∗G2/H
也就是:
a r g m i n x G x + 1 2 H x 2 = − G H , H > 0 m i n x G x + 1 2 H x 2 = − 1 2 G 2 H \begin{aligned} argmin_x Gx+\frac{1}{2}Hx² & =-\frac{G}{H}, H>0 \ min_x Gx+\frac{1}{2}Hx² & =-\frac{1}{2}\frac{G²}{H} \end{aligned} argminxGx+21Hx2minxGx+21Hx2=−HG,H>0=−21HG2
如何求叶子结点最优的值?接着继续变化目标函数:
-
定义 G j = Σ i ϵ I j g i G_j= \Sigma_{i\epsilon I_j}g_i Gj=ΣiϵIjgi
-
定义 H j = Σ i ϵ I j h i H_j = \Sigma_{i\epsilon I_j}h_i Hj=ΣiϵIjhi
O b j ( t ) = Σ j = 1 T [ ( Σ i ϵ I j g i ) w j + 1 2 ( Σ i ϵ I j h i + λ ) w j 2 ] + γ T + c o n s t a n t = Σ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T + c o n s t a n t \begin{aligned} Obj^{(t)}&= \Sigma_{j=1}^T[(\Sigma_{i\epsilon I_j} g_i)w_j+\frac{1}{2}(\Sigma_{i\epsilon I_j} h_i+\lambda)w_j²]+\gamma T+constant\ & = \Sigma_{j=1}^T[G_jw_j+\frac{1}{2}(H_j+\lambda)w_j²]+\gamma T+constant \end{aligned} Obj(t)=Σj=1T[(ΣiϵIjgi)wj+21(ΣiϵIjhi+λ)wj2]+γT+constant=Σj=1T[Gjwj+21(Hj+λ)wj2]+γT+constant

假设树的结构 q ( x ) q(x) q(x)是固定的,那么每一个叶子结点的权重的最优值为
w j ∗ = − G j / ( H j + λ ) w_j^*=-G_j/(H_j+\lambda) wj∗=−Gj/(Hj+λ)
目标函数的最优值为
O b j = − 1 2 Σ j = 1 T G j 2 H j + λ + γ T Obj=-\frac{1}{2}\Sigma_{j=1}^T\frac{G_j²}{H_j+\lambda}+\gamma T Obj=−21Σj=1THj+λGj2+γT
下图是前面公式讲解对应的一个实际例子。

这里再次总结一下,我们已经把目标函数变成了仅与 G 、 H 、 γ 、 λ 、 T G、H、\gamma、\lambda、T G、H、γ、λ、T 这五项已知参数有关的函数,把之前的变量 f t f_{t} ft消灭掉了,也就不需要对每一个叶子进行打分了!
那么现在问题来,刚才我们提到,以上这些是假设树结构确定的情况下得到的结果。但是树的结构有好多种,我们应该如何确定呢?
(7)贪婪算法生成树
上一部分中我们假定树的结构是固定的。但是,树的结构其实是有无限种可能的,本小节我们使用贪婪算法生成树:
-
首先生成一个深度为 0 的树(只有一个根结点,也叫叶子结点)
-
对于每棵树的每个叶子结点,尝试去做分裂(生成两个新的叶子结点,原来的叶子结点不再是叶子结点)。在增加了分裂后的目标函数前后变化为(我们希望增加了树之后的目标函数小于之前的目标函数,所以用之前的目标函数减去之后的目标函数):
G a i n = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ Gain=\frac{1}{2}(\frac{G_L²}{H_L+\lambda}+\frac{G_R²}{H_R+\lambda}-\frac{(G_L+G_R)²}{H_L+H_R+\lambda})-\gamma Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ
-
G L 2 H L + λ \frac{G_L²}{H_L+\lambda} HL+λGL2是左面叶子结点的值
-
G R 2 H R + λ \frac{G_R²}{H_R+\lambda} HR+λGR2是右面叶子结点的值
-
( G L + G R ) 2 H L + H R + λ \frac{(G_L+G_R)²}{H_L+H_R+\lambda} HL+HR+λ(GL+GR)2是未分裂前的值
-
γ \gamma γ是引入了多一个的叶子结点增加的复杂度
接下来要考虑的是如何寻找最佳分裂点。
例如,如果 x j x_j xj 是年龄,当分裂点是 a a a 的时候的增益 G a i n Gain Gain 是多少?
我们需要做的仅仅只是计算每一边的 g g g 和 h h h,然后计算
G a i n = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ Gain=\frac{1}{2}(\frac{G_L²}{H_L+\lambda}+\frac{G_R²}{H_R+\lambda}-\frac{(G_L+G_R)²}{H_L+H_R+\lambda})-\gamma Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ

对排序后的实例进行从左到右的线性扫描就足以决定特征的最佳分裂点。
所以,分裂一个结点的方法是:

- 对于每个节点,枚举所有特性
- 对于每个特性,按特性值对实例排序
- 使用线性扫描来决定该特征的最佳分裂点
- 采用所有特征中最好的分裂方案
时间复杂度:
-
对于一个有 d 个特征,深度为 K 的树,计算的时间复杂度为:O(dKnlog n)。其中每一层需要花费 O(nlog n)的时间做排序。
-
可以进一步优化(例如使用*似或缓存排序的特性)。
-
可以扩展到非常大的数据集。
(8)如何处理分类型变量
一些树学*算法分别处理分类变量和连续变量,我们可以很容易地使用我们推导出的基于分类变量的评分公式。但事实上,我们没有必要单独处理分类变量:
我们可以使用 one-hot 方式处理分类变量:
z j = { 1 if x is in category j 0 otherwise z_{j}=\left{\begin{array}{ll} 1 & \text { if } x \text { is in category } j \ 0 & \text { otherwise } \end{array}\right. zj={10 if x is in category j otherwise
如果有太多的分类的话,矩阵会非常稀疏,算法会优先处理稀疏数据。
(9)修剪和正则化
回顾之前的增益,当训练损失减少的值小于正则化带来的复杂度时,增益有可能会是负数:
G a i n = 1 2 ( G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ) − γ Gain=\frac{1}{2}(\frac{G_L²}{H_L+\lambda}+\frac{G_R²}{H_R+\lambda}-\frac{(G_L+G_R)²}{H_L+H_R+\lambda})-\gamma Gain=21(HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2)−γ

此时就是模型的简单性和可预测性之间的权衡。
-
前停止(Pre-stopping):当最佳分裂是负数时,停止分裂;但是一个分裂可能会对未来的分裂有益;
-
后剪枝(Post-Pruning):把一颗树生长到最大深度,递归修剪所有分裂为负增益的叶子。
2.XGBoost 核心原理归纳解析
1)目标函数与泰勒展开
XGBoost 也是一个 Boosting 加法模型,每一步迭代只优化当前步中的子模型。
第 m m m 步我们有:
F m ( x i ) = F m − 1 ( x i ) + f m ( x i ) F_m(x_i) = F_{m-1}(x_i) + f_m(x_i) Fm(xi)=Fm−1(xi)+fm(xi)
-
f m ( x i ) f_m(x_i) fm(xi)为当前步的子模型。
-
F m − 1 ( x i ) F_{m-1}(x_i) Fm−1(xi)为前 m − 1 m-1 m−1 个完成训练且固定了的子模型。
目标函数设计为「经验风险」+「结构风险」(正则项):
O b j = ∑ i = 1 N L [ F m ( x i ) , y i ] + ∑ j = 1 m Ω ( f j ) = ∑ i = 1 N L [ F m − 1 ( x i ) + f m ( x i ) , y i ] + ∑ j = 1 m Ω ( f j ) \begin{aligned} O b j &=\sum_{i=1}^{N} L\left[F_{m}\left(x_{i}\right), y_{i}\right]+\sum_{j=1}^{m} \Omega\left(f_{j}\right) \ &=\sum_{i=1}^{N} L\left[F_{m-1}\left(x_{i}\right)+f_{m}\left(x_{i}\right), y_{i}\right]+\sum_{j=1}^{m} \Omega\left(f_{j}\right) \end{aligned} Obj=i=1∑NL[Fm(xi),yi]+j=1∑mΩ(fj)=i=1∑NL[Fm−1(xi)+fm(xi),yi]+j=1∑mΩ(fj)
- 正则项 Ω ( f ) \Omega (f) Ω(f)表示子模型 f f f 的复杂度,用于控制过拟合。

在数学中,我们可以用泰勒公式*似 f ( x ) f(x) f(x),具体如下式。XGBoost 对损失函数运用二阶展开来*似。
f ( x 0 + Δ x ) ≈ f ( x 0 ) + f ′ ( x 0 ) Δ x + f ′ ′ ( x 0 ) 2 ( Δ x ) 2 f(x_0+\Delta x) \approx f(x_0)+f^{'}(x_0) \Delta x + \frac{f^{''}(x_0)}{2} (\Delta x)² f(x0+Δx)≈f(x0)+f′(x0)Δx+2f′′(x0)(Δx)2
(更多数学知识推荐阅读 ShowMeAI 的 AI 数学基础系列教程 图解 AI 数学基础:从入门到精通系列教程)。
对应 XGBoost 的损失函数,我们在上式里将 F m − 1 ( x i ) F_{m-1}(x_i) Fm−1(xi)视作 x 0 x_0 x0, f m ( x i ) f_{m}(x_i) fm(xi)视作 Δ x \Delta x Δx, L ( y i ^ , y i ) L(\hat{y_i},y_i) L(yi^,yi)视作关于 y i ^ \hat{y_i} yi^的函数,得到:
O b j = ∑ i = 1 N [ L [ F m − 1 ( x i ) , y i ] + ∂ L ∂ F m − 1 ( x i ) f m ( x i ) + 1 2 ∂ 2 L ∂ 2 F m − 1 ( x i ) f m 2 ( x i ) ] + ∑ j = 1 m Ω ( f j ) Obj = \sum_{i=1}^N \Big[ L[F_{m-1}(x_i),y_i] + \frac{\partial L}{\partial F_{m-1}(x_i)} f_m(x_i) + \frac{1}{2} \frac{\partial² L}{\partial² F_{m-1}(x_i)} f_m²(x_i) \Big] +\sum_{j=1}^m \Omega (f_j) Obj=i=1∑N[L[Fm−1(xi),yi]+∂Fm−1(xi)∂Lfm(xi)+21∂2Fm−1(xi)∂2Lfm2(xi)]+j=1∑mΩ(fj)

又因前 m − 1 m-1 m−1 个子模型已经确定了,故上式中除了关于 f m ( x ) f_{m} (x) fm(x)的部分都是常数,不影响对 f m ( x ) f_{m} (x) fm(x)的优化求解。目标函数可转化为:
O b j = ∑ i = 1 N [ g i f m ( x i ) + 1 2 h i f m 2 ( x i ) ] + Ω ( f m ) O b j=\sum_{i=1}^{N}\left[g_{i} f_{m}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{m}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{m}\right) Obj=i=1∑N[gifm(xi)+21hifm2(xi)]+Ω(fm)
-
g i = ∂ L ∂ F m − 1 ( x i ) g_i = \frac{\partial L}{\partial F_{m-1}(x_i)} gi=∂Fm−1(xi)∂L
-
h i = ∂ 2 L ∂ 2 F m − 1 ( x i ) h_i = \frac{\partial² L}{\partial² F_{m-1}(x_i)} hi=∂2Fm−1(xi)∂2L
-
这里的 L L L 代表损失函数,衡量一次预测的好坏程度
-
在 F m − 1 ( x ) F_{m-1}(x) Fm−1(x)确定了的情况下,对每个样本点 i i i 都可以轻易计算出一个 g i g_i gi和 h i h_i hi
2)XGBoost 的正则化
实际上,XGBoost 的基分类器对决策树和线性模型都支持,这里我们只讨论更常见的「基于树」的情况。为防止过拟合,XGBoost 设置了基于树的复杂度作为正则项:
Ω ( f ) = γ T + 1 2 λ ∣ ∣ w ∣ ∣ 2 \Omega(f) = \gamma T + \frac{1}{2} \lambda ||w||² Ω(f)=γT+21λ∣∣w∣∣2
-
T T T 为树 f f f 的叶节点个数
-
w w w 为所有叶节点输出回归值构成的向量, ∣ ∣ w ∣ ∣ 2 ||w||² ∣∣w∣∣2 为该向量 L2 范数(模长)的平方
-
γ \gamma γ、 λ \lambda λ为超参数
作为回归树,叶子节点越多、输出的回归值越大,树的复杂度越高。
最终目标函数如下:
O b j = ∑ i = 1 N [ g i f m ( x i ) + 1 2 h i f m 2 ( x i ) ] + γ T + 1 2 λ ∑ j = 1 T w j 2 Obj = \sum_{i=1}^N \Big[g_i f_m(x_i)+\frac{1}{2} h_i f_m²(x_i)\Big]+\gamma T + \frac{1}{2} \lambda \sum_{j=1}^T w_j² Obj=i=1∑N[gifm(xi)+21hifm2(xi)]+γT+21λj=1∑Twj2

下面是一个数学转换处理,为了使正则项和经验风险项合并到一起。我们把在样本层面上求和的经验风险项,转换为叶节点层面上的求和。
定义节点 j j j 上的样本集为 I ( j ) = { x i ∣ q ( x i ) = j } I(j)={x_i|q(x_i)=j} I(j)={xi∣q(xi)=j},其中 q ( x i ) q(x_i) q(xi)为将样本映射到叶节点上的索引函数,叶节点 j j j 上的回归值为 w j = f m ( x i ) , i ∈ I ( j ) w_j=f_m(x_i),i \in I(j) wj=fm(xi),i∈I(j)。
O b j = ∑ j = 1 T [ ( ∑ i ∈ I ( j ) g i ) w j + 1 2 ( ∑ i ∈ I ( j ) h i + λ ) w j 2 ] + γ T Obj = \sum_{j=1}^{T} \Big[ (\sum_{i\in I(j)} g_i) w_j + \frac{1}{2}(\sum_{i\in I(j)} h_i + \lambda) w_j² \Big] + \gamma T Obj=j=1∑T[(i∈I(j)∑gi)wj+21(i∈I(j)∑hi+λ)wj2]+γT
进一步简化表达,令 ∑ i ∈ I ( j ) g i = G j \sum_{i\in I(j)} g_i=G_j ∑i∈I(j)gi=Gj, ∑ i ∈ I ( j ) h i = H j \sum_{i\in I(j)} h_i=H_j ∑i∈I(j)hi=Hj注意这里 G 和 H 都是关于 j j j 的函数:
O b j = ∑ j = 1 T [ G j w j + 1 2 ( H j + λ ) w j 2 ] + γ T Obj = \sum_{j=1}^{T} \Big[ G_j w_j + \frac{1}{2}(H_j + \lambda) w_j² \Big] + \gamma T Obj=j=1∑T[Gjwj+21(Hj+λ)wj2]+γT

转化到这个形式后,我们可以看出,若一棵树的结构已经确定,则各个节点内的样本 ( x i , y i , g i , h i ) (x_i,y_i,g_i,h_i) (xi,yi,gi,hi)也是确定的,即 G j G_j Gj, H j H_j Hj、 T T T 被确定,每个叶节点输出的回归值应该使得上式最小,由二次函数极值点:
w j ∗ = − G j H j + λ w_j^*=-\frac{G_j}{H_j+\lambda} wj∗=−Hj+λGj

按此规则输出回归值后,目标函数值也就是树的评分如下公式,其值越小代表树的结构越好。观察下式,树的评分也可以理解成所有叶节点的评分之和:
O b j ∗ = ∑ j = 1 T ( − 1 2 G j 2 H j + λ + γ ) Obj^* = \sum_{j=1}^T \Big( -\frac{1}{2}\frac{G_j²}{H_j + \lambda} + \gamma \Big) Obj∗=j=1∑T(−21Hj+λGj2+γ)
3)节点分裂准则
我们之前文章【决策树模型详解】里给大家讲到了决策树模型是递归生长形成的,而 XGBoost 的子模型树也一样,需要要依赖节点递归分裂的贪心准则来实现树的生成。
我们之前文章决策树模型详解里给大家讲到了决策树模型是递归生长形成的,而 XGBoost 的子模型树也一样,需要要依赖节点递归分裂的贪心准则来实现树的生成。
(1)贪心准则
XGBoost 子树的基本处理思路和 CART 一样,会对特征值排序后遍历划分点,将其中最优的分裂收益作为该特征的分裂收益,选取具有最优分裂收益的特征作为当前节点的划分特征,按其最优划分点进行二叉划分,得到左右子树。

上图是一次节点分裂过程,很自然地,分裂收益是树 A 的评分减去树 B 的评分。虚线框外的叶节点,即非分裂节点的评分均被抵消,只留下分裂后的 LR 节点和分裂前的 S 节点进行比较,因此分裂收益的表达式为:
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ ] − γ Gain = \frac{1}{2} \Big[ \frac{G_L²}{H_L+\lambda} + \frac{G_R²}{H_R+\lambda} -\frac{(G_L+G_R)²}{H_L+H_R+\lambda}\Big]-\gamma Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2]−γ
(2)*似算法
基于性能的考量,XGBoost 还对贪心准则做了一个*似版本,简单说,处理方式是「将特征分位数作为划分候选点」。这样将划分候选点集合由全样本间的遍历缩减到了几个分位数之间的遍历。
展开来看,特征分位数的选取还有 global 和 local 两种可选策略:
-
global 在全体样本上的特征值中选取,在根节点分裂之前进行一次即可;
-
local 则是在待分裂节点包含的样本特征值上选取,每个节点分裂前都要进行。
这两种情况里,由于 global 只能划分一次,其划分粒度需要更细。
XGB 原始 paper 中对 Higgs Boson 数据集进行了实验,比较了精确贪心准则、global *似和 local *似三类配置的测试集 AUC,用 eps 代表取分位点的粒度,如 e p s = 0.25 eps=0.25 eps=0.25 代表将数据集划分为 1/0.25=4 个 buckets,发现 global(eps=0.05)和 local(eps=0.3)均能达到和精确贪心准则几乎相同的性能。
XGBoost 工具包支持上述提到的 3 类配置。
(3)加权分位数
查看目标函数 O b j = ∑ i = 1 N [ g i f m ( x i ) + 1 2 h i f m 2 ( x i ) ] + Ω ( f m ) Obj=\sum_{i=1}^{N}\left[g_{i} f_{m}\left(x_{i}\right)+\frac{1}{2} h_{i} f_{m}^{2}\left(x_{i}\right)\right]+\Omega\left(f_{m}\right) Obj=∑i=1N[gifm(xi)+21hifm2(xi)]+Ω(fm),令偏导为 0 易得 f m ∗ ( x i ) = − g i h i f_m^*(x_i)=-\frac{g_i}{h_i} fm∗(xi)=−higi,此目标函数可理解为以 h i h_i hi为权重, − g i h i -\frac{g_i}{h_i} −higi为标签的二次损失函数:
O b j = ∑ i = 1 N [ g i f m ( x i ) + 1 2 h i f m 2 ( x i ) ] + Ω ( f m ) = ∑ i = 1 N 1 2 h i [ f m ( x i ) − ( − g i h i ) ] 2 + Ω ( f m ) + C \begin{aligned} Obj &= \sum_{i=1}^N \Big[g_i f_m(x_i)+\frac{1}{2} h_i f_m²(x_i)\Big]+\Omega (f_m) \ & = \sum_{i=1}^N \frac{1}{2} h_i\Big[ f_m(x_i)-(-\frac{g_i}{h_i}) \Big]²+\Omega (f_m) + C \end{aligned} Obj=i=1∑N[gifm(xi)+21hifm2(xi)]+Ω(fm)=i=1∑N21hi[fm(xi)−(−higi)]2+Ω(fm)+C
在*似算法取分位数时,实际上 XGBoost 会取以二阶导 h i h_i hi为权重的分位数(Weighted Quantile Sketch),如下图表示的三分位。

4)列采样与学*率
XGBoost 为了进一步优化效果,在以下 2 个方面进行了进一步设计:
-
列采样
- 和随机森林做法一致,每次节点分裂并不是用全部特征作为候选集,而是一个子集。
- 这么做能更好地控制过拟合,还能减少计算开销。
-
学*率
- 也叫步长、shrinkage,具体的操作是在每个子模型前(即每个叶节点的回归值上)乘上该系数,不让单颗树太激进地拟合,留有一定空间,使迭代更稳定。XGBoost 默认设定为 0.3。
5)特征缺失与稀疏性
XGBoost 也能对缺失值处理,也对特征稀疏问题(特征中出现大量的 0 或 one-hot encoding 结果)做了一些优化。XGBoost 用「稀疏感知」策略来同时处理这两个问题:
- 简单说,它的做法是将缺失值和稀疏 0 值等同视作缺失值,将其「绑定」在一起,分裂节点的遍历会跳过缺失值的整体。这样大大提高了运算效率。
0 值在 XGB 中被处理为数值意义上的 0 还是 NA,需要结合具体平台的设置,预处理区分开作为数值的 0(不应该被处理为 NA)和作为稀疏值的 0(应该被处理为 NA)。

依然通过遍历得到分裂节点,NA 的方向有两种情况,在此基础上对非缺失值进行切分遍历。
如上图所示,若某个特征值取值为 1,2,5 和大量的 NA,XGBoost 会遍历以上 6 种情况(3 个非缺失值的切分点×缺失值的两个方向),最大的分裂收益就是本特征上的分裂收益,同时,NA 将被分到右节点。
3.XGBoost 工程优化
1)并行列块设计
XGBoost 将每一列特征提前进行排序,以块(Block)的形式储存在缓存中,并以索引将特征值和梯度统计量对应起来,每次节点分裂时会重复调用排好序的块。而且不同特征会分布在独立的块中,因此可以进行分布式或多线程的计算。

2)缓存访问优化
特征值排序后通过索引来取梯度 g i , h i g_i,h_i gi,hi会导致访问的内存空间不一致,进而降低缓存的命中率,影响算法效率。为解决这个问题,XGBoost 为每个线程分配一个单独的连续缓存区,用来存放梯度信息。
3)核外块计算
数据量非常大的情形下,无法同时全部载入内存。XGBoost 将数据分为多个 blocks 储存在硬盘中,使用一个独立的线程专门从磁盘中读取数据到内存中,实现计算和读取数据的同时进行。
为了进一步提高磁盘读取数据性能,XGBoost 还使用了两种方法:
-
① 压缩 block,用解压缩的开销换取磁盘读取的开销。
-
② 将 block 分散储存在多个磁盘中,提高磁盘吞吐量。
4.XGBoost vs GBDT
我们对之前讲解过的 GBDT(参考 ShowMeAI 文章【GBDT 算法详解】)和这里的 XGBoost 做一个对比总结:

-
GBDT 是机器学*算法,XGBoost 在算法基础上还有一些工程实现方面的优化。
-
GBDT 使用的是损失函数一阶导数,相当于函数空间中的梯度下降;XGBoost 还使用了损失函数二阶导数,相当于函数空间中的牛顿法。
-
正则化:XGBoost 显式地加入了正则项来控制模型的复杂度,能有效防止过拟合。
-
列采样:XGBoost 采用了随机森林中的做法,每次节点分裂前进行列随机采样。
-
缺失值:XGBoost 运用稀疏感知策略处理缺失值,GBDT 无缺失值处理策略。
-
并行高效:XGBoost 的列块设计能有效支持并行运算,效率更优。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | LightGBM 模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/195
声明:版权所有,转载请联系平台与作者并注明出处
引言
之前 ShowMeAI 对强大的 boosting 模型工具 XGBoost 做了介绍(详见 ShowMeAI 文章图解机器学* | XGBoost 模型详解)。本篇我们来学*一下 GBDT 模型(详见 ShowMeAI 文章 图解机器学* | GBDT 模型详解)的另一个进化版本:LightGBM。
LightGBM 是微软开发的 boosting 集成模型,和 XGBoost 一样是对 GBDT 的优化和高效实现,原理有一些相似之处,但它很多方面比 XGBoost 有着更为优秀的表现。官方给出的这个工具库模型的优势如下:
- 更快的训练效率
- 低内存使用
- 更高的准确率
- 支持并行化学*
- 可处理大规模数据
- 支持直接使用 category 特征
下图是一组实验数据,在这份实验中,LightGBM 比 XGBoost 快将* 10 倍,内存占用率大约为 XGBoost 的 1/6,准确率也略有提升。

1.LightGBM 动机
互联网领域的算法应用,通常背后都有海量的大数据。深度学*中一系列神经网络算法,都是以 mini-batch 的方式喂数据迭代训练的,总训练数据量不受内存限制。
但我们用到的机器学*算法,比如 GBDT(参考 ShowMeAI 文章 GBDT 详解)在每一次迭代的时候,都需要遍历整个训练数据多次。
- 如果把整个训练数据一次性装进内存,会明显限制训练数据的大小。
- 如果不装进内存,反复地读写训练数据又会消耗非常大的时间。
面对工业级海量的数据,普通的 GBDT 算法无法满足需求。LightGBM 提出的主要原因之一,就是为了解决上述大数据量级下的 GBDT 训练问题,以便工业实践中能支撑大数据量并保证效率。
2.XGBoost 优缺点
我们之前介绍过强大的 XGBoost(详见 ShowMeAI 文章图解机器学* | XGBoost 模型详解),但 XGBoost 也依旧存在一些缺点,LightGBM 针对其中的一部分进行了调整优化。XGB 优缺点归纳如下:
1)精确贪心算法
轮迭代时,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。
G a i n = 1 2 [ G L 2 H L + λ + G R 2 H R + λ − ( G L + G R ) 2 H L + H R + λ − γ ] Gain=\frac{1}{2}\left [ \frac{G_{L}^{2}}{H_{L}+\lambda} + \frac{G_{R}^{2}}{H_{R}+\lambda} - \frac{\left(G_{L}+G_{R}\right)^{2}}{H_{L}+H_{R}+\lambda} - \gamma \right ] Gain=21[HL+λGL2+HR+λGR2−HL+HR+λ(GL+GR)2−γ]

- 优点:可以找到精确的划分条件。
- 缺点:计算量巨大、内存占用巨大、易产生过拟合。
2)Level-wise 生长方式
XGBoost 采用 Level-wise 的增长策略:基于层进行生长,直到达到停止条件。这种增长策略方便并行计算每一层的分裂节点,提高了训练速度,但同时也因为节点增益过小增加了很多不必要的分裂,增加了计算量。

- 优点:可以使用多线程、可以加速精确贪心算法。
- 缺点:效率低下,可能产生不必要的叶结点。
3)对 cache 优化不友好
在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对 cache 进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的 cache miss。
3.LightGBM 优化点
上个部分其实也是 LightGBM 作者们,构建新算法时着重优化的点。概括来说,LightGBM 主要有以下特点:

- 基于 Histogram 的决策树算法
- 带深度限制的 Leaf-wise 的叶子生长策略
- 直方图做差加速
- 直接支持类别特征(Categorical Feature)
- Cache 命中率优化
- 基于直方图的稀疏特征优化
- 多线程优化
4.决策树算法
1)XGBoost:Pre-sorted 算法
XGBoost 使用的是 Pre-sorted 算法,能够更精确的找到数据分隔点。
- 首先,对所有特征按数值进行预排序。
- 其次,在每次的样本分割时,用 O(#data)的代价找到每个特征的最优分割点。
- 最后,找到最后的特征以及分割点,将数据分裂成左右两个子节点。
这种 pre-sorting 算法能够准确找到分裂点,但是在空间和时间上有很大的开销。
- 由于需要对特征进行预排序并且需要保存排序后的索引值(为了后续快速的计算分裂点),因此内存需要训练数据的两倍。
- 在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。
2)LightGBM:直方图算法
LightGBM 使用的是直方图算法(histogram algorithm),占用的内存更低,数据分割的复杂度更低。直方图算法思想是:

- 将连续的浮点特征离散成 k 个离散值,并构造宽度为 k 的 Histogram。
- 遍历训练数据,统计每个离散值在直方图中的累计统计量。
- 在进行特征选择时,只需要根据直方图的离散值,遍历寻找最优的分割点。
(1)内存优化
直方图算法可以很大程度降低内存消耗,它不仅不需要额外存储预排序的结果,还可以只保存特征离散化后的值(一般用 8 位整型存储就足够了)。

如图所示,用 8 位整型存储,内存消耗可以降低为原来的 1/8。
(2)计算量优化
应用直方图算法,计算代价也大幅降低,预排序算法每遍历一个特征值就需要计算一次分裂的增益,而直方图算法只需要计算 k 次(k 可以认为是常数),时间复杂度从 O(#data#feature)直接优化到 O(k#features)。
(3)注意点
直方图算法的理解和注意点如下:

-
使用分桶 bin 替代原始数据相当于增加了正则化。
-
使用分桶 bin 意味着很多数据的细节特征丢失,相似的数据如果划分到相同的桶中,数据之间的差异就无法捕获了。
-
分桶 bin 数量决定了正则化的程度,bin 越少惩罚越严重,欠拟合风险越高。
-
因为预先设定了 bin 的范围,构建直方图时不需要对数据进行排序。
-
直方图保存「划分阈值」、「当前 bin 内样本数」、「当前 bin 内所有样本的一阶梯度和」。
-
阈值的选取是按照直方图从小到大遍历,使用了上面的一阶梯度和,目的是得到划分之后△loss 最大的特征及阈值。
(4)直方图算法优缺点
-
Histogram 算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产生影响。但在实际的数据集上表明,离散化的分裂点对最终的精度影响并不大,甚至会好一些。原因在于 decision tree 本身就是一个弱学*器,采用 Histogram 算法会起到正则化的效果,有效地防止模型的过拟合。
-
时间上的开销由原来的 O(#data#features)降到 O(k#features)。由于离散化,#bin 远小于#data,因此时间上有很大的提升。
Histogram 算法还可以进一步加速。一个叶子节点的 Histogram 可以直接由父节点的 Histogram 和兄弟节点的 Histogram 做差得到。一般情况下,构造 Histogram 需要遍历该叶子上的所有数据,通过该方法,只需要遍历 Histogram 的 k 个捅。速度提升了一倍。
5.决策树生长策略
1)树生长策略调整
直方图算法之上,LightGBM 进行进一步的优化。它没有使用大多数 GBDT 工具使用的按层生长(Level-wise)的决策树生长策略,而使用了带有深度限制的按叶子生长(Leaf-wise)算法。
( p m , f m , v m ) = arg min ( p , f , v ) L ( T m − 1 ( X ) . split ( p , f , v ) , Y ) \left(p_{m}, f_{m}, v_{m}\right)=\arg \min {(p, f, v)} L\left(T(X) . \operatorname{split}(p, f, v), Y\right) (pm,fm,vm)=arg(p,f,v)minL(Tm−1(X).split(p,f,v),Y)
T m ( X ) = T m − 1 ( X ) . split ( p m , f m , v m ) T_{m}(X)=T_{m-1}(X) . \operatorname{split}\left(p_{m}, f_{m}, v_{m}\right) Tm(X)=Tm−1(X).split(pm,fm,vm)

2)XGBoost:Level-wise
XGBoost 采用的是 Level-wise(按层生长)策略生长的,能够同时分裂同一层的叶子,从而进行多线程优化,不容易过拟合。
但不加区分的对待同一层的叶子,带来了很多没必要的开销。因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。
3)LightGBM:Leaf-wise
LightGBM 采用 Leaf-wise(按叶子生长)生长策略,每次从当前所有叶子中找到分裂增益最大(一般也是数据量最大)的一个叶子,然后分裂,如此循环。

同 Level-wise 相比,在分裂次数相同的情况下,Leaf-wise 可以降低更多的误差,得到更好的精度。Leaf-wise 的缺点是可能会长出比较深的决策树,产生过拟合。因此 LightGBM 在 Leaf-wise 之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。
6.直方图差加速
LightGBM 另一个优化是 Histogram(直方图)做差加速。整个构建过程中可以观察到:一个叶子的直方图可以由它的父亲节点的直方图与它兄弟的直方图做差得到。

一般来说构造直方图,需要遍历该叶子上的所有数据,但直方图做差仅需遍历直方图的 k 个桶。利用上述特征,LightGBM 可以在构造一个叶子的直方图后,可以用非常微小的代价得到它兄弟叶子的直方图,在速度上可以提升一倍。
7.类别型特征支持
大多数机器学*工具都无法直接支持类别型特征,我们会先将其编码再做后续建模,如果使用 one-hot 这种编码方式还会降低空间和时间效率。
LightGBM 优化了对类别型特征的支持,可以直接输入类别特征,不需要额外的编码或 one-hot 0/1 展开。并在决策树算法上增加了类别型特征的决策规则。
1)树模型与 one-hot 编码
one-hot 编码是处理类别特征的一个通用方法,然而在树模型中,这可能并不一定是一个好的方法,尤其当类别特征中类别个数很多的情况下,主要的问题是:
问题 1:可能无法在这个类别特征上进行切分。
使用 one-hot 编码的话,意味着在每一个决策节点上只能使用 one vs rest(例如是不是男性,是不是一线城市等)的切分方式。当类别值很多时,每个类别上的数据可能会比较少,这时候切分会产生不平衡,这意味着切分增益也会很小。
问题 2:影响决策树的学*。
就算可以在这个类别特征进行切分,也会把数据切分到很多零碎的小空间上,如下左图所示。而决策树学*时利用的是统计信息,在这些数据量小的空间上,统计信息不准确,学*会变差。但如果使用下右图的分裂方式,数据会被切分到两个比较大的空间,进一步的学*也会更好。

圈中的数值表示该结点内的数据。右图中叶子节点 X=A || X=C 的含义是 X=A 或者 X=C 放到左孩子,其余放到右孩子。
2)LightGBM 类别型特征处理方式
LightGBM 采用了 Many vs Many 的切分方式解决 one-hot 编码带来的问题,实现了类别特征的最优切分。用 LightGBM 可以直接输入类别特征,并产生上右图的效果。
在 1 个 k 维的类别特征中寻找最优切分,朴素的枚举算法的复杂度是 O ( 2 k ) O(2^k) O(2k),而 LightGBM 采用了如 On Grouping For Maximum Homogeneity 的方法实现了 O ( k log k ) O(k\log k) O(klogk) 的算法。
算法流程如图所示:

-
①在枚举分割点之前,先把直方图按每个类别的均值进行排序。
-
②接着按照均值的结果依次枚举最优分割点。
从下图可以看到,Sum(y)/Count(y)为类别的均值。当然,这个方法很容易过拟合,所以在 LightGBM 中加入了很多对这个方法的约束和正则化。

求解类别型特征的最优切分的具体流程如下:
① 离散特征建立直方图的过程
统计该特征下每一种离散值出现的次数,并从高到低排序,并过滤掉出现次数较少的特征值。然后为每一个特征值,建立一个 bin 容器,对于在 bin 容器内出现次数较少的特征值直接过滤掉,不建立 bin 容器。
② 计算分裂阈值的过程
-
先看该特征下划分出的 bin 容器的个数,如果 bin 容器的数量小于 4,直接使用 one vs other 方式,逐个扫描每一个 bin 容器,找出最佳分裂点。
-
对于 bin 容器较多的情况,先进行过滤,只让子集合较大的 bin 容器参加划分阈值计算,对每一个符合条件的 bin 容器进行公式计算,得到一个值,根据该值对 bin 容器从小到大进行排序,然后分从左到右、从右到左进行搜索,得到最优分裂阈值。公式如下:
该 b i n 容 器 下 所 有 样 本 的 一 阶 梯 度 之 和 该 b i n 容 器 下 所 有 样 本 的 二 阶 梯 度 之 和 + 正 则 项 ( 参 数 c a t - s m o o t h ) \frac{该 bin 容器下所有样本的一阶梯度之和}{该 bin 容器下所有样本的二阶梯度之和} + 正则项(参数 {cat \text{-} smooth}) 该 bin 容器下所有样本的二阶梯度之和该 bin 容器下所有样本的一阶梯度之和+正则项(参数 cat-smooth)
这里为什么不是 label 的均值呢?其实上例中只是为了便于理解,只针对了学*一棵树且是回归问题的情况。这时候一阶导数是 Y,二阶导数是 1),
- 没有搜索所有的 bin 容器,而是设定了一个搜索 bin 容器数量的上限值,程序中设定是 32,即参数 max_num_cat。
- LightGBM 中对离散特征实行的是 many vs many 策略,这 32 个 bin 中最优划分的阈值的左边或者右边所有的 bin 容器就是一个 many 集合,而其他的 bin 容器就是另一个 many 集合。
③ 对于连续特征,划分阈值只有一个。对于离散值可能会有多个划分阈值,每一个划分阈值对应着一个 bin 容器编号。
当使用离散特征进行分裂时,只要数据样本对应的 bin 容器编号在这些阈值对应的 bin 集合之中,这条数据就加入分裂后的左子树,否则加入分裂后的右子树。
8.并行支持与优化
LightGBM 原生支持并行学*,目前支持「特征并行」和「数据并行」的两种,LightGBM 针对这两种并行方法都做了优化。
-
特征并行:在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。
-
数据并行:让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。
1)特征并行
LightGBM 在特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信。

2)数据并行
Lightgbm 在数据并行中使用分散规约(Reduce scatter)把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。

基于投票的数据并行则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行可以得到非常好的加速效果。

更具体的内容可以看 NIPS2016 的文章: A Communication-Efficient Parallel Algorithm for Decision Tree。
9.网络通信优化
XGBoost 由于采用 Pre-sorted 算法,直接通信代价比较大;LightGBM 采用的 histogram 算法通信代价小,通过使用集合通信算法,能够实现并行计算的线性加速。
10.参考资料
www.zhihu.com/question/51644470zhuanlan.zhihu.com/p/34698733lightgbm.readthedocs.io/en/latest/Features.htmlpapers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree.pdfhuangzhanpeng.github.io/2018/01/04/A-Highly-Ef%EF%AC%81cient-Gradient-Boosting-Decision-Tree/www.msra.cn/zh-cn/news/features/lightgbm-20170105
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-监督学*。
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 支持向量机模型详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/196
声明:版权所有,转载请联系平台与作者并注明出处
引言
本篇我们要讲解的模型是大名鼎鼎的支持向量机 SVM,这是曾经在机器学*界有着*乎「垄断」地位的模型,影响力持续了好多年。直至今日,即使深度学*神经网络的影响力逐渐增强,但 SVM 在中小型数据集上依旧有着可以和神经网络抗衡的极好效果和模型鲁棒性。
支持向量机学*方法,针对不同的情况,有由简至繁的不同模型:
-
线性可分支持向量机(linear support vector machine in linearly separable case):训练数据线性可分的情况下,通过硬间隔最大化(hard margin maximization),学*一个线性的分类器,即线性可分支持向量机(亦称作硬间隔支持向量机)。
-
线性支持向量机(linear support vector machine):训练数据*似线性可分的情况下,通过软间隔最大化(soft margin maximization),学*一个线性的分类器,称作线性支持向量机(又叫软间隔支持向量机)。
-
非线性支持向量机(non-linear support vector machine):训练数据线性不可分的情况下,通过使用核技巧(kernel trick)及软间隔最大化,学*非线性分类器,称作非线性支持向量机。

支持向量机可以借助核技巧完成复杂场景下的非线性分类,当输入空间为欧式空间或离散集合、特征空间为希尔贝特空间时,核函数(kernel function)表示将输入从输入空间映射到特征空间得到的特征向量之间的内积。
通过使用核函数可以学*非线性支持向量机,等价于隐式地在高维的特征空间中学*线性支持向量机。这样的方法称为核技巧。

1.最大间隔分类器
1)分类问题与线性模型
分类问题是监督学*的一个核心问题。在监督学*中,当输出变量取有限个离散值时,预测问题便成为分类问题。实际生活中,有很多问题的本质都是分类,如识别某种模式:文本分类、分词、词性标注、图像内容识别和目标检测等。

分类问题的数学理解是空间划分(或者寻找不同类别的决策边界),如下图所示是一个简单的线性分类器(这部分更详细的讲解参考 ShowMeAI 文章 图解机器学* | 机器学*基础知识 和 图解机器学* | 逻辑回归算法详解)。

2)最大间隔分类器
不同的模型在解决分类问题时,会有不同的处理方式,直观上看,我们会使用不同的决策边界对样本进行划分。
如下图中「冰墩墩」与「雪容融」两类样本点,我们对其进行分类,可以完成该分类任务的决策边界有无数个。而我们这里介绍到的 SVM 模型,要求更高一些,它不仅仅希望把两类样本点区分开,还希望找到鲁棒性最高、稳定性最好的决策边界(对应图中的黑色直线)。

这个决策边界与两侧「最*」的数据点有着「最大」的距离,这意味着决策边界具有最强的容错性,不容易受到噪声数据的干扰。直观的理解就是,如果决策边界抖动,最不容易「撞上」样本点或者进而导致误判。
2.支持向量机详解
1)线性可分 SVM 与硬间隔最大化
我们要找到把下图中红蓝两色的图标点分开的最优分界线。令红色的图标点 = + 1 =+1 =+1 ,蓝色的图标的点 = − 1 =-1 =−1 ,直线 f ( x ) = w ⋅ x + b f(x) = \boldsymbol{w}\cdot \boldsymbol{x} + b f(x)=w⋅x+b ,这里 w 、 x w、x w、x 是向量,其实公式等价于 f ( x ) = w 1 x 1 + w 2 x 2 + … + w n x n + b f(x) = w_1x_1 + w_2x_2 +…+ w_nx_n + b f(x)=w1x1+w2x2+…+wnxn+b 。

-
当向量 x x x 为二维向量时, f ( x ) f(x) f(x) 表示二维空间中的一条直线。
-
当向量 x x x 为三维向量时, f ( x ) f(x) f(x) 表示三维空间中的一个平面。
-
当向量 x x x 的 n n n 维向量( f n > 3 fn>3 fn>3 )时, f ( x ) f(x) f(x) 表示 n n n 维空间中的 n − 1 n-1 n−1 维超平面。
当有一个新的点 x x x 需要预测属于哪个分类的时候,我们用 s g n ( f ( x ) ) sgn(f(x)) sgn(f(x)) 就可以预测了。 s g n sgn sgn 表示符号函数:

-
当 f ( x ) > 0 f(x)>0 f(x)>0 的时候, s g n ( f ( x ) ) = + 1 sgn(f(x)) = +1 sgn(f(x))=+1 。
-
当 f ( x ) < 0 f(x) < 0 f(x)<0 的时候 s g n ( f ( x ) ) = – 1 sgn(f(x)) = –1 sgn(f(x))=–1 。
回到重点,我们怎样才能取得一个最优的划分直线 f ( x ) f(x) f(x) 呢?下图的直线表示几条可能的 f ( x ) f(x) f(x) :

我们希望这条直线满足「最大间隔」原则,也就是如下图的形态。图中位于红色和蓝色线上的图标就是所谓的支持向量(support vector)。

决策边界就是 f ( x ) f(x) f(x) ,红色和蓝色的线是支持向量(support vector)所在的面,红色、蓝色线之间的间隙就是我们要最大化的分类间的间隙 M(Margin Width)。

这里直接给出间隔 M 的计算公式: M = 2 ∥ w ∥ M=\frac{2}{\left | w \right | } M=∥w∥2 。

SVM 要求解能够正确划分训练数据集并且「几何间隔」最大的分离超平面。
如下图所示, w ⋅ x + b = 0 \boldsymbol{w} \cdot \boldsymbol{x}+b=0 w⋅x+b=0 即为分离超平面。对于线性可分的数据集来说,这样的超平面有无穷多个(即感知机),但是几何间隔最大的分离超平面却是唯一的。
我们先做一些定义,假设给定一个特征空间上的训练数据集: T = ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x N , y N ) T={(x_1, y_1),(x_2, y_2), \ldots,(x_N, y_N)} T=(x1,y1),(x2,y2),…,(xN,yN) 。且训练数据集是线性可分的,其中:
-
x i ∈ R n x_i \in \mathbb{R}^{n} xi∈Rn , y i ∈ { + 1 , − 1 } y_{i} \in \left {+1,-1 \right } yi∈{+1,−1} , i = 1 , 2 , … N , x i i=1,2, \ldots N,x_{i} i=1,2,…N,xi 为第 i i i 个特征向量。
-
y i y_{i} yi 为类标记,当它等于 + 1 +1 +1 时为正例;为 − 1 -1 −1 时为负例。

(1)几何间隔
对于给定的数据集 T T T 和超平面 w x + b = 0 wx+b=0 wx+b=0 。
-
定义超平面关于样本点 ( x i , y i ) (x_{i}, y_{i}) (xi,yi) 的几何间隔为: γ i = y i ( w ∥ w ∥ ⋅ x i + b ∥ w ∥ ) \gamma_{i} = y_i(\frac{w}{\left | w \right | } \cdot x_i + \frac{b}{\left | w \right | }) γi=yi(∥w∥w⋅xi+∥w∥b)
-
超平面关于所有样本点的几何间隔的最小值为: γ = min i = 1 , 2 … , N γ i \gamma = \min {i=1,2 \ldots, N} \gamma γ=mini=1,2…,Nγi ,实际上这个距离就是我们所谓的「支持向量到超平面的距离」。

① 根据以上定义,SVM 模型的「求解最大分割超平面问题」可以表示为以下约束最优化问题:
max w , b γ s . t . y i ( w ∥ w ∥ ⋅ x i + b ∥ w ∥ ) ≥ γ , i = 1 , 2 , … , N \begin{aligned} & \max {w,b} \gamma \ & s.t. \quad y(\frac{w}{\left | w \right |} \cdot x_i+\frac{b}{\left | w \right |}) \geq \gamma, i=1,2, \ldots, N\ \end{aligned} w,bmaxγs.t.yi(∥w∥w⋅xi+∥w∥b)≥γ,i=1,2,…,N
- 上面公式中 s.t 是 subject to 的缩写,也就是限制条件的意思。
② 将约束条件两边同时除以 γ \gamma γ 得到:
y i ( w ∥ w ∥ γ ⋅ x i + b ∥ w ∥ γ ) ≥ 1 y_{i}(\frac{w}{\left | w \right | \gamma} \cdot x_i+\frac{b}{\left | w \right |\gamma}) \geq 1 yi(∥w∥γw⋅xi+∥w∥γb)≥1
③ 因为 ∥ w ∥ \left | w \right | ∥w∥ 、 γ \gamma γ 都是标量,所以为了表达式简洁,令: w = w ∥ w ∥ γ w=\frac{w}{\left | w \right | \gamma} w=∥w∥γw 、 b = b ∥ w ∥ γ b=\frac{b}{\left | w \right | \gamma} b=∥w∥γb 得到:
y i ( w ⋅ x i + b ) ≥ 1 , i = 1 , 2 , … , N y_i(w \cdot x_i+b) \geq 1, i=1,2, \ldots, N yi(w⋅xi+b)≥1,i=1,2,…,N
④ 又因为最大化 γ \gamma γ ,等价于最大化 1 ∥ w ∥ \frac{1}{\left | w \right |} ∥w∥1 ,也就等价于最小化 1 2 ∥ w ∥ 2 \frac{1}{2}\left | w \right |^{2} 21∥w∥2 ,最终 SVM 模型的求解最大分割超平面问题又可以表示为以下约束最优化问题:
min w , b 1 2 ∥ w ∥ 2 s . t . y i ( w ⋅ x i + b ) ≥ 1 , i = 1 , 2 , … , N \begin{aligned} & \min {w, b} \frac{1}{2}\left | w \right |^{2}\ & s.t. \quad y(w \cdot x_i+b) \geq 1, i=1,2, \ldots, N \end{aligned} w,bmin21∥w∥2s.t.yi(w⋅xi+b)≥1,i=1,2,…,N
(2)对偶算法
求解线性可分支持向量机的最优化问题,我们很多时候会将它转化为对偶问题(dual problem)来求解,也就是应用「拉格朗日对偶性」,通过求解「对偶问题(dual problem)」得到「原始问题(primal problem)」的最优解,即线性可分支持向量机的对偶算法(dual algorithm)。
这样做有一些优点:
-
对偶问题往往更容易求解。
-
引入自然核函数,进而可以推广到非线性分类问题。
① 我们首先构建拉格朗日函数(Lagrange function)。为此,对每一个不等式约束引进拉格朗日乘子(Lagrange multiplier) α i ≥ 0 , i = 1 , 2 , … , N \alpha_i\geq 0,i=1,2,…,N αi≥0,i=1,2,…,N ,定义拉格朗日函数:
L ( w , b , α ) = 1 2 w T w + ∑ i = 1 N α i ( 1 − y i ( w T x i + b ) ) = 1 2 w T w − ∑ i = 1 N α i y i ( w T x i + b ) + ∑ i = 1 N α i \begin{aligned} L(w, b, \alpha)=&\frac{1}{2}wTw+\sum_{i=1}\alpha_i(1-y_i(w^T x_i + b)) \ =& \frac{1}{2}wTw-\sum_{i=1}\alpha_i y_i(w^T x_i + b) +\sum_{i=1}^{N}\alpha_i \end{aligned} L(w,b,α)==21wTw+i=1∑Nαi(1−yi(wTxi+b))21wTw−i=1∑Nαiyi(wTxi+b)+i=1∑Nαi
根据拉格朗日对偶性,原始问题的对偶问题是极大极小问题: max α min w , b L ( w , b , α ) \max_{\alpha}\min_{w,b}L(w, b, \alpha) maxαminw,bL(w,b,α) 。所以,为了得到对偶问题的解,需要先求 L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 对 w 、 b w、b w、b 的极小值,再求对 $\alpha $ 的极大值。
② 求 L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 对 w 、 b w、b w、b 的极小值
将拉格朗日函数 L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 分别对 w 、 b w、b w、b 求偏导,并令其值为 0。
∂ L ∂ w = w – ∑ i = 1 N α i y i x i = 0 ⇒ w = ∑ i = 1 N α i y i x i \frac{\partial L}{\partial w} = w – \sum_{i=1}^{N}\alpha_i y_i x_i =0 \Rightarrow w = \sum_{i=1}^{N}\alpha_i y_i x_i ∂w∂L=w–i=1∑Nαiyixi=0⇒w=i=1∑Nαiyixi
∂ L b = − ∑ i = 1 N α i y i = 0 ⇒ ∑ i = 1 N α i y i = 0 \frac{\partial L}{b}=-\sum_{i=1}^{N}\alpha_iy_i=0 \Rightarrow \sum_{i=1}^{N}\alpha_iy_i=0 b∂L=−i=1∑Nαiyi=0⇒i=1∑Nαiyi=0
将上式代入拉格朗日函数,即得:
min w , b L ( w , b , α ) = 1 2 ( ∑ i = 1 N α i y i x i ) T ∑ i = 1 N α i y i x i − ∑ i = 1 N α i y i ( ( ∑ i = 1 N α i y i x i ) T x i + b ) + ∑ i = 1 N α i = 1 2 ∑ i = 1 N ∑ j = 1 N α i y i α j y j x i T x j − ∑ i = 1 N ∑ j = 1 N α i y i α j y j x j T x i + ∑ i = 1 N α i = − 1 2 ∑ i = 1 N ∑ j = 1 N α i y i α j y j x i T x j + ∑ i = 1 N α i \begin{aligned} \min_{w,b} L(w, b,\alpha)=&\frac{1}{2} (\sum_{i=1}^{N}\alpha_i y_i x_i)^T \sum_{i=1}^{N}\alpha_i y_i x_i-\sum_{i=1}^{N}\alpha_i y_i((\sum_{i=1}^{N}\alpha_i y_i x_i)^T x_i + b) +\sum_{i=1}^{N}\alpha_i \ =&\frac{1}{2}\sum_{i=1}{N}\sum_{j=1}\alpha_i y_i\alpha_j y_jx_iTx_j-\sum_{i=1}\sum_{j=1}^{N}\alpha_i y_i\alpha_j y_jx_jTx_i+\sum_{i=1}\alpha_i \ =& -\frac{1}{2}\sum_{i=1}{N}\sum_{j=1}\alpha_i y_i\alpha_j y_jx_iTx_j+\sum_{i=1}\alpha_i \end{aligned} w,bminL(w,b,α)===21(i=1∑Nαiyixi)Ti=1∑Nαiyixi−i=1∑Nαiyi((i=1∑Nαiyixi)Txi+b)+i=1∑Nαi21i=1∑Nj=1∑NαiyiαjyjxiTxj−i=1∑Nj=1∑NαiyiαjyjxjTxi+i=1∑Nαi−21i=1∑Nj=1∑NαiyiαjyjxiTxj+i=1∑Nαi

③ 求 min w , b L ( w , b , α ) \min_{w,b}L(w, b,\alpha) minw,bL(w,b,α) 对 α \alpha α 的极大值,即对偶问题
max α − 1 2 ∑ i = 1 N ∑ j = 1 N α i y i α j y j x i T x j + ∑ i = 1 N α i s . t . ∑ i = 1 N α i y i = 0 α i ≥ 0 , i = 1 , 2 … N \begin{aligned} & \max_{\alpha} -\frac{1}{2}\sum_{i=1}{N}\sum_{j=1}\alpha_i y_i\alpha_j y_jx_iTx_j+\sum_{i=1}\alpha_i \ & s.t. \quad \sum_{i=1}^{N}\alpha_iy_i=0 \ & \quad \quad \alpha_i \geq 0,i=1, 2…N \end{aligned} αmax−21i=1∑Nj=1∑NαiyiαjyjxiTxj+i=1∑Nαis.t.i=1∑Nαiyi=0αi≥0,i=1,2…N
将式中的目标函数由求极大转换成求极小,就得到下面与之等价的对偶最优化问题:
min α 1 2 ∑ i = 1 N ∑ j = 1 N α i y i α j y j x i T x j − ∑ i = 1 N α i s . t . ∑ i = 1 N α i y i = 0 α i ≥ 0 , i = 1 , 2 … N \begin{aligned} & \min_{\alpha} \frac{1}{2}\sum_{i=1}{N}\sum_{j=1}\alpha_i y_i\alpha_j y_jx_iTx_j-\sum_{i=1}\alpha_i \ & s.t. \quad \sum_{i=1}^{N}\alpha_iy_i=0 \ & \quad \quad \alpha_i \geq 0,i=1, 2…N \end{aligned} αmin21i=1∑Nj=1∑NαiyiαjyjxiTxj−i=1∑Nαis.t.i=1∑Nαiyi=0αi≥0,i=1,2…N

④ 对线性可分训练数据集,假设对偶最优化问题对 α \alpha α 的解为 α ∗ = ( α 1 ∗ , α 2 ∗ , … , α N ∗ ) T \alpha*=(\alpha_1,\alpha_2*,…,\alpha_N)^ T α∗=(α1∗,α2∗,…,αN∗)T ,可以由 α ∗ \alpha^ α∗ 求得原始最优化问题的解 w ∗ 、 b ∗ w*、b w∗、b∗ **。
有下面的定理:设 α ∗ = ( α 1 ∗ , α 2 ∗ , … , α N ∗ ) T \alpha*=(\alpha_1,\alpha_2*,…,\alpha_N)^T α∗=(α1∗,α2∗,…,αN∗)T 是对偶最优化问题的解,则存在下标 j j j ,使得 α j ∗ > 0 \alpha_j^>0 αj∗>0 ,并可按下式求得原始最优化问题的解 w ∗ , b ∗ w*,b w∗,b∗ :
w ∗ = ∑ i = 1 ∗ N α i ∗ y i x i w*=\sum_{i=1}{N} \alpha_i^y_ix_i w∗=i=1∑∗Nαi∗yixi
b ∗ = y j − ∑ i = 1 ∗ N α i ∗ y i ( x i ∗ T x j ) b*=y_j-\sum_{i=1}{N} \alpha_i*y_i(x_iTx_j) b∗=yj−i=1∑∗Nαi∗yi(xi∗Txj)
证明:根据定理,KKT 条件成立,即得:
∂ L ( w ∗ , b ∗ , α ∗ ) ∂ w = w ∗ − ∑ i = 1 N α i ∗ y i x i = 0 ∂ L ( w ∗ , b ∗ , α ∗ ) ∂ b = − ∑ i = 1 N α i ∗ y i = 0 ∂ L ( w ∗ , b ∗ , α ∗ ) ∂ α = 0 α i ( 1 − y i ( w T x i + b ) ) = 0 α i ≥ 0 , i = 1 , 2 , … , N 1 − y i ( w T x i + b ) ≤ 0 , i = 1 , 2 , … , N \begin{aligned} & \frac{\partial L(w*,b,\alpha ^)}{\partial w} = w*-\sum_{i=1}\alpha_i^* y_i x_i=0 \ & \frac{\partial L(w*,b,\alpha ^)}{\partial b} = -\sum_{i=1}{N}\alpha_iy_i=0 \ & \frac{\partial L(w*,b,\alpha ^*)}{\partial \alpha} = 0 \ & \alpha_i(1-y_i(w^Tx_i+b)) =0 \ & \alpha_i \geq 0 , \ & i=1,2,…,N \ & 1-y_i(w^Tx_i+b) \leq 0 , i=1,2,…,N \end{aligned} ∂w∂L(w∗,b∗,α∗)=w∗−i=1∑Nαi∗yixi=0∂b∂L(w∗,b∗,α∗)=−i=1∑Nαi∗yi=0∂α∂L(w∗,b∗,α∗)=0αi(1−yi(wTxi+b))=0αi≥0,i=1,2,…,N1−yi(wTxi+b)≤0,i=1,2,…,N
由此得 w ∗ = ∑ i = 1 N α i ∗ y i x i w*=\sum_{i=1} \alpha_i^*y_ix_i w∗=∑i=1Nαi∗yixi
\其中至少有一个 α j ∗ > 0 \alpha_j^>0 αj∗>0 (用反正法,假设 α j ∗ = 0 \alpha_j^=0 αj∗=0 ,由式可知 w ∗ = 0 w^=0 w∗=0 ,而 w ∗ = 0 w^=0 w∗=0 不是原始最优化问题的解,产生矛盾),由此对 j j j 有: y j ( w ∗ ⋅ x j + b ∗ ) – 1 = 0 y_j(w^\cdot x_j+b^) – 1 = 0 yj(w∗⋅xj+b∗)–1=0
将式代入并注意到 y j 2 = 1 y_j²=1 yj2=1 ,即得: b ∗ = y j – w ∗ x j = y j – ∑ i = 1 N α i ∗ y i ( x i x j ) b^* = y_j – w^{}x_j = y_j – \sum_{i=1}^{N} \alpha_i^y_i(x_ix_j) b∗=yj–w∗xj=yj–∑i=1Nαi∗yi(xixj)
⑤ 由此定理可知,分离超平面可以写成
∑ i = 1 N α i ∗ y i ( x ⋅ x i ) + b ∗ = 0 \sum_{i=1}^{N} \alpha_i^y_i(x\cdot x_i) + b^ = 0 i=1∑Nαi∗yi(x⋅xi)+b∗=0
⑥ 分类决策函数可以写成
f ( x ) = s i g n ( ∑ i = 1 N α i ∗ y i ( x ⋅ x i ) + b ∗ ) f(x) = sign(\sum_{i=1}^{N} \alpha_i^y_i(x\cdot x_i) + b^) f(x)=sign(i=1∑Nαi∗yi(x⋅xi)+b∗)

也就是说,这里的决策函数只依赖于输入 x x x 和训练样本输入的内积。上式亦称作线性可分 SVM 的对偶形式。
综上所述,对于给定得线性可分训练数据集,可以首先求对偶问题的解 α ∗ \alpha^* α∗ ;再利用公式求得原始问题的解 w ∗ , b ∗ w*,b* w∗,b∗ ;从而得到分离超平面及分类决策函数。这种算法称为线性可分支持向量机的对偶学*算法,是线性可分支持向量机学*的基本算法。
2)线性 SVM 与软间隔最大化
我们前面提到的是线性可分的情况,但实际应用中完全线性可分的情况太少见了。如下图就是一个典型的线性不可分的分类图(我们没有办法找到一条直线,把空间划分为 2 个区域,一个区域只有黑点,一个区域只有白点)。
要对其进行切分,有 2 种方案:
方案 1:用曲线去将其完全分开,即非线性的决策边界,这会和之后谈到的核函数关联。

方案 2:还是使用直线,不过不追求完全可分,会适当包容一些分错的情况,在这个过程中我们会在模型中加入惩罚函数,尽量让分错的点不要太多太离谱。对分错点的惩罚函数就是这个点到其正确位置的距离,如下图所示:

图上黄色、蓝色的直线分别为支持向量所在的边界,黑色的线为决策函数,那些绿色的线表示分错的点到其相应的决策面的距离,这样我们可以在原函数上面加上一个惩罚函数,并且带上其限制条件为:
min 1 2 ∣ w ∣ 2 + C ∑ i = 1 R ε i , s . t . , y i ( w T x i + b ) ≥ 1 − ε i , ε i ≥ 0 \begin{aligned} & \min \frac{1}{2}|w|^{2}+C \sum_{i=1}^{R} \varepsilon_{i}, \ & s.t., y_{i}\left(w^{T} x_{i}+b\right) \geq 1-\varepsilon_{i}, \varepsilon_{i} \geq 0 \end{aligned} min21∣w∣2+Ci=1∑Rεi,s.t.,yi(wTxi+b)≥1−εi,εi≥0
上述公式为在线性可分问题的基础上加上的惩罚函数部分,当 x i x_i xi 在正确一边的时候, ε = 0 \varepsilon = 0 ε=0 ,R 为全部的点的数目,C 是一个由用户去指定的系数,表示对分错的点加入多少的惩罚:
- 当 C 很大的时候,分错的点就会更少,但是过拟合的情况可能会比较严重。
- 当 C 很小的时候,分错的点可能会很多,不过可能由此得到的模型也会不太正确。
实际我们也会调整和选择合适的 C 值。
经过这个变换之后,我们可以同样求解一个拉格朗日对偶问题,得到原问题的对偶问题的表达式:
max α ∑ i = 1 n α i − 1 2 ∑ i , j = 1 n α i α j y i y j x i T x j s.t. , C ≥ α i ≥ 0 , i = 1 , ⋯ , n , ∑ i = 1 n α i y i = 0 \begin{aligned} & \max {\alpha} \sum^{n} \alpha_{i}-\frac{1}{2} \sum_{i, j=1}^{n} \alpha_{i} \alpha_{j} y_{i} y_{j} x_{i}^{T} x_{j} \ & \text { s.t. }, C \geq \alpha_{i} \geq 0, i=1, \cdots, n , \sum_{i=1}^{n} \alpha_{i} y_{i}=0 \end{aligned} αmaxi=1∑nαi−21i,j=1∑nαiαjyiyjxiTxj s.t. ,C≥αi≥0,i=1,⋯,n,i=1∑nαiyi=0

在线性不可分情况下得到的对偶问题,不同的地方就是α的范围从[0, +∞),变为了[0, C],增加的惩罚 ε \varepsilon ε 没有为对偶问题增加太多复杂度。
3)非线性 SVM 与核函数
如果我们要处理的分类问题更加复杂,甚至不能像上面一样*似线性可分呢,这种情况下找到的超平面分错的程度太高不太可接受。
对于这样的问题,一种解决方案是将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分,然后再运用 SVM 求解,如下图所示:

比如下图中的典型线性不可分的情况:

当我们使用映射函数 z 1 = x 1 2 , z 2 = x 2 2 , z 3 = x 2 z_{1}=x_{1}^{2}, z_{2}=x_{2}^{2}, z_{3}=x_{2} z1=x12,z2=x22,z3=x2 把这两个类似于椭圆形的点映射到三维空间 ( z 1 , z 2 , z 3 ) (z_1,z_2,z_3) (z1,z2,z3) 后,对映射后的坐标加以旋转之后就可以得到一个线性可分的点集了。

我们回忆一下之前得到的对偶问题表达式:
max α ∑ i = 1 n α i − 1 2 ∑ i , j = 1 n α i α j y i y j x i T x j s . t . , C ≥ α i ≥ 0 , i = 1 , ⋯ , n , ∑ i = 1 n α i y i = 0 \begin{aligned} & \max {\alpha} \sum^{n} \alpha_{i}-\frac{1}{2} \sum_{i, j=1}^{n} \alpha_{i} \alpha_{j} y_{i} y_{j} x_{i}^{T} x_{j} \ & s.t. , C \geq \alpha_{i} \geq 0, i=1, \cdots, n, \sum_{i=1}^{n} \alpha_{i} y_{i}=0 \ \end{aligned} αmaxi=1∑nαi−21i,j=1∑nαiαjyiyjxiTxjs.t.,C≥αi≥0,i=1,⋯,n,i=1∑nαiyi=0
做一点小小的改造,令: x i T x j = κ ( x i , x j ) x_{i}^{T} x_{j}=\kappa\left(x_{i}, x_{j}\right) xiTxj=κ(xi,xj) 。这个式子所做的事情就是将线性的空间映射到高维的空间, κ ( x i , x j ) \kappa\left(x_{i}, x_{j}\right) κ(xi,xj) 有很多种,下面是比较典型的两种:
κ ( x i , x j ) = ( x i ⋅ x j + 1 ) d \kappa\left(x_{i}, x_{j}\right)=\left(x_{i} \cdot x_{j}+1\right)^{d} κ(xi,xj)=(xi⋅xj+1)d
κ ( x i , x j ) = exp ( − ( x i − x j ) 2 2 σ 2 ) \kappa\left(x_{i}, x_{j}\right)= \exp \left(-\frac{\left(x_{i}-x_{j}\right){2}}{2\sigma{2}}\right) κ(xi,xj)=exp(−2σ2(xi−xj)2)

上述两个核函数分别为多项式核和高斯核,高斯核甚至是将原始空间映射为无穷维空间,另外核函数有一些比较好的性质,比如说不会比线性条件下增加多少额外的计算量,等等,此处我们不深入。对于一个问题,不同的核函数可能会带来不同的结果,我们需要做一些尝试来支撑选择(关于这个部分,大家可以看最下方的 python 实现部分)。
3.SVM 总结
1)模型总结
支持向量机(Support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,他的学*策略就是间隔最大化,同时该方法可以形式化为一个求解图二次规划。

SVM 由简至繁可分为三类:线性可分支持向量机、硬间隔(hard-margin svm);线性支持向量机、软间隔(soft-margin svm);非线性支持向量机、Kernel SVM。
SVM 中存在三宝:间隔、对偶、核技巧。
2)模型优缺点
(1)SVM 模型优点

-
SVM 是一个凸优化问题,求得的解一定是全局最优而不仅仅是局部最优。
-
不仅适用于线性问题,还适用于非线性问题(借助核技巧)。
-
模型鲁棒性好,决策边界只取决于支持向量而不是全部数据集。
-
中小样本量数据集上效果优异。
-
无需依赖整个数据。
-
泛化能力比较强。
(2)SVM 模型缺点
-
二次规划问题求解将涉及 n 阶矩阵的计算(其中 n 为样本的个数),计算量随样本量上涨厉害,因此 SVM 不适用于超大数据集。
-
原始 SVM 仅适用于二分类问题。(当然,SVM 的推广 SVR 也适用于回归问题;我们也可以通过 one-vs-one,one-vs-rest 等思路组合 SVM 来解决多分类问题)。
-
对非线性问题没有通用解决方案,有时候很难找到一个合适的核函数。
-
对于核函数的高维映射解释力不强,尤其是径向基函数。
-
SVM 对缺失数据敏感。
更多监督学*的算法模型总结可以查看 ShowMeAI 的文章AI 知识技能速查 | 机器学*-监督学*。
4.基于 Python 的 SVM 代码实践
1)算法包说明
我们这里直接借助于 python 机器学*工具包 sklearn 来演示 SVM 的应用,sklearn 中对 SVM 的算法实现都包在 sklearn.svm 下面,具体见 sklearn 官方文档,其中 SVC 类是用来进行进行分类的任务,SVR 是用来进行数值回归任务的。
不同的核函数需要指定不同的参数。
-
针对线性函数,只需要指定参数 C,它表示对不符合最大间距规则的样本的惩罚力度。
-
针对多项式核函数,除了参数 C 外,还需要指定 degree,它表示多项式的阶数。
-
针对高斯核函数,除了参数 C 外,还需要指定 gamma 值,这个值对应的是高斯函数公式中 1 2 σ 2 \frac{1}{2\sigma ²} 2σ21 的值。
2)使用线性核函数
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
iris = datasets.load_iris()
X = iris.data[:, :2] # 只取前两维特征,方便可视化
y = iris.target
svc = svm.SVC(kernel='linear', C=1).fit(X, y)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
h = (x_max / x_min) / 100
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
plt.subplot(1, 1, 1)
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.title('SVC with linear kernel')
plt.show()

3)使用多项式核函数
初始化 svm 对象的代码替换为下面这行
svc = svm.SVC(kernel='poly', degree=3).fit(X, y)

4)使用 rbf 核函数(高斯核函数)
初始化 svm 对象的代码替换为下面这行
svc = svm.SVC(kernel='rbf', C=1).fit(X, y)

gamma 值越大,SVM 就会倾向于越准确的划分每一个训练集里的数据,这会导致泛化误差较大和过拟合问题。

C:错误项的惩罚参数 C。它还控制平滑决策边界和正确分类训练点之间的权衡。

参考链接
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=935770612&page=6
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
【双语字幕+资料下载】斯坦福 CS229 | 机器学*-吴恩达主讲(2018·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 聚类算法详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/197
声明:版权所有,转载请联系平台与作者并注明出处
引言
聚类(Clustering)是最常见的无监督学*算法,它指的是按照某个特定标准(如距离)把一个数据集分割成不同的类或簇,使得同一个簇内的数据对象的相似性尽可能大,同时不在同一个簇中的数据对象的差异性也尽可能地大。也即聚类后同一类的数据尽可能聚集到一起,不同类数据尽量分离。
聚类算法在很多场景下都有应用,例如新闻自动分组,用户分群,图像分割等等。很多时候,无监督的聚类算法,得到的聚类结果还可以作为特征在后续监督学*中应用,提升整体效果。本篇内容 ShowMeAI 带大家一起来学*一下聚类算法。
(本篇聚类算法部分内容涉及到机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识。
1.聚类问题
1)聚类问题与核心概念
俗话说人以类聚物以群分,聚类算法做的事情,就是对无标签的数据,基于数据分布进行分群分组,使得相似的数据尽量落在同一个簇内。

我们先对比区分一下聚类和分类:
- 聚类是一种无监督学*,而分类是一种有监督的学*。
- 聚类只需要人工指定相似度的标准和类别数就可以,而分类需要从训练集学*分类的方法。

2)聚类算法用途
聚类算法应用非常广泛。在面对未知的世界时,先分类,再逐个研究,是人类探索未知世界的一个基本方法。聚类算法可以应用于探索性数据挖掘、统计分析、生物信息学、数据压缩、计算机图像识别、医学影像分析等,在商业领域可以用来做市场研究、商品归类,在社会科学领域可以用来做犯罪区域分析等等。
下图中有一些样本点,我们根据物理距离的远*,把所有的点分成 3 类。你只需要告诉算法这些信息,算法就可以按照你的要求完成聚类:
- 分类数量为 3;
- 分类标准是物理距离;
- 分好的类分别用红、绿、蓝表示。

实际上,除了物理距离,现实生活中任何你能想到、计算机可以通过运算和逻辑进行判断的规则,都可以作为分类标准。
下面我们用图像压缩作为例子来解释一下。最左边是一张彩色照片,大小约 1Mb,通过压缩可以把它变成几十到几百 Kb,这就是压缩软件的实现过程。那么压缩软件的实现原理是什么呢?其中一种就是聚类算法。
从原始图片到压缩存储的过程如下图所示:

聚类算法同样可以用于图像分割。图像中每一个像素点是一个 3 维向量,对应 [R, G, B] 像素值。给定聚类中类别个数 K,算法用 K 个不同的颜色来表示原来的图像,每个像素点用 K 个颜色中一个表示。具体如下:

对于文档、新闻、商品而言,很多时候我们会使用嵌套的归类方法,这是一种层次化聚类:

3)主流聚类算法
我们先对聚类算法做个了解,主流的聚类算法可以分成两类:划分聚类(Partitioning Clustering)和层次聚类(Hierarchical Clustering)。他们的主要区别如图中所示:
划分聚类算法会给出一系列扁平结构的簇(分开的几个类),它们之间没有任何显式的结构来表明彼此的关联性。
- 常见算法有 K-Means/K-Medoids、Gaussian Mixture Model (高斯混合模型)、Spectral Clustering(谱聚类)、Centroid-based Clustering 等。
层次聚类会输出一个具有层次结构的簇集合,因此能够比划分聚类输出的无结构簇集合提供更丰富的信息。层次聚类可以认为是是嵌套的划分聚类。
- 常见算法有 Single-linkage、Complete-linkage、Connectivity-based Clustering 等。
这两类算法在聚类过程中用到的具体算法不一样,后文我们会重点展开讲一下 K-Means 算法、Single-linkage 算法和 Complete-linkage 算法。

2.K-Means 聚类算法
K-Means 算法是聚类算法中一个非常基础的算法,同时应用又非常广泛,下面 ShowMeAI 给大家展开讲解算法原理。
1)K-Means 算法核心概念
我们提到了聚类算法要把 n 个数据点按照分布分成 k 类(很多算法的 k 是人为提前设定的)。我们希望通过聚类算法得到 k 个中心点,以及每个数据点属于哪个中心点的划分。
-
中心点可以通过迭代算法来找到,满足条件:所有的数据点到聚类中心的距离之和是最小的。
-
中心点确定后,每个数据点属于离它最*的中心点。
在进入「如何寻找中心点」这个核心问题之前,我们先解决几个小问题:

Q1:数据点到中心点的距离如何计算?
- 我们一般选择几何距离,就是 L2 距离的平方。
Q2:中心点是否唯一,或者说,是不是存在全局最优解?
- 对于多个中心点的情况,全局最优是一个相当难的问题。理论上存在一个全局最优解,但是不一定能找到。既然全局最优解不好找,那我们退而求其次,看能不能找到局部最优解。
Q3:聚类结果如何表示?
- 采用空间分割的方式:将空间分割成多个多边形,每个多边形对应一个 cluster 中心。
2)K-Means 算法步骤
K-Means 采用 EM 算法迭代确定中心点。流程分两步:
-
① 更新中心点:初始化的时候以随机取点作为起始点;迭代过程中,取同一类的所有数据点的重心(或质心)作为新中心点。
-
② 分配数据点:把所有的数据点分配到离它最*的中心点。
重复上面的两个步骤,一直到中心点不再改变为止。过程如图所示:

-
左侧 Assignments:一开始随机选取三个点,作为三个类的中心,基于其它点和这三个中心点的距离分配簇;每一类重新计算和分配中心。
-
右侧 Refitted Means:根据新的中心点,重新分配所有的数据点(原来属于绿色中心点的 1 个点,此次迭代后变成属于红色中心点了)。
下图的示例展示了 K-Means 动态迭代收敛的过程:

-
图(a)上有一群散落的点,我们设定簇数 K=2。
-
图(b)为随机找 2 个点作为中心初始化后,第一次分类的结果。
- 可以看到,红蓝分界线在这群点的中央穿过。这显然有问题,不过没关系,算法继续往下走。对红蓝两类分别计算它们的中心。
-
图(c)可以看到,一个落在左下方这一团里,另一个落在右上方那一团里。以新的中心点进行第二次分类。
-
图(d)的分界线就基本是已经可以把两团分开了。
-
图(f)、(g)显示后续重复计算你「中心点-分类数据点」的过程已经收敛,数据点分配基本不动了,聚类完成。
下方的动图能更清晰地展示这个过程:

3.K-Means 缺点与改进
1)K-Means 算法缺点
K-Means 算法简单易用,它有什么缺点呢?我们将 K-Means 算法的一些缺点总结如下:
-
缺点 1:中心点是所有同一类数据点的质心,所以聚类中心点可能不属于数据集的样本点。
-
缺点 2:计算距离时我们用的是 L2 距离的平方。对离群点很敏感,噪声(Noisy Data)和离群点(Outlier)会把中心点拉偏,甚至改变分割线的位置。
2)K-Medoids 算法
针对 K-Means 算法的缺点改进得到了 K-Medoids 算法:
(1)限制聚类中心点必须来自数据点。
-
求中心点的计算方法,由原来的直接计算重心,变成计算完重心后,在重心附*找一个数据点作为新的中心点。
-
K-Medoids 重拟合步骤比直接求平均的 K-Means 要复杂一些。
(2)为避免平方计算对离群点的敏感,把平方变成绝对值。
总结来说,K-Medoids 算法的迭代过程与 K-Means 是一致的,不同点如下所示:

-
起始点不是随机点,而是任意选择数据集中的点。
-
距离使用 L1 距离,而不是 L2 距离。
-
新的中心点,也不是同类所有点的重心,而是同一类别所有数据点中,离其它点最*的点。
-
复杂度方面,相比于 K-Means 的 O ( n ) O(n) O(n) ,K-Medoids 更新中心点的复杂度 O ( n 2 ) O(n²) O(n2) 要更高一些。
下图是 K-Means 和 K-Medoids 两个算法的一个系统对比:

4.层次聚类算法
相比于 K-Means 这类划分聚类,我们有另外一类层次化聚类算法。
1)层次聚类 vs 划分聚类
划分聚类得到的是划分清晰的几个类,而层次聚类最后得到的是一个树状层次化结构。

从层次化聚类转换为划分聚类很简单,在层次化聚类的某一层进行切割,就得到 1 个划分聚类。如下图所示:

2)Single-Linkage 算法
接下来我们介绍一个层次聚类中的 Single-Linkage 算法。这个算法是构造一棵二叉树,用叶节点代表数据,而二叉树的每一个内部节点代表一个聚类。如图所示:

这是一个从下而上的聚类。这棵树是先有叶子,顺着叶子逐渐长树枝,树枝越长越大一直到树根。
如果叶子很多,这个生长过程需要合并的类就会很多。图中有 11 个数据点,一共发生了 10 次合并。
3)Complete-Linkage 算法
与 Single-Linkage 算法相似,Complete-Linkage 的迭代思路是一样的,不同的是在合并类时,Single-Linkage 是用两个类中距离最小的两个点作为类之间的距离,而 Complete-Linkage 恰恰相反,用距离最远的两个数据点之间的距离作为这两个类之间的距离。
这两种计算方法各有利弊。总的来说,层次聚类的计算复杂度是 O ( n 3 ) O(n³) O(n3) 级别,算是很高的了。可以用优先队列的数据结构对算法加速,加速后能减低到 O ( n 2 log n ) O(n^{2} \log{n} ) O(n2logn) 的级别。

5.DB-SCAN 算法
1)DB-SCAN 算法
在前面的内容中我们介绍了划分聚类和层次聚类的算法,接下来我们学*另外一个聚类算法:DB-SCAN 算法。
DB-SCAN 是一个基于密度的聚类。如下图中这样不规则形态的点,如果用 K-Means,效果不会很好。而通过 DB-SCAN 就可以很好地把在同一密度区域的点聚在一类中。

2)DB-SCAN 算法的关键概念
核心对象(Core Object),也就是密度达到一定程度的点。
- 若 x j x_j xj的 ∈ − \in - ∈−邻域至少包含 MinPts 个样本,即 ∣ N ∈ ( x j ) ∣ ≥ M i n P t s |N_\in (x_j )|≥MinPts ∣N∈(xj)∣≥MinPts,则 x j x_j xj是一个核心对象。
密度直达(directly density-reachable),密度可达(density-reachable):核心对象之间可以是密度直达或者密度可达。
-
若 x i x_i xi位于 x j x_j xj的 ∈ − \in - ∈−邻域中,且 x j x_j xj是核心对象,则称 x j x_j xj由 x j x_j xj密度直达。
-
对 x i x_i xi与 x j x_j xj,若存在样本序列 p 1 , p 2 , … , p n p_1,p_2, \dots, p_n p1,p2,…,pn,其中 p 1 = x i p_1=x_i p1=xi, p n = x j p_n=x_j pn=xj且 p i + 1 p_i+1 pi+1 由 p i p_i pi密度直达,则称 x j x_j xj由 x i x_i xi密度可达。
密度相连(density-connected):所有密度可达的核心点就构成密度相连。
- 对 x i x_i xi与 x j x_j xj,若存在 x k x_k xk使得 x i x_i xi与 x j x_j xj,均由 x k x_k xk密度可达,则称 x i x_i xi与 x j x_j xj密度相连。
我们通过下图深入理解一下刚才提到的几个基本概念。

先假设要求的最小点密度 MinPts 是 3。
-
在一个半径范围内, x 1 x_1 x1这个点周围的点数是 5,超过了阈值 3,所以 x 1 x_1 x1是一个核心对象。同样, x 2 x_2 x2、 x 3 x_3 x3和 x 4 x_4 x4也是核心对象。
-
x 1 x_1 x1与 x 2 x_2 x2处于一个邻域,所以二者是密度直达的关系,而 x 3 x_3 x3与 x 2 x_2 x2也是密度直达的关系,通过 x 2 x_2 x2, x 1 x_1 x1与 x 3 x_3 x3是密度可达的关系。
-
x 3 x_3 x3与 x 4 x_4 x4通过多个核心对象实现密度相连。
3)DB-SCAN 算法伪代码

这个过程用直白的语言描述就是:
-
对于一个数据集,先规定最少点密度 MinPts 和半径范围。
-
先找出核心对象:如果在半径范围内点密度大于 MinPts,则这个点是核心对象。把所有的核心对象放到一个集合中。
-
从这个核心对象集合中,随机找一个核心对象,判断其它的数据点与它是否密度直达,如果是,则归入聚类簇中。
-
继续判断其它点与聚类簇中的点是否密度直达,直到把所有的点都检查完毕,这时候归入聚类簇中的所有点是一个密度聚类。
更多无监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-无监督学*。
视频教程
可以点击 B 站 查看视频的【双语字幕】版本
player.bilibili.com/player.html?aid=975327190&page=13
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
【双语字幕+资料下载】MIT 6.036 | 机器学*导论(2020·完整版)
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程

图解机器学* | 降维算法详解

作者:韩信子@ShowMeAI
教程地址:www.showmeai.tech/tutorials/34
本文地址:www.showmeai.tech/article-detail/198
声明:版权所有,转载请联系平台与作者并注明出处
引言
在互联网大数据场景下,我们经常需要面对高维数据,在对这些数据做分析和可视化的时候,我们通常会面对「高维」这个障碍。在数据挖掘和建模的过程中,高维数据也同样带来大的计算量,占据更多的资源,而且许多变量之间可能存在相关性,从而增加了分析与建模的复杂性。
我们希望找到一种方法,在对数据完成降维「压缩」的同时,尽量减少信息损失。由于各变量之间存在一定的相关关系,因此可以考虑将关系紧密的变量变成尽可能少的新变量,使这些新变量是两两不相关的,那么就可以用较少的综合指标分别代表存在于各个变量中的各类信息。机器学*中的降维算法就是这样的一类算法。
主成分分析(Principal Components Analysis,简称 PCA)是最重要的数据降维方法之一。在数据压缩消除冗余和数据噪音消除等领域都有广泛的应用。本篇我们来展开讲解一下这个算法。
(本篇降维算法部分内容涉及到机器学*基础知识,没有先序知识储备的宝宝可以查看 ShowMeAI 的文章 图解机器学* | 机器学*基础知识。
1.PCA 与最大可分性
对于 X = [ x 1 x 2 . . . x n ] X = \begin {bmatrix} x_1 \ x_2 \ ... \ x_n \end{bmatrix} X=⎣⎢⎢⎡x1x2...xn⎦⎥⎥⎤ , X ∈ R n X \in R^n X∈Rn 。我们希望 X X X 从 n n n 维降到 n ′ n^{'} n′ 维,同时希望信息损失最少。比如,从 n = 2 n = 2 n=2 维降到 n ′ = 1 n^{'} = 1 n′=1 。

左图为一个典型的例子,假如我们要对一系列人的样本进行数据降维(每个样本包含「身高」「体重」两个维度)。右图我们既可以降维到第一主成分轴,也可以降维到第二主成分轴。
哪个主成分轴更优呢?从直观感觉上,我们会认为「第一主成分轴」优于「第二主成分轴」,因为它比较大程度保留了数据之间的区分性(保留大部分信息)。
对 PCA 算法而言,我们希望找到小于原数据维度的若干个投影坐标方向,把数据投影在这些方向,获得压缩的信息表示。下面我们就一步一步来推导一下 PCA 算法原理。
2.基变换
先来复*一点点数学知识。我们知道要获得原始数据 X X X 新的表示空间 Y Y Y ,最简单的方法是对原始数据进行线性变换(也叫做基变换) Y = P X Y = PX Y=PX 。其中, X X X 是原始样本, P P P 是基向量, Y Y Y 是新表达。
数学表达为:
[ p 1 p 2 ⋮ p r ] r × n [ x 1 x 2 ⋯ x m ] n × m = [ p 1 x 1 p 1 x 2 ⋯ p 1 x m p 2 x 1 p 2 x 2 ⋯ p 2 x m ⋮ ⋮ ⋱ ⋮ p r x 1 p r x 2 ⋯ p r x m ] r × m \begin{bmatrix} p_1 \ p_2 \ \vdots \ p_r \end{bmatrix}{r \times n} \begin{bmatrix} x_1 & x_2 & \cdots & x_m \end{bmatrix} = \begin{bmatrix} p_1 x_1 & p_1 x_2 & \cdots & p_1 x_m \ p_2 x_1 & p_2 x_2 & \cdots & p_2 x_m \ \vdots & \vdots & \ddots & \vdots \ p_r x_1 & p_r x_2 & \cdots & p_r x_m\end{bmatrix}_{r\times m} ⎣⎢⎢⎢⎡p1p2⋮pr⎦⎥⎥⎥⎤r×n[x1x2⋯xm]n×m=⎣⎢⎢⎢⎡p1x1p2x1⋮prx1p1x2p2x2⋮prx2⋯⋯⋱⋯p1xmp2xm⋮prxm⎦⎥⎥⎥⎤r×m
-
其中 p i p_i pi 是行向量,表示第 i i i 个基;
-
x j x_j xj 是一个列向量,表示第 j j j 个原始数据记录。
当 r < n r < n r<n 时,即「基的维度<数据维度」时,可达到降维的目的,即 X ∈ R n × m → Y ∈ R r × m X \in R^{n \times m} \rightarrow Y \in R^{r \times m } X∈Rn×m→Y∈Rr×m 。

以直角坐标系下的点 ( 3 , 2 ) (3,2) (3,2) 为例,要把点 ( 3 , 2 ) (3,2) (3,2) 变换为新基上的坐标,就是用 ( 3 , 2 ) (3,2) (3,2) 与第一个基做内积运算,作为第一个新的坐标分量,然后用 ( 3 , 2 ) (3,2) (3,2) 与第二个基做内积运算,作为第二个新坐标的分量。

上述变化,在线性代数里,我们可以用矩阵相乘的形式简洁的来表示:
[ 1 2 1 2 − 1 2 1 2 ] [ 3 2 ] = [ 5 2 − 1 2 ] \begin{bmatrix}\frac{1}{\sqrt 2} & \frac{1}{\sqrt 2} \ -\frac{1}{\sqrt 2} & \frac{1}{\sqrt 2} \end{bmatrix} \begin{bmatrix} 3 \ 2\end{bmatrix} = \begin{bmatrix} \frac{5}{\sqrt 2} \ - \frac{1}{\sqrt 2} \end{bmatrix} [2 1−2 12 12 1][32]=[2 5−2 1]
再稍微推广一下,假如我们有 m 个二维向量,只要将二维向量按列排成一个两行 m 列矩阵,然后用「基矩阵」乘以这个矩阵,就得到了所有这些向量在新基下的值。例如(1,1)、(2,2)、(3,3),想变换到刚才那组基上,可以如下这样表示:
[ 1 2 1 2 − 1 2 1 2 ] [ 1 2 3 1 2 3 ] = [ 2 2 4 2 6 2 0 0 0 ] \begin{bmatrix}\frac{1}{\sqrt 2} & \frac{1}{\sqrt 2} \ -\frac{1}{\sqrt 2} & \frac{1}{\sqrt 2} \end{bmatrix} \begin{bmatrix} 1 & 2 & 3 \ 1 & 2 & 3\end{bmatrix} = \begin{bmatrix} 2\sqrt 2 & 4\sqrt2 & 6\sqrt2 \ 0 & 0 & 0 \end{bmatrix} [2 1−2 12 12 1][112233]=[22 042 062 0]
3.方差
在本文的开始部分,我们提到了,降维的目的是希望压缩数据但信息损失最少,也就是说,我们希望投影后的数据尽可能分散开。在数学上,这种分散程度我们用「方差」来表达,方差越大,数据越分散。
-
定义方差 V a r Var Var :对于单一随机变量 a a a , V a r ( a ) = 1 m ∑ i = 1 m ( a i − μ ) 2 Var(a) = \frac{1}{m} \sum_{i = 1}^m (a_i - \mu)² Var(a)=m1∑i=1m(ai−μ)2
-
对数据做去中心化(方便后面操作): V a r ( a ) = 1 m ∑ i = 1 m a i 2 Var(a) = \frac{1}{m} \sum_{i = 1}^m a_i ² Var(a)=m1∑i=1mai2
V a r ( a ) Var(a) Var(a) 表示 a a a 的取值与其数学期望之间的偏离程度。若 V a r ( a ) Var(a) Var(a) 较小,意味着 a a a 的取值主要集中在期望 μ \mu μ 也就是 E ( a ) E(a) E(a) )的附*;反之,若 V a r ( a ) Var(a) Var(a) 较大,意味着 a a a 的取值比较分散。
我们来看一个具体的例子。假设我们 5 个样本数据,分别是 x 1 = [ 1 1 ] x_1 = \begin{bmatrix} 1 \ 1 \end{bmatrix} x1=[11] 、 x 2 = [ 1 3 ] x_2 = \begin{bmatrix} 1 \ 3\end{bmatrix} x2=[13] 、 x 3 = [ 2 3 ] x_3 = \begin{bmatrix} 2 \ 3\end{bmatrix} x3=[23] 、 x 4 = [ 4 4 ] x_4 = \begin{bmatrix} 4 \ 4\end{bmatrix} x4=[44] 、 x 5 = [ 2 4 ] x_5 = \begin{bmatrix} 2 \ 4 \end{bmatrix} x5=[24] ,将它们表示成矩阵形式: X = [ 1 1 2 4 2 1 3 3 4 4 ] X = \begin{bmatrix} 1 & 1 & 2 & 4 & 2 \ 1 & 3 & 3 & 4 & 4 \end {bmatrix} X=[1113234424] 。

为了后续处理方便,我们首先将每个字段内所有值都减去字段均值,其结果是将每个字段都变为均值为 0。
我们看上面的数据,设第一个特征为 a a a ,第二个特征为 b b b ,则某个样本可以写作 x i = [ a b ] x_i = \begin{bmatrix} a \ b \end {bmatrix} xi=[ab]
且特征 a a a 的均值为 2,特征 b b b 的均值为 3。所以,变换后
X = [ − 1 − 1 0 2 0 − 2 0 0 1 1 ] X = \begin{bmatrix} -1 & -1 & 0 & 2 & 0 \ -2 & 0 & 0 & 1 & 1 \end{bmatrix} X=[−1−2−10002101]
V a r ( a ) = 6 5 Var(a ) = \frac{\sqrt 6} {5} Var(a)=56
V a r ( b ) = 6 5 Var(b ) = \frac{\sqrt 6} {5} Var(b)=56
4.协方差
协方差(Covariance)在概率和统计学中用于衡量两个变量的总体误差。比如对于二维随机变量 x i = [ a b ] x_i = \begin{bmatrix} a \ b \end{bmatrix} xi=[ab] ,特征 a 、 b a、b a、b 除了自身的数学期望和方差,还需要讨论 a 、 b a、b a、b 之间互相关系的数学特征。
定义协方差 C o v Cov Cov :
C o v ( a , b ) = 1 m ∑ i = 1 m a i b i Cov(a, b) = \frac{1}{m}\sum_{i = 1}^m a_i b_i Cov(a,b)=m1i=1∑maibi
当 C o v ( a , b ) = 0 Cov(a, b) = 0 Cov(a,b)=0 时,变量 a 、 b a、b a、b 完全独立,这也是我们希望达到的优化目标。方差是协方差的一种特殊情况,即当两个变量是相同的情况 C o v ( a , a ) = V a r ( a ) Cov(a, a) = Var(a) Cov(a,a)=Var(a) 。
5.协方差矩阵
对于二维随机变量 x i = [ a b ] x_i = \begin{bmatrix} a \ b \end {bmatrix} xi=[ab] ,定义协方差矩阵 C = [ V a r ( a ) C o v ( a , b ) C o v ( b , a ) V a r ( b ) ] C = \begin{bmatrix} Var(a) & Cov(a, b) \ Cov(b, a) &Var(b)\end{bmatrix} C=[Var(a)Cov(b,a)Cov(a,b)Var(b)] 。
对于 n n n 维随机变量
x i = [ x 1 x 2 ⋮ x n ] x_{i}=\left[\begin{array}{c} x_{1} \ x_{2} \ \vdots \ x_{n} \end{array}\right] xi=⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤
C = [ V a r ( x 1 ) C o v ( x 1 , x 2 ) ⋯ C o v ( x 1 , x n ) C o v ( x 2 , x 1 ) V a r ( x 2 ) ⋯ C o v ( x 1 , x n ) ⋮ ⋮ ⋱ ⋮ C o v ( x n , x 1 ) C o v ( x n , x 2 ) ⋯ V a r ( x n ) ] C = \begin{bmatrix} Var(x_1) & Cov(x_1, x_2) &\cdots & Cov(x_1, x_n)\ Cov(x_2, x_1)& Var(x_2) & \cdots & Cov(x_1, x_n)\ \vdots & \vdots & \ddots & \vdots \ Cov(x_n, x_1) & Cov(x_n, x_2) & \cdots &Var(x_n) \end{bmatrix} C=⎣⎢⎢⎢⎡Var(x1)Cov(x2,x1)⋮Cov(xn,x1)Cov(x1,x2)Var(x2)⋮Cov(xn,x2)⋯⋯⋱⋯Cov(x1,xn)Cov(x1,xn)⋮Var(xn)⎦⎥⎥⎥⎤
我们可以看到,协方差矩阵是 n n n 行 n n n 列的对称矩阵,主对角线上是方差,而协对角线上是协方差。
我们再来用一个示例对应讲解一下。还是同样的 5 个样本数据
-
x 1 = [ 1 1 ] x_1 = \begin{bmatrix} 1 \ 1 \end{bmatrix} x1=[11]
-
x 2 = [ 1 3 ] x_2 = \begin{bmatrix} 1 \ 3\end{bmatrix} x2=[13]
-
x 3 = [ 2 3 ] x_3 = \begin{bmatrix} 2 \ 3\end{bmatrix} x3=[23]
-
x 4 = [ 4 4 ] x_4 = \begin{bmatrix} 4 \ 4\end{bmatrix} x4=[44]
-
x 5 = [ 2 4 ] x_5 = \begin{bmatrix} 2 \ 4 \end{bmatrix} x5=[24]
去中心化后表示成矩阵
X = [ − 1 − 1 0 2 0 − 2 0 0 1 1 ] X = \begin{bmatrix} -1 & -1 & 0 & 2 & 0 \ -2 & 0 & 0 & 1 & 1 \end{bmatrix} X=[−1−2−10002101]
那如果有 m m m 个样本的话, X = [ a 1 a 2 ⋯ a m b 1 b 2 ⋯ b m ] X =\begin{bmatrix} a_1 & a_2 & \cdots &a_m \ b_1 & b_2 & \cdots & b_m\end{bmatrix} X=[a1b1a2b2⋯⋯ambm] 。对 X X X 做一些变换,用 X X X 乘以 X X X 的转置,并乘上系数 1 / m 1/m 1/m :
1 m X X T = 1 m [ a 1 a 2 ⋯ a m b 1 b 2 ⋯ b m ] [ a 1 b 1 a 2 b 2 ⋮ ⋮ a m b m ] = = [ 1 m ∑ i = 1 m a i 2 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m b i 2 ] \frac{1}{m}XX^T = \frac{1}{m}\begin{bmatrix} a_1 & a_2 & \cdots &a_m \ b_1 & b_2 & \cdots & b_m\end{bmatrix}\begin{bmatrix} a_1 & b_1 \ a_2 & b_2 \ \vdots & \vdots \ a_m &b_m \end{bmatrix}== \begin{bmatrix} \frac{1}{m} \sum_{i = 1}^m a_i ² & \frac{1}{m}\sum_{i = 1}^m a_i b_i \ \frac{1}{m}\sum_{i = 1}^m a_i b_i& \frac{1}{m} \sum_{i = 1}^m b_i² \end{bmatrix} m1XXT=m1[a1b1a2b2⋯⋯ambm]⎣⎢⎢⎢⎡a1a2⋮amb1b2⋮bm⎦⎥⎥⎥⎤==[m1∑i=1mai2m1∑i=1maibim1∑i=1maibim1∑i=1mbi2]
这正是协方差矩阵!我们归纳得到:设我们有 m m m 个 n n n 维数据记录,将其按列排成 n n n 乘 m m m 的矩阵 X X X ,设 C = 1 m X X T C = \frac{1}{m}XX^T C=m1XXT ,则 C C C 是一个对称矩阵,其对角线分别个各个特征的方差,而第 i i i 行 j j j 列和 j j j 行 i i i 列元素相同,表示 i i i 和 j j j 两个特征之间的协方差。
6.协方差矩阵对角化
再回到我们的场景和目标:
-
现在我们有 m m m 个样本数据,每个样本有 n n n 个特征,那么设这些原始数据为 X X X , X X X 为 n n n 行 m m m 列的矩阵。
-
想要找到一个基 P P P ,使 Y r × m = P r × n X n × m Y_{r \times m} = P_{r \times n}X_{n \times m} Yr×m=Pr×nXn×m ,其中 $r<n $,达到降维的目的。
设 X X X 的协方差矩阵为 C C C , Y Y Y 的协方差矩阵为 D D D ,且 Y = P X Y = PX Y=PX 。
- 我们的目的变为:对原始数据 X X X 做 PCA 后,得到的 Y Y Y 的协方差矩阵 D D D 的各个方向方差最大,协方差为 0。
那么 C C C 与 D D D 是什么关系呢?
D = 1 m Y Y T = 1 m ( P X ) ( P X ) T = 1 m P X X T P T = 1 m P ( X X T ) P T = P C P T = P [ 1 m ∑ i = 1 m a i 2 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m b i 2 ] P T \begin{aligned} D & =\frac{1}{m} Y Y^{T} \ & =\frac{1}{m}(P X)(P X)^{T} \ & =\frac{1}{m} P X X^{T} P^{T} \ & =\frac{1}{m} P\left(X X^{T}\right) P^{T} \ & =P C P^{T} \ & =P\left[\begin{array}{cc} \frac{1}{m} \sum_{i=1}^{m} a_{i}^{2} & \frac{1}{m} \sum_{i=1}^{m} a_{i} b_{i} \ \frac{1}{m} \sum_{i=1}^{m} a_{i} b_{i} & \frac{1}{m} \sum_{i=1}^{m} b_{i}^{2} \end{array}\right] P^{T} \end{aligned} D=m1YYT=m1(PX)(PX)T=m1PXXTPT=m1P(XXT)PT=PCPT=P[m1∑i=1mai2m1∑i=1maibim1∑i=1maibim1∑i=1mbi2]PT
我们发现,要找的 P P P 不是别的,而是能让原始协方差矩阵对角化的 P P P 。
换句话说,优化目标变成了寻找一个矩阵 P P P ,满足 P C P T PCP^T PCPT 是一个对角矩阵,并且对角元素按从大到小依次排列,那么 $P 的前 $K 行就是要寻找的基,用 P P P 的前 K K K 行组成的矩阵乘以 X X X 就使得 X X X 从 N N N 维降到了 K K K 维并满足上述优化条件。
最终我们聚焦在协方差矩阵对角化这个问题上。
由上文知道,协方差矩阵 C C C 是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:
1)实对称矩阵不同特征值对应的特征向量必然正交。
2)设特征向量 λ \lambda λ 重数为 r r r ,则必然存在 r r r 个线性无关的特征向量对应于 λ \lambda λ ,因此可以将这 r r r 个特征向量单位正交化。
由上面两条可知,一个 n n n 行 n n n 列的实对称矩阵一定可以找到 n n n 个单位正交特征向量,设这 n n n 个特征向量为 e 1 , e 2 , ⋯ , e n e_1,e_2,⋯,e_n e1,e2,⋯,en ,我们将其按列组成矩阵:
E = [ e 1 e 2 ⋯ e n ] E = \begin{bmatrix} e_1 & e_2 & \cdots \ e_n\end{bmatrix} E=[e1e2⋯ en]
则对协方差矩阵 C C C 有如下结论:
E T C E = Λ = [ λ 1 λ 2 ⋱ λ n ] E^T C E = \Lambda = \begin{bmatrix} \lambda_1 \ & \lambda_2 \ &&\ddots \ &&&\lambda_n\end {bmatrix} ETCE=Λ=⎣⎢⎢⎡λ1λ2⋱λn⎦⎥⎥⎤
其中 Λ \Lambda Λ 为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。
结合上面的公式:
D = P C P T D = PCP^T D=PCPT
其中, D D D 为对角矩阵,我们可以得到:
P = E T P = E^T P=ET
P P P 是协方差矩阵 C C C 的特征向量单位化后按行排列出的矩阵,其中每一行都是 C C C 的一个特征向量。如果设 P P P 按照 Λ \Lambda Λ 中特征值的从大到小,将特征向量从上到下排列,则用 P P P 的前 K K K K K K 行组成的矩阵乘以原始数据矩阵 X X X ,就得到了我们需要的降维后的数据矩阵 Y Y Y 。
7.PCA 算法
总结一下 PCA 的算法步骤:

设有 m m m 条 n n n 维数据。
1)将原始数据按列组成 n n n 行 m m m 列矩阵 X X X
2)将 X X X 的每一行(代表一个特征)进行零均值化,即减去这一行的均值
3)求出协方差矩阵 C = 1 m X X T C=\frac{1}{m}XX^T C=m1XXT
4)求出协方差矩阵 C C C 的特征值及对应的特征向量
5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前 k k k 行组成矩阵 P P P
6) Y = P X Y=PX Y=PX 即为降维到 k k k 维后的数据
8.PCA 代码实践
我们这里直接使用 python 机器学*工具库 scikit-learn 来给大家演示 PCA 算法应用(相关知识速查可以查看 ShowMeAI 文章 AI 建模工具速查|Scikit-learn 使用指南),sklearn 工具库中与 PCA 相关的类都在 sklearn.decomposition 包里,最常用的 PCA 类就是 sklearn.decomposition.PCA。
1)参数介绍
sklearn 中的 PCA 类使用简单,基本无需调参,一般只需要指定需要降维到的维度,或者降维后的主成分的方差和占原始维度所有特征方差和的比例阈值就可以了。
下面是sklearn.decomposition.PCA的主要参数介绍:
-
n_components:PCA 降维后的特征维度数目。
-
whiten:是否进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化,让方差都为 1,默认值是 False,即不进行白化。
-
svd_solver:奇异值分解 SVD 的方法,有 4 个可以选择的值:{‘auto’,‘full’,‘arpack’,‘randomized’}。
除上述输入参数,还有两个 PCA 类的成员属性也很重要:
-
① explained_variance_,它代表降维后的各主成分的方差值。
-
② explained_variance_ratio_,它代表降维后的各主成分的方差值占总方差值的比例。
2)代码实例
# 构建数据样本并可视化
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
from sklearn.datasets import make_blobs
# X 为样本特征,Y 为样本簇类别, 共 1000 个样本,每个样本 3 个特征,共 4 个簇
X, y = make_blobs(n_samples=10000, n_features=3, centers=[[3,3, 3], [0,0,0], [1,1,1], [2,2,2]], cluster_std=[0.2, 0.1, 0.2, 0.2],
random_state =9)
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=30, azim=20)
plt.scatter(X[:, 0], X[:, 1], X[:, 2],marker='x')

先不降维,只对数据进行投影,看看投影后的三个维度的方差分布,代码如下:
from sklearn.decomposition import PCA
pca = PCA(n_components=3)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
输出如下:
[0.98318212 0.00850037 0.00831751]
[3.78521638 0.03272613 0.03202212]
可以看出投影后三个特征维度的方差比例大约为 98.3%:0.8%:0.8%。投影后第一个特征占了绝大多数的主成分比例。现在我们来进行降维,从三维降到 2 维,代码如下:
pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
输出如下:
[0.98318212 0.00850037]
[3.78521638 0.03272613]
这个结果其实可以预料,因为上面三个投影后的特征维度的方差分别为:[ 3.78521638 0.03272613],投影到二维后选择的肯定是前两个特征,而抛弃第三个特征。为了有个直观的认识,我们看看此时转化后的数据分布,代码如下:
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1],marker='x')
plt.show()

从上图可以看出,降维后的数据依然清楚可见之前三维图中的 4 个簇。现在我们不直接指定降维的维度,而指定降维后的主成分方差和比例,来试验一下。
pca = PCA(n_components=0.9)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
我们指定了主成分至少占 90%,输出如下:
[0.98318212]
[3.78521638]
1
可见只有第一个投影特征被保留。这也很好理解,我们的第一个主成分占投影特征的方差比例高达 98%。只选择这一个特征维度便可以满足 90%的阈值。我们现在选择阈值 99%看看,代码如下:
pca = PCA(n_components=0.99)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
此时的输出如下:
[0.98318212 0.00850037]
[3.78521638 0.03272613]
2
这个结果也很好理解,因为我们第一个主成分占了 98.3%的方差比例,第二个主成分占了 0.8%的方差比例,两者一起可以满足我们的阈值。最后我们看看让 MLE 算法自己选择降维维度的效果,代码如下:
pca = PCA(n_components= 'mle',svd_solver='full')
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
print(pca.n_components_)
输出结果如下:
[0.98318212]
[3.78521638]
1
可见由于我们的数据的第一个投影特征的方差占比高达 98.3%,MLE 算法只保留了我们的第一个特征。
更多无监督学*的算法模型总结可以查看 ShowMeAI 的文章 AI 知识技能速查 | 机器学*-无监督学*。
参考链接
ShowMeAI 相关文章推荐
- 1.机器学*基础知识
- 2.模型评估方法与准则
- 3.KNN 算法及其应用
- 4.逻辑回归算法详解
- 5.朴素贝叶斯算法详解
- 6.决策树模型详解
- 7.随机森林分类模型详解
- 8.回归树模型详解
- 9.GBDT 模型详解
- 10.XGBoost 模型最全解析
- 11.LightGBM 模型详解
- 12.支持向量机模型详解
- 13.聚类算法详解
- 14.PCA 降维算法详解
ShowMeAI 系列教程推荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学基础:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学*算法:从入门到精通系列教程



浙公网安备 33010602011771号