在监督学习的分类中,我们了解到有回归问题和分类问题。回归问题我们采用线性回归和梯度下降算法进行求解,我们在之前已经进行过学习。在分类问题中,要预测的变量 y 为离散的值。我们将学习一种叫做逻辑回归 (Logistic Regression) 的算法,这是目前最流行使用的一种分类算法。
先来谈谈二分类问题。课程中先给出了几个例子。
我们将因变量(dependant variable)可能属于的两个类分别称为负向类(negative class)和正向类(positive class),则因变量,其中 0 表示负向类,1 表示正向类。
如果我们使用线性回归进行分类模型的求解,y的取值只有0和1,训练集画出来如下图所示,我们用线性回归得到粉色直线,如果认为模拟直线的取值小于0.5时则预测值就为0,如果模拟直线的取值大于0.5时预测值就为1,感觉还不错。但是将圆圈中点加入后,线性回归得到的蓝色直线,就显得不是很完美了。并且我们知道所有得到的预测值要是0或者1,经过线性回归求解得到大量的小于0和大于1的数据,所以经过大量的实验证明,线性回归不适合这种训练集。
所以我们在接下来的要研究的算法就叫做逻辑回归算法,这个算法的性质是:它的输出值永远在 0 到 1 之间。
我们引入一个新的模型,逻辑回归,该模型的输出变量范围始终在 0 和 1 之间。 逻辑回归模型的假设是: ℎ() = () 其中: 代表特征向量 代表逻辑函数(logistic function)是一个常用的逻辑函数为 S 形函数(Sigmoid function),公式为:
则:
# python 代码实现:
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
在逻辑回归中,我们预测:当ℎ() >= 0.5时,预测 = 1。 当ℎ() < 0.5时,预测 = 0 。
根据上面绘制出的 S 形函数图像,我们知道当 = 0 时 () = 0.5 > 0 时 () > 0.5 < 0 时 () < 0.5 又 = ,即: >= 0 时,预测 = 1 < 0 时,预测 = 0
现在假设我们有一个模型:
并且参数 是向量[-3 1 1]。 则当−3 + 1 + 2 ≥ 0,即1 + 2 ≥ 3时,模型将预测 = 1。 我们可以绘制直线1 + 2 = 3,这条线便是我们模型的分界线,将预测为 1 的区域和预测为 0 的区域分隔开。
当数据如下图分布时:
因为需要用曲线才能分隔 = 0 的区域和 = 1 的区域,我们需要二次方特征:ℎ() = (0 + 11 + 22 + 312 + 422)是[-1 0 0 1 1],则我们得到的判定边界恰好是圆点在原点且半径为 1 的圆形。
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们
也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将ℎ() 带入到这样
定义了的代价函数中时,我们得到的代价函数将是一个非凸函数(non-convexfunction)。
图像呈现出非凸性,这意味着我们的代价函数有许多局部最小值。也就是说,如果我们运用梯度下降法,不能保证算法收敛到全局最小值。
所以,对于逻辑回归问题,我们定义新的代价函数如下所示 :
ℎ()与 (ℎ(), )之间的关系如下图所示:
这样构建的(ℎ(), )函数的特点是:当实际的 = 1 且ℎ()也为 1 时误差为 0, 当 = 1 但ℎ()不为 1 时误差随着ℎ()变小而变大;当实际的 = 0 且ℎ()也为 0 时代价为 0,当 = 0 但ℎ()不为 0 时误差随着 ℎ()的变大而变大。
将构建的 (ℎ(), )简化如下:
# 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))
在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的
参数了。算法为:
完整推导过程:
除了梯度下降算法以外,还有一些常被用来令代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常比梯度下降算法要更加快速。这些算法有:共轭梯度(Conjugate Gradient),局部优化法(Broyden fletcher goldfarb shann,BFGS)和有限内存局部优化法(LBFGS) 。
多类分类问题的数据集可能如下图:
现在有一个训练集,用三角形表示 y=1,方框表示 y=2,叉叉表示 y=3。下面要做的就是使用一个训练集,将其分成三个二元分类问题。
我们先从用三角形代表的类别 1 开始,实际上我们可以创建一个,新的"伪"训练集,类型 2 和类型 3 定为负类,类型 1 设定为正类,我们创建一个新的训练集,如下图所示的那样,我们要拟合出一个合适的分类器。
这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为 1,圆形的值为 0,下面我们来训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。
为了能实现这样的转变,我们将多个类中的一个类标记为正向类(y=1),然后将其他所有类都标记为负向类 。接着,类似地我们选择另一个类标记为正向类(y=2),再将其它类都标记为负向类,依此类推。
最后,在我们需要做预测时,我们将所有的分类机都运行一遍,然后对每一个输入变量,都输入我们三个分类器中,之后选择最高可能性的输出变量。
到现在为止,我们已经学习了几种不同的学习算法,包括线性回归和逻辑回归,它们能够有效地解决许多问题,但是当将它们应用到某些特定的机器学习应用时,会遇到过度拟合(over-fitting)的问题,可能会导致它们效果很差。 如果我们有非常多的特征,我们通过学习得到的假设可能能够非常好地适应训练集(代价函数可能几乎为 0),但是可能会不能推广到新的数据。
第一个模型是一个线性模型,欠拟合,不能很好地适应我们的训练集;第三个模型是一个四次方的模型,过于强调拟合原始数据,而丢失了算法的本质:预测新数据。虽然能非常好地适应我们的训练集但在新输入变量进行预测时可能会效果不好,是过拟合;而中间的模型似乎最合适。
分类问题中也存在这样的问题:
overfitting通常是由一个复杂的函数造成的,这个函数会产生大量与数据无关的不必要的曲线和角度。
有两个主要的选择来解决过度拟合的问题:
1)减少特征的数量:
采用正则化来解决过拟合问题的思想就是:将相应的参数值变小。具体例子如下。
例如,在之前的基于房间大小来预测房价例子中,正则化的线性回归损耗函数为:
这里值的设定也非常重要,如果其值过大,会导致无法解决过拟合问题、会产生欠拟合问题和训练过程可能无法收敛。
我们将首先处理线性回归。 一共有两种方法,梯度下降和正规方程。
针对逻辑回归问题,我们在之前的课程已经学习过两种优化算法:我们首先学习了使用梯度下降法来优化代价函数(),接下来学习了更高级的优化算法,这些高级优化算法需要你自己设计代价函数()。
在原本代价函数的基础上增加一个正则化表达式,得到代价函数:
# 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:theta.shape[1]],2))
return np.sum(first - second) / (len(X)) + reg