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

可以看出,损失函数曲线比较【浪】,拥有多个局部最优解,曲线非凸,如果用这样的代价函数来让机器学习迭代,则容易陷入局部最优解中,而找不到全局最优解,即找不到使得损失函数值最小的loss,也就找不到最优化的模型。
故,不可用采用平方损失函数,作为替代,我们可以采取【交叉熵损失函数】
凸函数:
对于实数集上的凸函数,一般的判别方法是求它的二阶导数,如果其二阶导数在区间上非负,就称为凸函数 简单的例子 y = x^2 二阶导为2 > 0,故其为凸函数(形状上看上去是凹的,千万别弄反!)
在这里,我们定义损失函数 :
其中:
复习一下对数函数,简单的 函数经过点(1,0)、(2,1)函数图像如下:

下面,让我们推导一波公式:是
函数(单调递增,导数>0),
函数隐藏了常数项底数,我们设其为a=2,简化一下上面的
函数
t 的取值范围为(0,1)
当 y = 1时, 函数单调递减,且t** **趋于1时,
趋于 0。示意图左下:

当 y = 0时, 函数单调增,且 t 趋于0,
趋于 0,示意图右上。
最后,合并一下:
此损失/代价函数即为可以进行梯度下降求导的,没有局部最优解的凸函数:
证明过程见文章末尾
Python代码实现如下:
import numpy as npdef 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)

注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的与线性回归中不同,所以实际上是不一样的。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。
如果把这个更新规则和我们之前用在线性回归上的进行比较的话,你会惊讶地发现,这个式子正是我们用来做线性回归梯度下降的。那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看看发生了哪些变化。实际上,假设的定义发生了变化。
对于线性回归假设函数:
而逻辑回归中假设函数:
因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。
最后还有一点,我们之前在谈线性回归时讲到的特征缩放,我们看到了特征缩放是如何提高梯度下降的收敛速度的,这个特征缩放的方法,也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。
就是这样,现在你知道如何实现逻辑回归,这是一种非常强大,甚至可能世界上使用最广泛的一种分类算法。
