轻松入门自然语言处理系列 05 机器学习基础

前言

本文主要介绍了机器学习基础,包括朴素贝叶斯的基础概念、训练、优化,决策树的基本概念、不确定性和过拟合,随机森林的基本概念、方差分析、训练和过拟合。

一、理解朴素贝叶斯

1.初试朴素贝叶斯

朴素贝叶斯模型是文本领域永恒的经典,广泛应用在各类文本分析的任务上。通常来讲,只要遇到了文本分类问题,第一个需要想到的方法就是朴素贝叶斯,它在文本分类任务上是一个非常靠谱的基准(baseline)。比如对于垃圾邮件的分类,朴素贝叶斯是一个极其有效且简单的模型。不要小看一个简单的模型,实际上,我们真正需要的是既简单同时又有效的模型,因为最终的目的是用最小成本来解决问题。一个简单的模型既有利于短时间内训练,也有助于后续的维护和管理。

朴素贝叶斯,名字里的朴素源自于概率统计里的条件独立,因为在构造模型过程中做了一层基于条件独立的简化操作。朴素贝叶斯模型作为分类算法,非常适合用在各类文本分类任务上,如下:

  • 垃圾邮件分类
    自动判断一个邮件是否为垃圾邮件或者正常邮件。
  • 文本主题分类
    把一个文本按照主题做分类如体育类、娱乐类等。
  • 情感分析
    把给定的文本分类成正面或者负面情感。

2.朴素贝叶斯核心思想

朴素贝叶斯的核心思想极其简单:统计出不同文本类别中出现的单词的词频

比如,对于垃圾邮件的分类任务,只需要统计出哪些单词经常出现在垃圾邮件中、哪些单词经常出现在正常邮件中就可以了。如果在邮件里看到了“广告”、“购买”、“链接”等关键词,可以认为这个邮件很可能是垃圾邮件,因为这些单词经常出现在垃圾邮件中,其实很多邮件过滤系统就是这样过滤垃圾邮件的。当然,也可以自行设定一些规则来过滤垃圾邮件。在这种规则中,通常也是指定哪些单词跟垃圾邮件相关。

如果按照词库来判断一个邮件是垃圾邮件还是正常邮件,即以词库为依据来直接判定邮件的种类有点类似于“一刀切”的方法,是存在一定的问题的,其问题在于:即便出现了一些广告类单词,但并不一定是垃圾邮件;没有出现任何广告类单词也不一定是正常邮件。所以每个单词虽然有倾向性,但不能以偏概全。其实更好的方案是加入一些概率的要素,把不确定性也加进来,比如虽然出现了“广告”、“推销”等关键词,但同时也出现了大量的没有包含在词库里的单词,并将这些不同的单词以概率统计的方式整合在一起,最终在概率的角度来判定是正常邮件或者垃圾邮件,这实际上就是朴素贝叶斯模型的核心思想。

使用朴素贝叶斯模型一般需要两个步骤:

(1)首先,统计出每一个单词对一个邮件成为垃圾邮件或正常邮件的贡献。比如p(广告∣垃圾)、p(广告∣正常),分别代表在垃圾/正常邮件里出现“广告”这个关键词的概率;

(2)其次,用这些统计的结果对一个新的邮件做预测。

3.朴素贝叶斯的应用:垃圾邮件分类

朴素贝叶斯广泛地应用在文本分类任务中,其中最为经典的场景为垃圾文本分类,即给定一个邮件,把它自动分类为垃圾或者正常邮件。这个任务本身是属于文本分析任务,因为对应的数据均为文本类型,所以对于此类任务,首先需要把文本转换成向量的形式,然后再输入到模型中。

举例如下:

在这里插入图片描述

垃圾邮件的数据集如下:

在这里插入图片描述

可以看到,第一列是邮件标签,其中ham表示正常邮件、spam表示垃圾邮件,第二列是邮件的具体内容。所以这是一个典型的二分类任务。在进行分类前,还需要对文本进行处理,包括分词、向量化(tf-idf、词向量、句向量等)。

(1)查看数据基本状况

# 统计数量
# 数据形状
print(data.shape)
# 非垃圾邮件和垃圾邮件的数目
print(data.label.value_counts())

输出:

(5572, 2)
ham     4825
spam     747
Name: label, dtype: int64

(2)类别标签数值化

# 将类别标签数值化
data['numLabel'] = data['label'].map({'ham': 0, 'spam': 1})
data.head()

输出:

在这里插入图片描述

(3)构建词向量

# 基于词频表示构建文本向量
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(data.message)
y = data.numLabel

(4)数据划分训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=100)
print('训练样本数:', X_train.shape[0], '测试样本数:', X_test.shape[0])

输出:

训练样本数: 4457 测试样本数: 1115

(5)训练和测试

# 利用朴素贝叶斯进行训练
clf = MultinomialNB(alpha=1.0, fit_prior=True)
clf.fit(X_train, y_train)
# 进行测试
y_pred = clf.predict(X_test)
print('accuracy on test data: ', accuracy_score(y_test, y_pred))

输出:

accuracy on test data:  0.979372197309417

(6)使用混淆矩阵进行分析

# 混淆矩阵进行分析
confusion_matrix(y_test, y_pred, labels=[0, 1])

输出:

array([[955,  13],
       [ 10, 137]], dtype=int64)

其中,混淆矩阵是一个很好的分类任务的工具,可以帮助分析分类不准确的原因,以促进进一步修改。

完整代码和数据可参考https://download.csdn.net/download/CUFEECR/82439916

二、朴素贝叶斯的训练

正如之前说过的一样,朴素贝叶斯训练的核心步骤就是统计各个单词在不同类别中的概率。举个例子,当我们去分析一个文件是否为垃圾邮件或者正常邮件时,一个判断的依据是如果很多跟垃圾邮件相关的关键词出现在了文本里,我们即可以把它归类为垃圾邮件,这些决策最终基于概率统计的方式来实现。

总体来讲,朴素贝叶斯分为两个阶段:

  1. 计算每个单词在不同分类中所出现的概率,这个概率是基于语料库(训练数据)来获得的。
  2. 利用已经计算好的概率,再结合贝叶斯定理就可以算出对于一个新的文本,它属于某一个类别的概率值,并通过这个结果做最后的分类决策。

通过给定的正常和垃圾邮件数据(文本内容)训练出模型,在给定新的邮件时,即可使用模型判断该邮件是正常邮件还是垃圾邮件。如下:

在这里插入图片描述

1.计算单词的概率

以垃圾邮件分类为例,计算正常邮件和垃圾邮件中每个单词的概率:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

可以看到,对于一些词,比如“购买”、“物品”等,在正常邮件和垃圾邮件中概率相差较大,而对于另外一些词,例如“不是”等,则差别不大,因此可以使用这些概率来进行类别判断。

除此之外,还需要进行先验概率的计算:

在这里插入图片描述

2.利用计算好的概率来预测

现在已经算好了每一个单词在不同类别中的概率,以及垃圾邮件和正常邮件在整个数据集中的占比,后者也称之为先验概率(prior)。统计完这些概率之后,就可以使用它们来预测一个邮件是否为垃圾或者正常邮件,即整合这些信息来完成识别任务:

在这里插入图片描述

3.贝叶斯定理

为了表示两个条件概率值 p(垃圾|邮件内容)和 p(正常|邮件内容),需要用到一个著名的概率公式:贝叶斯定理。利用贝叶斯定理可以把上述条件概率做进一步的分解,最终可以计算出它们的值。如下:

在这里插入图片描述

贝叶斯定理的更多解释可参考https://zhuanlan.zhihu.com/p/45432367

4.计算预测概率

朴素贝叶斯模型的训练实质上就是统计和计算每个单词在不同条件下的概率。在使用贝叶斯定理时,需要用到条件独立(conditional independence)的假设。

举例如下:

在这里插入图片描述

从计算结果可以看出,该邮件被分类为正常邮件是不合理的,这是因为“这”单词没有在垃圾邮件中出现过,因此在计算P(垃圾|邮件内容)时,概率乘积有一项为0,导致最终结果为0。这个问题可以通过平滑的方式来解决。

在预测过程中使用条件独立的假设,简单来讲,基于这个性质可以把条件概率p(x,y∣z)写成p(x,y∣z)=p(x∣z)p(y∣z)的形式,这时候可以说变量x和变量y是条件独立于变量z的。这也是为什么把朴素贝叶斯说成“朴素”的主要原因,因为做了一层计算上的简化。如果不使用条件独立的假设,我们是不能把概率p(x,y∣z)写成上述形式的,这样一来问题就变得格外地复杂。条件独立的性质可以延展到更多的变量,如p(x1,x2,x3∣y)=p(x1∣y)p(x2∣y)p(x3∣y)。当把这里的每个变量xi看作每一个单词的时候,就得到了朴素贝叶斯模型。

5.处理概率为0的情况——平滑

在上述过程中可以看到分子的计算过程涉及到了很多概率的乘积,一旦遇到这种情形,就要知道可能会有潜在的风险。比如其中一个概率值等于0,那不管其他概率值是多少,最后的结果一定为0,有点类似于“功亏一篑”的情况,明明出现了很多垃圾邮件相关的单词,就是因为其中的一个概率0,最后判定为属于垃圾邮件的概率为0,这显然是不合理的。为了避免单词出现次数为0进而导致概率为0的情况,需要进行平滑处理。常用的方式是加1平滑(Add-one Smoothing)。

如下:

在这里插入图片描述

可以看到,在进行调整时,分母加v是为了保证条件概率的合理性。

6.朴素贝叶斯练习

再举一个例子,基于6封邮件构建朴素贝叶斯模型。

需要先构建词库,进而计算正常邮件和垃圾邮件中各个词的概率,再使用朴素贝叶斯模型进行计算:

在这里插入图片描述

在计算过程中,因为每个概率都很小,因此可能出现underflow的情况,即每个数都很小,得到的乘积结果也很小,此时可以使用对数的形式。

三、朴素贝叶斯的优化

1.朴素贝叶斯的最大似然估计

前面已经涉及了朴素贝叶斯模型以及如何估算每个单词的概率,并用这个概率来预测一个文本的分类。计算语料库中每个单词的条件概率,这个过程实际上是模型训练的过程。现在从另外一个更严谨的角度来学习朴素贝叶斯。首先,构造朴素贝叶斯的目标函数,之后再试着去寻找朴素贝叶斯的最优解。最终会发现,以这种方式得出来的最优解恰恰就是上一节里计算出的结果。为了推导出朴素贝叶斯的目标函数,我们仍需要从最大似然开始入手,并通过最大似然估计来获得朴素贝叶斯的目标函数。

最大似然估计是机器学习领域最为常见的用来构建目标函数的方法,它的核心思想是根据观测到的结果来预测其中的未知参数。如下:

在这里插入图片描述

假设未知参数为θ,已知的样本为D,最大似然估计通过最大化p(Dlθ)来求解未知参数θ,如下:

在这里插入图片描述

现在分析朴素贝叶斯的最大似然估计,以离散型的朴素贝叶斯为例,如下:

在这里插入图片描述

可以看到,这里使用的是生成式模型,也就是最大化的是每个样本的特征向量和标签的联合概率,而不是条件概率。而之前的逻辑函数最大化的是条件概率,属于判别式模型

可以看到,此时还不能从模型中区分出参数,需要进一步构造参数,如下:

在这里插入图片描述

现在就得到了朴素贝叶斯的目标函数,此时就只有参数θ和π是未知参数,需要通过后续的优化来求得最优解。

2.带限制条件的优化

从上述目标函数中可以发现它具有一个限制条件,这样的优化问题也称之为带限制条件的优化(constrained optimization)。在逻辑回归中的优化就属于无限制条件的优化问题,带限制条件的优化相比无限制条件的优化稍微复杂一些。

先看无约束条件的优化:

在这里插入图片描述

再看带约束条件的优化,此时需要用到拉格朗日乘法项(Lagrangian Multiplier)。如下:

在这里插入图片描述

3.朴素贝叶斯目标函数的优化

现在对目标函数进行优化:

先求解π:

在这里插入图片描述

再求解θ:

在这里插入图片描述

可以看到,π的含义就是种类k的样本数占总样本数的比例,这与前面使用朴素贝叶斯进行计算的直观感觉是相同的;再理解θ,对于第k个类别,分子的含义是第j个单词出现的次数,分母的含义是所有单词出现的总次数,与前面使用朴素贝叶斯进行计算的方式也是一样的。

可以看到,通过这种方式得出来的结果跟前面计算的结果是吻合的。可以说,任何一个计算结果实际上都是有背后的依据的。为了更好地理解每一个知识点,我们需要尝试着去深挖底层的细节,这样才能达到打通知识体系的目的。

四、认识和理解决策树

1.决策树的应用

决策树在机器学习领域的地位很高,还是几个经典集成模型(随机森林、提升树)的基础。其实我们每天都在使用决策树,这是我们做日常决策的工具。举个例子,“明天如果下雨我就不出门了。” 在这里我们用了一个决策条件:是否下雨,然后基于这个条件会有不同的结果:出门和不出门。 这就是一个经典的决策树。再举个稍微复杂点的,“如果完整地学完NLP系列,可以胜任算法岗位。” 这里的决策条件是:课程学完与否,以及是否做完作业,结果是:能否胜任算法岗位。这就是决策树。可以说,在所有的机器学习模型中,决策树是最贴近实际生活的。

举例如下:

在这里插入图片描述

张三和李四都是医生,但他们的诊断逻辑还是不太一样的,具体如上图所示。虽然都去关注“肌肉疼痛”和“发烧”两个症状,张医生首先判断患者是否有发烧症状,李医生则先看患者是否有肌肉疼痛感。这个例子中涉及到了几个核心点:(1)两位医生都具有属于自己的决策树,而且他们在诊断过程中都会按照自己的决策树逻辑来诊断。(2)医生的能力也有好坏之分,在这里我们可以把这两个决策树看作是两位医生的能力,而且这种能力是由大量的临床经验获得的。这样一来,哪一个决策树好就等同于哪一位医生的医术更加高明。我们把临床经验可以看作是历史样本数据。(3)为了判断哪位医生的医术更高明,需要知道哪一个决策树更好,这就要求我们定义出一种评估决策树好坏的标准。

在机器学习中,基于历史的样本或者经验,可以构造出不同的决策树,但只要定义出了一种评估方式则可以选出其中最好的那棵决策树,这其实就是决策树的训练过程。

2.决策树的形态与决策边界

决策树由节点和边组成:

在这里插入图片描述

可以看到,节点包含了决策边界,边是具体的条件。

一棵决策树有对应的决策边界,举例如下:

在这里插入图片描述

从数据中学到决策树,需要学习三件东西:

  • 树的形状
  • 每一个决策的阈值θi
  • 叶节点的值

通过这3个要素可以唯一地确定一棵决策树。一棵决策树拥有大量的参数,但树本身是具有一定结构的。结构的学习也叫作Structured Prediction,因为这种问题不像之前讨论的比如回归问题只需要预测一个值就可以了,而是同时也要学出树的结构。结构的学习一般来说都很难,很多都是NP-hard问题,简单来讲NP-hard问题就是那些多项式时间复杂度内基本上解不出来的问题,一般需要指数级复杂度。在计算机世界里存在大量的NP-hard问题等待我们去解决。一般对于这类的问题是没有一个很好的方式来求出全局最优解的。既然这样,我们通常会使用近似算法来找到“相对”最好的解,一个经典的近似算法就是贪心算法:这类算法每次只考虑局部最好的情况,所以一般带来的是相对最好的解决方案。但在某些特定的情况下,也可以给出全局最优解。给定数据并学出最好的决策树本身也是很难的问题,因此也通常使用贪心算法来做每一步的决策,比如使用信息增益来判断下一个节点上需要放哪一个特征。

3.认识决策树

现在分析基于给定数据构造决策树:

在这里插入图片描述

两种方案如下:

在这里插入图片描述

可以看到,第1个决策树要优于第2个决策树,因为它的准确率更高。由于这个问题本身及其简单,所以可以罗列出所有可能的决策树,然后再判断哪一个最好。

在通常情况下,给定数据的维度很大,可能有几百或者上千、上万个特征,决策树的种类也会很大,一般就是指数级的关系,不可能一一罗列:
在这里插入图片描述

计算量很大。此时就需要用到贪心算法,从庞大的决策树集合中选出针对当前数据最优的决策树。

五、决策树中的不确定性

1.好的特征

我们希望得到的是分类效果好的决策树,而且越简单越好。如下:

在这里插入图片描述

一个好的特征具有很好的区分度,能够尽可能简单地划分出类别。因此是否头痛是一个更好的特征,因为这个特征可以把所有的样本分类得正确。

2.信息熵:不确定性

好的特征可以减少不确定性:

在这里插入图片描述

根据某一个特征做分割之后,不确定性变小了,用数学语言表示就是信息熵

信息熵的定义如下:

H ( X ) = − ∑ p ( x i ) log ⁡ ( p ( x i ) ) H(X)=-\sum p\left(x_{i}\right) \log \left(p\left(x_{i}\right)\right) H(X)=p(xi)log(p(xi))

其中,信息熵越大,不确定性越大,信息熵越小,不确定性越小。

举例如下:

在这里插入图片描述

3.信息增益:不确定性的减少

(1)不确定性减少

在选择特征构建决策树时,需要选择使得不确定性降低最多的特征作为当前根节点,不确定性的减少即信息增益(information gain),是原来的不确定性减去现在的不确定性,公式如下:

I G ( T , a ) = H ( T ) − H ( T ∣ a ) I G(T, a)=H(T)-H(T \mid a) IG(T,a)=H(T)H(Ta)

在这里插入图片描述

可以看到,选择是否疼痛时,不确定性减少的幅度更大,因此选择是否疼痛作为当前的根节点。

(2)从零开始构建决策树

构建决策树的过程就是每一步通过信息增益来选择最好的特征作为当前的根节点,以此类推,持续把树构造起来。下面,通过一个稍微复杂一点的例子来说明一棵决策树从零开始构建的完整过程。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到,最后计算出了选择4个特征作为根节点的信息增益。其中,count surface特征对应的信息增益最大,因此选择该特征作为根节点。第一层决策树搭建如下:
在这里插入图片描述

可以看到,在得到的4个子树中,3个子树的类别是相同的,不确定性极小、不需要再分裂,只有Clay子树还需要进一步分裂:

在这里插入图片描述

得到决策树的搭建结果如下:

在这里插入图片描述

可以看到,此时所有的子树都不能再进行进一步分裂,构建过程可以到此结束。可以看到,这是一个递归的过程,需要不断进行,直到不能再分裂为止。

总结一下,每一步的构建过程其实就是选择当前最好的特征作为根节点,然后持续地重复以上过程把整棵树构建起来。其中,信息增益充当着每次选择特征的标准。当然,除了信息增益,也可以选择其他的指标作为选择特征的标准。其实还有几个重要问题需要考虑,比如如何让决策树避免过拟合、如何处理连续型特征、如何使用决策树来解决回归问题等。

六、决策树的过拟合

1.决策树表现与节点数目之间的关系

什么时候可以停止分裂:

  • 当一个叶节点(leaf node)里包含的所有的样本都属于同一个类别时停止分裂;
  • 当一个叶节点里包含的所有样本的特征都一样时可以停止分裂。

满足以上两个条件就可以停止继续构建决策树了。首先,当所有的样本属于同一类别时就可以停下来,因为已经达成了最终的目的。另外,所有的特征都一样的时候其实也没办法继续了。所以,满足上面的条件就说明我们已经构建了完整的决策树。

决策树性能与节点个数之间的关系:

在这里插入图片描述

可以看到,随着节点数的增加,在训练集上的准确率越来越高,而在测试集上的准确率越来越低,这就是过拟合。节点数也是一个重要的超参数,需要通过调参找出最合适的节点数。

在逻辑回归里,可以通过加入正则的方式来减少过拟合现象。加入正则相当于限制了参数的大小,小的参数会有效防止过拟合现象。对于决策树来说,决策树里的节点个数跟过拟合有着很大的关系,因为节点个数越多,可以理解成模型的复杂度越高。减少过拟合现象的方式是决策树越简单越好,更简单的决策树的重要标准就是决策树中节点的个数,节点个数越少说明这棵决策树就越简单。

2.用于防止过拟合的方案

直接减少节点个数在实际操作中不太容易实现,因为决策树的构建过程其实是递归的过程。因此可以通过限制其他的方式来调节节点个数比如树的深度。只要是跟节点个数相关的变量,都可以用来控制决策树的复杂度。总体来讲,有以下2种方法可以用来减少决策树的过拟合:

  • 设置树的最大深度(maximum depth)
    树的深度越深,一般来讲节点个数也会越多,所以都是有一定的关系的。

  • 当叶节点里的样本个数少于阈值时停止分裂

    具体阈值选择多少取决于交叉验证的结果。

对决策树调参的时候,无非主要来调整树的深度、每一个叶节点样本的个数等。具体最优的参数一般通过交叉验证的方式来获得,这与其他模型是一样的。

七、集成模型随机森林

1.集成模型概念

对于几乎所有的分类问题(图像识别除外,因为对于图像识别问题,目前深度学习是标配),集成模型很多时候是首选。比如构建一个评分卡系统,业界的标配是GBDT或者XGBoost等集成模型,主要因为它的效果确实好,而且稳定。

还有一点是这些模型的可解释性也很好,不像深度学习模型就像个黑盒子。可解释性对于工业界应用来说尤其重要。比如一个模型出错了,希望第一时间能够找出问题的根源,但如果模型的可解释性比较差,则很难及时把问题定位出来。举个例子,金融类的应用是直接跟金钱挂钩的,一旦出了问题之后后果不堪设想。所以模型上线之前需要做大量的测试,而且提前要清楚地了解模型里的每个细节以及可能出错之后带来的后果。之所以集成模型的可解释性好,是因为随机森林或者提升树模型其实是基于决策树的,同时决策树模型的可解释性本来就很好。集成模型可以简单理解成决策树的集合

除了工业界应用,在各类数据竞赛上,集成模型也扮演着极其重要的角色。对于大部分的竞赛,使用集成模型是通向第一名的最快的捷径。当然,也离不开特征工程的部分。

集成模型是实际工作中可以采用的最有效的方法之一,如果对模型的选择没有好的想法,选择集成模型至少可以保证不会出错。

2.集成模型的优势

需要一个新的技术方案场景如下:

在这里插入图片描述

前者一个人做决策能力有限、考虑的可能不够周到,会存在一些缺陷;后者互相讨论并作决策,大家都会有各自的想法,进行思维的碰撞,从而得到更加完美的方案,可以避免一些严重的错误,这就是类似于集成模型的思想。

“三个臭皮匠顶个诸葛亮”也从侧面反映了集成模型的思想,多个人一起决策要优于一个人单干,至少多听取不同的建议会让自己少犯一些愚蠢的错误。

3.构造集成模型

构建集成模型,通常有两种方法:

  • Bagging
    随机森林采用的是Bagging方法。
  • Boosting
    GBDT和XGBoost采用的是Boosting方法。

基于Bagging的预测:

在这里插入图片描述

可以看到,通过投票决策的方式,结合了多个模型的预测结果,来作为最终的预测结果。随机森林是经典的Bagging模型,等同于同时训练了很多棵决策树,并同时用这些决策树来做决策。需要注意,各个模型之间是独立的,训练时也是独立训练的,这与Boosting是不同的。

八、随机森林与方差分析

1.方差和稳定性

在训练模型时,目的是要训练出泛化能力强的模型。为了一个模型具有较强的泛化能力,需要解决模型的过拟合现象。“不稳定的模型”的模型容易过拟合,也就是训练出来的模型放在训练数据上表现特别好,但放在真实的线上环境时就不行了。 就好比一个学生平时成绩非常好,但一到关键时刻就不灵了,这种现象可以简单地理解为不稳定,所以我们的目的是希望训练出一个稳定的模型。

在统计学里,方差和标准差是可以用来表示稳定性的。稳定性越高,则方差或者标准差越小。比如一个学生过去六次考试成绩分别是:50、55、54、56、56、54。可以说这个学生表现非常稳定,虽然一直是倒数第一名。当然我们希望这名学生努力奋斗,到了第二年时可以得到:98、99、100、96、97、94。这样的成绩,既稳定又优秀。训练模型也是一样的,我们希望这个模型既稳定、准确率也高。之所以集成模型更稳定,是因为如果通过集成模型做预测,它会减少方差(或者标准差),即可以认为模型稳定。

2.方差和稳定性举例

对于集成模型决策的方差和稳定性举例,如下:

假设我们邀请了7位专家,而且每一位专家在决策上犯错误的概率为0.3,那他们共同决策时最终犯错误的概率是多少?决策上采用多数服从少数原则,比如4个人选YES 、3个人选NO,最终预测结果是YES。

在这里插入图片描述

可以看到,进行集体决策的时候会降低犯错误的概率。

平均会带来方差的减少(Variance Reduction):假如有N个模型,每个模型在预测时的方差为 σ 2 σ^2 σ2,则通过N个模型—起预测时的方差会被平均,是 σ 2 N \frac{\sigma^{2}}{N} Nσ2

多个模型共同预测确实会降低方差,也就意味着提高模型的稳定性。但准确率不一定会保证提升,但通常来说集成模型的准确率还是要高于其他简单模型的。

九、随机森林的训练

1.随机森林的核心思想

Bagging流程如下:

在这里插入图片描述

构造模型时是并行的,各个模型之间互不相关;进行预测时先使用各个模型分别决策,再进行综合、得到最终预测结果。

既然随机森林也属于Bagging类型,训练和预测过程也跟上面是一样的。随机森林里有两个关键词,分别是随机森林:森林就是很多树的集合,也说明了模型本身的特点。

随机森林是通过多棵决策树共同做决策:

在这里插入图片描述

随机森林的预测过程就是多棵决策树共同作出决策:对于分类型问题,可以通过投票的方式;对于回归问题,可以采用平均法则。

2.随机森林的构造

构造随机森林的过程如下:

在这里插入图片描述

每棵决策树有自己的擅长点,可以捕获到不同的特征。

构造随机森林时需要考虑的点:

  • 只有一份训练数据
  • 确保多颗决策树要优于单颗决策树

这两点看起来没什么特别,但实际上非常重要。因为目的是要训练出效果更好、更稳定的模型,如果最后训练出来的多棵决策树比单棵决策树还要差,那就没必要使用随机森林了。

如果我们得出来的多棵决策树之间相关性比较大,其实做不到增加稳定性的作用,至少效果不会好。稳定性的基础是多样性(Diversity),只有多样性才能保证随机森林的效果,就比如在构建团队的时候,也希望每个人有自己的特点,这样可以起到很好的互补作用,补偿取短。构造出很多具备多样性的决策树的关键就在于随机

随机森林的“随机”体现在以下两方面:

  • 训练样本的随机化
    不选择全部样本,只随机选择部分样本。
  • 特征选择时的随机化
    不选择全部特征,只随机选择部分特征。

通过两个方面的随机操作,可以得出具备多样性的决策树。这也是为什么我们把它叫作“随机”森林的主要原因。

第一种随机化来自于样本的采样,也就是说每一棵决策树来自于不同的训练样本。随机采样(抽取样本)如下:

在这里插入图片描述

采样得到样本后训练得到决策树的过程是可以并行化的。

采样的过程称为Bootstrap,是一种抽样的方式,但可以重复抽样同样的样本(sample with replacement)。如下:

在这里插入图片描述

重复采样可以使得得到的决策树模型更具有多样性。

除了样本的随机化,在构造每一棵决策树的时候也会随机化特征。回顾之前的决策树模型,当要选择当前最好的特征作为根节点的时候,我们把所有可能的特征全部尝试了一遍然后选其中最好的。但在随机森林里,选择特征的时候首先会进行特征采样,比如从100个特征里选择10个,然后从10个当中选择最好的特征作为当前的根节点。 所以,每一次进行分裂的时候先要做特征的采样,然后一一进行比较,最后选择效果最好的。这两个方面的随机化可以保证带来多样化的决策树。当然除了这两个,还可以设计更多的随机化,但还是以这两个为主。

3.随机森林的预测

在训练好决策树、构建完随机森林之后,就可以使用得到的决策树进行共同预测:

在这里插入图片描述

根据不同的问题类型,选择不同的综合策略,例如分类问题就可以使用投票、回归问题就可以使用求均值。

十、随机森林的过拟合

1.随机森林的参数

随机森林模型本身对避免过拟合现象是有着不错的表现的,但这并不代表随机森林就不会出现过拟合。任何的一个机器学习模型都存着过拟合的风险。对于这个问题,目前主流的方法还是调参。前面已经提到过随机森林的调参中经常涉及到的超参数,包括split的时候随机选出来的特征个数等。

使用举例如下:

# -*- coding: utf-8 -*-

'''
@Author   :   Corley
@Time     :   2022-02-27 11:37
@Project  :   NLPDevilCamp-random_forest_digit
'''

from sklearn.datasets import load_digits  # 导入数字识别数据集
from sklearn.ensemble import RandomForestClassifier  # 导入随机森林分类器
from sklearn.model_selection import train_test_split

# 导入数据
digits = load_digits()
X = digits.data
y = digits.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

clf = RandomForestClassifier(n_estimators=400, criterion='entropy', max_depth=5, min_samples_split=3,
                             max_features='sqrt', random_state=0)
clf.fit(X_train, y_train)
print("训练集上的准确率为:%.2f, 测试数据上的准确率为:%.2f" % (clf.score(X_train, y_train), clf.score(X_test, y_test)))

输出:

训练集上的准确率为:0.98, 测试数据上的准确率为:0.95

可以看到,在训练集和预测集上的效果都是较好的。

2.案例:员工离职率预测

预测员工的离职率案例的问题核心是根据员工的一些数据来预测员工是否会有离职倾向,这是一个经典的二分类问题。对于这个问题,这里使用随机森林来预测。

(1)查看数据情况

# 计算离职员工的百分比和没有离职的百分比
turnover_rate = data.turnover.value_counts() / len(data)
print("样本数据中,离职率为:%.2f%%" % (turnover_rate[1] * 100))

输出:

样本数据中,离职率为:23.81%

(2)类别型特征数据转换

# 将string类型转换为整数类型
data["department"] = data["department"].astype('category').cat.codes
data["salary"] = data["salary"].astype('category').cat.codes

(3)训练决策树模型

# 训练模型

# 训练决策树
dtree = DecisionTreeClassifier(
    criterion='entropy',
    min_weight_fraction_leaf=0.01  # 定义叶子节点最少需要包含多少个样本(使用百分比表达), 防止过拟合
)
dtree = dtree.fit(X_train, y_train)
print("---决策树---")
print(classification_report(y_test, dtree.predict(X_test)))

输出:

---决策树---
              precision    recall  f1-score   support

           0       0.97      0.98      0.97      1714
           1       0.93      0.89      0.91       536

    accuracy                           0.96      2250
   macro avg       0.95      0.93      0.94      2250
weighted avg       0.96      0.96      0.96      2250

(4)训练随机森林模型

# 随机森林
rf = RandomForestClassifier(
    criterion='entropy',
    n_estimators=1000,
    min_samples_split=10  # 定义至少多少个样本的情况下才继续分叉
)
rf.fit(X_train, y_train)
print("---随机森林---")
print(classification_report(y_test, rf.predict(X_test)))

输出:

---随机森林---
              precision    recall  f1-score   support

           0       0.98      1.00      0.99      1714
           1       0.99      0.94      0.96       536

    accuracy                           0.98      2250
   macro avg       0.99      0.97      0.98      2250
weighted avg       0.98      0.98      0.98      2250

可以看到,决策树和随机森林模型的准确率都较高,同时随机森林模型相对决策树又有一定的提升。

完整代码和数据可参考https://download.csdn.net/download/CUFEECR/82576794

总结

包括朴素贝叶斯、决策树和随机森林在内的模型都是机器学习中常见且很重要的模型,为了进一步理解其他更加复杂和深入的模型,需要理解这些基础模型。

本文原文转载自问我社区,原文链接http://www.wenwoha.com/19/course_article?act_id=191http://www.wenwoha.com/19/course_article?act_id=202http://www.wenwoha.com/19/course_article?act_id=203

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI码东道主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值