逻辑回归与线性回归的联系与区别
线性回归
用一组变量的(特征)的线性组合,来建立与结果之间的关系。
模型表达:y(x,w)=w0+w1x1+…+wnxn
逻辑回归
逻辑回归用于分类,而不是回归。
在线性回归模型中,输出一般是连续的, 对于每一个输入的x,都有一个对应的输出y。因此模型的定义域和值域都可以是无穷。
但是对于逻辑回归,输入可以是连续的[-∞, +∞],但输出一般是离散的,通常只有两个值{0, 1}。
这两个值可以表示对样本的某种分类,高/低、患病/ 健康、阴性/阳性等,这就是最常见的二分类逻辑回归。因此,从整体上来说,通过逻辑回归模型,我们将在整个实数范围上的x映射到了有限个点上,这样就实现了对x的分类。因为每次拿过来一个x,经过逻辑回归分析,就可以将它归入某一类y中。
逻辑回归与线性回归的关系
可以认为逻辑回归的输入是线性回归的输出,将逻辑斯蒂函数(Sigmoid曲线)作用于线性回归的输出得到输出结果。
线性回归y = ax + b, 其中a和b是待求参数;
逻辑回归p = S(ax + b), 其中a和b是待求参数, S是逻辑斯蒂函数,然后根据p与1-p的大小确定输出的值,通常阈值取0.5,若p大于0.5则归为1这类。
具体的:
线性函数如下:
构造预测函数
逻辑回归的损失函数:
逻辑回归采用交叉熵作为代价函数,即对数损失函数。能够有效避免梯度消失.
对数损失函数(logarithmic loss function) 或对数似然损失函数(log-likehood loss function):
L(Y,P(Y|X))=−logP(Y|X)
逻辑回归中,采用的是负对数损失函数。如果损失函数越小,表示模型越好。
极大似然估计:
极大似然原理的直观想法是,一个随机试验如有若干个可能的结果A,B,C,… ,若在一次试验中,结果A出现了,那么可以认为实验条件对A的出现有利,也即出现的概率P(A)较大。一般说来,事件A发生的概率与某一未知参数θ有关, θ取值不同,则事件A发生的概率也不同,当我们在一次试验中事件A发生了,则认为此时的θ值应是一切可能取值中使P(A|θ)达到最大的那一个,极大似然估计法就是要选取这样的θ值作为参数的估计值,使所选取的样本在被选的总体中出现的可能性为最大。
在逻辑回归中目标函数均为最大化条件概率p(y|x),其中x是输入样本
似然:选择参数使似然概率p(y|x,)最大,y是实际标签
过程:目标函数→单个样本的似然概率→所有样本的似然概率→log变换, 将累乘变成累加→负号, 变成损失函数
选择一组参数使得实验结果具有最大概率。
损失函数的由来:
已知估计函数为:
则似然概率分布为(即输出值为判断为1的概率,但在输出标签值时实际只与0.5作比较):
由最大似然估计原理,我们可以通过m个训练样本值,来估计出值,使得似然函数值(所有样本的似然函数之积)最大
求log:
取负数,得损失函数:
逻辑回归参数迭代,利用反向传播(梯度下降)进行计算:
为什么逻辑回归采用似然函数,而不是平方损失函数?
可以从两个角度理解。
交叉熵损失函数的好处是可以克服方差代价函数更新权重过慢的问题(针对**函数是sigmoid的情况)。
原因是其梯度里面不在包含对sigmoid函数的导数:
而如果使用的是平方损失函数加sigmoid函数,则计算梯度时:
会包含sigmoid的导数(sigmoid的导数值始终小于1),使梯度下降变慢。
图1 最小二乘作为逻辑回归模型的损失函数(非凸),theta为待优化参数
图2 最大似然作为逻辑回归模型的损失函数,theta为待优化参数
逻辑回归为什么使用sigmoid函数
1.也可以从两点来进行理解
Sigmoid 函数自身的性质
因为这是一个最简单的,可导的,0-1阶跃函数
sigmoid 函数连续,单调递增
sigmiod 函数关于(0,0.5) 中心对称
对sigmoid函数求导简单
2.逻辑回归函数的定义
因此, 逻辑回归返回的概率是指判别为1类的概率.
逻辑回归和SVM的异同点
相同点:
第一,LR和SVM都是分类算法。
第二,如果不考虑核函数,LR和SVM都是线性分类算法,也就是说他们的分类决策面都是线性的。
第三,LR和SVM都是监督学习算法。
第四,LR和SVM都是判别模型。
判别模型会生成一个表示P(Y|X)的判别函数(或预测模型),而生成模型先计算联合概率p(Y,X)然后通过贝叶斯公式转化为条件概率。简单来说,在计算判别模型时,不会计算联合概率,而在计算生成模型时,必须先计算联合概率。
不同点:
第一,本质上是其loss function不同
逻辑回归的损失函数是交叉熵函数:
SVM的损失函数:
逻辑回归方法基于概率理论,假设样本为1的概率可以用sigmoid函数来表示,然后通过极大似然估计的方法估计出参数的值;
支持向量机基于几何间隔最大化原理,认为存在最大几何间隔的分类面为最优分类面;
第二,支持向量机只考虑局部的边界线附近的点,而逻辑回归考虑全局(远离的点对边界线的确定也起作用)。
第三,在解决非线性问题时,支持向量机采用核函数的机制,而LR通常不采用核函数的方法。
这个问题理解起来非常简单。分类模型的结果就是计算决策面,模型训练的过程就是决策面的计算过程。通过上面的第二点不同点可以了解,在计算决策面时,SVM算法里只有少数几个代表支持向量的样本参与了计算,也就是只有少数几个样本需要参与核计算(即kernal machine解的系数是稀疏的)。然而,LR算法里,每个样本点都必须参与决策面的计算过程,也就是说,假设我们在LR里也运用核函数的原理,那么每个样本点都必须参与核计算,这带来的计算复杂度是相当高的。所以,在具体应用时,LR很少运用核函数机制。
第四,SVM的损失函数就自带正则
参考
逻辑回归:https://www.cnblogs.com/Belter/p/6128644.html
逻辑回归推导:http://blog.csdn.net/pakko/article/details/37878837
极大似然估计:http://blog.csdn.net/star_liux/article/details/39666737
刘建平:https://www.cnblogs.com/pinard/p/6035872.html
逻辑回归和SVM的比较:https://www.cnblogs.com/zhizhan/p/5038747.html
逻辑回归损失函数推导及求导
优点
实现简单;
分类时计算量非常小,速度很快,存储资源低
缺点
容易欠拟合,一般准确度不太高
只能处理两分类问题(在此基础上衍生出来的softmax可以用于多分类),且必须线性可分
损失函数
逻辑回归的公式为:
假设有N个样本,样本的标签只有0和1两类,可以用极大似然估计法估计模型参数,从而得到逻辑回归模型
设yi=1的概率为pi,yi=0的概率为1 - pi,那么观测的概率为:
概率由逻辑回归的公式求解,那么带进去得到极大似然函数:
取对数之后:
上面这个式子的计算过程还用到了对数的一些相关的性质,对L(w)求极大值,得到w的估计值
其实实际操作中会加个负号,变成最小化问题,通常会采用随机梯度下降法和拟牛顿迭代法来求解
梯度
现在已经知道损失函数:
现在开始求导:
通常来说,是用梯度下降法来求解的,所以会在损失函数前面加个负号求最小值,所以最终的导数变成:
正则化与模型评估指标
使用梯度下降法来优化代价函数????(????),接下来学习了更高级的优化算法,这些高级优化算法需要
你自己设计代价函数????(????)。
自己计算导数同样对于逻辑回归,我们也给代价函数增加一个正则化的表达式,得到代
价函数:
要最小化该代价函数,通过求导,得出梯度下降算法为:
注:看上去同线性回归一样,但是知道 ℎ???? (????) = ????(????????????),所以与线性回归不同。
注意:
1. 虽然正则化的逻辑回归中的梯度下降和正则化的线性回归中的表达式看起来一样,
但由于两者的ℎ???? (????)不同所以还是有很大差别。
2. ????0不参与其中的任何一个正则化。
1. 平均绝对误差(MAE)
平均绝对误差MAE(Mean Absolute Error)又被称为l1
2. 平均平方误差(MSE)
平均平方误差MSE(Mean Squared Error)又被称为l2
3、均方根误差(RMSE)
RMSE虽然广为使用,但是其存在一些缺点,因为它是使用平均误差,而平均值对异常点(outliers)较敏感,如果回归器对某个点的回归值很不理性,那么它的误差则较大,从而会对RMSE的值有较大影响,即平均值是非鲁棒的。
4、解释变异
解释变异( Explained variance)是根据误差的方差计算得到的:
5、决定系数
决定系数(Coefficient of determination)又被称为R2
逻辑回归的优缺点
优点:
1)预测结果是界于0和1之间的概率;
2)可以适用于连续性和类别性自变量;
3)容易使用和解释;
缺点:
1)对模型中自变量多重共线性较为敏感,例如两个高度相关自变量同时放入模型,可能导致较弱的一个自变量回归符号不符合预期,符号被扭转。需要利用因子分析或者变量聚类分析等手段来选择代表性的自变量,以减少候选变量之间的相关性;
2)预测结果呈“S”型,因此从log(odds)向概率转化的过程是非线性的,在两端随着log(odds)值的变化,概率变化很小,边际值太小,slope太小,而中间概率的变化很大,很敏感。 导致很多区间的变量变化对目标概率的影响没有区分度,无法确定阀值。
样本不均衡问题解决办法
1、人为将样本变为均衡数据。
上采样:重复采样样本量少的部分,以数据量多的一方的样本数量为标准,把样本数量较少的类的样本数量生成和样本数量多的一方相同。
下采样:减少采样样本量多的部分,以数据量少的一方的样本数量为标准。
2、调节模型参数(class_weigh,sample_weight,这些参数不是对样本进行上采样下采样等处理,而是在损失函数上对不同的样本加上权重)
(A)逻辑回归中的参数class_weigh;
在逻辑回归中,参数class_weight默认None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签的比例是1:1。所以当样本不均衡的时候,我们可以使用形如{标签的值1:权重1,标签的值2:权重2}的字典来输入真实的样本标签比例(例如{“违约”:10,“未违约”:1}),来提高违约样本在损失函数中的权重。
或者使用”balanced“模式,sklearn内部原理:直接使用n_samples/(n_classes * np.bincount(y)),即样本总数/(类别数量*y0出现频率)作为权重,可以比较好地修正我们的样本不均衡情况。
(B)在SVM中使用SVC类的参数class_weigh和接口fit中可以设定的sample_weight:
SVC类的参数class_weigh:
对于class_weight,输入形如{“标签的值1”:权重1,“标签的值2”:权重2}的字典,则不同类别的C将会自动被设为不同的值:
sklearn内部原理:标签的值为1的C:权重1 * C,标签的值为2的C:权重2*C
或者,可以使用“balanced”模式,sklearn内部原理:这个模式使用y的值自动调整与输入数据中的类频率成反比的权重为 n_samples/(n_classes * np.bincount(y)
fit接口参数sample_weight:
参数形式:数组,结构为 (n_samples, ),则模型参数C则变为,每个样本的权重 * C值,这样迫使分类器强调权重更大的样本。通常,较大的权重加在少数类的样本上,以迫使模型向着少数类的方向建模
sklearn参数
**penalty:**惩罚项,str类型,可选参数为l1和l2,默认为l2。用于指定惩罚项中使用的规范。newton-cg、sag和lbfgs求解算法只支持L2规范。L1G规范假设的是模型的参数满足拉普拉斯分布,L2假设的模型参数满足高斯分布,所谓的范式就是加上对参数的约束,使得模型更不会过拟合(overfit),但是如果要说是不是加了约束就会好,这个没有人能回答,只能说,加约束的情况下,理论上应该可以获得泛化能力更强的结果。
dual:对偶或原始方法,bool类型,默认为False。对偶方法只用在求解线性多核(liblinear)的L2惩罚项上。当样本数量>样本特征的时候,dual通常设置为False。
tol:停止求解的标准,float类型,默认为1e-4。就是求解到多少的时候,停止,认为已经求出最优解。
c:正则化系数λ的倒数,float类型,默认为1.0。必须是正浮点型数。像SVM一样,越小的数值表示越强的正则化。
fit_intercept:是否存在截距或偏差,bool类型,默认为True。
intercept_scaling:仅在正则化项为”liblinear”,且fit_intercept设置为True时有用。float类型,默认为1。
class_weight:用于标示分类模型中各种类型的权重,可以是一个字典或者’balanced’字符串,默认为不输入,也就是不考虑权重,即为None。如果选择输入的话,可以选择balanced让类库自己计算类型权重,或者自己输入各个类型的权重。举个例子,比如对于0,1的二元模型,我们可以定义class_weight={0:0.9,1:0.1},这样类型0的权重为90%,而类型1的权重为10%。如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越多,则权重越低,样本量越少,则权重越高。当class_weight为balanced时,类权重计算方法如下:n_samples / (n_classes * np.bincount(y))。n_samples为样本数,n_classes为类别数量,np.bincount(y)会输出每个类的样本数,例如y=[1,0,0,1,1],则np.bincount(y)=[2,3]。
那么class_weight有什么作用呢?
在分类模型中,我们经常会遇到两类问题:
第一种是误分类的代价很高。比如对合法用户和非法用户进行分类,将非法用户分类为合法用户的代价很高,我们宁愿将合法用户分类为非法用户,这时可以人工再甄别,但是却不愿将非法用户分类为合法用户。这时,我们可以适当提高非法用户的权重。
第二种是样本是高度失衡的,比如我们有合法用户和非法用户的二元样本数据10000条,里面合法用户有9995条,非法用户只有5条,如果我们不考虑权重,则我们可以将所有的测试集都预测为合法用户,这样预测准确率理论上有99.95%,但是却没有任何意义。这时,我们可以选择balanced,让类库自动提高非法用户样本的权重。提高了某种分类的权重,相比不考虑权重,会有更多的样本分类划分到高权重的类别,从而可以解决上面两类问题。
random_state:随机数种子,int类型,可选参数,默认为无,仅在正则化优化算法为sag,liblinear时有用。
solver:优化算法选择参数,只有五个可选参数,即newton-cg,lbfgs,liblinear,sag,saga。默认为liblinear。solver参数决定了我们对逻辑回归损失函数的优化方法,有四种算法可以选择,分别是:
liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。
saga:线性收敛的随机优化算法的的变重。
总结:
liblinear适用于小数据集,而sag和saga适用于大数据集因为速度更快。
对于多分类问题,只有newton-cg,sag,saga和lbfgs能够处理多项损失,而liblinear受限于一对剩余(OvR)。啥意思,就是用liblinear的时候,如果是多分类问题,得先把一种类别作为一个类别,剩余的所有类别作为另外一个类别。一次类推,遍历所有类别,进行分类。
newton-cg,sag和lbfgs这三种优化算法时都需要损失函数的一阶或者二阶连续导数,因此不能用于没有连续导数的L1正则化,只能用于L2正则化。而liblinear和saga通吃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正则化了。
**max_iter:**算法收敛最大迭代次数,int类型,默认为10。仅在正则化优化算法为newton-cg, sag和lbfgs才有用,算法收敛的最大迭代次数。
multi_class:分类方式选择参数,str类型,可选参数为ovr和multinomial,默认为ovr。ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。
OvR和MvM有什么不同
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了。
verbose:日志冗长度,int类型。默认为0。就是不输出训练过程,1的时候偶尔输出结果,大于1,对于每个子模型都输出。
**warm_start:**热启动参数,bool类型。默认为False。如果为True,则下一次训练是以追加树的形式进行(重新使用上一次的调用作为初始化)。
**n_jobs:**并行数。int类型,默认为1。1的时候,用CPU的一个内核运行程序,2的时候,用CPU的2个内核运行程序。为-1的时候,用所有CPU的内核运行程序。