逻辑斯蒂回归_统计学习方法 第6章:逻辑斯蒂回归

本文深入探讨逻辑斯蒂回归,包括模型提出、参数估计(梯度下降法)、广义线性模型理论及模型可解释性。此外,详细介绍了如何通过softmax函数扩展到多分类问题,以及在实际应用中的学习策略。
摘要由CSDN通过智能技术生成

github链接:https://github.com/gdutthu/Statistical-learning-method

知乎专栏链接:https://zhuanlan.zhihu.com/c_1252919075576856576

算法总结:

  1. 对比感知机模型,logistics不不仅能进行分类,还能计算出样本点属于每个类别的概率;
  2. logistics和最大熵模型都是对数线性模型(一般而言,logistics被认为是广义线性模型)。
  3. 普通的logistic回归只能针对二分类问题。要要实现多分类,需要对原始logistic回归进行修改。(一般而言是引入softmax函数);

补充知识:

  1. sigmoid函数;
  2. OvR 与 OvO。

1 提出模型

感知机模型和传统的logistics模型都是线性二分类模型,都是期望找到一个线性决策边界从而将两种不同类别的数据区分开。这两个算法具有一定的相似性。 在感知机模型中,我们可通过梯度下降方法来学习模型参数,最终找到一个线性超平面

将两种线性可分数据区分开。

6b12f4214572b43d3ed909e899489f37.png
感知机模型

但是在感知机我们只能得到最终的划分结果,并不知道样本点属于各个类别的概率。 若样本点A和样本点B同时被模型

判断为正样本。但是实际上样本点A为正样本的概率为0.91,样本点B为正样本的概率为0.56。那么相比于样本点B,样本A属于正样本类别的信息更多一些,我们也希望获得这方面的信息。因此提出了logistics模型。

为了计算样本点属于各个类别的概率,我们引入了sigmoid函数。将感知机分类超平面的输入映射到[0,1]区间。 sigmoid是一个S型函数,它的表达式为

,函数图像分别如下

fca384a27ef15674cf7cce80f0b1467e.png
sigmoid函数图像

补充知识:sigmoid函数的特点

1、定义域为

,值域为
。 (能满足超平面各式各样的输入,将其和概率区间对应起来)

2、 函数对输入超过一定范围就会不敏感;

3、sigmoid函数的导数

4、在定义域内为连续和光滑函数。 (这点最为重要,这满足梯度下降法的使用前提) 5、因为逻辑回归的损失函数L是一个连续的凸函数(conveniently convex)。这样的函数的特征是,它只会有一个全局最优的点,不存在局部最优。

我们结合sigmoid函数和线性回归函数,把线性回归模型的输出作为sigmoid函数的输入。于是最后就变成了逻辑回归模型:

假设我们已经训练好了一组权值

。只要把需要预测样本点A的特征向量
代入到上面的方程,输出的y值就是这个标签为A的概率,我们就能够判断输入数据是属于哪个类别。

假设只有两个标签1和0,

,我们把采集到的任何一组样本看做一个事件的话,那么这个事件发生的概率假设为
。我们的模型y的值等于标签为0的概率也就是
。则y的值等于标签为1的概率也就是

我们把单个样本看做一个事件,那么这个事件发生的概率就是

为了符号简单的,对权值向量和输入向量进行扩充。即将原先的

,
,
,改记为
,

那么logistics模型的概率表达式可改写为

2 参数估计

2.1 目标函数

在上一小节中,我们得到logistics模型的概率表达式为

其中

那么一个样本点的似然函数为

进一步得,模型的似然函数为

为了避免由于概率值太小导致在计算过程中出现浮点数下溢的问题,进行对数化处理。则对数似然函数为

这个就是交叉熵公式

对数似然函数

求极大值,得到对应的
参数的估计值。

现在我们的问题变成了,找到一个

使得我们的总事件发生的概率,即对数似然函数函数
取得最大值,这句话用数学语言表达就是:

结合上面的分析,那我们可以将目标函数

定义为

那么对数似然函数

的极大值求解问题,就转变成对目标函
的极小值求解问题

2.2 梯度下降法

因为我们需要求解目标函数

的极小值,在这里采用梯度下降法(也可以采用牛顿法或者拟牛顿法),对参数
进行估计

上一小节中,我们得到目标函数的表达式为

其中

因为

目标函数

对参数w进行求偏导数

对上面式子进行化简可得

综上可得,目标函数对参数w的偏导数为

则可得如下的参数更新公式

梯度下降法:核心思想就是先随便初始化一个

,然后给定一个步长
,通过上述的参数更新公式来更新参数
,从而最后靠近到达取得最小值的点,即不断进行下面的迭代过程,直到达到指定次数,或者梯度等于0为止。

3 相关理论细节

3.1 广义线性模型

判断一个模型是否是线性模型就看它的决策边界(decision boundary)是否是线性的。(决策边界就是几个类别的边界)

根据logistics的定义,以二分类为例,模型的决策边界就是样本点属于两个类别概率相等时的边界,即

展开式子得

可以看出,logistics模型的决策边界是

,故logistics模型是线性模型。

662d95262ee69c553cd9be8e4f085f53.png
logistics的决策边界

因为logistics模型中还包含了sigmoid非线性函数,所以我们一般称logistics模型为广义线性模型。

3.2 模型可解释性

逻辑回归最大的特点就是可解释性很强。 在模型训练完成之后,我们获得了一组n维的权重向量w跟偏差 b。

对于权重向量w ,它的每一个维度的值,代表了这个维度的特征对于最终分类结果的贡献大小。假如这个维度是正,说明这个特征对于结果是有正向的贡献,那么它的值越大,说明这个特征对于分类为正起到的作用越重要。

对于偏差b (Bias),一定程度代表了正负两个类别的判定的容易程度。假如b是0,那么正负类别是均匀的。如果b大于0,说明它更容易被分为正类,反之亦然。

根据逻辑回归里的权重向量在每个特征上面的大小,就能够对于每个特征的重要程度有一个量化的清楚的认识,这就是为什么说逻辑回归模型有着很强的解释性的原因。

4 logistics多分类模型

参考博客:https://www.zhihu.com/collection/549030983

4.1 改进思路

我们已经知道,普通的logistic回归只能针对二分类(Binary Classification)问题,要想实现多分类,需要对传统的logistics模型进行改进。关于这种改进,有两种方式可以做到。

方法一 是直接根据每个类别,都建立一个二分类器,带有这个类别的样本标记为1,带有其他类别的样本标记为0。假如我们有k个类别,最后我们就得到了k个针对不同标记的普通的logistic二分类器。(本质上就是ovr的做法)

方法二 是修改logistic回归的损失函数,让其适应多分类问题。这个损失函数不再笼统地只考虑二分类非1就0的损失,而是具体考虑每个样本标记的损失。这种方法叫做softmax回归,即logistic回归的多分类版本。

补充知识:OvR 与 OvO OvR(One vs Rest):一对剩余的意思,有时候也称它为 OvA(One vs All);一般使用 OvR,更标准; OvO(One vs One):一对一的意思;

4.2 学习策略

因为方法一本质上就是样本点的label的处理,在原理上没有新东西要讲。在下面内容中将对方法二进行详细介绍。

在传统的logistics二分类模型中,我们只需要准备一个分类模型

,通过计算样本点属于正类别的概率
。若
,则该样本点属于正类别,反之属于负类别。 但是在多分类(假设数据集类别总数为
)问题中,我们需要训练
个分类器
。其中在对于
的训练中,将类别为
的样本标记为1,将剩下的不带标记
的样本标记为0。针对每个分类器,都按上述步骤构造训练集进行训练。

5f3ced8d27e54b62df328cf1bce72384.png

然后在测试集中将训练好的分类器计算出测试样本点属于各个类别的概率,分类函数输出值最大的那一个,即为测试样本的标记。

4.3 softmax函数

在softmax回归设置中,我们对多类分类感兴趣(而不是仅对二元分类),所以

可以取
个不同的取值。因此,在我们的训练集

具体地说,我们的假设

采用以下形式:

其中,

是模型的参数,
是归一化项。

为方便起见,我们还会向量法来表示模型的所有参数。当你实现

回归时,将
表示为通过堆叠
成行获得的k-by(n + 1)矩阵通常很方便,这样

损失函数

补充知识

1、在下面的公式中,​是示性函数,其取值规则为:

例如:​

2、上述公式是logistic回归代价函数的推广。logistic回归代价函数可以改为:

求导后,可得

其中

为在
模型中将该样本分到
类的概率

根据梯度下降法,更新参数

5 代码附录

在这里采用mnist数据集进行logistics多分类实验,采用TensorFlow2.0进行加载数据(懒得写函数加载模块了hhh)。在代码环节中,对测试集中的所有实例点都进行了测试,所需时间较长。

import  tensorflow as  tf
import numpy as np

#加载训练mnist数据集的数据集和测试数据集
def MnistData():
    #原始的训练数据集是60000张尺寸为28*28的灰色照片,测试数据集是10000张尺寸为28*28的灰色照片
    mnist = tf.keras.datasets.mnist
    (train_data, train_label), (test_data, test_label) = mnist.load_data()
    train_data = train_data.reshape(60000, 784)
    test_data = test_data.reshape(10000, 784)

    #图像色素点数据在0~255之间
    #data数据集进行归一化,这样数据范围在0~1之间
    train_data=train_data/255
    test_data=test_data/255
    return (train_data, train_label), (test_data, test_label)

#logistics模型训练
#采用随机梯度下降方法,训练logistics模型模型
#epoch:迭代次数上限,learnRate:学习率
def logistics(train_data,train_label,test_data, test_label,epoch=3000,learnRate=0.005):
   dataNum = len(train_label)           # 获取原始标签数据集的样本个数
   # np.unique(train_label)对标签数据集去重处理,返回处理后的数据
   classNum=len(np.unique(train_label)) #label数据集中类别的总数,此时classNum=10

   #对权值向量和输入向量进行扩充
   #在原始数据集合权值向量最后一列单位列向量
   train_data_one=np.ones(shape=(len(train_label),1))
   test_data_one=np.ones(shape=(len(test_label),1))
   train_data=np.c_[train_data,train_data_one]
   test_data=np.c_[test_data,test_data_one]

   #对标签数据集进行onehot处理
   train_label=one_hot(train_label)

   # 初始化多分类模型参数
   #十组类别的模型参数
   w=np.random.rand(classNum,train_data.shape[1])

   for i in range(epoch):  # 开始迭代训练,迭代次数上限是epoch
       z = np.dot(train_data, w.T)        # z:(60000,10) 即60000*10维的矩阵
       h = 1 / (1 + np.exp(-z))           # sigmoid非线性处理
       error = h - train_label            # 误差
       w_grad = np.dot(error.T, train_data) / dataNum #最大似然函数对参数w,b的偏导数

       # 参数w,b更新
       w= w - learnRate * w_grad

       if i %100==0 :   #每迭代训练一百次,就打印模型的分类准确率
           acc=modelTest(test_data, test_label,w)
           print(' %d epoch,model accuracy is %f '%(i,acc))
   return w

#one-hot处理
#one-hot处理的核心想法由于是多分类,我们的类别有10个类,所以需要训练10个分类器,每个分类器都是一个二分类器
# 例如:对于数字0的分类器来说,我们将标签为0的数据的标签重新改成正类1,
# 将非0标签对应的数据的标签改为负类0,即变为一个二分类问题,
# 其他分类器一样,将标签是对应分类的类别的标签改为1, 其他置为0
def one_hot(label):
    dataNum = len(label)  # 获取原始标签数据集的样本个数
    # 对标签数据集去掉重复元素,再计算此时元素个数,此时classNum=10
    classNum=len(np.unique(label)) #label数据集中类别的总数
    label_one_hot=np.zeros(shape=(dataNum,classNum))  #生成零矩阵
    for i in range(dataNum):        #按照onehot处理规则进行赋值
        label_one_hot[i,label[i]]=1
    return label_one_hot


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

#logistics模型测试
def modelTest(test_data, test_label,w):
    acc = 0  # 记录测试集中分类准确点的数量
    for i in range(len(test_label)):
        sample = test_data[i]      #提取出当前样本点的特征向量
        label = test_label[i]      #提取出当前样本点的标签向量
        linear=np.dot(sample,w.T)  #样本数据和模型参数进行矩阵相乘,进行线性变换
        prob=sigmoid(linear)       #对线性变化数据进行sigmoid处理
        predict=np.argmax(prob)    #概率值最大的类别即为预测的类别
        if predict==label:         #若模型预测的类别与样本的真实类别一致,计数器加一
            acc  +=1
    return acc / len(test_label) * 100


if __name__=="__main__":
    # 加载mnist数据集中label=0和label=+1的数据,并且将label=0改成label=-1
    (train_data, train_label), (test_data, test_label)=MnistData()
    #训练模型
    w=logistics(train_data,train_label,test_data, test_label,epoch=5000,learnRate=0.5)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值