1. 简介
逻辑回归是面试当中非常喜欢问到的一个机器学习算法,因为表面上看逻辑回归形式上很简单,很好掌握,但是一问起来就容易懵逼。所以在面试的时候给大家的第一个建议不要说自己精通逻辑回归,非常容易被问倒,从而减分。下面个人总结梳理下面试知识点。
2. 正式介绍
如何凸显你是一个对逻辑回归已经非常了解的人呢。那就是用一句话概括它!逻辑回归假设数据服从伯努利分布,通过极大化似然函数的方法,运用梯度下降来求解参数,来达到将数据二分类的目的。
这里面其实包含了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
-
-
逻辑回归的损失函数
- 逻辑回归的损失函数是它的极大似然函数
L θ ( x ) = ∏ i = 1 m h θ ( x i ; θ ) y i ∗ ( 1 − h θ ( x i ; θ ) ) 1 − y i L_\theta\left(x\right )= \prod _{i=1}^{m}h_\theta(x^{i};\theta )^{y{i}}*(1-h_\theta(x^{i};\theta))^{1-y^{i}} Lθ(x)=i=1∏mhθ(xi;θ)yi∗(1−hθ(xi;θ))1−yi
- 逻辑回归的损失函数是它的极大似然函数
-
逻辑回归的求解方法
- 由于该极大似然函数无法直接求解,我们一般通过对该函数进行梯度下降来不断逼急最优解。在这个地方其实会有个加分的项,考察你对其他优化方法的了解。因为就梯度下降本身来看的话就有随机梯度下降,批梯度下降,small batch 梯度下降三种方式,面试官可能会问这三种方式的优劣以及如何选择最合适的梯度下降方式。
- 简单来说 批梯度下降会获得全局最优解,缺点是在更新每个参数的时候需要遍历所有的数据,计算量会很大,并且会有很多的冗余计算,导致的结果是当数据量大的时候,每个参数的更新都会很慢。
- 随机梯度下降是以高方差频繁更新,优点是使得sgd会跳到新的和潜在更好的局部最优解,缺点是使得收敛到局部最优解的过程更加的复杂。
- 小批量梯度下降结合了sgd和batch gd的优点,每次更新的时候使用n个样本。减少了参数更新的次数,可以达到更加稳定收敛结果,一般在深度学习当中我们采用这种方法。
- 由于该极大似然函数无法直接求解,我们一般通过对该函数进行梯度下降来不断逼急最优解。在这个地方其实会有个加分的项,考察你对其他优化方法的了解。因为就梯度下降本身来看的话就有随机梯度下降,批梯度下降,small batch 梯度下降三种方式,面试官可能会问这三种方式的优劣以及如何选择最合适的梯度下降方式。
-
- 其实这里还有一个隐藏的更加深的加分项,看你了不了解诸如Adam,动量法等优化方法。因为上述方法其实还有两个致命的问题。
- 第一个是如何对模型选择合适的学习率。自始至终保持同样的学习率其实不太合适。因为一开始参数刚刚开始学习的时候,此时的参数和最优解隔的比较远,需要保持一个较大的学习率尽快逼近最优解。但是学习到后面的时候,参数和最优解已经隔的比较近了,你还保持最初的学习率,容易越过最优点,在最优点附近来回振荡,通俗一点说,就很容易学过头了,跑偏了。
- 第二个是如何对参数选择合适的学习率。在实践中,对每个参数都保持的同样的学习率也是很不合理的。有些参数更新频繁,那么学习率可以适当小一点。有些参数更新缓慢,那么学习率就应该大一点。这里我们不展开,有空我会专门出一个专题介绍。
- 其实这里还有一个隐藏的更加深的加分项,看你了不了解诸如Adam,动量法等优化方法。因为上述方法其实还有两个致命的问题。
-
逻辑回归的目的
-
该函数的目的便是将数据二分类,提高准确率。
-
逻辑回归如何分类
- 逻辑回归作为一个回归(也就是y值是连续的),如何应用到分类上去呢。y值确实是一个连续的变量。逻辑回归的做法是划定一个阈值,y值大于这个阈值的是一类,y值小于这个阈值的是另外一类。阈值具体如何调整根据实际情况选择。一般会选择0.5做为阈值来划分。
3. 对逻辑回归的进一步提问
逻辑回归虽然从形式上非常的简单,但是其内涵是非常的丰富。有很多问题是可以进行思考的
-
逻辑回归的损失函数为什么要使用极大似然函数作为损失函数?
-
损失函数一般有四种,平方损失函数,对数损失函数,Hinge Loss, 0-1损失函数,绝对值损失函数。将极大似然函数取对数以后等同于对数损失函数。在逻辑回归这个模型下,对数损失函数的训练求解参数的速度是比较快的。至于原因大家可以求出这个式子的梯度更新
θ 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)这个式子的更新速度只和 x j i x^{i}_j xji , y i y^{i} yi 相关。和sigmod函数本身的梯度是无关的。这样更新的速度是可以自始至终都比较的稳定。
-
为什么不选平方损失函数的呢?其一是因为如果你使用平方损失函数,你会发现梯度更新的速度和sigmod函数本身的梯度是很相关的。sigmod函数在它在定义域内的梯度都不大于0.25。这样训练会非常的慢。
-
-
逻辑回归在训练的过程当中,如果有很多的特征高度相关或者说有一个特征重复了100遍,会造成怎样的影响?
- 先说结论,如果在损失函数最终收敛的情况下,其实就算有很多特征高度相关也不会影响分类器的效果。
- 但是对特征本身来说的话,假设只有一个特征,在不考虑采样的情况下,你现在将它重复100遍。训练以后完以后,数据还是这么多,但是这个特征本身重复了100遍,实质上将原来的特征分成了100份,每一个特征都是原来特征权重值的百分之一。
- 如果在随机采样的情况下,其实训练收敛完以后,还是可以认为这100个特征和原来那一个特征扮演的效果一样,只是可能中间很多特征的值正负相消了。
-
为什么我们还是会在训练的过程当中将高度相关的特征去掉?
- 去掉高度相关的特征会让模型的可解释性更好
- 可以大大提高训练的速度。如果模型当中有很多特征高度相关的话,就算损失函数本身收敛了,但实际上参数是没有收敛的,这样会拉低训练的速度。其次是特征多了,本身就会增大训练的时间。
4. 逻辑回归的数学公式推导
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)
5. 逻辑回归的损失函数推导(交叉熵推导)
说起交叉熵损失函数「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^)]
我们已经对这个交叉熵函数非常熟悉,大多数情况下都是直接拿来使用就好。但是它是怎么来的?为什么它能表征真实样本标签和预测概率之间的差值?上面的交叉熵函数是否有其它变种?也许很多朋友还不是很清楚!没关系,接下来我将尽可能以最通俗的语言回答上面这几个问题。
6. 交叉熵损失函数的数学原理
我们知道,在二分类问题模型:例如逻辑回归「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))]
这样,我们已经完整地实现了交叉熵损失函数的推导过程。
7. 逻辑回归的优缺点总结
面试的时候,别人也经常会问到,你在使用逻辑回归的时候有哪些感受。觉得它有哪些优缺点。
在这里我们总结了逻辑回归应用到工业界当中一些优点:
-
形式简单,模型的可解释性非常好。从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大。
-
模型效果不错。在工程上是可以接受的(作为baseline),如果特征工程做的好,效果不会太差,并且特征工程可以大家并行开发,大大加快开发的速度。
-
训练速度较快。分类的时候,计算量仅仅只和特征的数目相关。并且逻辑回归的分布式优化sgd发展比较成熟,训练的速度可以通过堆机器进一步提高,这样我们可以在短时间内迭代好几个版本的模型。
-
资源占用小,尤其是内存。因为只需要存储各个维度的特征值,。
-
方便输出结果调整。逻辑回归可以很方便的得到最后的分类结果,因为输出的是每个样本的概率分数,我们可以很容易的对这些概率分数进行cutoff,也就是划分阈值(大于某个阈值的是一类,小于某个阈值的是一类)。
但是逻辑回归本身也有许多的缺点:
-
准确率并不是很高。因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布。
-
很难处理数据不平衡的问题。举个例子:如果我们对于一个正负样本非常不平衡的问题比如正负样本比 10000:1.我们把所有样本都预测为正也能使损失函数的值比较小。但是作为一个分类器,它对正负样本的区分能力不会很好。
-
处理非线性数据较麻烦。逻辑回归在不引入其他方法的情况下,只能处理线性可分的数据,或者进一步说,处理二分类的问题 。
-
逻辑回归本身无法筛选特征。有时候,我们会用gbdt来筛选特征,然后再上逻辑回归。