逻辑回归中如何应用梯度下降算法与损失函数

版权声明:本文为博主原创文章,转载请附上此地址。 https://blog.csdn.net/qq_36523839/article/details/83549457

前面一篇博客介绍了关于梯度下降算法来由以及说明了为什么梯度的负方向就是梯度下降最快方向,本文将会在上文的知识下简述在逻辑回归(Logistic Regression)中为什么可以使用以及如何使用梯度下降算法。

梯度下降算法是个比较简单容易理解的算法,就像吴老师或很多资料上记载的一样:每次从新起点寻找一个到达目的地最快的方向并移动一定距离,以此重复直到终点。对于目标函数是凸函数,则可以到达全局最优点(非凸函数则可能到达局部最优点)。

很多人听完介绍或者看完图片就能理解其思想,但对于其中的数学原理或公式推导则比较迷茫,由此前面一篇文章专门对梯度下降算法的由来做了介绍,其中的思想简略表达就是:

    通过局部线性相似的原理求得一阶泰勒展开式,利用递降的思想转化展开式中的部分公式,再利用两向量相乘最小值的余弦思想求得公式中的值,最后得出公式。

正文:

本文将不再叙述梯度下降原始由来的公式推导,而讲述其具体的方法在逻辑回归中的使用。

对于一般的简单数据点,我们也可以使用线性回归来预测,将0.5作为分界点,但是这样也会存在误分的情况,并且还会出现负值的情况 。

Sigmoid函数:

所以我们通过引入Sigmoid函数将值压缩到 0-1 ,且 0.5 作为分界点。

0 点处发生阶跃变化,所以我们可以考虑将两者结合起来,把线性回归的拟合结果通过Sigmoid函数压缩到 0-1 。如果线性函数的y值越大,那概率也就越接近与 1,反之越接近 -1。(所以逻辑回归其本质还是线性回归问题)

由此我们可以定义以下公式:

              预测值:                      z_{i} = w_{0}x_{0}+w_{1}x_{1}+\cdot \cdot \cdot +w_{i}x_{i} = w^{T}x

              Sigmoid压缩:                       f(y_{i}) = \frac{1}{1+e^{-z_{i}}}

一般情况,w_{0}=bx_{0}=1表示截距项,(为了满足公式方便计算,一般会添加一列不会影响结果的 1)。下面将两个公式结合:

                                                   h_{w}(x) = f(w^{T}x)

对数损失函数:

接下来就是重点了,在利用w系数向量与特征x求得结果时,如何度量该结果的可信程度?这里就要使用到损失函数,我们用损失函数衡量预测值和真实值差异,不同于线性回归的最小二乘法,逻辑回归中通常使用对数损失函数,下面解释。

                                                 J(w) =\frac{1}{m}\sum_{i=1}^{m}[-y_{i}log(h_{w}(x_{i}))-(1-y_{i})log(1-h_{w}(x_{i}))]

并且这里强调一点,可能有人一直搞不清楚逻辑回归中哪里用到了梯度下降算法,或者逻辑回归中是如何使用梯度下降算法的。现在就是答案了,逻辑回归中我们使用梯度下降来最优化损失函数J(w),当该函数值最小,即拟合效果最佳

现在来说说为什么不使用平方损失函数?通过数学上的解释:设置损失函数的目的是接下来通过最优化方法求得损失函数的最小值,损失最小即代表模型最优。在最优化求解中,只有凸函数才能求得全局最小值,非凸函数往往得到的是局部最优。然而,平方损失函数用于逻辑回归求解时得到的是非凸函数,即大多数情况下无法求得全局最优。所以,这里使用了对数损失函数避免这个问题。

所以我们对对数损失函数J(w)求偏导,得到梯度方向(过程省略):

                                                  \frac{\partial J}{\partial w} = \frac{1}{m}X^{T}(h_{w}(x)-y)

(矩阵中即每条样本的每个特征与对应误差矩阵相乘,再除样本数)

有了梯度方向后,又要引入一个概念 ——步长\alpha,由于上面求得的只是最值的移动方向,而并没有距离上的移动,所以引入一个参数,步长\alpha一般又叫学习率,该值太大局部线性近似就不成立,偏差较大;该值太小收敛太慢,导致一个长时间的训练。所以后续调参需要注意该值的选择。

有了学习率与梯度方向,现在就可以通过多次迭代使用梯度下降来优化对数损失函数,过程如下:

                                                  w := w-\alpha \frac{\partial J}{\partial w}

代码示例:

上面将部分概念与公式给出,下面利用代码来叙述:

# Sigmoid 函数
def sigmoid(z):
    sigmoid = 1.0 / (1.0 + np.exp(-z))
    return sigmoid

# 对数损失函数
def loss(h, y):
    loss = (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()
    return loss

# 梯度方向
def gradient(X, h, y):
    gradient = np.dot(X.T, (h - y)) / y.shape[0]
    return gradient

# 逻辑回归过程
def Logistic_Regression(x, y, lr=0.05, count=200):
    intercept = np.ones((x.shape[0], 1)) # 初始化截距为 1
    x = np.concatenate((intercept, x), axis=1)
    w = np.zeros(x.shape[1]) # 初始化参数为 0

    for i in range(count): # 梯度下降迭代
        z = np.dot(x, w) # 线性函数
        h = sigmoid(z)

        g = gradient(x, h, y) # 计算梯度
        w -= lr * g # 通过学习率 lr 计算步长并执行梯度下降

        l = loss(h, y) # 计算损失函数值

    return l, w # 返回迭代后的梯度和参数

l,w = Logistic_Regression(x, y, lr, count)    # x特征矩阵,y目标值

参考文章:

    部分概念:https://blog.csdn.net/bitcarmanlee/article/details/51165444

猜你喜欢

转载自blog.csdn.net/qq_36523839/article/details/83549457