美文网首页
Logistic 回归

Logistic 回归

作者: 疯了个魔 | 来源:发表于2018-12-04 12:53 被阅读0次

    逻辑回归

    逻辑回归( Logistic Regression):是一种用于解决监督学习(Supervised Learning)问题的学习算法。
    进行逻辑回归的目的是使训练数据的标签值与预测出来的值之间的误差最小化。
    逻辑回归一般用于二分类(Binary Classification)问题中,给定一些输入,输出结果是离散值。
    Logistic 回归中使用的参数如下:

    • 输入的特征向量:{\rm{x}} \in {R^{{n_x}}}
    • 用于训练的标签:{y \in 0,1}
    • 权重:{\rm{w}} \in {R^{{n_x}}}
    • 偏置:{b \in R}
    • 输出:\hat y = \sigma ({w^T}x + b)
    • Sigmoid函数:
      \sigma (z) = \frac{1}{{1 + {e^{ - z}}}}
      之所以引入Sigmoid函数是为了将输出控制在[0 1]范围之内。
      绘制Sigmoid函数:
    import  matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.ticker import MultipleLocator
    
    def Sigmoid(z):
        return 1 / (1 + np.exp(-z))
    
    def plot_Sigmoid():
        x = np.arange(-10,10,0.1)
        y = Sigmoid(x)
        plt.plot(x,y,color="b",label=r"$\sigma (z) = \frac{1}{{1 + {e^{ - z}}}}$")
        plt.legend()
        plt.title('Sigmoid')
        plt.xlabel('x')
        plt.ylabel('y')
        plt.grid(color = "black",linestyle = "-.")
        ax = plt.gca()
        ax.xaxis.set_major_locator(MultipleLocator(1))
        ax.yaxis.set_major_locator(MultipleLocator(0.1))
        plt.show()
    
    if __name__  == '__main__':
        plot_Sigmoid()
    

    如图所示:


    Sigmoid 函数
    • 当z趋近于正无穷大时,σ(z)=1;
    • 当z趋近于负无穷大时,σ(z)=0;
    • 当z=0时,σ(z)=0.5。

    成本函数

    损失函数(Loss Function):衡量单个样本预测值{\hat y}^{(i)}与真实值y^{(i)}之间的差异,即损失函数用来计算单个训练样本的预测值与真实值之间的误差。
    最简单的损失函数定义方式为平方差损失
    L(\hat{y},y) = \frac{1}{2}(\hat{y}-y)^2
    但 Logistic 回归中我们并不倾向于使用这样的损失函数,因为之后讨论的优化问题会变成非凸的,最后会得到很多个局部最优解,梯度下降法可能找不到全局最优值。
    对逻辑回归模型,希望满足条件概率:
    p(y|x) = \begin{cases} \hat{y}, & \text{$(y=1)$} \\ 1 - \hat{y}, & \text{$(y=0)$} \end{cases}
    将上下两个式子合二为一,可写成:
    p(y|x) = \hat{y}^y (1 - \hat{y})^{(1 - y)}
    对两边取对数,进一步化简为:
    log\ p(y|x) = ylog\ \hat y+(1-y)log\ (1-\hat y)
    p(y|x)的值需要最大化,而损失函数需要最小化,所以在原来的式子中填上负号,就可以将它作为一个损失函数。在上式右边添加一个负号,就推导出了应用很广的交叉熵(Cross Entropy)损失函数,表达式为:
    {\mathcal{L}(\hat y,y)=-(ylog\ \hat y+(1-y)log\ (1-\hat y))}
    交叉熵损失函数有如下性质:

    • y^{(i)}=1时,{\mathcal{L}({\hat y}^{(i)},y^{(i)})=-log\ {\hat y}^{(i)}}
    • y^{(i)}=0时,{\mathcal{L}({\hat y}^{(i)},y^{(i)})=-log\ (1-{\hat y}^{(i)})}
      代价函数(cost function,或成本函数):衡量的是在全体训练样本上的表现,即衡量参数 w 和 b 的效果。
      对m个训练样本整体的成本函数,可以使用数理统计中的极大似然估计法推导出来。假设所有训练样本独立同分布,则联合概率为所有样本概率的乘积:
      P = \prod_{i=1}^m p(y^{(i)}|x^{(i)})
      对上式进行极大似然估计,还是两边取对数得:
      log\ P = \sum_{i=1}^m log\ p(y^{(i)}|x^{(i)}) = -\sum_{i=1}^m \mathcal{L}(\hat{y}^{(i)}, y^{(i)})
      对上式再取平均值,得成本函数为:
      {J(w,b) = \frac{1}{m} \sum_{i=1}^m \mathcal{L}({\hat y}^{(i)}, y^{(i)})}

    梯度下降

    想找到使成本函数的值最小的参数w和b的值,一般采用梯度下降法。
    函数的梯度(gradient)指出了函数的最陡增长方向。即是说,按梯度的方向走,函数增长得就越快。那么按梯度的负方向走,函数值自然就降低得最快了。

    J(w,b)
    在空间坐标中以w,b为轴画出损失函数J(w,b)的三维图像,可知这个函数为一个凸函数。为了找到合适的参数,先将w和b赋一个初始值,正如图中的小红点。选择这样的代价函数就保证了无论我们初始化模型参数如何,都能够寻找到合适的最优解。
    梯度下降就是从起始点开始,试图在最陡峭的下降方向下坡,以便尽可能快地下坡到达最低点,这个下坡的方向便是此点的梯度值。 J(w,b)二维图像
    参数 w 的更新公式为:
    计算图示例
    令a=5,b=3,c=2
    正向传播过程:
    从左到右,则u=bc=6,v=a+u=11,J=3v=33
    反向传播过程:
    用到的链式求导法则,求得:
    计算图
    考虑单个样例,已知:
    {\mathcal{L}(a,y)=-(ylog\ a+(1-y)log\ (1-a))}
    a = \sigma (z)
    \sigma (z) = \frac{1}{{1 + {e^{ - z}}}}
    z = {w_1}{{\rm{x}}_1} + {w_2}{x_2} + b
    首先反向求出 L 对于 a 的导数:
    da=\frac{dL(a,y)}{da}=−\frac{y}{a}+\frac{1−y}{1−a}
    然后继续反向求出 L 对于 z 的导数:
    dz=\frac{dL}{dz}=\frac{dL(a,y)}{dz}=\frac{dL}{da}\frac{da}{dz}=a−y
    这里需要注意的是:
    \frac{{da}}{{dz}} = a(1 - a)
    同理:
    d{w_1} = \frac{{dL}}{{d{w_1}}} = \frac{{dL}}{{da}}\frac{{da}}{{dz}}\frac{{da}}{{d{w_1}}} = {x_1}(a - y)
    d{w_2} = \frac{{dL}}{{d{w_2}}} = \frac{{dL}}{{da}}\frac{{da}}{{dz}}\frac{{da}}{{d{w_2}}} = {x_2}(a - y)
    db = \frac{{dL}}{{db}} = \frac{{dL}}{{da}}\frac{{da}}{{dz}}\frac{{da}}{{db}} = (a - y)
    参数更新:
    w _1:=w _1−\alpha dw _1
    w _2:=w _2−\alpha dw _2
    b:=b−\alpha db
    接下来我们需要将对于单个用例的损失函数扩展到整个训练集的代价函数:
    J(w,b)=\frac{1}{m}\sum^m_{i=1}L(a^{(i)},y^{(i)})
    a^{(i)}=\hat{y}^{(i)}=\sigma(z^{(i)})=\sigma(w^Tx^{(i)}+b)
    求导得:
    d{w_1} = \frac{1}{m}\sum\nolimits_i^m {{x_1}^{(i)}({a^{(i)}} - {y^{(i)}})}
    d{w_2} = \frac{1}{m}\sum\nolimits_i^m {{x_2}^{(i)}({a^{(i)}} - {y^{(i)}})}
    db = \frac{1}{m}\sum\nolimits_i^m {({a^{(i)}} - {y^{(i)}})}
    那么执行一次参数更新的伪代码流程可以表示为:
    J=0;dw1=0;dw2=0;db=0;
    
    for i = 1 to m
        z(i) = wx(i)+b;
        a(i) = sigmoid(z(i));
        J += -[y(i)log(a(i))+(1-y(i))log(1-a(i));
        dz(i) = a(i)-y(i);
        dw1 += x1(i)dz(i);
        dw2 += x2(i)dz(i);
        db += dz(i);
    
    J/= m;
    dw1/= m;
    dw2/= m;
    db/= m;
    w=w-alpha*dw
    b=b-alpha*db
    

    如果进行n轮迭代,那么就要使用两个for循环,这种方式效率很低。

    向量化

    向量化(Vectorization)实现代替for循环能够有效提高计算效率。实现 Logistic 回归的梯度下降一次的过程可以表示为:
    Z=w^TX+b=np.dot(w.T, x) + b
    A=\sigma(Z)
    dZ=A-Y
    dw=\frac{1}{m}XdZ^T
    db=\frac{1}{m}np.sum(dZ)
    w:=w-\sigma dw
    b:=b-\sigma db
    执行多次迭代的梯度下降再使用 for 循环。

    相关文章

      网友评论

          本文标题:Logistic 回归

          本文链接:https://www.haomeiwen.com/subject/ihemcqtx.html