zoukankan      html  css  js  c++  java
  • 02-12 Logistic(逻辑)回归


    更新、更全的《机器学习》的更新网站,更有python、go、数据结构与算法、爬虫、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11686958.html

    逻辑回归

    虽然逻辑回归的名字里有“回归”两个字,但是它并不是一个回归算法,事实上它是一个分类算法。

    一、逻辑回归学习目标

    1. 二元逻辑回归的目标函数
    2. 最小化二元逻辑回归目标函数
    3. 二元逻辑回归的正则化
    4. 多元逻辑回归
    5. 逻辑回归的流程
    6. 逻辑回归的优缺点

    二、逻辑回归引入

    曾经在感知机引入时我们讲过,操场上男生和女生由于受传统思想的影响,男生和女生分开站着,并且因为男生和女生散乱在操场上呈线性可分的状态,因此我们总可以通过感知机算法找到一条直线把男生和女生分开,并且最终可以得到感知机模型为

    [f(x)=sign((w^*)^Tx) ]

    如果你细心点会发现,由于感知模型使用的是sign函数,如果当计算一个样本点(w^Tx=0.001)的时候,(sign(w^Tx)=1),即该函数会把该样本归为(1),但是为什么他不能是(0)类呢?并且由于sign函数在(x=0)处有一个阶跃,即函数不连续,该函数在数学上也是不方便处理的。

    由此逻辑函数使用sigmoid函数对(w^Tx)做处理,并且把sigmoid函数得到的值(hat{y})当成概率进行下一步处理,这也正是逻辑回归对感知机的改进。

    上述整个过程其实就是逻辑回归一步一步被假想出来的的一个过程,接下来将从理论层面抽象的讲解逻辑回归。

    # 感知机引入图例
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.font_manager import FontProperties
    
    %matplotlib inline
    font = FontProperties(fname='/Library/Fonts/Heiti.ttc')
    
    np.random.seed(1)
    x1 = np.random.random(20)+1.5
    y1 = np.random.random(20)+0.5
    x2 = np.random.random(20)+3
    y2 = np.random.random(20)+0.5
    
    # 一行二列第一个
    plt.subplot(121)
    plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)')
    plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)')
    plt.vlines(2.8, 0, 2, colors="r", linestyles="-", label='$wx+b=0$')
    plt.title('线性可分', fontproperties=font, fontsize=20)
    plt.xlabel('x')
    plt.legend(prop=font)
    
    # 一行二列第二个
    plt.subplot(122)
    plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)')
    plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)')
    plt.scatter(3.5, 1, s=50, color='b')
    plt.title('线性不可分', fontproperties=font, fontsize=20)
    plt.xlabel('x')
    plt.legend(prop=font)
    plt.show()
    

    png

    三、逻辑回归详解

    3.1 线性回归与逻辑回归

    线性回归的假设函数为

    [hat{y} = omega^Tx ]

    此时的(hat{y})是连续值,所以它是一个回归模型,如果(hat{y})是离散值呢?

    可能你已经想到了,对假设函数得到的连续值再做一次转换,即(g(hat{y})),并且令(g(hat{y}))函数值在(hat{y})属于某个区间时为(c_1)类;(hat{y})属于另一个区间时为(c_2)类,这样就能得到一个二元分类模型。

    3.2 二元逻辑回归的假设函数

    上一节讲到对线性回归的结果通过函数(g)做一次转换即可得逻辑回归。在逻辑回归当中函数(g)通常使用Sigmoid函数替代,即函数(g)

    [g(z) = {frac{1}{1+e^{-z}}} ]

    3.2.1 让步比

    让步比可以理解成有利于某一特定事件的概率,可以定义为

    [{frac{p}{1-p}} ]

    在已知二分类问题的情况下每个分类的概率分别为(hat{y_i})(1-hat{y_i}),可以定义logit函数,即让步比的对数形式(log-odds)为

    [egin{align} log{it}(hat{y_i}) & = log{frac{p(y=1|x,omega)}{p(y=0|x,omega)}} \ & = log{frac{hat{y_i}}{1-hat{y_i}}} \ & = log{frac{{frac{1}{1+e^{-omega^Tx}}}}{{frac{-omega^Tx}{1+e^{-omega^Tx}}}}} \ & = omega^Tx end{align} ]

    其中(log{it}(p))函数等于事件发生的概率除以不发生的概率取对数,即表示特征值和对数概率之间的线性关系。

    然而特征值和对数概率之间的线性关系并不重要,重要的是预测值与它发生的概率的关系,即让步比的逆形式,也就是上述说到的Sigmoid函数。

    [w^Tx = log{frac{p}{1-p}} \ e^{w^Tx} = {frac{p}{1-p}} \ p = {frac{1}{1+e^{-w^Tx}}} \ ]

    3.2.2 Sigmoid函数图像

    # Sigmoid函数图像图例
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline
    
    
    def sigmoid(z):
        return 1 / (1 + np.exp(-z))
    
    
    ax = plt.subplot(111)
    
    # 描绘十字线
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.spines['bottom'].set_position(('data', 0))
    ax.yaxis.set_ticks_position('left')
    ax.spines['left'].set_position(('data', 0))
    
    z = np.linspace(-10, 10, 256)
    hat_y = sigmoid(z)
    plt.plot(z, hat_y, c='r', label='Sigmoid')
    
    # 描绘y=0.5和y=1.0两条直线
    plt.yticks([0.0, 0.5, 1.0])
    ax = plt.gca()
    ax.yaxis.grid(True)
    
    plt.xlabel('z')
    plt.ylabel('$hat{y}$')
    plt.legend()
    plt.show()
    

    png

    上图为Sigmoid函数图像,可以看出当(z)趋于正无穷时,(g(z))趋于1;当(z)趋于负无穷时,(g(z))趋于0,这个属性非常适合上述所说的分类模型。

    因此可以把线性函数的假设函数看成是Sigmoid函数的自变量,即逻辑回归的假设函数为

    [hat{y} = {frac{1}{1+e^{-omega^Tx}}} ]

    虽然改变了逻辑回归的假设函数,但是Sigmoid函数的输出值是((0,1))范围内的连续值,并不是二元分类模型想要的二元离散值,因此需要对逻辑回归的假设函数做进一步处理,即

    [egin{cases} hat{y}>0.5即omega^Tx>0, quad y=1 \ hat{y}<0.5即omega^Tx<0, quad y=0 \ end{cases} ]

    如果(hat{y}=0.5即omega^Tx=0),不在逻辑回归模型的讨论范围内,一般而言视具体情况而定。

    3.3 二元逻辑回归的目标函数

    得到了逻辑回归的假设函数,则需要通过最小化目标函数即最小化误差找到最合适的参数(omega)

    由于线性回归是预测连续值的模型,因此可以使用均方误差代价函数。但是逻辑回归是预测离散值的模型,因此可以使用极大似然估计推导出逻辑回归的目标函数。

    上一节假设逻辑回归的输出为类别(0)或类别(1),用概率表达方式为

    [egin{align} & p(y=1|x,omega)=pi(x) \ & p(y=0|x,omega)=1-pi(x) end{align} ]

    由于(y)只可能是(0)(1),则可以把上述两个公式联立可得(y)的概率分布函数表达式

    [p(y|x,omega) = (pi(x))^y(1-pi(x))^{(1-y)} ]

    通过(y)的概率分布函数表达式即可得似然函数为

    [L(omega) = prod_{i=1}^m [pi(x_i)]^{y_i}[(1-pi{x_i})]^{(1-y_i)} ]

    其中(m)为样本的个数。

    通过似然函数得到对数似然函数即目标函数(注:该目标函数与交叉熵损失函数的形式一致,二元逻辑回归可以理解为交叉熵损失函数两个类变量的特殊形式,交叉熵详见《熵和信息增益》)为

    [egin{align} J(omega) & = log{L(omega)} \ & = sum_{i=1}^m [y_ilogpi(x_i)+(1-y_i)log(1-pi(x_i))] end{align} ]

    (J(omega))求极大值,即可得到(omega)的估计值。

    一般采用梯度上升法或拟牛顿法求解(omega)的估计值。

    3.3.1 不同样本分类的代价

    逻辑回归的目标函数为

    [J(omega) = sum_{i=1}^m [y_ilogpi(x_i)+(1-y_i)log(1-pi(x_i))] ]

    对于二分类问题,可以求出(y=1)(y=0)的代价函数

    [J(omega) = egin{cases} -logpi(x) quad if y=1 \ -log(1-pi(x)) quad if y=0 \ end{cases} ]

    # 不同样本实例分类的代价图例
    def cost_1(z):
        return -np.log(sigmoid(z))
    
    
    def cost_0(z):
        return -np.log(1-sigmoid(z))
    
    
    z = np.linspace(-10, 10, 256)
    pi_x = sigmoid(z)
    c1 = [cost_1(i) for i in z]
    c0 = [cost_0(i) for i in z]
    plt.plot(pi_x, c1, c='r', linestyle='--',
             label='$J(omega), quad if quad y=1$')
    plt.plot(pi_x, c0, c='g', label='$J(omega), quad if quad y=0$')
    plt.xlabel('$pi(x)$')
    plt.ylabel('$J(omega)$')
    plt.legend()
    plt.show()
    

    png

    上图可以看出如果正确地预测样本属于第(1)类,代价会接近0(虚线);如果正确的预测(y=0)(实线),代价也会接近0。如果预测错误,代价则会趋近于无穷大,即用越来越大的代价惩罚错误的预测。

    3.4 二元逻辑回归目标函数最大化

    3.4.1 梯度上升法

    二元逻辑回归的目标函数为

    [J(omega) = sum_{i=1}^m [y_ilnpi(x_i)+(1-y_i)ln(1-pi(x_i))] ]

    得到二元逻辑回归的目标函数,我们需要最大化似然函数,即最大化二元逻辑回归的目标函数。

    目标函数对(omega)的偏导为

    [egin{align} {frac{partial{J(omega)}}{partial{omega_j}}} & = sum_{i=1}^m({frac{y_i}{pi(x_i)}}-{frac{1-y_i}{1-pi(x_i)}}){frac{partial{pi(x_i)}}{partial{omega_j}}} \ & = sum_{i=1}^m({frac{y_i}{g(omega^Tx_i)}}-{frac{1-y_i}{1-g(omega^Tx_i)}}){frac{partial{g(omega^Tx_i)}}{partial{omega_j}}} \ & = sum_{i=1}^m({frac{y_i}{g(omega^Tx_i)}}-{frac{1-y_i}{1-g(omega^Tx_i)}})g(omega^Tx_i)(1-g(omega^Tx_i)){frac{partial{omega^Tx_i}}{partial{omega_j}}} \ & = sum_{i=1}^m (y_i(1-g(omega^Tx_i))-(1-y_i)g(omega^Tx_i)){x_i}_j \ & = sum_{i=1}^m (y_i - g(omega^Tx_i)){x_i}_j end{align} ]

    其中(i)为第(i)个样本,(j)为第(j)个特征。

    逻辑回归参数的学习规则为

    [omega_j = omega_j + alpha{sum_{i=1}^m (y_i - g(omega^Tx_i)){x_i}^{(j)}} ]

    3.4.2 线性回归和逻辑回归的参数更新

    线性回归的参数学习公式为

    [omega_j = omega_j - alpha{sum_{i=1}^m (y_i - h(omega^Tx_i)){x_i}^{(j)}} ]

    逻辑回归的参数学习公式为

    [omega_j = omega_j + alpha{sum_{i=1}^m (y_i - g(omega^Tx_i)){x_i}^{(j)}} ]

    从上述两个参数学习公式可以看出线性回归和逻辑回归的参数更新方式有着相同的公式,但是由于线性回归是最小化目标函数,而逻辑回归是最大化似然函数即最大化目标函数,因此线性回归是梯度下降法、逻辑回归是梯度上升法,曾经也讲过其实梯度下降法和梯度上升法可以转换。

    3.4.3 拟牛顿法

    收敛速度更快,但是如果特征维度较大计算时间漫长。

    3.5 二元逻辑回归模型

    假设求得逻辑回归参数为为(omega^T),则二元逻辑回归模型为

    [egin{align} & p(y=1|x) = {frac{e^{-omega^T{x}}}{1+e^{-omega^T{x}}}} \ & p(y=0|x) = {frac{1}{1+e^{-omega^T{x}}}} end{align} ]

    3.6 二元逻辑回归的正则化

    3.6.1 L1正则化

    二元逻辑回归的L1正则化与普通线性回归的L1正则化类似,增加了L1范数作为惩罚,即

    [J(omega) = sum_{i=1}^m [y_i(omega{x_i} - ln(1+exp(omega(x_i))] + lambda||omega||_1 ]

    二元逻辑回归L1正则化目标函数常用的优化方法有坐标轴下降和最小角回归。

    3.6.2 L2正则化

    二元逻辑回归的L2正则化与普通线性回归的L2正则化类似,增加了L2范数作为惩罚,即

    [J(omega) = sum_{i=1}^m [y_i(omega{x_i} - ln(1+exp(omega(x_i))] + {frac{1}{2}}lambda||omega||_2 ]

    3.7 多元逻辑回归

    上面介绍的逻辑回归都是二元分类模型,用于二分类问题,可以使用以下三种方法将其推广为多元逻辑回归。OvR和MvM主要是对数据做处理,这里不介绍其具体过程。而Softmax回归则是优化模型,因此主要讲解Softmax回归。

    3.7.1 OvR

    假设一个数据集(D)(c_1,c_2,ldots,c_k)(k)个类别,则可以把(c_1)看成一个类别,把(c_2,c_3,ldots,c_k)看成另外一个类别,即把(D)分为两个子集,把多分类问题则变成了关于(c_1)(c_2,c_3,ldots,c_k)的二分类问题,然后对含有多个类别的子集再次使用OvR方法,直至无法分类为止。通常这种方法称为OvR(One-vs-Rest)。

    3.7.2 MvM

    假设一个数据集(D)(c_1,c_2,ldots,c_k)(k)个类别,则可以先把(c_1,c_2,ldots,c_i, quad i<k)看成一个类别,把(c_i,c_{i+1},ldots,c_k)看成另外一个类别,即把(D)分为两个子集,多分类问题则变成了关于(c_1,c_2,ldots,c_i)(c_i,c_{i+1},ldots,c_k)的二分类问题,然后对两个子集再次使用MvM方法,直至无法分类为止。通常这种方法称为MvM(Many-vs-Many)。

    如果每次只选择两个个类别进行分类的话,则该方法称为OvO(One-vs-One),一般情况下首先考虑使用OvO。

    3.7.3 Softmax回归

    详见《Softmax回归》

    四、逻辑回归流程

    4.1 输入

    (m)个实例(n)维特征的数据集

    [T={(x_1,y_1),(x_2,y_2),cdots,(x_m,y_m)} ]

    其中(x_i)是实例的特征向量即(({x_i}^{(1)},{x_i}^{(2)},cdots,{x_i}^{(n)}))

    4.2 输出

    (omega)和二元逻辑回归模型。

    4.3 流程

    1. 选取初值(omega=0)
    2. 训练集中选取数据((x_i,y_i)),对(omega)使用梯度上升更新

    [omega = omega + alpha(y_i - g(omega^Tx_i)){x_i}^{(j)} ]

    1. 重复步骤2,直至(omega)收敛停止更新
    2. 得到最小化的目标函数(J(omega)),同时可以得到最优的(omega^*),二元逻辑回归模型为

    [egin{align} & p(y=1|x) = {frac{e^{-omega^T{x}}}{1+e^{-omega^T{x}}}} \ & p(y=0|x) = {frac{1}{1+e^{-omega^T{x}}}} end{align} ]

    五、逻辑回归优缺点

    5.1 优点

    1. 由于计算量只和特征的数目有关,训练速度相较其他的分类器例如支持向量机快
    2. 形式简单,模型的可解释性非常好。从特征的权重可以看到不同的特征对最后结果的影响,某个特征的权重值比较高,那么这个特征最后对结果的影响会比较大
    3. 可以手动调整阈值(并不一定要0.5),输出结果可以手动调节控制,灵活

    5.2 缺点

    1. 因为类似线性回归很容易欠拟合,分类精度不高
    2. 假设数据分类严重不平衡,例如1:10000,则分类时会有倾向问题
    3. 逻辑回归本身无法筛选特征,通常通过GBDT筛选特征后再使用逻辑回归

    六、小结

    逻辑回归引入时说到逻辑回归一定程度上也是基于感知机演化而来,在替换sigmoid函数的同时,将sigmoid函数得到的值转换为概率的形式,进而可以最大化似然函数得到最优(w^*),这也是逻辑回归的巧妙之处,但是两者还是换汤不换药,都是基于特征的线性模型分类。

    由于感知机、线性回归和逻辑回归都和线性模型有一定的关系,因此放在一起讲,下面将会将一个单独的算法,它从理论上而言是最简单易懂的一个算法,即k近邻算法。

  • 相关阅读:
    HDU 1890 Robotic Sort (splay tree)
    POJ 3468 A Simple Problem with Integers (splay tree入门)
    1588: [HNOI2002]营业额统计 (splay tree)
    HDU 4597 Play Game (DP,记忆化搜索)
    HDU 4499 Cannon (搜索)
    HDU 4497 GCD and LCM (合数分解)
    升级到 Android Studio 3.0 + Gradle 4.1 遇到的一些坑及解决方案
    关于The specified Android SDK Build Tools version (26.0.2) is ignored, as it is below the minimum...
    Android Studio启动时出现unable to access android sdk add-on list
    unable to access android sdk add-on list(转)
  • 原文地址:https://www.cnblogs.com/nickchen121/p/11686724.html
Copyright © 2011-2022 走看看