逻辑回归
2021-9-30
| 2023-8-6
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property

原理

线性回归到逻辑回归

线性回归的模型是求出输出特征向量 和输入样本矩阵之间的线性关系系数,满足是连续的,所以是回归模型。如果是离散的话,怎么办呢?一个可以想到的办法是,对于这个再做一次函数转换,变为。令的值在某个实数区间的时候是类别A,在另一个实数区间的时候是类别B,以此类推,就得到了一个分类模型。如果结果的类别只有两种,那么就是一个二元分类模型了。
 

二元逻辑回归的模型

对线性回归的结果做一个在函数上的转换,可以变化为逻辑回归。这个函数在逻辑回归中一般取sigmoid函数,形式如下:
它有一个非常好的性质,即当趋于正无穷时, 趋于1,而当趋于负无穷时, 趋于0,这非常适合分类概率模型。另外,它还有一个很好的导数性质:
 
如果令中的 为:,这样就得到了二元逻辑回归模型的一般形式:
为样本输入, 为模型输出(某一分类的概率大小),为模型参数
 
对于模型输出,让它和二元样本输出(假设为0和1)有这样的对应关系:
,即 输出为1;若 ,即 为0; 是临界情况,此时, 从逻辑回归模型本身无法确定分类。
的值越小,而分类为0的的概率越高,反之,值越大的话分类为1的的概率越高。如果靠近临界点,则分类准确率会下降。
 
此处也可以将模型写成矩阵模式:
为模型输出,的维度; 为样本特征矩阵,的维度; 为模型系数,的向量。
 

二元逻辑回归的损失函数

由于线性回归是连续的,所以可以使用模型误差的的平方和来定义损失函数。但是逻辑回归不是连续的,自然线性回归损失函数定义的经验就用不上了。不过可以用最大似然法来推导损失函数。
按照第节二元逻辑回归的定义,假设样本输出是0或者1两类。那么有:
把这两个式子写成一个式子,就是:
的取值只能是0或者1
得到了的概率分布函数表达式,就可以用似然函数最大化来求解需要的模型系数
 
为了方便求解,这里用对数似然函数最大化,对数似然函数取反即为损失函数
似然函数的代数表达式为:
为样本的个数
对似然函数对数化取反的表达式,即损失函数表达式为:
逻辑回归的损失函数是交叉熵损失函数只有两个类别变量时候的特殊形式
 
损失函数用矩阵法表达更加简洁:
其中为全1向量。
 

二元逻辑回归的损失函数的优化方法

对于二元逻辑回归的损失函数极小化,有比较多的方法,最常见的有梯度下降法,坐标轴下降法,等牛顿法等。这里用矩阵法推导出梯度下降法中每次迭代的公式:
对于向量求导可得:
这一步用到了向量求导的链式法则,和下面三个基础求导公式的矩阵形式:
对于求导公式化简可得:
从而在梯度下降法中每一步向量 的迭代公式如下:
其中, 为梯度下降法的步长
 

二元逻辑回归的正则化

逻辑回归也会面临过拟合问题,所以也要考虑正则化,常见的有 正则化和 正则化。
二元逻辑回归的L1正则化损失函数表达式如下:
逻辑回归的 正则化损失函数的优化方法常用的有坐标轴下降法和最小角回归法
 
二元逻辑回归的 正则化损失函数表达式如下:
逻辑回归的 正则化损失函数的优化方法和普通的逻辑回归类似。
 
 

二元逻辑回归的推广:多元逻辑回归

二元逻辑回归的模型和损失函数很容易推广到多元逻辑回归。
比如总是认为某种类型为正值,其余为0值,这种方法为最常用的one-vs-rest,简称OvR.
另一种多元逻辑回归的方法是Many-vs-Many(MvM),它会选择一部分类别的样本和另一部分类别的样本来做逻辑回归二分类。最常用的是One-Vs-One(OvO),OvO是MvM的特例。每次选择两类样本来做二元逻辑回归。
 
这里介绍多元逻辑回归的softmax回归的一种特例推导:
回顾下二元逻辑回归:
其中 只能取到0和1。则有:
如果要推广到多元逻辑回归,则模型要稍微做下扩展。
 
假设是元分类模型,即样本输出的取值为
根据二元逻辑回归的经验,有:
...
上面有个方程。
加上概率之和为1的方程如下:
从而得到个方程,里面有个逻辑回归的概率分布。
解出这个元一次方程组,得到元逻辑回归的概率分布如下:
多元逻辑回归的损失函数推导以及优化方法和二元逻辑回归类似
二元逻辑回归用的是sigmoid函数,多元逻辑回归用的是softmax函数

补充

逻辑回归为什么不用MSE作为损失函数?

  • 平方损失函数加上sigmoid的函数将会是一个非凸的函数,不易求解,会得到局部解,用对数似然函数得到高阶连续可导凸函数,可以得到最优解
  • 使用平方损失函数,会发现梯度更新的速度和sigmod函数本身的梯度是很相关的。sigmod函数在它在定义域内的梯度都不大于0.25,这样训练会非常的慢
  • 使用平方损失函数意味着我们默认数据服从正态分布,用统计术语来说就意味着假设了高斯先验。但很显然,分类问题的数据并不服从正态分布,比如二分类问题则服从伯努利分布。
 
 
 

代码

从零实现

notion image
 
 
notion image
 
 

scikit-learn实现

scikit-learn中,与逻辑回归有关的主要是这3个类:LogisticRegression LogisticRegressionCV logistic_regression_path
 
其中LogisticRegressionLogisticRegressionCV的主要区别是LogisticRegressionCV使用了交叉验证来选择正则化系数C。而LogisticRegression需要自己每次指定一个正则化系数。除了交叉验证,以及选择正则化系数C以外,使用方法基本相同
 
logistic_regression_path类则比较特殊,它拟合数据后,不能直接来做预测,只能为拟合数据选择合适逻辑回归的系数和正则化系数。主要是用在模型选择的时候,一般情况用不到这个类。
此外,scikit-learn里面有个容易让人误解的类RandomizedLogisticRegression,虽然名字里有逻辑回归的词,但是主要是用L1正则化的逻辑回归来做特征选择的,属于维度规约的算法类,不属于分类算法的范畴
 
 
 
 
 
正则化选择参数:penalty
LogisticRegression和LogisticRegressionCV默认就带了正则化项。
penalty参数可选择的值为"l1"和"l2",分别对应L1的正则化和L2的正则化,默认是L2的正则化。
在调参时如果主要的目的只是为了解决过拟合,一般penalty选择L2正则化就够了。但是如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。
penalty参数的选择会影响损失函数优化算法的选择。即参数solver的选择,如果是L2正则化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,而{‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的一阶或者二阶连续导数。而‘liblinear’并没有这个依赖。
 
优化算法选择参数:solver
solver参数决定了我们对逻辑回归损失函数的优化方法,有4种算法可以选择,分别是:
  • liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数
  • lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数
  • newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数
  • sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候
newton-cg,lbfgs和sag这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear通吃L1正则化和L2正则化。
同时,sag每次仅仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,而如果样本量非常大,比如大于10万,sag是第一选择。但是sag不能用于L1正则化,所以有大量的样本,又需要L1正则化的话就要自己做取舍了。要么通过对样本采样来降低样本量,要么回到L2正则化。
 
既然newton-cg,lbfgs和sag这么多限制,如果不是大样本,选择liblinear不就行了嘛?
因为liblinear也有自己的弱点!逻辑回归有二元逻辑回归和多元逻辑回归。对于多元逻辑回归常见的有one-vs-rest(OvR)和many-vs-many(MvM)两种。而MvM一般比OvR分类相对准确一些。郁闷的是liblinear只支持OvR,不支持MvM,这样如果需要相对精确的多元逻辑回归时,就不能选择liblinear了。也意味着如果需要相对精确的多元逻辑回归不能使用L1正则化了
 
 
分类方式选择参数:multi_class
multi_class参数决定了分类方式的选择,有 ovr和multinomial两个值可以选择,默认是 ovr。
ovr即one-vs-rest(OvR),而multinomial即many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
OvR的思想很简单,无论你是多少元逻辑回归,都可以看做二元逻辑回归。具体做法是,对于第K类的分类决策,把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。
而MvM则相对复杂,这里举MvM的特例one-vs-one(OvO)作讲解。如果模型有T类,每次在所有的T类样本里面选择两类样本出来,不妨记为T1类和T2类,把所有的输出为T1和T2的样本放在一起,把T1作为正例,T2作为负例,进行二元逻辑回归,得到模型参数。一共需要T(T-1)/2次分类。
从上面的描述可以看出OvR相对简单,但分类效果相对略差(这里指大多数样本分布情况,某些样本分布下OvR可能更好)。而MvM分类相对精确,但是分类速度没有OvR快。
如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg, lbfgs和sag都可以选择。但是如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。
 
类型权重参数: class_weight
class_weight参数用于标示分类模型中各种类型的权重,可以不输入,即不考虑权重,或者说所有类型的权重一样。如果选择输入的话,可以选择balanced让类库自己计算类型权重,或者我们自己输入各个类型的权重,比如对于0,1的二元模型,可以定义class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,而类型1的权重为10%。
如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越多,则权重越低,样本量越少,则权重越高。
 
那么class_weight有什么作用呢?在分类模型中,经常会遇到两类问题:
  • 第一种是误分类的代价很高。比如对合法用户和非法用户进行分类,将非法用户分类为合法用户的代价很高,我们宁愿将合法用户分类为非法用户,这时可以人工再甄别,但是却不愿将非法用户分类为合法用户。这时,可以适当提高非法用户的权重。
  • 第二种是样本是高度失衡的,比如有合法用户和非法用户的二元样本数据10000条,里面合法用户有9995条,非法用户只有5条,如果不考虑权重,则可以将所有的测试集都预测为合法用户,这样预测准确率理论上有99.95%,但是却没有任何意义。这时,可以选择balanced,让类库自动提高非法用户样本的权重。
提高了某种分类的权重,相比不考虑权重,会有更多的样本分类划分到高权重的类别,从而可以解决上面两类问题。
当然,对于第二种样本失衡的情况,还可以考虑用样本权重参数: sample_weight,不使用class_weight
 
 
样本权重参数: sample_weight
由于样本可能不平衡,导致样本不是总体样本的无偏估计,从而可能导致模型预测能力下降。遇到这种情况,可以通过调节样本权重来尝试解决这个问题。调节样本权重的方法有两种:
  • 在class_weight使用balanced
  • 调用fit函数时,通过sample_weight来自己调节每个样本权重
scikit-learn做逻辑回归时,如果两种方法都用到了,那么样本的真正权重是class_weight*sample_weight
 
 
 
  • Scikit-Learn
  • 线性回归最大熵模型
    目录