博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
逻辑回归
阅读量:2241 次
发布时间:2019-05-09

本文共 9582 字,大约阅读时间需要 31 分钟。

逻辑回归

目录

一、概述

1、介绍

2、作用

二、sklearn 中逻辑回归

1、二元逻辑回归的损失函数

2、重要参数penalty & C

3、梯度下降:重要参数max_iter

一、概述

1、介绍

我们接触了不少带“回归”二字的算法,回归树,随机森林的回归,线性回归,无一例外他们都是区别于分类算法们,用来处理和预测连续型标签的算法。然而逻辑回归,是一种名为“回归”的线性分类器,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法。要理解逻辑回归从何而来,得要先从线性回归开始。线性回归是机器学习中最简单的的回归算法,对任意样本 i i i,它写作一个几乎人人熟悉的方程:

z i = w 0 + w 1 x i 1 + w 2 x i 2 + . . . + w n x i n z_i=w_0+w_1x_{i1}+w_2x_{i2}+...+w_nx_{in} zi=w0+w1xi1+w2xi2+...+wnxin
写成矩阵形式:
z = [ w 0 , w 1 , w 2 . . . w n ] ∗ [ x 0 x 1 x 2 . . . x n ] = w T x ( x 0 = 1 ) z=\begin{bmatrix} w_0,w_1,w_2...w_n \end{bmatrix}*\begin{bmatrix} x_0\\ x_1\\ x_2\\ ...\\ x_n \end{bmatrix}=w^Tx(x_0=1) z=[w0,w1,w2...wn]x0x1x2...xn=wTx(x0=1)
通过函数 z z z,线性回归使用输入的特征矩阵X来输出一组连续型的标签值y_pred,以完成各种预测连续型变量的任务(比如预测产品销量,预测股价等等)。那如果我们的标签是离散型变量,尤其是,如果是满⾜足0-1分布的离散型变量,我们要怎么办呢?我们可以通过引入联系函数(link function),将线性回归方程z变换为g(z),并且令g(z)的值分布在(0,1)之间,且当g(z)接近0时样本的标签为类别0,当g(z)接近1时样本的标签为类别1,这样就得到了一个分类模型。而这个联系函数对于逻辑回归来说,就是Sigmoid函数:
g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+ez1
在这里插入图片描述

Sigmoid函数的公式和性质:

Sigmoid函数是一个S型的函数,当自变量量z趋近正无穷时,因变量量g(z)趋近于1,而当z趋近负无穷时,g(z)趋近于0,它能够将任何实数映射到(0,1)区间,使其可用于将任意值函数转换为更适合二分类的函数。因为这个性质,Sigmoid函数也被当作是归一化的一种方法,与我们之前学过的极值归一化法同理(减去最小值除以极差),是属于数据预处理中的“缩放”功能,可以将数据压缩到[0,1]之内。区别在于,极值归一化之后,是可以取到0和1的(最大值归一化后就是1,最小值归一化后就是0),但Sigmoid函数只是无限趋近于0和1。同时在支持向量机中,它做为一个核函数,又叫双曲正切,主要处理非线性问题,相对于其他核函数表现一般,所以使用较少。

线性回归中 z = w T x z=w^Tx z=wTx,于是我们将带入,就得到了二元逻辑回归模型的一般形式:

g ( z ) = y ( x ) = 1 1 + e − w T x g(z)=y(x)=\frac{1}{1+e^{-w^Tx}} g(z)=y(x)=1+ewTx1
y ( x ) y(x) y(x)就是我们逻辑回归返回的标签值。此时, y ( x ) y(x) y(x)的取值都在[0,1]之间,因此 y ( x ) y(x) y(x) 1 − y ( x ) 1-y(x) 1y(x)相加必然为1。如果我们 y ( x ) y(x) y(x)令除以 1 − y ( x ) 1-y(x) 1y(x)可以得到形似几率(odds)的,在此基础上取对数,可以
很容易就得到:

在这里插入图片描述

不难发现, y ( x ) y(x) y(x)的形似几率取对数的本质其实就是我们的线性回归 z z z。因此,其对应的模型被称为”对数几率回归“(logistic Regression),也就是我们的逻辑回归,这个名为“回归”却是用来做分类工作的分类器。

之前我们提到过,线性回归的核心任务是通过求解 w w w构建 z z z这个预测函数,并希望预测函数 z z z能够尽量拟合数据,因此逻辑回归的核心任务也是类似的:求解 w w w来构建一个能够尽量拟合数据的预测函数$y(x) $,并通过向预测函数中输入特征矩阵来获取相应的标签值y。

在这里插入图片描述

2、作用

逻辑回归是一个受工业商业热爱,使用广泛的模型,因为它有着不可替代的优点:

①逻辑回归对线性关系的拟合效果好到丧心病狂,特征与标签之间的线性关系极强的数据,比如⾦金融领域中的信用卡欺诈,评分卡制作,电商中的营销预测等等相关的数据,都是逻辑回归的强项。虽然现在有了梯度提升树GDBT,比逻辑回归效果更好,也被许多数据咨询公司启用,但逻辑回归在金融领域,尤其是银行业中的统治地位依然不可动摇(相对的,逻辑回归在非线性数据的效果很多时候比瞎猜还不如,所以如果你已经知道数据之间的联系是非线性的,千万不要迷信逻辑回归)

②逻辑回归计算快:对于线性数据,(大部分时候)逻辑回归的拟合和计算都非常快,计算效率优于SVM和随机森林,大数据中更为明显。

③逻辑回归返回的分类结果不是固定的0,1,而是以小数形式呈现的类概率数字:我们因此可以把

逻辑回归返回的结果当成连续型数据来利用。比如在评分卡制作时,我们不仅需要判断客户是否会违约,还需要给出确定的”信用分“,而这个信用分的计算就需要使用类概率计算出的对数几率,而决策树和随机森林这样的分类器,可以产出分类结果,却无法帮助我们计算分数(当然,在sklearn中,决策树也可以产生概率,使用接口predict_proba调用就好,但一般来说,正常的决策树没有这个功能)。

另外,逻辑回归还有抗噪能力力强的优点。福布斯杂志在讨论逻辑回归的优点时,甚至有着“技术上来说,最佳模型的AUC面积低于0.8时,逻辑回归非常明显优于树模型”的说法。并且,逻辑回归在小数据集上表现更好,在大型的数据集上,树模型有着更好的表现。

由此,我们已经了解了逻辑回归的本质,它是一个返回对数几率的,在线性数据上表现优异的分类器,它主要被应用在金融领域。其数学目的是求解能够让模型对数据拟合程度最高的参数的值 w w w,以此构建预测函数$ y(x) $,然后将特征矩阵输入预测函数来计算出逻辑回归的结果y。注意,虽然我们熟悉的逻辑回归通常被用于处理理二分类问题,但逻辑回归也可以做多分类。

二、sklearn 中逻辑回归

1、二元逻辑回归的损失函数

衡量参数 w w w的优劣的评估指标,用来求解最优参数的工具

损失函数小,模型在训练集上表现优异,拟合充分,参数优秀
损失函数大,模型在训练集上表现差劲,拟合不足,参数糟糕
我们追求,能够让损失函数最小化的参数组合

逻辑回归的损失函数是由极大似然估计推导出来的,具体结果可以写作:

J ( w ) = − ∑ i = 1 m ( y i ∗ l o g ( y w ( x i ) ) + ( 1 − y i ) ∗ l o g ( 1 − y w ( x i ) ) ) J(w)=-\sum_{i=1}^{m}(y_i*log(y_w(x_i))+(1-y_i)*log(1-y_w(x_i))) J(w)=i=1m(yilog(yw(xi))+(1yi)log(1yw(xi)))
其中, w w w表示求解出来的一组参数,m是样本的个数, y i y_i yi是样本i上真实的标签, y w ( x i ) y_w(x_i) yw(xi)是样本i上,基于参数 w w w计算出来的逻辑回归返回值, x i x_i xi是样本i各个特征的取值。我们的目标,就是求解出使 J ( w ) J(w) J(w)最小的 w w w取值。注意,在逻辑回归的本质函数y(x)里,特征矩阵x是自变量,参数是 w w w。但在损失函数中,参数 w w w是损失函数的自变量,x和y都是已知的特征矩阵和标签,相当于是损失函数的参数。不同的函数中,自变量和参数各有不同。

由于我们追求损失函数的最小值,让模型在训练集上表现最优,可能会引发另一个问题:如果模型在训练集上表示优秀,却在测试集上表现糟糕,模型就会过拟合。虽然逻辑回归和线性回归是天生欠拟合的模型,但我们还是需要控制过拟合的技术来帮助我们调整模型,对逻辑回归中过拟合的控制,通过正则化来实现。

在这里插入图片描述

2、重要参数penalty & C

正则化是用来防止模型过拟合的过程,常用的有L1正则化和L2正则化两种选项,分别通过在损失函数后加上参数向量的L1范式和L2范式的倍数来实现。这个增加的范式,被称为“正则项”,也被称为"惩罚项"。损失函数改变,基于损失函数的最优化来求解的参数取值必然改变,我们以此来调节模型拟合的程度。其中L1范式表现为参数向量中的每个参数的绝对值之和,L2范数表现为参数向量中的每个参数的平方和的开方值。

J ( W ) L 1 = C ∗ J ( w ) + ∑ j = 1 n ∣ w j ∣ ( j ⩾ 1 ) J(W)_{L1}=C*J(w)+\sum_{j=1}^{n}\left | w_j \right |(j\geqslant 1) J(W)L1=CJ(w)+j=1nwj(j1)

J ( W ) L 2 = C ∗ J ( w ) + ∑ j = 1 n ( w j ) 2 ( j ⩾ 1 ) J(W)_{L2}=C*J(w)+\sqrt{\sum_{j=1}^{n}(w_j)^{2}}(j\geqslant 1) J(W)L2=CJ(w)+j=1n(wj)2 (j1)

其中 J ( w ) J(w) J(w)是我们之前提过的损失函数,C是用来控制正则化程度的超参数,n是方程中特征的总数,也是方程中参数的总数,j代表每个参数。在这里,j要大于等于1,是因为我们的参数向量 w w w中,第一个参数是 w 0 w_0 w0,是我们的截距,它通常是不参与正则化的。

sklearn当中,常数项C是在损失函数的前面,通过调控损失函数本身的大小,来调节对模型的惩罚。

在这里插入图片描述

L1正则化和L2正则化虽然都可以控制过拟合,但它们的效果并不相同。当正则化强度逐渐增大(即C逐渐变小),参数 w w w的取值会逐渐变小,但L1正则化会将参数压缩为0,L2正则化只会让参数尽量量小,不会取到0。

在L1正则化在逐渐加强的过程中,携带信息量小的、对模型贡献不大的特征的参数,会比携带大量信息的、对模型有巨大贡献的特征的参数更快地变成0,所以L1正则化本质是一个特征选择的过程,掌管了参数的“稀疏性”。L1正则化越强,参数向量中就越多的参数为0,参数就越稀疏,选出来的特征就越少,以此来防止过拟合。因此,如果特征量很大,数据维度很高,我们会倾向于使用L1正则化。由于L1正则化的这个性质,逻辑回归的特征选择可以由Embedded嵌入法来完成。

相对的,L2正则化在加强的过程中,会尽量让每个特征对模型都有一些小的贡献,但携带信息少,对模型贡献不大的特征的参数会非常接近于0。通常来说,如果我们的主要目的只是为了了防止过拟合,选择L2正则化就足够了了。但是如果选择L2正则化后还是过拟合,模型在未知数据集上的效果表现很差,就可以考虑L1正则化。

from sklearn.linear_model import LogisticRegression as LRfrom sklearn.datasets import load_breast_cancerimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_scoredata = load_breast_cancer()X = data.datay = data.targetdata.data.shapelrl1 = LR(penalty="l1",solver="liblinear",C=0.5,max_iter=1000)lrl2 = LR(penalty="l2",solver="liblinear",C=0.5,max_iter=1000)Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.3                                          ,random_state=420)lr1.fit(Xtrain,Ytrain)lr1.coef_ # 返回很多参数为0lr2.fit(Xtrain,Ytrain)lr2.coef_  #没有0

可以看见,当我们选择L1正则化的时候,许多特征的参数都被设置为了0,这些特征在真正建模的时候,就不会出现在我们的模型当中了了,而L2正则化则是对所有的特征都给出了参数。那到底哪个较好?下面来画图看看。

l1=[]l2=[]l1test=[]l2test=[]for i in np.linspace(0.05,1,19):    lrl1 = LR(penalty="l1",solver="liblinear",C=i,max_iter=1000)    lrl2 = LR(penalty="l2",solver="liblinear",C=i,max_iter=1000)        lrl1 = lrl1.fit(Xtrain,Ytrain)    l1.append(accuracy_score(lrl1.predict(Xtrain),Ytrain))    l1test.append(accuracy_score(lrl1.predict(Xtest),Ytest))        lrl2 = lrl2.fit(Xtrain,Ytrain)    l2.append(accuracy_score(lrl2.predict(Xtrain),Ytrain))    l2test.append(accuracy_score(lrl2.predict(Xtest),Ytest))graph = [l1,l2,l1test,l2test]color = ["green","black","lightgreen","gray"]label = ["L1","L2","L1test","L2test"]    plt.figure(figsize=(6,6))for i in range(len(graph)):    plt.plot(np.linspace(0.05,1,19),graph[i],color[i],label=label[i])plt.legend(loc=4) #图例的位置4表示右下角plt.show()

在这里插入图片描述

可见,至少在乳腺癌数据集下,两种正则化的结果区别不大。但随着C的逐渐变大,正则化的强度越来越小,模型在训练集和测试集上的表现都呈上升趋势,直到C=0.8左右,训练集上的表现依然在走高,但模型在未知数据集上的表现开始下跌,这时候就是出现了了过拟合。我们可以认为,C设定为0.8会比较好。在实际使用时,基本就默认使⽤用L2正则化,如果感觉到模型的效果不好,那就换L1试试看。

3、梯度下降:重要参数max_iter

逻辑回归的数学目的是求解能够让模型最优化,拟合程度最好的参数的值,即求解能够让损失函数$ J(w) 最 小 化 的 最小化的 w$值。对于二元逻辑回归来说,有多种方法可以用来求解参数,最常见的有梯度下降法(Gradient Descent),坐标下降法(Coordinate Descent),牛顿法(Newton-Raphson method)等,其中又以梯度下降法最为著名。

梯度下降求解逻辑回归过程详见链接

https://blog.csdn.net/AIjiankeji/article/details/99692970

那梯度有什么含义呢?梯度是一个向量,因此它有大小也有方向。它的大小,就是偏导数组成的向量的大小,又叫做向量的模,记作。它的方向,几何上来说,就是损失函数的值增加最快的方向,就是小球每次滚动的方向的反方向。只要沿着梯度向量的反方向移动坐标,损失函数的取值就会减少得最快,也就最容易找到损失函数的最小值。

θ i + 1 = θ i − α 1 m ∑ i = 1 m [ h ( x i ) − y i ] x i n \theta _{i+1}=\theta _{i}-α\frac{1}{m}\sum_{i=1}^{m}\left[ h{(x_{i})}- y_{i}\right ]x_{in} θi+1=θiαm1i=1m[h(xi)yi]xin
其中 θ i + 1 \theta _{i+1} θi+1是第i次迭代后的参数向量, θ i \theta _{i} θi是第i次迭代是的参数向量, α α α被称为步长,控制着每走一步(每迭代一次)后 w w w的变化,并以此来影响每次迭代后的梯度向量的大小和方向。

步长的解释:

来看下面这一张二维平面的求导三角型图。类比到我们的损失函数和梯度概念上,图中的抛物线就是我们的损失函数 J ( w ) J(w) J(w) A ( w a , J ( w a ) ) A(w_a,J(w_a)) A(wa,J(wa)) 就是小球最初在的位置, B ( w b , J ( w b ) ) B(w_b,J(w_b)) B(wb,J(wb)) 就是一次滚动后小球移动到的位置。从A到B的方向就是梯度向量的反方向,指向损失函数在A点下降最快的方向。而梯度向量的大小是点A在图像上对求导后的结果,也是点A切线方向的斜率,橙色角的tan结果,记作 d d d

在这里插入图片描述

梯度下降每走一步,损失函数减小的量,是损失函数在 w w w变化之后的取值的变化,写作 J ( w b ) − J ( w a ) J(w_b)-J(w_a) J(wb)J(wa),这是二维平面的求导三角型中的“对边”。

梯度下降每走一步,参数向量的变化,写作 w a − w b w_a-w_b wawb,根据我们参数向量的迭代公式,就是我们的 步长梯度向量的大小,记作 α ∗ d α*d αd ,这是二维平面的求倒三角形中的“邻边”。

梯度下降中每走一步,下降的距离,是 ( α ∗ d ) 2 + ( J ( w b ) − J ( w a ) ) 0.5 (α*d)^2+(J(w_b)-J(w_a))^{0.5} (αd)2+(J(wb)J(wa))0.5,是对边和邻边的根号下平方和,是二维平面的求导三⻆角型中的’‘斜边’’。

所以,步长不是任何物理距离,它甚至不是梯度下降过程中任何距离的直接变化,它是梯度向量的大小上的一个比例,影响着参数向量每次迭代后改变的部分。

既然参数迭代是靠梯度向量的大小 d d d* 步长α来实现的,而 J ( w ) J(w) J(w)的降低又是靠调节 w w w来实现的,所以步长可以调节损失函数下降的速率。在损失函数降低的方向上,步长越长, w w w的变动就越大。相对的,步长如果很短, w w w的每次变动就很小。具体地说,如果步长太大,损失函数下降得就非常快,需要的迭代次数就很少,但梯度下降过程可能跳过损失函数的最低点,无法获取最优值。而步长太小,虽然函数会逐渐逼近我们需要的最低点,但迭代的速度却很缓慢,迭代次数就需要很多。

在sklearn当中,我们设置参数max_iter最大迭代次数来代替步长,帮助我们控制模型的迭代速度并适时地让模型停下。max_iter越大,代表步长越小,模型迭代时间越长,反之,则代表步长设置很大,模型迭代时间很短。

来看看乳腺癌数据集下,max_iter的学习曲线:

l2=[]l2test=[]for i in np.arange(1,201,10):    lr2 = LR(penalty='l2',C=0.9,max_iter=i,solver='liblinear')# solver,四个参数,liblinear表示坐标下降法(l1和l2都可以用,小数据l1),sag表示随机梯度下降法(l2可以用,大于10万数据使用),newton-cg、lbfgs表示牛顿法(l2可以用)    lr2.fit(Xtrain,Ytrain)    l2.append(lr2.score(Xtrain,Ytrain))    l2test.append(lr2.score(Xtest,Ytest))graph=[l2,l2test]color=['black','gray']label=['l2','l2test']plt.figure(figsize=(20,5))for i in range(len(graph)):    plt.plot(np.arange(1,201,10),graph[i],color[i],label=label[i])plt.legend(loc=4)plt.xticks(np.arange(1,201,10))plt.show()lr2.n_iter_ #我们可以使⽤属性.n_iter_来调⽤本次求解中真正实现的迭代次数

当max_iter中限制的步数已经走完了,逻辑回归却还没有找到损失函数的最小值,参数的值还没有被收敛,sklearn就会弹出这样的红色警告。

range(1,201,10),graph[i],color[i],label=label[i])

plt.legend(loc=4)
plt.xticks(np.arange(1,201,10))
plt.show()

lr2.n_iter_ #我们可以使⽤属性.n_iter_来调⽤本次求解中真正实现的迭代次数

当max_iter中限制的步数已经走完了,逻辑回归却还没有找到损失函数的最小值,参数的值还没有被收敛,sklearn就会弹出这样的红色警告。这是在提醒我们:参数没有收敛,请增大max_iter中输入的数字。但我们不一定要听sklearn的。max_iter很大,意味着步长小,模型运行得会更加缓慢。虽然我们在梯度下降中追求的是损失函数的最小值,但这也可能意味着我们的模型会过拟合(在训练集上表现得太好,在测试集上却不一定),因此,如果在max_iter报红条的情况下,模型的训练和预测效果都已经不错了,那我们就不需要再增大max_iter中的数目了,毕竟一切都以模型的预测效果为基准——只要最终的预测效果好,运行又快,那就一切都好,无所谓是否报红色警告了。
你可能感兴趣的文章
用验证曲线 validation curve 选择超参数
查看>>
用 Grid Search 对 SVM 进行调参
查看>>
用 Pipeline 将训练集参数重复应用到测试集
查看>>
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>
使聊天机器人具有个性
查看>>
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>
Logistic regression 为什么用 sigmoid ?
查看>>
Logistic Regression 为什么用极大似然函数
查看>>