【吴恩达机器学习】第三周—逻辑回归、过拟合、正则化

31.jpg

1.分类问题(Regression)

在分类问题中,你要预测的变量 是离散的值,我们将学习一种叫做逻辑回归 (Logistic Regression) 的算法,这是目前最流行使用最广泛的一种学习算法。顺便说一下,逻辑回归算法是分类算法,我们将它作为分类算法使用。有时候可能因为
这个算法的名字中出现了“回归”使你感到困惑,但逻辑回归算法实际上是一种分类算法,它适用于标签 取值离散的情况,如:1 0 0 1。

为什么不用线性回归来解决分类问题 ?
简单来说,因为分类问题的y取值为固定的几个类别,譬如肿瘤分类为0 表示良性、1表示恶性,如果同样用线性回归y = k * x + b来表示,x为肿瘤尺寸,则得出的y范围可能远 > 1,但结果总会落到0和1上,会显得很奇怪。

2.逻辑回归(Logistic Regression)

前面说了,逻辑回归是适用于分类问题的常见算法,这个算法的性质是:它的输出值永远在 0 到 1 之间。

3.假设函数表达式Hypothesis Representation

回到之前的乳腺癌分类上,我希望输出的预测值是介于0~1之间,此时用逻辑回归算法怎么实现呢?
其实,逻辑回归中,可以用Sigmoid函数,来实现在R区间的输入,得到0~1之间的输出Sigmoid函数:
函数图像如下:

屏幕快照 2019-07-11 22.02.31.png
则,经过Sigmoid改良后的假设函数如下:

看图可知,对于任意参数z:如果 = 0.5,那么其为恶性/良性的概率为50% > 0.5,则我们判定预测值y = 1
< 0.5,则我们判定预测值y = 0。例如,如果对于给定的,通过已经确定的参数计算得出h () = 0.7,则表示有 70%的几率为1(正向类),相应地为0(负向类)的几率为 1-0.7=0.3。
而 根据图像可知:
z > 0时 > 0.5 预测值y 为1
z < 0时 < 0.5 预测值y 为0

4.判定边界Decision Boundary

现在假设我们有一个模型:

1.png
并且参数 是向量[-3 1 1]。 则当−3 + 1 + 2 ≥ 0,即1 + 2 ≥ 3时,模型将预测 =1。 我们可以绘制直线:
1 + 2 = 3,这条线便是我们模型的分界线,将预测为 1 的区域和预测为 0 的区域分隔开。
这条线即被称为—判定边界Decision Boundary


假设我们的数据呈现这样的分布情况,怎样的模型才能适合呢? 其实,判定边界不一定是直线,还可能是曲线,如下:
2.png

因为需要用曲线才能分隔 = 0 的区域和 = 1 的区域,我们需要二次方特征:
h ()=( + + + 2 + 2)是[-1 0 0 1 1],则我们得到的判定边界恰好是圆点在原点且半径为 1 的圆形。

5.损失函数Cost Function

在之前的房间-面积模型中(单变量线性回归问题),我们用到的是平方差损失函数,那么对此处的分类问题,我们可不可以用之前的平方差损失函数呢 ? 先给结论,不行,此处我们应该用交叉熵损失函数
为什么?而此处带入后得到的损失函数比较复杂,不过可以通过图像看出和的关系:

3.png
可以看出,损失函数曲线比较【浪】,拥有多个局部最优解,曲线非凸,如果用这样的代价函数来让机器学习迭代,则容易陷入局部最优解中,而找不到全局最优解,即找不到使得损失函数值最小的loss,也就找不到最优化的模型。
故,不可用采用平方损失函数,作为替代,我们可以采取【交叉熵损失函数】

凸函数:
对于实数集上的凸函数,一般的判别方法是求它的二阶导数,如果其二阶导数在区间上非负,就称为凸函数
简单的例子 y = x^2 二阶导为2 > 0,故其为凸函数(形状上看上去是凹的,千万别弄反!)

在这里,我们定义损失函数 :
其中:

复习一下对数函数,简单的 函数经过点(1,0)、(2,1)函数图像如下:

image.png

下面,让我们推导一波公式:
是函数(单调递增,导数>0),函数隐藏了常数项底数,我们设其为a=2,简化一下上面的函数

t 的取值范围为(0,1)
y = 1时, 函数单调递减,且t趋于1时, 趋于 0。示意图左下:

7.png
y = 0时, 函数单调增,且t 趋于0, 趋于 0,示意图右上。

最后,合并一下:

此损失/代价函数即为可以进行梯度下降求导的,没有局部最优解的凸函数:


9.png

证明过程见文章末尾

Python代码实现如下:

import numpy as np
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X* theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X* theta.T)))
return np.sum(first - second) / (len(X))

在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:
8.png

一些梯度下降算法之外的选择:
除了梯度下降算法以外,还有一些常被用来令代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常比梯度下降算法要更加快速。这些算法有:

  • 共轭梯度(Conjugate Gradient)
  • 局部优化法(Broyden fletcher goldfarb shann,BFGS)
  • 有限内存局部优化法(LBFGS)

10.png
注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的与线性回归中不同,所以实际上是不一样的。
另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。

6.简化的损失函数和梯度下降

在上面我们得出损失函数公式如下:
那么为了使损失函数尽量小,我们对其求梯度(求导过程见第5.点末尾):​

image

现在,如果你把这个更新规则和我们之前用在线性回归上的进行比较的话,你会惊讶地发现,这个式子正是我们用来做线性回归梯度下降的。那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看
看发生了哪些变化。实际上,假设的定义发生了变化。
对于线性回归假设函数:

而逻辑回归中假设函数:
因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。
最后还有一点,我们之前在谈线性回归时讲到的特征缩放,我们看到了特征缩放是如何提高梯度下降的收敛速度的,这个特征缩放的方法,也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。
就是这样,现在你知道如何实现逻辑回归,这是一种非常强大,甚至可能世界上使用最广泛的一种分类算法。

7.高级优化

现在我们换个角度来看什么是梯度下降,我们有个代价函数,而我们想要使其最小化,那么我们需要做的是编写代码,当输入参数时,它们会计算出两样东西:以及j等于 0、 1 直到n时的偏导数项。

11.png
假设我们已经完成了可以实现这两件事的代码,那么梯度下降所做的就是反复执行这些更新。对于梯度下降来说,我认为从技术上讲,你实际并不需要编写代码来计算代价函数。你只需要编写代码来计算导数项,但是,如果你希望代码还要能够监控的收敛性,那么我们就需要自己编写代码来计算代价函数和偏导项


梯度下降并不是我们可以使用的唯一算法,还有其他一些算法,更高级、更复杂。如果我们能用这些方法来计算代价函数和偏导数项的话,那么这些算法就是为我们优化代价函数的不同方法, 共轭梯度法 BFGS (变尺度法) 和 L-BFGS (限制变尺度法) 就是其中一些更高级的优化算法。它们需要有一种方法来计算以及需要一种方法计算导数项,然后使用比梯度下降更复杂的算法来最小化代价函数。
这三种算法有许多优点:
一个是使用这其中任何一个算法,你
通常不需要手动选择学习率
,所以对于这些算法的一种思路是,给出计算导数项和代价函数的方法,你可以认为算法有一个智能的内部循环,而且,事实上,他们确实有一个智能的内部循环,称为线性搜索(line search)算法,它可以自动尝试不同的学习率 ,并自动选择一个好的学习速率,因此它甚至可以为每次迭代选择不同的学习速率,那么你就不需要自己选择。这些算法实际上在做更复杂的事情,而不仅仅是选择一个好的学习率,所以它们往往最终收敛得远远快于梯度下降,不过关于它们到底做什么的详细讨论,已经超过了本门课程的范围。

8.多元/多类别分类Multiclass Classification

这里插播一句,吴恩达老师的课实在是太好了,生动形象....点赞

现实世界中,没有那么多的非黑即白的二元分类问题,更多的是多分类,譬如给你柑橘类水果?
可能是橘子、柚子、芦柑、橙子...这么多分类。那么问题来了,如果你用AI模型来判断,模型会告诉你它是橙子,概率在50%,那么它究竟是怎么运作的?
模型会生成一系列置信度,譬如:水果是橘子、柚子、芦柑、橙子的概率分别是20%、35%、38%、50%,最终挑选一个概率最高的类别label,将这个水果归类到label中。
比较一下二元分类问题和多元分类问题,他们的数据集看上去可能是这样:

12.png
我们之前学习过了二元分类问题的模型和算法,用逻辑回归 + 梯度下降可以完美地解决,那么对于三元、多元分类问题呢 ?其实原理是类似的
用白话过一遍流程:
遍历每个类、譬如第一轮我只关注绿色三角,那么我可以建立模型将绿三角标记为正向类 y = 1、将红叉叉和蓝框框都标记为负向类;经过这一轮的模型,我就可以判断出一个数据是绿三角的概率了;然后再对红叉叉建立模型将红叉叉标记为正相类 y = 2,绿三角和蓝框框都标为负向类,最后建立模型来对蓝框框做同样的操作。
总之就是有N个类别就建立N个模型,对于一个样本,我们需要用这N个模型依次检验其在该模型下属于正向类的概率。

9.过拟合over-fitting

过拟合

过度拟合的意思,意味着模型训练过程中,对训练集的模拟和学习过度贴合;
过拟合带来的影响:模型训练时的检测率很高效果很好,但是用于实际检验时,效果很差,模型不能很准确地预测,即泛化能力差。

欠拟合

和过拟合相对,欠拟合是指模型和数据集间的拟合程度不够,学习不足。
欠拟合的影响:和过拟合相对,欠拟合是指模型和数据集间的拟合程度不够,可能是学习轮数不够、数据集特征不规则、模型选择有问题等。欠拟合时,模型的泛化能力同样会很差。

泛化能力(generalization ability)

是指一个机器学习算法对于没有见过的样本的识别能力。泛化能力自然是越高越好。

分类问题和回归问题中都可能存在过拟合的问题,见下图:
image.png

解决或改善?

1.丢弃一些不能帮助我们正确预测的特征。可以是手工选择保留哪些特征,或者使用一些模型选择的算法来帮忙(例如 PCA)
2.正则化。 保留所有的特征,但是减少参数的大小(magnitude)。

10.正则化

假设回归问题中,过拟合的模型如下:
从第9.点中图像上,我们可以看出,正是那些高次项导致了过拟合的产生,所以降低高次项的系数我们就能降低过拟合程度。但是,我们不能直接修改模型中的参数大小,而通过修改代价函数中参数大小来实现“曲线救国”
正常回归问题的损失函数如下:对损失函数做梯度下降算法,如下:
[图片上传失败...(image-d793a0-1583758276758)]可见,每次迭代中,为了使迭代后的参数变更小,我们需要使尽可能大,而学习率固定,所以我们只能想办法让倒数项尽可能大。所以我们可以对损失/代价函做一波修改:

14.png
可见,我们给参数和加上了系数,这可以称为【惩罚】,对修改后的代价函数,做梯度下降算法对的更新如下:
对的更新如下:

可见,对于参数和,因为有系数的存在,每次求导都会让其降低的更多更快,而且,不会影响其他参数项的下降,从而达到比较理想的效果。

1.一般表示

如果我们有 总计n个参数(通常不用惩罚),通常会对所有的参数进行惩罚,并设置系数,这样的结果是得到了一个较为简单的能防止过拟合问题的假设函数:

15.png
其中被称为正则化参数****Regularization Parameter
经过正则化处理后的模型与原模型对比图如下:
16.png
蓝色是处理前,过拟合的模型数据表现,粉红色的是经过正则化处理后的表现。
如果正则化系数过小,将会导致效果不好,模型的拟合度依旧很高;
如果正则化系数过大,则会将除了以外的所有系数都惩罚殆尽,导致假设函数近似: 即变成图中的红线。

2.正则化线性回归

此处比较简单,我就直接贴图了:
image.png

3.正则化逻辑回归

此处比较简单,我就直接贴图了:

19.png
20.png

需要说明的是:虽然加了正则化后、逻辑回归和线性回归的梯度下降公式看上去一样,但实际意义由于假设函数的不同,而完全不同。
Python代码:

import numpy as np
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X*theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X*theta.T)))
reg = (learningRate / (2 * len(X))* np.sum(np.power(theta[:,1:the
ta.shape[1]],2))
return np.sum(first - second) / (len(X)) + reg

你可能感兴趣的:(【吴恩达机器学习】第三周—逻辑回归、过拟合、正则化)