【Machine Learning】02-Advanced Learning Algorithms

2. Advanced Learning Algorithms

2.1 Neural Network

2.1.1 概述

​ 人脑是极为发达且复杂的系统,在上世纪八十年代,人类就开始尝试对人脑的工作原理进行研究与模仿,这就催化了神经网络(neural networks)这门学科的诞生。在machine learning中谈论的神经学习,指的是“神经网络学习”,或者说是机器学习和神经网络这两个学科领域的交叉部分。

​ 神经元是人脑中非常重要的元素,它可以接受别的神经元的输入电信号,通过处理再转化为电信号输出给别的神经元。计算机科学对神经元处理问题的方法进行了模仿,例如在下图中的T恤衫销量预测案例中,最左侧为输入层(input layer),用来输入一些有关T恤衫的原始数据,最右侧为输出层(output layer),输出这款T恤是否可以大卖。

​ 我们可能会认为,一件T恤是否可以大卖取决于这几个点:负担能力,知名度,质量感知(可能因人而异,存在偏见)。这三个点就是我们想要创造的三个神经元节点(逻辑回归单元),例如:通过价格与运输成本来预测负担能力;通过市场来预测知名度,通过价格与材质来预测质量感知。最后通过一个神经元接收这三个数据,输出T恤大卖的概率。

​ 在神经网络中,我们把中间三个神经元组合为一层(layer),它被输入相同或相似的特征,然后输出几个数字。我们也常把中间层中的特征称为激活项(activations),中间层也被称为**“隐藏层”(hidden layer)。在实际运用中,我们并不需要亲自给出隐藏层应该有哪些参数,神经网络会根据输入层自动找到隐藏层中使用的特征,这就是神经网络的强大之处**。

image-20230410143756356

​ 此外,隐藏层并不只有一层,根据具体问题的需要可以设置多层隐藏层。我们考虑的就是输入的原始特征,以及需要几层隐藏层,每个隐藏层有几个神经元。选择合适的上述的数据就是一个重要的步骤,它们对算法性能有很大影响。

​ 【注】类似的多层神经网络也被称为多层感知机(multilayer perception)。

image-20230410150534167

2.1.2 Neural network model

image-20230410161142476
a j [ l ] = g ( w ⃗ j [ l ] ⋅ a ⃗ [ l − 1 ] + b j [ l ] ) a^{[l]}_j = g( \vec{w}^{[l]}_j · \vec{a}^{[l-1]} + b^{[l]}_j) aj[l]=g(w j[l]a [l1]+bj[l])
​ 上图是一个四层神经网络,上式是计算第 l l l层第 j j j号神经元值的计算公式, g ( ) g() g()是逻辑回归模型中的Sigmoid函数,在神经网络中也被称为激活函数(activation function)。其中, x ⃗ = a ⃗ [ 0 ] \vec{x}=\vec{a}^{[0]} x =a [0]

​ 下面介绍一个手写数字试别的案例:

​ 我们知道计算机中任何信息都是以二进制存储的,图片也不例外,在计算机中应当如何区别图片中的数字呢?以0和1为例,下图是一个8*8的矩阵,其中不同数字代表不同的颜色。为完成试别工作,我们构建了一个三层神经网络,其中第一层有25个神经元,第二层有15个,第三层则作为输出层输出结果。

image-20230410164915716

image-20230410165959561

​ 由于整个计算是从左到右,这个过程也被称为前向传播(forward propagation)

2.1.3 TensorFlow的实现

​ TensorFlow是实现深度学习算法的主流框架之一,另一个主流框架是PyTorch

2.1.4 Neural network implementation in Python

​ 在Python中实现简单的前向传播

2.1.5 强人工智能(AGI)

​ AGI即Artificial general intelligence的简写,计算机科学与技术专业用语,专指通用人工智能。这一领域主要专注于研制像人一样思考、像人一样从事多种用途的机器,即:强人工智能。

image-20230410191142171

2.2 Vectorization

​ 向量与矩阵的计算,有基础,可跳过。

2.2.1 矩阵使得运算更快

2.2.2 矩阵乘法

2.2.3 矩阵乘法的代码

2.3 Neural Network Training

2.3.1 TensorFlow的实现

import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense

model = Sequential([
	Dense(units=25, activation='sigmoid'),
	Dense(units=15, activation='sigmoid'),
	Dense(units=1, activation='sigmoid')
])


from tensorflow.keras.losses import BinaryCrossentropy

model.compile(loss=BinaryCrossentropy())
model.fit(X,Y,epochs=100)

2.3.2 模型训练步骤

  1. 定义模型:指定如何计算输出(输入x和参数w,b)

  2. 计算代价函数与损失函数

  3. 梯度下降

2.4 Activation Functions

2.4.1 激活函数的选择

​ 我们对已有的神经网络的每一层都使用了Sigmoid函数,但是如果我们选用别的某些函数,神经网络就会变得更加强大。

​ 在预计T恤是否可以大卖的案例中,隐藏层有一参数为知名度,在Sigmoid函数中我们把这个值定义为了0到1之间,但这显然不太符合事实,因为知名度也存在大小关系,但绝对不可能是一个负数,所以似乎应该定义该值为非负数。为此引入ReLU函数

image-20230412164655635

​ 那么应该如何选取不同的激活函数?

​ 首先考虑输出层,如果是一个二分类问题,那么应当使用Sigmoid函数;如果预测结果有正有负,应当使用线性函数;如果预测结果永远非负,则应使用ReLU函数。

image-20230412180600345

​ 在隐藏层中,ReLU函数则是使用最多的,他的速度明显比Sigmoid函数要快,而且在梯度下降时也能有更好的表现,可以有效避免梯度消失问题,加快学习速度。

2.5 多分类与Softmax函数

​ 在很多显示问题中,我们要做的可能是多分类问题,而非二分类问题。比如数字识别中,每一位数字有十种可能(0-9),这就是一个十分类问题。

image-20230412183632279

​ Softmax函数是逻辑回归的泛化,是一种针对多分类环境的二元分类算法。

image-20230410164915716

image-20231017164410359

image-20230412193127765

2.6 Multi-label Classification(多标签分类)

2.7 其他的神经网络概念

2.7.1 Adam算法

​ Adam: Adaptive Moment estimation(自适应距离估计)

​ 在梯度下降过程中,学习率是一个需要尽力设计好的参数,学习率过小会导致每次下降的步长太小,迭代很多次也无法达到学习曲线最低处;学习率太大又会导致浮动过大,无法收敛。Adam算法可以让程序自动调整学习率,当发现学习率过大或过小,自动对之进行相反的调整。

# model
model = Sequential([
	tf.keras.layers.Dense(units=25, activation='sigmoid'),
	tf.keras.layers.Dense(units=15, activation='sigmoid'),
	tf.keras.layers.Dense(units=10, activation='linear')
])
# compile
model.fit(X,Y,epochs=100)
# fit
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
			  loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True))

2.7.2 Convolutional Neural Network

​ 对于隐藏层,如果后一层神经元的计算使用了前一层的全部数据,我们称之为Dense Layer(全连接层)。如果我们让后一层神经元只获取部分数据,设置多个神经元来分开获取前一层的数据,我们称之为Convolutional Layer(卷积层)。如下图中,左侧为3*3像素点的图像,右侧为一层神经网络,我们让神经元来计算对应颜色的像素点,这样的神经网络被称为Convolutional Neural Network(卷积神经网络),即CNN。

CNN的优点:计算速度快;因为需要的训练数据少,而减小过拟合。

image-20230412211252463

2.8 测试模型&选择模型

2.8.1 测试模型

​ 在之前的学习中,我们已经见到过了过拟合的情况,也就是模型可以很好的拟合训练集中的数据,但是无法泛化(generalize)到训练集以外的数据中。

训练集(training set)的数据往往是有限的,如果把这些数据全部拿来拟合模型,我们就没有多余的数据拿来测试。因为如果拿训练集中的数据来进行测试的话,就相当于让计算机做一道已经知道了答案的题目。所以如果需要拟合出一个好的模型的同时保证可以进行测试,就必须对训练集进行划分,抽取部分数据(比如30%的数据)出来作为测试集(test set)。

​ 下面是线性回归和逻辑回归的训练与测试过程,训练过程通过使用划分出来的训练集来最小化代价函数,从而确定参数。然后用确定好参数的模型分别计算训练集代价与测试集代价,从而判断该模型是否优秀。需要注意的是,在模型的拟合过程中用到了正则化,而计算过程则没有,因为正则化是用来确定参数的,确定好参数正则化项也就没有存在的必要了。

(一)针对线性回归(with平方误差代价函数)的训练&测试过程

​ 1. 通过最小化代价函数 J ( w ⃗ , b ) J(\vec{w},b) J(w ,b)来确定参数
J ( w ⃗ , b ) = 1 2 m t r a i n ∑ i = 1 m t r a i n [ f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ] 2 + λ 2 m t r a i n ∑ j = 1 n w j 2 J(\vec{w},b)= \frac{1}{2m_{train}} \sum_{i=1}^{m_{train}} [ f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} ]^2 + \frac{\lambda}{2m_{train}} \sum_{j=1}^nw_j^2 J(w ,b)=2mtrain1i=1mtrain[fw ,b(x (i))y(i)]2+2mtrainλj=1nwj2
​ 2. 计算训练集代价
J t r a i n ( w ⃗ , b ) = 1 2 m t r a i n ∑ i = 1 m t r a i n [ f w ⃗ , b ( x ⃗ t r a i n ( i ) ) − y t r a i n ( i ) ] 2 J_{train}(\vec{w},b)= \frac{1}{2m_{train}} \sum_{i=1}^{m_{train}} [ f_{\vec{w},b}(\vec{x}_{train}^{(i)}) - y_{train}^{(i)} ]^2 Jtrain(w ,b)=2mtrain1i=1mtrain[fw ,b(x train(i))ytrain(i)]2
​ 3. 计算测试集代价
J t e s t ( w ⃗ , b ) = 1 2 m t e s t ∑ i = 1 m t e s t [ f w ⃗ , b ( x ⃗ t e s t ( i ) ) − y t e s t ( i ) ] 2 J_{test}(\vec{w},b)= \frac{1}{2m_{test}} \sum_{i=1}^{m_{test}} [ f_{\vec{w},b}(\vec{x}_{test}^{(i)}) - y_{test}^{(i)} ]^2 Jtest(w ,b)=2mtest1i=1mtest[fw ,b(x test(i))ytest(i)]2
(二)针对逻辑回归的训练&测试过程

​ 1. 通过最小化代价函数 J ( w ⃗ , b ) J(\vec{w},b) J(w ,b)来确定参数
J ( w ⃗ , b ) = − 1 m t r a i n ∑ i = 1 m t r a i n {   y ( i ) l o g [ f w ⃗ , b ( x ⃗ ( i ) ) ] + ( 1 − y ( i ) ) l o g [ 1 − f w ⃗ , b ( x ⃗ ( i ) ) ]   } + λ 2 m t r a i n ∑ j = 1 n w j 2 J(\vec{w},b)= -\frac{1}{m_{train}} \sum_{i=1}^{m_{train}} \{\ y^{(i)}log[f_{\vec{w},b}(\vec{x}^{(i)})] +(1-y^{(i)})log[1-f_{\vec{w},b}(\vec{x}^{(i)})] \ \} + \frac{\lambda}{2m_{train}} \sum_{j=1}^nw_j^2 J(w ,b)=mtrain1i=1mtrain{ y(i)log[fw ,b(x (i))]+(1y(i))log[1fw ,b(x (i))] }+2mtrainλj=1nwj2
​ 2. 计算训练集代价
J t r a i n ( w ⃗ , b ) = − 1 m t r a i n ∑ i = 1 m t r a i n {   y t r a i n ( i ) l o g [ f w ⃗ , b ( x ⃗ t r a i n ( i ) ) ] + ( 1 − y t r a i n ( i ) ) l o g [ 1 − f w ⃗ , b ( x ⃗ t r a i n ( i ) ) ]   } J_{train}(\vec{w},b)= -\frac{1}{m_{train}} \sum_{i=1}^{m_{train}} \{\ y_{train}^{(i)}log[f_{\vec{w},b}(\vec{x}_{train}^{(i)})] +(1-y_{train}^{(i)})log[1-f_{\vec{w},b}(\vec{x}_{train}^{(i)})] \ \} Jtrain(w ,b)=mtrain1i=1mtrain{ ytrain(i)log[fw ,b(x train(i))]+(1ytrain(i))log[1fw ,b(x train(i))] }
​ 3. 计算测试集代价
J t e s t ( w ⃗ , b ) = − 1 m t e s t ∑ i = 1 m t e s t {   y t e s t ( i ) l o g [ f w ⃗ , b ( x ⃗ t e s t ( i ) ) ] + ( 1 − y t e s t ( i ) ) l o g [ 1 − f w ⃗ , b ( x ⃗ t e s t ( i ) ) ]   } J_{test}(\vec{w},b)= -\frac{1}{m_{test}} \sum_{i=1}^{m_{test}} \{\ y_{test}^{(i)}log[f_{\vec{w},b}(\vec{x}_{test}^{(i)})] +(1-y_{test}^{(i)})log[1-f_{\vec{w},b}(\vec{x}_{test}^{(i)})] \ \} Jtest(w ,b)=mtest1i=1mtest{ ytest(i)log[fw ,b(x test(i))]+(1ytest(i))log[1fw ,b(x test(i))] }

2.8.2 选择模型

​ 我们已经掌握了如何智能化的选择模型中的参数,即通过正则化。但是应该如何选择合适的模型呢?

​ 以线性回归为例,应该如何确定模型的阶数?其实,测试集代价函数 J t e s t ( w ⃗ , b ) J_{test}(\vec{w},b) Jtest(w ,b)可以更好的估计出模型的泛化能力。利用该函数,我们可以比较模型的好坏。

image-20230415183537415

​ 我们可以同时拟合多个不同阶数的模型,d表示最高阶数的大小。通过最小化代价函数依次确定所有模型的参数,然后依次计算出测试集代价函数 J t e s t ( w ⃗ , b ) J_{test}(\vec{w},b) Jtest(w ,b)。此时选择测试集代价函数最小的模型,就是最优模型。

​ 但是我们选到的最小的测试集代价函数 J t e s t ( w ⃗ , b ) J_{test}(\vec{w},b) Jtest(w ,b)可能是有误差的,它可能低于实际的泛化误差,即进行了乐观估计。

​ 我们通过训练集确定了参数 w ⃗ , b \vec{w},b w ,b,但是无法通过训练集来评估模型好坏(即参数 w ⃗ , b \vec{w},b w ,b是否优秀),如果用训练集来测试,那么就会乐观估计,因此引入测试集概念。

【难点】同理,我们通过测试集在给定的一些模型中确定了参数 d d d,但是也无法通过测试集来评估模型好坏(即参数 d d d是否真正优秀)。因为我们只是针对测试集的数据选择了使测试集代价函数最低的参数 d d d,但是模型是否有很好的泛化能力依然是一个问题。

​ 因此,我们不再将模型划分为两个子集,现在划分为三个子集:训练集、交叉验证集(cross validation set)、测试集。比如可以选择60%的数据作为训练集、20%的数据作为交叉验证集、20%作为测试集。交叉验证集也被称为验证集(validation set)或开发集(development set / dev set)。

​ 针对之前的测试集代价和训练集代价,可以得到交叉验证集代价(或验证集代价,或开发集代价):
J c v ( w ⃗ , b ) = 1 2 m c v ∑ i = 1 m c v [ f w ⃗ , b ( x ⃗ c v ( i ) ) − y c v ( i ) ] 2 J_{cv}(\vec{w},b)= \frac{1}{2m_{cv}} \sum_{i=1}^{m_{cv}} [ f_{\vec{w},b}(\vec{x}_{cv}^{(i)}) - y_{cv}^{(i)} ]^2 Jcv(w ,b)=2mcv1i=1mcv[fw ,b(x cv(i))ycv(i)]2
​ 然后用交叉验证集代价 J c v ( w ⃗ , b ) J_{cv}(\vec{w},b) Jcv(w ,b)(代替之前测试集代价)来确定参数 d d d,选择众多模型中最合适的模型。然后就可以通过测试集代价来估算这个模型的泛化能力

同理,也适用于神经网络(逻辑回归模型)。

2.9 Bias and variance(偏差&方差)

2.9.1 偏差&方差

image-20230416122718476

​ 在欠拟合的例子中, J t r a i n J_{train} Jtrain很高,表示算法有很高的偏差(bias)。同时 J c v J_{cv} Jcv也很高。

​ 在过拟合的例子中, J t r a i n J_{train} Jtrain很低,但 J c v J_{cv} Jcv会很高,如果出现这种情况,那就说明算法有很高的方差(variance)

​ 在“just right”中, J t r a i n J_{train} Jtrain J c v J_{cv} Jcv都比较低,这是一个比较优秀的模型。

​ 我们可以令从左至右参数d分别为1,2,4,于是就有下图:

image-20230416123727134

​ 我们可以得出以下结论:当 J t r a i n J_{train} Jtrain很高同时 J t r a i n ≈ J c v J_{train}\approx J_{cv} JtrainJcv,模型高偏差、欠拟合;当 J c v > > J t r a i n J_{cv}>> J_{train} Jcv>>Jtrain,同时 J t r a i n J_{train} Jtrain可能很低,模型高方差、过拟合;当 J t r a i n J_{train} Jtrain很高同时 J c v > > J t r a i n J_{cv}>> J_{train} Jcv>>Jtrain,模型高偏差、高方差,这种情况在线性回归中不常见,在神经网络中可能会见到+。

高偏差意味着算法在训练集上表现很差,高方差则意味着算法在交叉验证集上的表现比训练集上的表现差的很多。

2.9.2 正则化参数 λ \lambda λ的选择

​ 以线性回归的正则化为例,针对模型 f w ⃗ , b ( x ) = w 1 x + w 2 x 2 + w 3 x 3 + w 4 x 4 + b f_{\vec{w},b}(x)=w_1x+w_2x^2+w_3x^3+w_4x^4+b fw ,b(x)=w1x+w2x2+w3x3+w4x4+b,有下述带正则化项的代价函数:
J ( w ⃗ , b ) = 1 2 m ∑ i = 1 m [ f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ] 2 + λ 2 m ∑ j = 1 n w j 2 J(\vec{w},b)= \frac{1}{2m} \sum_{i=1}^{m} [ f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} ]^2 + \frac{\lambda}{2m} \sum_{j=1}^nw_j^2 J(w ,b)=2m1i=1m[fw ,b(x (i))y(i)]2+2mλj=1nwj2
​ 我们通过最小化该代价函数来确定参数 w ⃗ , b \vec{w},b w ,b,这就涉及到正则化参数 λ \lambda λ的选择,我们可以利用“选择模型”中的方法,假设不同的 λ \lambda λ值,计算出对应的参数 w ⃗ , b \vec{w},b w ,b,进而计算对应的 J c v ( w ⃗ , b ) J_{cv}(\vec{w},b) Jcv(w ,b),找到最小的交叉验证集代价函数,来确定参数 λ \lambda λ的值。最后还可以通过计算 J t e s t ( w ⃗ , b ) J_{test}(\vec{w},b) Jtest(w ,b)来确定泛化误差。

image-20230416130737957

2.9.3 学习曲线

image-20230416153646663

​ 构建一个二维坐标系,横轴为训练集大小,纵轴为错误率,就可以构建 J c v ( w ⃗ , b ) J_{cv}(\vec{w},b) Jcv(w ,b) J t r a i n ( w ⃗ , b ) J_{train}(\vec{w},b) Jtrain(w ,b)的图像。

​ 当训练集很小的时候,模型可以很好的用低次方程模拟数据,同时可以做到训练集代价很低,当数据规模增大,无法再完美拟合所有数据,所以产生的训练集代价越来越大。

​ 同时当训练数据规模增大,训练到的模型对数据的拟合情况也就越来越好,交叉验证集代价就降低了。

​ 同时可以发现 J c v ( w ⃗ , b ) J_{cv}(\vec{w},b) Jcv(w ,b)始终比 J t r a i n ( w ⃗ , b ) J_{train}(\vec{w},b) Jtrain(w ,b)要高,这是因为我们不断进行调参的目的就是使训练集代价尽可能小。所以交叉验证集代价往往比训练集代价要高。

(一)high bias

image-20230416161604739

​ 当训练集误差很大时,往往产生了高偏差,也就是模型不能很好的拟合数据。当训练集规模越来越大,训练集代价越来越大,交叉验证集代价相对降低,二者逐渐趋于平稳,但是始终高于人类大脑的误差值。对于这种情况,增大数据集也无法减小高偏差影响。

(二)high variance

image-20230416162111925

​ 当训练集误差很小(小于人脑误差值),但是交叉验证集误差很高,这就出现了高方差。对于这种情况,增大数据集可以减小高方差影响。

image-20230416162858732

2.10 查准率&查全率

​ 在实际应用中,交叉验证集的预测结果往往有四种,真阳性(Ture positive)、真阴性(Ture negative)、假阳性(False positive)、假阴性(False negative)。

image-20230417191337571

​ 为了描述分类精度,引入两个定义:查准度(精确度,Precision)与查全度(召回,Recall)。通过这两个数据,可以判断分类算法是否优秀。
P r e c i s i o n = T r u e P o s i t i v e T r u e P o s i t i v e + F a l s e P o s i t i v e ,分类为 T r u e 的中,有多少是真 T r u e Precision=\frac{True Positive}{True Positive+False Positive},分类为True的中,有多少是真True Precision=TruePositive+FalsePositiveTruePositive,分类为True的中,有多少是真True

R e c a l l = T r u e P o s i t i v e T r u e P o s i t i v e + F a l s e N e g a t i v e ,对于所有的 T r u e ,有多少被正确分类 Recall=\frac{True Positive}{True Positive+False Negative},对于所有的True,有多少被正确分类 Recall=TruePositive+FalseNegativeTruePositive,对于所有的True,有多少被正确分类

​ 对于一般的二分类,我们会规定一个阈值来对预测结果进行分类,我们一般首先想到的就是设为0.5,即大于等于0.5,预测结果为1,小于0.5则预测为零。但是实际情况中我们可能会对阈值做出调整,比如在做患病几率检测时,如果患病检查成本很大/患病后对人体影响甚微,我们可以适当上调阈值,以减小被诊断为患病的几率,所以False negative(患病了但是没有被检测出来)的几率增大了,同时False positive(检测患病但实际没有患病)的几率减小了,这样查准度上升了,查全度就下降了;同理也可以对阈值下调,会得到相反的结果。

​ 可见查准率和查全率的变化是相反的,我们往往想要一个合适的值,F1评分(F1 score)可以自动结合查准率和查全率,帮我们选择最佳的阈值,比如有三种算法,一种查准度很高但查全度很低、一种查全度很高但查准度很低、一种居于二者中间,我们应当选择哪个算法作为模型?
F 1   s c o r e = 1 1 2 ( 1 P + 1 R ) = 2 P R P + R F1\ score = \frac{1}{ \frac{1}{2} ( \frac{1}{P} + \frac{1}{R} ) } = 2 \frac{PR}{P+R} F1 score=21(P1+R1)1=2P+RPR
​ 我们通过F1评分来选择最优算法,F1评分放大了更小值带来的影响,使得P和R相互制衡,选择更合适的值,而避免了算术平均使得更小值带来的影响更小。(在数学中F1评分也被称为调和平均数,harmonic mean)

2.11 决策树(Decision Trees)

2.11.1 决策树介绍

​ 决策树是一种机器学习中监督学习的一种方法。决策树是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果。决策树是一种十分常用的分类方法,通过学习这些样本得到一个决策树,这个决策树能够对新的数据给出正确的分类。

image-20230410164915716

image-20230410165959561

​ 比如在猫猫狗狗分类中,我们划分出三类特征,耳型(耸立or下垂),脸型(圆or不圆),胡须(有or无),根据这三类特征通过算法构造一棵决策树(决策树并不唯一,但应当选用更优的树),如右图,通过三类特征成功构建出一颗决策树,如果有新的数据,根据决策树就可以确定是猫猫还是狗狗。

​ 但是也产生了问题,第一就是如何为每一个节点选择合适的特征来分类?答案是最大化纯度(或最小化不纯度),也就是最接近彻底分类的选择,显然第一个纯度最高。

image-20230417222446118

​ 第二给问题就是,何时停止划分?第一个选择是当一个节点被完全(100%)划分出来的时候停止划分;第二个选择是给定一个最大深度,达到最大深度停止划分。**保持树的小巧可以减小过拟合的情况;**第三个选择是当划分带来的纯度提升小于某个给定值时停止划分,同样也可以减小过拟合的风险;第四个选择是当节点的数据低于某个给定值时停止划分。

2.11.2 熵与信息增益(Entropy&Information Gain)

​ 在信息论和概率统计中,熵(entropy)指的是随机变量不确定性的度量。

image-20230418140426978

​ 比如在猫猫狗狗分类案例中,用 p 1 p_1 p1来表示猫猫的占比,可以看到当猫猫占比大或占比小的时候,熵都是很低的,所以熵不是用来衡量某一变量的多少,而是用来衡量整个系统的混乱程度。

​ 我们假设 p 0 p_0 p0为狗狗的占比,则显然有 p 0 = 1 − p 1 p_0=1-p_1 p0=1p1,于是熵的计算公式就是:
H ( p 1 ) = − p 1 l o g 2 ( p 1 ) − p 0 l o g 2 ( p 0 ) = − p 1 l o g 2 ( p 1 ) − ( 1 − p 1 ) l o g 2 ( 1 − p 1 ) d e f : 0 l o g 0 = 0 H(p_1) = -p_1 log_2(p_1) - p_0 log_2(p_0) = -p_1 log_2(p_1) - (1-p_1) log_2(1-p_1)\\ def:0log0=0 H(p1)=p1log2(p1)p0log2(p0)=p1log2(p1)(1p1)log2(1p1)def:0log0=0

​ 以猫猫狗狗分类案例为例,在选择分类所用的特征时,我们采用熵值来量化每个特征是否为最佳选择。针对三个特征,可以分别计算左右结点的熵,然后应当将这两个数字以某种算法合二为一,以此值为该特征最终的熵值。

image-20230418185534269

​ 在分类时我们也希望能够分的更均等一些,这样对优化决策树型也有帮助。所以这种算法就考虑到了这点,将结点处的熵值乘以结点权重(即结点内元素占全体元素的比例)。这其实被称为加权平均熵。但是在实际运用中,通常会用根节点的熵减去这个加权平均熵,这不会影响对比结果,但可以突出熵值的改变量。在案例中,根节点的熵值为1,用这个值减去左右结点的加权平均熵,就得到了图中的结果。我们选用熵减最大的方案,即第一个。

​ 相减得到的结果我们也成为信息增益(Information Gain),它所衡量的是决策树在分裂过程中的熵减。系统的定义一下信息增益的公式,我们定义权重为 w w w,就可以得到公式:
I n f o r m a t i o n G a i n = H ( p 1 r o o t ) − [ w l e f t H ( p 1 l e f t ) + w r i g h t H ( p 1 r i g h t ) ] InformationGain = H(p_1^{root}) - [ w^{left} H(p_1^{left}) + w^{right} H(p_1^{right}) ] InformationGain=H(p1root)[wleftH(p1left)+wrightH(p1right)]
通过对上文中讲述到的算法进行递归使用,就得到了下图中的决策树。

image-20230418192912132

2.11.3 独热编码(One-hot Encoding)

​ 在上文中的猫猫狗狗分类案例中,每个特征对应的值都只有两种,现实中遇到的特征往往是多元的,我们对案例进行简单修改,让耳型不再是二元,修改为:耸立、下垂、圆形(新增)。这样在构建决策树时,就会有三个子结点,通过**独热编码(One-hot Encoding)**就可以解决这种问题。

​ 如图,我们将原本有三个值的耳型特征拆分为三个二元特征,也可以推广到有k个值的特征,拆分为k个二元特征。观察拆分后的结果,我们发现拆分后的多个特征只有一个值为1而其余为0,这也是叫做独热编码的原因。

image-20230418195518720

2.11.4 连续值的划分

​ 在上文中的猫猫狗狗分类案例中,每个特征对应的值不管是二元还是多元,都是离散的,现实中也可能会遇到值连续的特征,比如动物的体重(我们知道猫猫的体重往往是比狗狗轻一些)。我们在案例中增加一个体重特征,其值是连续的。

image-20230410164915716

image-20230410165959561

​ 对于这样的连续值,我们也选择信息增益法,当选用不同的值划分,就会得到不同的信息增益,比如:
选 8 作为分界 : H ( 0.5 ) − [ 2 10 H ( 2 2 ) + 8 10 H ( 3 8 ) ] = 0.24 选 9 作为分界 : H ( 0.5 ) − [ 4 10 H ( 4 4 ) + 6 10 H ( 1 6 ) ] = 0.61 选 13 作为分界 : H ( 0.5 ) − [ 7 10 H ( 5 7 ) + 3 10 H ( 0 3 ) ] = 0.40 选8作为分界:H(0.5)-[ \frac{2}{10}H(\frac{2}{2}) + \frac{8}{10}H(\frac{3}{8}) ] = 0.24 \\ 选9作为分界:H(0.5)-[ \frac{4}{10}H(\frac{4}{4}) + \frac{6}{10}H(\frac{1}{6}) ] = 0.61 \\ 选13作为分界:H(0.5)-[ \frac{7}{10}H(\frac{5}{7}) + \frac{3}{10}H(\frac{0}{3}) ] = 0.40 8作为分界:H(0.5)[102H(22)+108H(83)]=0.249作为分界:H(0.5)[104H(44)+106H(61)]=0.6113作为分界:H(0.5)[107H(75)+103H(30)]=0.40
​ 选用最大信息增益,即9作为分界。

2.11.5 树集(Tree Ensembles)

​ 使用单一决策树有一个缺点:决策树对数据的微小变化十分敏感。让算法变得不那么敏感或更稳健的一个解决方案是,构建多棵决策树,我们称为树集(Tree Ensembles)。当面对新的测试数据,通过多棵树来得到多个结果,并对这些结果进行统计,选择结果更大的那个。

​ 有一种技术叫:有放回抽样(Sampling with replacement)。对于有N个数据的训练集,每次抽出1个并记录,然后从这N个中再抽取一个,抽出N个数据,这就是有放回抽样的一次抽样过程。

​ 如果要建立一个有B棵树的树集,训练集大小为N,我们可以重复B次有放回抽样,针对每次抽样抽出的N个数据来构建一颗决策树,就可以得到B棵决策树。根据经验,树集的大小会选64到228之间的任何数值。但树集不是越大越好,在超过某个值之后提升树集大小带来的增益越来越小,所以应当选用合适大小的树集。这样的算法我们称为袋装决策树算法(the bagged decision tree algorithm)。

​ 但是这样构建的树集中可能有很多棵树的树根部分都是相似的,为了尽量避免这种情况,我们采用随机化特征选择法。在每个结点,当要选择一个特征用于分割时,如果有n个特征可以选用,则选择k<n个特征的随机子集,并且强制算法仅可从这k个随机子集中挑选。真正使用时,特征可能有数十或上百个,通常令 k = n k=\sqrt{n} k=n 。这样生成的树集我们称为随机森林(random forest)。

QUESTION: Where does a machine learning engineer go camping?

ANSWER by Andrew NG: In a random forest! ^_^

2.11.6 XGBoost

​ 针对上文中的袋装决策树算法,现有一个对之进行优化的算法,叫做XGBoost算法,全称为eXtreme Gradient Boosting,极端梯度增强。

​ XGBoost算法针对袋装决策树算法做出了修改,即进行有放回抽样时,不再完全随机的进行抽样,而是增大被分类错的数据被选中的概率。比如,第一次循环时正常进行抽样,构建好一颗决策树,然后用该决策树对原始训练集中的每个数据进行预测,标记分类失败的数据;第二次循环在抽样时,增大上一轮中错分数据被选中的概率,用这些数据来构建第二棵决策树;后续进行类第二次的循环。

​ 类似这样增大概率的方法,被称为刻意练习(deliberate practice)

image-20230418224043243

2.11.7 神经网络与决策树的比较

​ 决策树(包括树集)以及神经网络都是很强大的算法,但是应该如何选择?

神经网络:

  1. 适用于所有类型的数据,包括结构化数据或非结构化数据;
  2. 训练速度比决策树慢;
  3. 可以和迁移学习搭配使用;
  4. 多个神经网络串在一起构建大型机器学习系统更容易。

决策树与树集:

	1. 可以很好的处理表格数据,即结构化数据;
	1. 不建议使用在非结构化数据上,如图像、视频、音频、文本;
	1. 训练起来很快;
	1. 小型的决策树更易读。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值