逻辑回归是面试当中非常喜欢问到的一个机器学习算法,因为表面上看逻辑回归形式上很简单,很好掌握,但是一问起来就容易懵逼。所以在面试的时候给大家的第一个建议不要说自己精通逻辑回归,非常容易被问倒,从而减分。下面个人总结梳理下面试知识点。
如何凸显你是一个对逻辑回归已经非常了解的人呢。那就是用一句话概括它!逻辑回归假设数据服从伯努利分布,通过极大化似然函数的方法,运用梯度下降来求解参数,来达到将数据二分类的目的。
这里面其实包含了5个点 1:逻辑回归的假设,2:逻辑回归的损失函数,3:逻辑回归的求解方法,4:逻辑回归的目的,5:逻辑回归如何分类。这些问题是考核你对逻辑回归的基本了解。
逻辑回归的基本假设
任何的模型都是有自己的假设,在这个假设下模型才是适用的。逻辑回归的第一个基本假设是 假设数据服从伯努利分布。 伯努利分布有一个简单的例子是抛硬币,抛中为正面的概率是 p,抛中为负面的概率是 1−p.在逻辑回归这个模型里面是假设 h θ ( x ) h_\theta\left(x\right ) hθ(x) 为样本为正的概率, 1 − h θ ( x ) 1- h_\theta\left(x\right ) 1−hθ(x) 为样本为负的概率。那么整个模型可以描述为
h θ ( x ; θ ) = p h_\theta\left(x;\theta \right )=p hθ(x;θ)=p
逻辑回归的第二个假设是假设样本为正的概率是:
p = 1 1 + e − θ T x p=\frac{1}{1+e^{-\theta^{T} x}} p=1+e−θTx1
所以逻辑回归的最终形式 :
h θ ( x ; θ ) = 1 1 + e − θ T x h_\theta\left(x;\theta \right )=\frac{1}{1+e^{-\theta^{T} x}} hθ(x;θ)=1+e−θTx1
逻辑回归的损失函数
逻辑回归的求解方法
逻辑回归的目的
该函数的目的便是将数据二分类,提高准确率。
逻辑回归如何分类
逻辑回归虽然从形式上非常的简单,但是其内涵是非常的丰富。有很多问题是可以进行思考的
逻辑回归的损失函数为什么要使用极大似然函数作为损失函数?
损失函数一般有四种,平方损失函数,对数损失函数,Hinge Loss, 0-1损失函数,绝对值损失函数。将极大似然函数取对数以后等同于对数损失函数。在逻辑回归这个模型下,对数损失函数的训练求解参数的速度是比较快的。至于原因大家可以求出这个式子的梯度更新
θ j = θ j − ( y i − h θ ( x i ; θ ) ) ∗ x j i \theta _j=\theta _j-\left ( y^{i} -h_\theta (x^{i};\theta ) \right )\ast x^{i}_j θj=θj−(yi−hθ(xi;θ))∗xji
这个式子的更新速度只和 x j i x^{i}_j xji , y i y^{i} yi 相关。和sigmod函数本身的梯度是无关的。这样更新的速度是可以自始至终都比较的稳定。
为什么不选平方损失函数的呢?其一是因为如果你使用平方损失函数,你会发现梯度更新的速度和sigmod函数本身的梯度是很相关的。sigmod函数在它在定义域内的梯度都不大于0.25。这样训练会非常的慢。
逻辑回归在训练的过程当中,如果有很多的特征高度相关或者说有一个特征重复了100遍,会造成怎样的影响?
为什么我们还是会在训练的过程当中将高度相关的特征去掉?
logistic回归算法是一种分类算法,主要用于二分类的实现,其数学模型为
p = h ( θ ) = 1 1 + e − θ T x , g ( z ) = 1 1 + e − z , g ( z ) ′ = g ( z ) ( 1 − g ( z ) ) p=h(\theta)=\frac{1}{1+e^{-\theta^Tx}}, g(z)=\frac{1}{1 + e^{-z}} , g(z)^{'} = g(z)(1-g(z)) p=h(θ)=1+e−θTx1,g(z)=1+e−z1,g(z)′=g(z)(1−g(z))
假设
p ( y = 1 ∣ x , θ ) = h 0 ( x ) p(y=1|x,\theta) = h_{0}(x) p(y=1∣x,θ)=h0(x)
p ( y = 0 ∣ x , θ ) = 1 − h 0 ( x ) p(y=0|x,\theta) = 1- h_{0}(x) p(y=0∣x,θ)=1−h0(x)
即 p ( y ∣ x , θ ) = ( h 0 ( x ) ) y ( 1 − ( h 0 ( x ) ) 1 − y p(y|x,\theta) = (h_{0}(x))^y(1-(h_{0}(x))^{1-y} p(y∣x,θ)=(h0(x))y(1−(h0(x))1−y
根据似然函数
L ( θ ) = p ( y ∣ x ; θ ) = ∏ i = 1 m h 0 ( x ( i ) ) y ( i ) ( 1 − h 0 ( x ( i ) ) 1 − y ( i ) L(\theta)=p(y|x;\theta)=\prod_{i=1}^{m}h_{0}(x^{(i)})^{y^{(i)}}(1-h_{0}(x^{(i)})^{1-y^{(i)}} L(θ)=p(y∣x;θ)=i=1∏mh0(x(i))y(i)(1−h0(x(i))1−y(i)
取对数
l ( θ ) = l o g ( L ( θ ) ) = ∑ i = 1 m ( y ( i ) l o g h 0 ( x ( i ) ) + ( 1 − y ( i ) ) l o g ( 1 − h 0 ( x ( i ) ) ) l(\theta) = log(L(\theta))=\sum_{i=1}^{m}{(y^{(i)}logh_{0}(x^{(i)}) + (1-y^{(i)})log(1-h_{0}(x^{(i)}))} l(θ)=log(L(θ))=i=1∑m(y(i)logh0(x(i))+(1−y(i))log(1−h0(x(i)))
求导数
δ l ( θ ) δ θ j = ∑ i = 1 m ( y ( i ) h 0 ( x ( i ) ) − 1 − y ( i ) 1 − h 0 ( x ( i ) ) ) δ h ( x ( i ) ) δ θ j \frac{\delta l(\theta)}{\delta \theta_{j}} = \sum_{i=1}^{m}{(\frac{y^{(i)}}{h_{0}(x^{(i)})}-\frac{1-y^{(i)}}{1-h_{0}(x^{(i)})})\frac{\delta h(x^{(i)})}{\delta \theta_j}} δθjδl(θ)=i=1∑m(h0(x(i))y(i)−1−h0(x(i))1−y(i))δθjδh(x(i))
= ∑ i = 1 m ( y ( i ) h 0 ( x ( i ) ) − 1 − y ( i ) 1 − h 0 ( x ( i ) ) ) δ g ( θ T x ( i ) ) δ θ j = \sum_{i=1}^{m}{(\frac{y^{(i)}}{h_{0}(x^{(i)})}-\frac{1-y^{(i)}}{1-h_{0}(x^{(i)})})\frac{\delta g(\theta^Tx^{(i)})}{\delta \theta_j}} =i=1∑m(h0(x(i))y(i)−1−h0(x(i))1−y(i))δθjδg(θTx(i))
= ∑ i = 1 m ( y ( i ) − g ( θ T x ( i ) ) x j ( i ) = \sum_{i=1}^{m}{(y^{(i)}} - g(\theta^Tx^{(i)})x_{j}^{(i)} =i=1∑m(y(i)−g(θTx(i))xj(i)
logistic求解 θ \theta θ 可以使用梯度下降, α \alpha α 为学习率
如果采用Batch gradient descent:
θ j = θ j + α ∑ i = 1 m ( y ( i ) − h 0 ( x i ) ) x j ( i ) \theta_{j} = \theta_{j} + \alpha \sum_{i=1}^{m}(y^{(i)} - h_{0}(x^{i}))x_{j}^{(i)} θj=θj+αi=1∑m(y(i)−h0(xi))xj(i)
若是采用SGD:
θ j = θ j + α ( y ( i ) − h 0 ( x i ) ) x j ( i ) \theta_{j} = \theta_{j} + \alpha (y^{(i)} - h_{0}(x^{i}))x_{j}^{(i)} θj=θj+α(y(i)−h0(xi))xj(i)
说起交叉熵损失函数「Cross Entropy Loss」,脑海中立马浮现出它的公式:
L = − [ y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ] L=-[ylog\ \hat y+(1-y)log\ (1-\hat y)] L=−[ylog y^+(1−y)log (1−y^)]
我们已经对这个交叉熵函数非常熟悉,大多数情况下都是直接拿来使用就好。但是它是怎么来的?为什么它能表征真实样本标签和预测概率之间的差值?上面的交叉熵函数是否有其它变种?也许很多朋友还不是很清楚!没关系,接下来我将尽可能以最通俗的语言回答上面这几个问题。
我们知道,在二分类问题模型:例如逻辑回归「Logistic Regression」、神经网络「Neural Network」等,真实样本的标签为 [0,1],分别表示负类和正类。模型的最后通常会经过一个 Sigmoid 函数,输出一个概率值,这个概率值反映了预测为正类的可能性:概率越大,可能性越大。
Sigmoid 函数的表达式和图形如下所示:
g ( s ) = 1 1 + e − s g(s)=\frac{1}{1+e^{-s}} g(s)=1+e−s1
其中 s 是模型上一层的输出,Sigmoid 函数有这样的特点:s = 0 时,g(s) = 0.5;s >> 0 时, g ≈ 1,s << 0 时,g ≈ 0。显然,g(s) 将前一级的线性输出映射到 [0,1] 之间的数值概率上。这里的 g(s) 就是交叉熵公式中的模型预测输出 。
我们说了,预测输出即 Sigmoid 函数的输出表征了当前样本标签为 1 的概率:
y ^ = P ( y = 1 ∣ x ) \hat y=P(y=1|x) y^=P(y=1∣x)
很明显,当前样本标签为 0 的概率就可以表达成:
1 − y ^ = P ( y = 0 ∣ x ) 1-\hat y=P(y=0|x) 1−y^=P(y=0∣x)
重点来了,如果我们从极大似然性的角度出发,把上面两种情况整合到一起:
P ( y ∣ x ) = y ^ y ⋅ ( 1 − y ^ ) 1 − y P(y|x)=\hat y^y\cdot (1-\hat y)^{1-y} P(y∣x)=y^y⋅(1−y^)1−y
不懂极大似然估计也没关系。我们可以这么来看:
当真实样本标签 y = 0 时,上面式子第一项就为 1,概率等式转化为:
P ( y = 0 ∣ x ) = 1 − y ^ P(y=0|x)=1-\hat y P(y=0∣x)=1−y^
当真实样本标签 y = 1 时,上面式子第二项就为 1,概率等式转化为:
P ( y = 1 ∣ x ) = y ^ P(y=1|x)=\hat y P(y=1∣x)=y^
两种情况下概率表达式跟之前的完全一致,只不过我们把两种情况整合在一起了。
重点看一下整合之后的概率表达式,我们希望的是概率 P(y|x) 越大越好。首先,我们对 P(y|x) 引入 log 函数,因为 log 运算并不会影响函数本身的单调性。则有:
l o g P ( y ∣ x ) = l o g ( y ^ y ⋅ ( 1 − y ^ ) 1 − y ) = y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) log\ P(y|x)=log(\hat y^y\cdot (1-\hat y)^{1-y})=ylog\ \hat y+(1-y)log(1-\hat y) log P(y∣x)=log(y^y⋅(1−y^)1−y)=ylog y^+(1−y)log(1−y^)
我们希望 log P(y|x) 越大越好,反过来,只要 log P(y|x) 的负值 -log P(y|x) 越小就行了。那我们就可以引入损失函数,且令 Loss = -log P(y|x)即可。则得到损失函数为:
L = − [ y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ] L=-[ylog\ \hat y+(1-y)log\ (1-\hat y)] L=−[ylog y^+(1−y)log (1−y^)]
非常简单,我们已经推导出了单个样本的损失函数
上面说的都是一个样本的时候,多个样本的表达式是:
多个样本的概率即联合概率,等于每个的乘积。
p ( y ∣ x ) = ∏ i m p ( y ( i ) ∣ x ( i ) ) p(y|x) = \prod _{i}^{m} p(y^{(i)}| x^{(i)}) p(y∣x)=i∏mp(y(i)∣x(i))
l o g p ( y ∣ x ) = ∑ i m l o g p ( y ( i ) ∣ x ( i ) ) log p(y|x) = \sum _{i}^{m} log p(y^{(i)}| x^{(i)}) logp(y∣x)=i∑mlogp(y(i)∣x(i))
l o g p ( y ( i ) ∣ x ( i ) ) = − L ( y ( i ) ∣ x ( i ) ) logp(y^{(i)}| x^{(i)}) = - L(y^{(i)}| x^{(i)}) logp(y(i)∣x(i))=−L(y(i)∣x(i))
l o g p ( y ( i ) ∣ x ( i ) ) = − ∑ i m L ( y ( i ) ∣ x ( i ) ) logp(y^{(i)}| x^{(i)})=-\sum _{i}^{m}L(y^{(i)}| x^{(i)}) logp(y(i)∣x(i))=−i∑mL(y(i)∣x(i))
加上 1 m \frac{1}{m} m1对式子进行缩放,便于计算。
J ( w , b ) = 1 m ∑ i m L ( y ( i ) ∣ x ( i ) ) J(w,b) =\frac{1}{m}\sum _{i}^{m} L(y^{(i)}| x^{(i)}) J(w,b)=m1i∑mL(y(i)∣x(i))
J = − 1 m Σ i = 1 m [ y ( i ) l o g y ^ ( i ) + ( 1 − y ( i ) ) l o g ( 1 − y ^ ( i ) ) ] J = - \frac{1}{m}\Sigma_{i=1}^{m}[y^{(i)} log \hat{y}^{(i)} + (1-y^{(i)})log(1- \hat{y}^{(i)})] J=−m1Σi=1m[y(i)logy^(i)+(1−y(i))log(1−y^(i))]
这样,我们已经完整地实现了交叉熵损失函数的推导过程。
面试的时候,别人也经常会问到,你在使用逻辑回归的时候有哪些感受。觉得它有哪些优缺点。
在这里我们总结了逻辑回归应用到工业界当中一些优点:
形式简单,模型的可解释性非常好。从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大。
模型效果不错。在工程上是可以接受的(作为baseline),如果特征工程做的好,效果不会太差,并且特征工程可以大家并行开发,大大加快开发的速度。
训练速度较快。分类的时候,计算量仅仅只和特征的数目相关。并且逻辑回归的分布式优化sgd发展比较成熟,训练的速度可以通过堆机器进一步提高,这样我们可以在短时间内迭代好几个版本的模型。
资源占用小,尤其是内存。因为只需要存储各个维度的特征值,。
方便输出结果调整。逻辑回归可以很方便的得到最后的分类结果,因为输出的是每个样本的概率分数,我们可以很容易的对这些概率分数进行cutoff,也就是划分阈值(大于某个阈值的是一类,小于某个阈值的是一类)。
但是逻辑回归本身也有许多的缺点:
准确率并不是很高。因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布。
很难处理数据不平衡的问题。举个例子:如果我们对于一个正负样本非常不平衡的问题比如正负样本比 10000:1.我们把所有样本都预测为正也能使损失函数的值比较小。但是作为一个分类器,它对正负样本的区分能力不会很好。
处理非线性数据较麻烦。逻辑回归在不引入其他方法的情况下,只能处理线性可分的数据,或者进一步说,处理二分类的问题 。
逻辑回归本身无法筛选特征。有时候,我们会用gbdt来筛选特征,然后再上逻辑回归。