1 逻辑回归
在分类问题中,我们要预测的变量y是离散的值,即判断其结果是否属于某一个类。具体来说,在二分类问题中,我们将因变量可能属于的两个类分别称为负类 ( y = 0 ) (y=0) (y=0)和正类 ( y = 1 ) (y=1) (y=1)。那如何可以将线性回归的连续模型转化为离散模型呢?
这里我们要设定一个阈值 0.5 0.5 0.5,当 y > 0.5 y>0.5 y>0.5时,我们认为其属于正向类,反之,属于反向类。但是如果使用线性回归,那么假设函数的输出值可能远大于 1 1 1,或者远小于 0 0 0,这时,我们就需要对y进行一个函数转化来使其值永远在0到1之间。
这个函数转化就称为逻辑函数(logistic function),也称Sigmoid function,其公式为 g ( z ) = 1 1 + e − z g ( z ) = \frac { 1 } { 1 + e ^ { - z } } g(z)=1+e−z1,图像如下图,当z趋于正无穷时, g ( z ) g(z) g(z)趋于1,而当z趋于负无穷时, g ( z ) g(z) g(z)趋于0,正符合我们上面所说的情况。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/6f2a9726e98339cf938e036b309af756.png)
然后把 z = x θ z = x\theta z=xθ带入上式中,就可以得到逻辑回归的假设函数 h θ ( x ) = g ( x θ ) = 1 1 + e − x θ h _ { \theta } ( x ) =g (x\theta)= \frac { 1 } { 1 + e ^ { - x \theta } } hθ(x)=g(xθ)=1+e−xθ1,对于给定的输入 x x x。也可以理解为,根据参数计算输出结果=1(正向类)的可能性,即 h θ ( x ) = P ( y = 1 ∣ x ; θ ) h _ { \theta } ( x ) = P ( y = 1 | x ; \theta ) hθ(x)=P(y=1∣x;θ)。若将其写为矩阵形式,则 h θ ( X ) = 1 1 + e − X θ h _ { \theta } ( X ) = \frac { 1 } { 1 + e ^ { - X \theta }} hθ(X)=1+e−Xθ1,其中X为 m × ( n + 1 ) m \times (n+1) m×(n+1)的特征矩阵。
2 损失函数
在线性回归模型中,我们选择的代价函数是所有模型误差的平方和,如果我们对逻辑回归模型也用这样的代价函数的话,我们得到的代价函数将会是一个非凸函数,如下图,这就意味着代价函数有许多局部最小值,难以找到其最优值。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/960764fc12cc13185f02dcc85112a17c.png)
下面使用最大似然函数来求逻辑回归的损失函数。由上部分可以知道 { P ( y = 1 ∣ x ; θ ) = h θ ( x ) P ( y = 0 ∣ x ; θ ) = 1 − h θ ( x ) \left\{ \begin{array} { l } { P ( y = 1 | x ; \theta ) = h _ { \theta } ( x ) } \\ { P ( y = 0 | x ; \theta ) = 1 - h _ { \theta } ( x ) } \end{array} \right. {P(y=1∣x;θ)=hθ(x)P(y=0∣x;θ)=1−hθ(x)将其写为一般形式可以表示为 P ( y ∣ x ; θ ) = h θ ( x ) y ( 1 − h θ ( x ) ) 1 − y P ( y | x ; \theta ) = h _ { \theta } ( x ) ^ { y } \left( 1 - h _ { \theta } ( x ) \right) ^ { 1 - y } P(y∣x;θ)=hθ(x)y(1−hθ(x))1−y其似然函数为 L ( θ ) = ∏ i = 1 m ( h θ ( x ( i ) ) ) y ( i ) ( 1 − h θ ( x ( i ) ) ) 1 − y ( i ) L ( \theta ) = \prod _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) \right) ^ { y ^ { ( i ) } } \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) ^ { 1 - y ^ { ( i ) } } L(θ)=i=1∏m(hθ(x(i)))y(i)(1−hθ(x(i)))1−y(i)对左右两边取对数 ln L ( θ ) = ∑ i = 1 m ( y ( i ) log ( h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ) \ln L ( \theta ) = \sum _ { i = 1 } ^ { m } \left( y ^ { ( i ) } \log \left( h _ { \theta } \left( x ^ { ( i ) } \right) \right) + \left( 1 - y ^ { ( i ) } \right) \log \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) \right) lnL(θ)=i=1∑m(y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i))))这样,上式右边最大时,似然函数就最大,对其求反并求均值就可以得到损失函数,即目标最小化的函数 J ( θ ) = − 1 m ∑ i = 1 m ( y ( i ) log ( h θ ( x ( i ) ) ) + ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ) J ( \theta ) = - \frac{1}{m}\sum _ { i = 1 } ^ { m } \left( y ^ { ( i ) } \log \left( h _ { \theta } \left( x ^ { ( i ) } \right) \right) + \left( 1 - y ^ { ( i ) } \right) \log \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) \right) J(θ)=−m1i=1∑m(y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i))))同理可以得到损失函数的矩阵方法 J ( θ ) = − 1 m ( Y log ( h θ ( X ) ) − ( 1 − Y ) log ( 1 − h θ ( X ) ) ) J ( \theta ) = - \frac{1}{m}\left(Y\log(h _ \theta ( X ) )- ( 1 - Y ) \log \left( 1 - h _ \theta ( X ) \right)\right) J(θ)=−m1(Ylog(hθ(X))−(1−Y)log(1−hθ(X)))通过观察损失函数,可以看出当实际y=1时, h θ ( x ) h _ { \theta } ( x ) hθ(x) 越接近1误差越小;当实际y=0时, h θ ( x ) h _ { \theta } ( x ) hθ(x)越接近0误差越小。
3 损失函数求解
对于Sigmoid function来说,有一个很好的性质可以帮助我们对损失函数进行求导:
g
′
(
z
)
=
d
d
z
1
1
+
e
−
z
=
1
(
1
+
e
−
z
)
2
(
e
−
z
)
=
1
(
1
+
e
−
z
)
⋅
(
1
−
1
(
1
+
e
−
z
)
)
=
g
(
z
)
(
1
−
g
(
z
)
)
\begin{aligned} g ^ { \prime } ( z ) & = \frac { d } { d z } \frac { 1 } { 1 + e ^ { - z } } = \frac { 1 } { \left( 1 + e ^ { - z } \right) ^ { 2 } } \left( e ^ { - z } \right) = \frac { 1 } { \left( 1 + e ^ { - z } \right) } \cdot \left( 1 - \frac { 1 } { \left( 1 + e ^ { - z } \right) } \right) = g ( z ) ( 1 - g ( z ) ) \end{aligned}
g′(z)=dzd1+e−z1=(1+e−z)21(e−z)=(1+e−z)1⋅(1−(1+e−z)1)=g(z)(1−g(z))
然后对损失函数进行求导
∂
∂
θ
j
J
(
θ
)
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
1
g
(
x
(
i
)
θ
)
−
(
1
−
y
(
i
)
)
1
1
−
g
(
x
(
i
)
θ
)
)
∂
∂
θ
j
g
(
x
(
i
)
θ
)
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
1
g
(
x
(
i
)
θ
)
−
(
1
−
y
(
i
)
)
1
1
−
g
(
x
(
i
)
θ
)
)
g
(
x
(
i
)
θ
)
(
1
−
g
(
x
(
i
)
θ
)
)
∂
∂
θ
j
(
x
(
i
)
θ
)
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
(
1
−
g
(
x
(
i
)
θ
)
)
−
(
1
−
y
(
i
)
)
g
(
x
(
i
)
θ
)
)
x
j
(
i
)
=
−
1
m
∑
i
=
1
m
(
y
(
i
)
−
h
θ
(
x
(
i
)
)
)
x
j
(
i
)
\begin{aligned} \frac { \partial } { \partial \theta_j } J( \theta ) & = - \frac{1}{m}\sum_{i=1}^{m}\left( y^{(i)} \frac { 1 } { g \left( x^{(i)}\theta\right) } - ( 1 - y^{(i)} ) \frac { 1 } { 1 - g \left( x ^{(i)} \theta\right) } \right) \frac { \partial } { \partial \theta_j } g \left( x^{(i)} \theta \right) \\ & =- \frac{1}{m}\sum_{i=1}^{m} \left( y^{(i)} \frac { 1 } { g \left( x^{(i)}\theta\right) } - ( 1 - y^{(i)} ) \frac { 1 } { 1 - g \left( x ^{(i)} \theta\right) } \right) g \left(x^{(i)} \theta \right) \left( 1 - g ( x^{(i)} \theta )\right) \frac { \partial } { \partial \theta_j } (x^{(i)} \theta) \\ & =- \frac{1}{m}\sum_{i=1}^{m} \left( y^{(i)} \left( 1 - g \left( x^{(i)} \theta\right) \right) - ( 1 - y^{(i)} ) g \left(x^{(i)} \theta\right) \right) x^{(i)} _ { j } \\ & = - \frac{1}{m}\sum_{i=1}^{m} \left( y ^{(i)} - h _ { \theta } ( x ^{(i)} ) \right) x ^{(i)} _ { j } \end{aligned}
∂θj∂J(θ)=−m1i=1∑m(y(i)g(x(i)θ)1−(1−y(i))1−g(x(i)θ)1)∂θj∂g(x(i)θ)=−m1i=1∑m(y(i)g(x(i)θ)1−(1−y(i))1−g(x(i)θ)1)g(x(i)θ)(1−g(x(i)θ))∂θj∂(x(i)θ)=−m1i=1∑m(y(i)(1−g(x(i)θ))−(1−y(i))g(x(i)θ))xj(i)=−m1i=1∑m(y(i)−hθ(x(i)))xj(i)
因此,使用批量梯度下降得到损失函数的最优值的迭代过程为:
θ
j
:
=
θ
j
−
α
1
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
\theta _ { j } : = \theta _ { j } - \alpha \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { j } ^ { ( i ) }
θj:=θj−αm1i=1∑m(hθ(x(i))−y(i))xj(i)
使用矩阵方式进行迭代的过程为:
θ
=
θ
−
α
X
T
(
h
θ
(
X
)
−
Y
)
\theta = \theta - \alpha X ^ { T } \left( h _ { \theta } ( X ) - Y \right)
θ=θ−αXT(hθ(X)−Y)
采用随机梯度下降的方法:
θ
j
:
=
θ
j
−
α
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
\theta _ { j } : = \theta _ { j } - \alpha \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) x _ { j } ^ { ( i ) }
θj:=θj−α(hθ(x(i))−y(i))xj(i)
当然,除了梯度下降法之外,还有一些高级优化算法和高级优化概念,这些方法可以使梯度下降进行逻辑回归的速度大大提高,也更适合解决大型机器学习问题,比如牛顿法等等优化方法,之后再做补充。
4 正则化
4.1 过拟合
如下图所示的回归问题,第一个模型是线性模型,欠拟合,不能很好地适应训练集;第三个模型就属于过拟合,太过于强调训练数据,而不能推广到新的数据,进行对新数据的预测。中间的模型最为合适。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2c38aae481534fa18048cd6bb2ccab9b.png)
同样的,在分类问题中也有这种现象:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8921d8091cb3679bb496914e18d949db.png)
如何处理过拟合问题:
- 丢弃一些不能帮助我们正确预测的特征。可以手工选择保留哪些特征,或使用模型算法来帮忙
- 正则化,保留所有的特征,但是减少参数的大小
在上面的回归问题中我们的过拟合模型为:
h
θ
(
x
)
=
θ
0
+
θ
1
x
1
+
θ
2
x
2
+
θ
3
x
3
+
θ
4
x
4
h_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2+\theta_3x_3+\theta_4x_4
hθ(x)=θ0+θ1x1+θ2x2+θ3x3+θ4x4
可以看出,正是高次项导致了过拟合的产生,如果我们能让这些高次项接近0的话,就可以解决这个问题。所以我们要在一定程度上减小
θ
3
,
θ
4
\theta_3,\theta_4
θ3,θ4的大小,即在代价函数上进行修改,在
θ
3
,
θ
4
\theta_3,\theta_4
θ3,θ4上设置惩罚:
min
θ
1
m
[
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
+
1000
θ
3
2
+
10000
θ
4
2
]
\min_\theta \frac{1}{m}[ \sum_{i=1}^m (h_\theta(x^{(i)}) -y^{(i)} )^2 + 1000\theta_3^2 + 10000\theta_4^2 ]
θminm1[i=1∑m(hθ(x(i))−y(i))2+1000θ32+10000θ42]通过这样的代价函数,得到的
θ
3
,
θ
4
\theta_3,\theta_4
θ3,θ4就会比以前的小很多。假如数据过多的话,我们就要对所有的特征进行惩罚:
min
θ
1
m
[
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
+
λ
∑
j
=
1
n
θ
j
2
]
\min_\theta \frac{1}{m}[ \sum_{i=1}^m (h_\theta(x^{(i)}) -y^{(i)} )^2 + \lambda \sum_{j=1}^n \theta_j^2 ]
θminm1[i=1∑m(hθ(x(i))−y(i))2+λj=1∑nθj2]其中
λ
\lambda
λ称为正则化参数(Regularization Parameter),根据惯例,我们不对
θ
0
\theta_0
θ0进行惩罚。
另外,上面的损失函数也可以看为是经验风险项(第一项)和结构风险项(第二项,正则化项)。第1项的经验风险较小的模型可能较复杂(有多个非零参数),这时第2项的模型复杂度会较大。正则化的作用是选择经验风险与模型复杂度同时较小的模型。
除了上述的算法外,正则项也有其他不同的算法:
- 正则化项为参数向量的L2范数, ∥ θ ∥ \| \mathbf { \theta } \| ∥θ∥表示参数向量的L2范数,与上例相同 1 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∥ θ ∥ 2 ] \frac{1}{m}[ \sum_{i=1}^m (h_\theta(x^{(i)}) -y^{(i)} )^2 + \lambda \| \mathbf { \theta } \|^2 ] m1[i=1∑m(hθ(x(i))−y(i))2+λ∥θ∥2]
- 正则化项为参数向量的L1范数, ∥ θ ∥ 1 \| \mathbf { \theta } \|_1 ∥θ∥1表示参数向量的L1范数 1 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + λ ∥ θ ∥ 1 ] \frac{1}{m}[ \sum_{i=1}^m (h_\theta(x^{(i)}) -y^{(i)} )^2 + \lambda \| \mathbf { \theta } \|_1 ] m1[i=1∑m(hθ(x(i))−y(i))2+λ∥θ∥1]
经过正则化后,模型的前后对比如下图,若 λ \lambda λ过大,则所有参数都会变小,模型就会变成 h θ ( x ) = θ 0 h_\theta(x)=\theta_0 hθ(x)=θ0,也就是图中红色直线的情况。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/31fad59c17805766ca510f9d87fa0a8e.png)
4.2 正则化应用于逻辑回归
正则化逻辑回归得代价函数:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
log
(
h
θ
(
x
(
i
)
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
]
+
λ
2
m
∑
j
=
1
n
θ
j
2
J ( \theta ) = -\frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left[ y ^ { ( i ) } \log \left( h _ { \theta } \left( x ^ { ( i ) } \right) \right) + \left( 1 - y ^ { ( i ) } \right) \log \left( 1 - h _ { \theta } \left( x ^ { ( i ) } \right) \right) \right] + \frac { \lambda } { 2 m } \sum _ { j = 1 } ^ { n } \theta _ { j } ^ { 2 }
J(θ)=−m1i=1∑m[y(i)log(hθ(x(i)))+(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2
梯度下降算法为:
θ
0
:
=
θ
0
−
α
1
m
∑
i
=
1
m
(
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
⋅
x
0
(
i
)
)
\theta _ { 0 } : = \theta _ { 0 } - \alpha \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) \cdot x _ { 0 } ^ { ( i ) } \right)
θ0:=θ0−αm1i=1∑m((hθ(x(i))−y(i))⋅x0(i))
θ
j
:
=
θ
j
−
α
1
m
∑
i
=
1
m
(
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
⋅
x
j
(
i
)
+
λ
m
θ
j
)
\theta _ { j } : = \theta _ { j } - \alpha \frac { 1} { m } \sum _ { i = 1 } ^ { m } \left( \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) \cdot x _ { j } ^ { ( i ) } + \frac { \lambda } { m } \theta _ { j } \right)
θj:=θj−αm1i=1∑m((hθ(x(i))−y(i))⋅xj(i)+mλθj)
5 模型评估
在分类问题中,有一个叫做混淆矩阵(confusion matrix)的工具可以帮助我们更好地了解分类中的错误,同时也可以用来评价一个分类器的好坏优劣,如下图所示,如果混淆矩阵中的非对角线元素均为0,那么我们就得到一个完美的分类器。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/064f86aad57b88952e1bf066699e760b.png)
在二分类问题中,准确率是最常见的评估参数,但是在数据集正反例不平衡时,准确率就没有多少参考价值,因此我们需要更多的评估参数。真假阳性及灵敏度、特异度、精确率等等对于模型的评估都有重要帮助,在下表之中加以列出,之后可以继续加以补充。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/c7c5f9f3b41b925aa79d02ce74d2b6f3.png)
另外,ROC (Receiver Operating Characteristic) 曲线和 AUC (Area Under the Curve) 值常被用来评价二分类器,其中ROC曲线的横纵坐标分别为假阳性率(FPR)和真阳性率(TPR)。在一个二分类模型中,假设采用逻辑回归分类器,其给出针对每个实例为正类的概率,那么通过设定一个阈值如0.6,概率大于等于0.6的为正类,小于0.6的为负类。对应的就可以算出一组(FPR,TPR),在平面中得到对应坐标点。随着阈值的逐渐减小,越来越多的正例被划分为正类(TP),但是这些正类中同样也掺杂着真正的负实例(FP),即TPR和FPR会同时增大。阈值最大时,对应坐标点为(0,0),阈值最小时,对应坐标点(1,1)。这样就形成了ROC曲线,线上每个点都对应一幅阈值。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/43447a02c1c3a6dad191f5e6f6d9aec5.png)
AUC (Area Under the Curve)值被定义为ROC曲线下的面积,一般AUC的取值范围在0.5-1之间,AUC越大分类器效果越好。AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的概率值将这个正样本排在负样本前面的概率就是AUC值。当然,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。
另外ROC有一个很好地特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。
6 sklearn 实例
sklearn.linear_model.LogisticRegression
参数 | 类型/默认 | 解释 |
---|---|---|
penalty | str/‘l2’ | 正则化项。l2可选solver {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’},l1可选solver{‘liblinear’} |
solver | str/‘liblinear’ | 优化算法。【newton-cg】利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数; 【lbfgs】拟牛顿法的一种;【liblinear】使用了坐标轴下降法来迭代优化损失函数,适合小数据;【sag】随机平均梯度下降,每次迭代仅仅用一部分的样本来计算梯度;【saga】 |
C | float/1 | 正则化项系数,C越小正则化程度越高 |
multi_class | str/‘ovr’ | 多分类方式选择参数,【ovr】对第K类的分类决策,把所有第K类的样本作为正例,其余所有样本都作为负例,然后在上面做二元逻辑回归,从而实现多分类; 【multinomial】从多类样本中选出两类,进行二元逻辑回归,得到模型参数,从而实现多分类,假设共有T类,要进行T(T-1)/2次分类。 |
class_weight | dict/None | 类型权重参数,用于标示分类模型中各种类型的权重,如class_weight={0:0.9, 1:0.1} |
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
import matplotlib.pyplot as plt
# 读入乳腺癌数据集 将其分为训练测试集
breast_data = datasets.load_breast_cancer()
X, y = breast_data.data, breast_data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
# 训练预测
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# 计算模型评估参数
Accuracy = metrics.accuracy_score(y_test, y_pred)
F1score = metrics.f1_score(y_test, y_pred)
Recall = metrics.recall_score(y_test, y_pred)
Precision = metrics.precision_score(y_test, y_pred)
AUC = metrics.roc_auc_score(y_test, y_pred)
# 画ROC曲线
y_prob = model.predict_proba(X_test)[:, 1]
fpr, tpr, thresholds = metrics.roc_curve(y_test, y_prob, pos_label=1)
rocAUC = metrics.auc(fpr, tpr)
plt.title('BreastData-LogisticRegression-ROC')
plt.plot(fpr, tpr, 'b', label='AUC = %0.4f' % AUC)
plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1], 'r--')
plt.ylabel('TPR')
plt.xlabel('FPR')
plt.show()