逻辑回归(Logistic Regression)算法小结

一、逻辑回归简述:

  回顾线性回归算法,对于给定的一些n维特征(x1,x2,x3,......xn),我们想通过对这些特征进行加权求和汇总的方法来描绘出事物的最终运算结果。从而衍生出我们线性回归的计算公式:

      逻辑回归(Logistic Regression)算法小结

向量化表达式:

逻辑回归(Logistic Regression)算法小结

这一系列W值(w1,w2,w3....wn)和截距b就是拟合了我们这些特征对应于结果f(x)的线性关系,当我们给出新的一些特征x的是时候,可以根据这些W值特征x进行内积加截距b来预测出给定的新特征x对应的结果f(x)。

  然而在采用回归模型分析实际问题中,我们想得出的结果不单纯是一个结果f(x)值,我们需要得出一个分类结果。比如我们给定一些指标年龄、性别、体质指数、平均血压、疾病指数,来判断就一个人是否患有糖尿病(Y=0表示未患病,Y=1表示患病),我们想要的结果f(x)不是一个连续变量,而是一个二分类变量(0-1)。这个时候单纯的线性回归得出的f(x)就不是我们想要的结果,我们需要对得出的线性回归结果f(x)通过一个sigmoid函数转换成我们的逻辑回归模型,从而得出我们想要的结果。从中我们可以总结:线性回归模型通常是处理因变量是连续变量的问题,如果因变量是定性变量,线性回归模型就不在适用,需要采取逻辑回归模型进行求解。也就引出我们逻辑回归的公式:

逻辑回归(Logistic Regression)算法小结

逻辑回归(Logistic Regression)算法小结逻辑回归(Logistic Regression)算法小结逻辑回归(Logistic Regression)算法小结

逻辑回归(Logistic Regression)是用于处理因变量为分类变量的回归问题,常见的是二分类或二项分布问题,也可以处理多分类问题。线性回归通过sigmoid函数转换得出一个概率值,y值的取值范围[0,1],我们根据sigmoid函数的特性,在(0,0.5)这个点上随着x的变化呈现出不同的变化趋势,如图所示:

逻辑回归(Logistic Regression)算法小结

从图中可以得出以下信息:我们线性回归得出的f(x)即图中的Z取值范围(-∞,+∞),我们为了的解决二分类问题,我们对得出的结果Z通过sigmoid函数转换使我们的结果取值在[0,1]之间。通俗的说就是如果有了一个测试点x,那么就可以用Sigmoid 函数算出来的结果来当做该点x属于类别1和0的概率大小。 当我们的Z>0时得出Z值越大我们将其划分为1的概率越大,反之,得出的Z<0,Z越小我们将其划分为0的概率越大。

逻辑回归(Logistic Regression)算法小结

二、逻辑回归损失函数:(注:由于很多公式不好用键盘敲出,本人截取了很多别的博主的公式,导致通篇公式不一致)

  基于当y取1的时候,我们的h(x)越趋近于1 要求我们的损失函数越小,当y=0时我们的h(x)越趋近于0要求我们的损失函数越小,我们需要对得出的h(x)取对数才能贴合我们的损失函数要求,故得出损失函数如下:

  逻辑回归(Logistic Regression)算法小结逻辑回归(Logistic Regression)算法小结

有了损失函数,我们可以通过梯度上升法对我们的损失函数进行求解,得出Θ的最佳参数。

逻辑回归(Logistic Regression)算法小结

逻辑回归(Logistic Regression)算法小结

、逻辑回归中的一些参数:

1. 正则化选择参数:penalty
    LogisticRegression和LogisticRegressionCV默认就带了正则化项。penalty参数可选择的值为"l1"和"l2".分别对应L1的正则化和L2的正则化,默认是L2的正则化。

    在调参时如果我们主要的目的只是为了解决过拟合,一般penalty选择L2正则化就够了。但是如果选择L2正则化发现还是过拟合,即预测效果差的时候,就可以考虑L1正则化。另外,如果模型的特征非常多,我们希望一些不重要的特征系数归零,从而让模型系数稀疏化的话,也可以使用L1正则化。

    penalty参数的选择会影响我们损失函数优化算法的选择。即参数solver的选择,如果是L2正则化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,而{‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的一阶或者二阶连续导数。而‘liblinear’并没有这个依赖。

2. 优化算法选择参数:solver

    solver参数决定了我们对逻辑回归损失函数的优化方法,有4种算法可以选择,分别是:

    a) liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。

    b) lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。

    c) newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。

    d) sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候,SAG是一种线性收敛算法,这个速度远比SGD快。关于SAG的理解,参考博文线性收敛的随机优化算法之 SAG、SVRG(随机梯度下降)

    从上面的描述可以看出,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正则化了。

总结而言,liblinear支持L1和L2,只支持OvR做多分类,“lbfgs”, “sag” “newton-cg”只支持L2,支持OvR和MvM做多分类。

    具体OvR和MvM有什么不同我们下一节讲。

3. 分类方式选择参数: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了。

4. 类型权重参数: class_weight
    class_weight参数用于标示分类模型中各种类型的权重,可以不输入,即不考虑权重,或者说所有类型的权重一样。如果选择输入的话,可以选择balanced让类库自己计算类型权重,或者我们自己输入各个类型的权重,比如对于0,1的二元模型,我们可以定义class_weight={0:0.9, 1:0.1},这样类型0的权重为90%,而类型1的权重为10%。

    如果class_weight选择balanced,那么类库会根据训练样本量来计算权重。某种类型样本量越多,则权重越低,样本量越少,则权重越高。

sklearn的官方文档中,当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,让类库自动提高非法用户样本的权重。

    提高了某种分类的权重,相比不考虑权重,会有更多的样本分类划分到高权重的类别,从而可以解决上面两类问题。

    当然,对于第二种样本失衡的情况,我们还可以考虑用下一节讲到的样本权重参数: sample_weight,而不使用class_weight。sample_weight在下一节讲。

5. 样本权重参数: sample_weight
    上一节我们提到了样本不失衡的问题,由于样本不平衡,导致样本不是总体样本的无偏估计,从而可能导致我们的模型预测能力下降。遇到这种情况,我们可以通过调节样本权重来尝试解决这个问题。调节样本权重的方法有两种,第一种是在class_weight使用balanced。第二种是在调用fit函数时,通过sample_weight来自己调节每个样本权重。

    在scikit-learn做逻辑回归时,如果上面两种方法都用到了,那么样本的真正权重是class_weight*sample_weight.

    以上就是scikit-learn中逻辑回归类库调参的一个小结,还有些参数比如正则化参数C(交叉验证就是 Cs),迭代次数max_iter等,由于和其它的算法类库并没有特别不同,这里不多累述了。

上一篇:swift - if let Optional 语法


下一篇:如何开启ubuntu的SSH服务(不要和openssl搞混淆了)