说明
在本专栏机器学习_墨@#≯的博客-CSDN博客之前的博文中,已经对感知机[1]、SVM[2]以及线性回归问题[3]做过探讨和实践。感知机以及SVM是用来做分类的,线性回归是用来做拟合的。本文将要探讨的Logistic回归(逻辑回归)则是使用线性回归的方法来做分类(二分类)。它的核心思想是:将输入特征映射到0和1之间的连续值以表示属于某一类别(类别0或类别1)的概率。
逻辑回归和感知机的核心区别在于:虽然分类问题的输出要么是0要么是1,但是逻辑回归增加了概率值,这在一些需要置信度的应用场合,以及拓展至多分类问题时有优势。此外,感知机的激活函数是阶跃函数sign,只能处理线性可分的数据集,对于线性不可分的情况,需要引入额外的特征(比如特征的多次幂)或者使用核函数来解决,而逻辑回归虽然也用的线性模型,但是其激活函数是非线性的sigmoid函数,所以可以处理一定复杂度的非线性数据集。
本文的目的在于捋清楚逻辑回归的相关概念,并使用逻辑回归对一些简单但典型的分类问题进行实践。为更方便理解,本文会同时对比线性回归和感知机进行论述,读者在阅读本文前,可以先了解一下博文[1]和[3]的内容。
考虑到本专栏之前的博文已经对机器学习的一些概念有过阐述和实践,所以本文的一些论述会更简化。
Blog
2024.10.24 博文第一次写作
目录
一、Logistic回归概述
1.1 逻辑回归简介以及相关概念回顾
在了解逻辑回归之前,我以为回归就只是训练得到某个函数去拟合数据(比如博文[3]中所实践的拟合二维平面内的曲线、拟合房屋价格),然后基于得到的函数去预测样本值,回归是回归,分类是分类,它们之间是独立且没有关联的。
但是逻辑回归就像是搭建了回归和分类之间的桥梁:逻辑回归将输入特征映射到0和1之间的连续值以表示属于某一类别(类别0或类别1)的概率,从而完成分类任务。 就像是对基于线性回归解决拟合问题的拓展?
在线性回归中,我们一般设计线性模型来拟合样本输出与输入之间的关系:
(1-1)
式中,n为样本特征数。其实在感知机中,我们也是用的上述模型,不过我们用以拟合的是分类超平面,并进一步地,得到感知机的分类模型为:
(1-2)
这就是前文说明中所提及的感知机所使用的激活函数。
1.2 逻辑回归的模型、学习准则、优化算法
类似[3]中的论述,本节也按照模型、学习准则、优化算法这解决机器学习问题的三要素对逻辑回归展开探讨。
逻辑回归的分类模型:
逻辑回归中我们也是使用式(1-1)的线性模型来对数据集做回归,但是相较于式(1-2),逻辑回归中,我们引入了sigmoid函数作为激活函数对数据进行分类。sigmoid函数的表达式为(这里对x取反了):
(1-3)
该函数x和y之间的关系如下图所示:
图1.1 Sigmoid函数图像
该函数在x = 0处取值0.5,y随着x的增大而无限逼近于1,随着x的减小无限逼近于0。 这是一个取值在(0 1)区间的连续函数。
引入该激活函数后,逻辑回归的分类模型我们设计为:
(1-4)
代入f(x)的表达式,并向量化,得到:
(1-5)
式中,θ为各参数构成的向量:
(1-6)
x是由各特征构成的向量:
(1-7)
n为特征数。基于式(1-5)以及前面对sigmoid函数的介绍,我们可以知道:该分类模型将样本映射到了(0 1)区间内,随后我们可以简单地认为:当得到的映射值大于0.5时,可认为该数据属于类别1,当小于0.5时,该数据属于类别0,从而完成分类。此外,由于函数值是连续的,同时我们也可以得到概率值:比如映射值为0.7,那么我们可以说该数据属于类别1的概率为70%。
逻辑回归的学习准则(损失函数):
有了模型后,下一步就是要得到参数值θ。在这之前我们一般需要设计学习准则(损失函数)。 在线性回归中,我们把损失函数设计为样本值与所拟合模型下样本值的均方误差和:
(1-8)
式中,m为训练集的样本数。在感知机中,我们将损失函数设计为各误分类的样本到分离超平面的距离和:
(1-9)
在训练(优化)过程中,我们都是要想办法最小化前述两个公式。
而在逻辑回归,我们使用的损失函数为:
(1-10)
至于怎么就将损失函数设计成上面这个表达式了,这里面涉及到基于最大似然法等的一些比较复杂的数学推导,这里就不做展开了,读者可以找找别的资料。我这里比较定性地对该式做一点解释:
首先:损失函数是一个关于参数值θ的函数,而参数值θ是样本各特征的权值,损失函数的本质是训练集各个样本的损失值的和,虽然在线性回归、感知机以及这里的逻辑回归中,对损失值的定义各不相同,但总之我们优化的目标是让损失函数的值最小。 在前述基础上:对应到分类问题时,我们是想尽可能地对训练集的样本进行正确的分类,那么在训练(优化)过程中,如果某个样本没有被正确分类,我们自然是希望该样本对应的损失值应该越大越好(或者说对它的惩罚越大),只有这样,我们才“更有动力”去调整参数值以减小其影响。最终,在优化完成后,得到一组使全部训练样本影响下损失值最低的参数值。
回到式(1-10),其更原始的表达式其实是:
(1-11)
其中,cost函数就对应训练集各个样本的损失值,该函数被设计为:
(1-12)
的定义式为(1-5),是一个(0 1)区间内的值,ln是以e为底的对数值。函数-ln以及-ln(1-x)的函数图像如下:
图1.2 函数-ln以及-ln(1-x)的函数图像
对于,当y=1,即样本类别为1时,如果分类正确,h(x)应该趋近于1,此时其损失值
趋近于0;相反,如果分类不正确,h(x)趋近于0,此时其损失值将趋近于无穷(也即我们对其惩罚越大)。 对
则是相反的效果。 为了使损失值变小,我们只有通过不断调整参数值,以尽可能地全部正确分类!
我们可以合并式(1-12),将之改写成:
(1-13)
该式和(1-12)是等价的。【不过这里需要注意的是:在逻辑回归中,我们的样本值y是取0和1以分别代表两个类别;而在感知机中,我们是取-1和1以代表两个类别。这两种方法都可以,只不过在逻辑回归中取0和1更方便我们构建损失函数】。 将上式带入式(1-11)就得到了式(1-10)。
逻辑回归的优化算法:
有了前述损失函数后,我们就需要设计优化算法以求解得到参数值。这里和之前的线性回归以及感知机一样,还是用到梯度下降法,梯度下降法我已经在博文[3]中有过比较详细的说明,这里不做展开,直接给出逻辑回归下梯度下降法的参数迭代表达式:
(1-14)
我们还是通过减去偏导数的方法来迭代参数值,将式(1-10)代入并求解,可以得到:(具体的推导这里不做介绍了)
(1-15)
m为训练集中的样本数,每次迭代时按上式更新参数值。其实该公式和线性回归中的迭代公式是一样的!但是模型函数h(x)不一样!也正是因为这样,线性回归中的正规方程解法不能用在逻辑回归里。
二、二分类实践
本章基于逻辑回归进行二分类的实践。数据集为自编代码在二维平面内生成的点集。(和我在博文[1]以及[2]中所使用的数据集一样)
2.1 数据生成情况
在二维平面内生成两个类别的数据(共180组):
图2.1 数据集生成情况
随后在两类数据中各随机选取2/3的数据作为训练集,剩余1/3的数据作为测试集。
图2.2 选取的训练集和测试集
图中,实心的为训练集,空心的为测试集。
2.2 基于梯度下降法的逻辑回归实践
整个代码的实现流程大致如下:
图2.3 处理流程示意图
在本章的实践中,预设学习率为1.2,各权值在(0 1)区间内随机初始化,迭代次数设置为5000。得到的结果如下:
图2.4 损失值随迭代次数的变化
收敛情况还不错,不过也可以看到收敛的速度比较慢,甚至在第5000次的时候似乎还有往下降的趋势。(为加快收敛,可以考虑提高学习率,但是学习率的提高可能会产生损失值随迭代次数而震荡的情况,读者可以基于代码再做更多的尝试)。
进一步地,基于训练得到的函数,分别对训练集和测试集的数据进行分类处理。得到的结果如下:
图2.5 分类器对训练集的分类概率值
我将训练集的样本全部给到训练好的函数,求得各个训练样本的概率值,并基于概率值分类:小于0.5则归类0,否则归为类1。并将分类结果与样本的真实类别对比,如果分类错误,会把点标识为实心的黑色,否则分别基于类别标识为空心的红色和蓝色。 从上图来看,没有误分类的点!分类器(训练得到的函数)对训练集样本的分类准确率为100%。
同理,把测试集的样本给到分类器,得到的结果如下:
图2.6 分类器对测试集的分类概率值
从图中可以看到,有三个样本点被误分类(显示为黑色实心圆)。从概率值可以看出,原本应该被归类为0的三个样本点被误归类为1(分类器对其概率值的计算不符合实际)。
进一步地,得到的权值、最终的损失值、以及对训练集和测试集的分类准确率如下:
图2.7 训练结果&测试结果
本章实践的结果符合预期。验证了理论以及所编代码的正确性。
三、多分类实践
3.1 多分类解决思路
逻辑回归和感知机、SVM一样,都是用来解决二分类问题的。如果需要拓展至多分类,典型的处理思路就是基于“一对多”或者“一对一”的方法训练得到多个分类器,随后在实际应用时,让这些分类器都对样本做一次分类,综合多个分类器的分类结果实现对该样本的分类。
关于多分类的解决方案,我在博文[2]的1.5节有过很详细的介绍,读者可以移步阅读。在后文中,我将实践“一对多”思路下的多分类实践。
3.2 数据集说明
本章的实践中,所选用的数据集和之前在关于SVM的博文[4]以及关于聚类的博文[5]中使用的一样,还是UCI里的Iris鸢尾花卉数据集[6],读者可以自行通过该链接下载,当然我也和代码一并上传到了第六章的链接中。关于该数据集比较细致的介绍读者可以参考博文[5]的2.1节。
总之,该数据集一共有150个样本,分为三类,每类有50个样本,每个样本有4个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)。
后续使用时,我将分别随机地从各个类中挑选38个样本作训练集,剩下的12个样本作为测试集。进行模型的训练和分类实践。
3.3 “一对多”思路下的多分类实践
3.3.1 对分类器的训练思路
处理的流程和2.2节给出的基本一致,只不过本章我们需要构造和训练三个分类器。这三个分类器分别要解决的问题是:(假设数据集的三种类别分别为A、B、C)
表3.1 分类器设置列表
分类器ID |
区分类别 |
类别设置(对训练集的样本) |
1 |
类别A和 类别(B、C) |
类别A的设置为类别0,类别B和C都设置为类别1 |
2 |
类别B和 类别(A、C) |
类别B的设置为类别0,类别A和C都设置为类别1 |
3 |
类别C和 类别(A、B) |
类别C的设置为类别0,类别A和B都设置为类别1 |
在进行训练时,训练集和测试集三个分类器共用,不过在训练时,我们给训练样本的类别标签不一样(具体如上表所示)。
3.3.2 各个分类器训练结果与测试
首先看看训练得到的三个分类器分别对训练集和测试集的分类结果:
预设三个分类器的学习率都为0.12(当然,也可以设置三个学习率),三个分类器初始权值在(0 1)区间内随机产生,迭代次数都设置为1000次。
图3.1 三个分类器的损失值随迭代次数的变化
从上图来看,分类器1(用于对类别A和类别(B、C)进行分类)的收敛情况最好,表现为:一是更容易收敛,二是最终的损失值很接近0。分类器2的效果最差,考虑原因是类别B和类别(A、C)之间间隔近,比较难区分。
类似第二章的处理,基于训练得到的函数(分类器),分别对各自训练集和测试集的数据进行分类处理。得到的结果如下
图3.2 分类器1对训练集的分类概率分布
图3.3 分类器1对测试集的分类概率分布
不管是训练集还是测试集的数据,两类分别集中在0和1的周围,说明两类被分得很开!(且没有黑色实心圆点,说明没有误分类的点,分类准确率为100%)
图3.4 分类器2对训练集的分类概率分布
图3.5 分类器2对测试集的分类概率分布
分类器2的效果要差很多,图中黑色的实心圆对应分类出错的样本。从图中可以看到,很多原本属于类0的样本,被分类器错误地将其概率计算为>0.5,从而导致分类出错。
图3.6 分类器3对训练集的分类概率分布
图3.7 分类器3对测试集的分类概率分布
分类器3对训练集的分类存在误分类点,不过对测试集的分类准确率为100%。从上面三个分类器单独的分类效果来看,与图3.1所示的损失值与迭代次数的变化曲线是相对应的。
3.3.3 多分类的思路和测试结果
为完成多分类,我们需要综合三个分类器的结果。对测试集完成多分类的方法及结果如下:
判断样本所属类别的方法如下:
对于每个样本,使用三个分类器分别对其进行分类,每个分类器会输出一个概率值:不妨假设分类器1、2、3输出的概率值分别为a、b、c。于是可以得到每个样本所属三个类别的概率:
表3.2 每个样本所属每个类别的概率
所属类别A概率 |
所属类别B概率 |
所属类别C概率 |
|
分类器1 |
1-a |
a/2 |
a/2 |
分类器2 |
b/2 |
1-b |
b/2 |
分类器3 |
c/2 |
c/2 |
1-c |
综合概率值 |
(1-a+b/2+c/2) |
(1-b+a/2+c/2) |
(1-c+a/2+b/2) |
标准化概率 |
(1-a+b/2+c/2)/3 |
(1-b+a/2+c/2)/3 |
(1-c+a/2+b/2)/3 |
备注:以分类器1对类别A和类别(B、C)的分类为例,因为在训练分类器时,我们是把所属类别A的所有样本的类别设定为0,所以当给定测试样本时,如果分类器输出的概率值为a,则其所属类别A(类0)的概率就是(1-a),所属类别B和类别C,我们取a的一半赋值给它们。对分类器2和分类器3的处理类似。于是我们可以得到如上表格。
随后,我们认为其中概率最大值对应的类别是样本所属类别,从而完成分类。
对全部测试集样本的处理结果如下:
图3.8 各样本所属各类别的概率值
图中,横坐标为测试集每个样本的ID,纵坐标为概率值,每个样本有三个概率值,分别对应属于类别A、B、C的概率值。最上面的连线对应的就是样本所属类别。随后与样本实际的类别进行比较,可以计算得到分类的准确率。
一些更具体的结果如下:
图3.9 分类器1的权值以及对训练集、测试集的分类准确率
图3.10 分类器2的权值以及对训练集、测试集的分类准确率
图3.11 分类器3的权值以及对训练集、测试集的分类准确率
图3.12 多分类的分类准确率为1
3.3.4 小结
同样的数据集,我在博文[4]的第一章中,使用SVM对其分类的准确率其实没有本章的结果好!(虽然本章没有用蒙特卡罗法去多次仿真,不过我跑了好几次代码,多分类的准确率都是1)。
本节的实践结果验证了基于“一对多”的思路进行多分类的可行性以及所编代码的正确性。
3.4 “一对一”思路下的多分类实践
不再给出,读者可以结合[2]中1.5节的论述和3.3节提供的参考代码自行实践。
3.5 本章小结
本章首先对基于逻辑回归的多分类解决思路进行了阐述,随后介绍了一份可用于多分类实践的公开数据集,并基于“一对多”的思路对该数据集进行了分类实践,分类的结果符合预期。
在实际应用中,虽然我们也确实可以基于本章的方法来进行多分类,但其实我们还有更直接的多分类解决方案:比如softmax回归,我会在后续的博文中探讨和实践该softmax回归。
四、总结
本文对逻辑回归进行了探讨和实践。首先,结合在之前的博文中探讨过的线性回归和感知机,对逻辑回归的相关概念和理论进行了阐述;随后,在理论的指导下,自编代码实践了二分类和多分类,分类的结果都符合预期。(读者可以基于本文提供的代码做更多的尝试:比如改变学习率、实践一对一思路下的多分类、实践其它的数据集)
本文的工作为后续更复杂的机器学习问题的理解、以及更复杂的分类问题的解决打下了基础。
五、参考资料
[1] 感知机及其实践-CSDN博客
[2] SVM及其实践1 --- 概念、理论以及二分类实践-CSDN博客
[3] 回归问题探讨与实践-CSDN博客
[4] SVM及其实践2 --- 对典型数据集的多分类实践-CSDN博客
[5] (毫米波雷达数据处理中的)聚类算法(2) – DBSCAN算法及其实践-CSDN博客
[6] https://archive.ics.uci.edu/