逻辑回归之原理分析与实践

本文详细介绍了逻辑回归的原理,包括sigmoid函数、线性边界、预测函数以及损失函数的构建。通过实例解释了逻辑回归如何对二分类问题进行概率预测,并探讨了梯度下降法在参数更新中的应用。最后,展示了在Python环境下进行逻辑回归编程测试的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简述

上一篇博客写到线性回归,它是一个线性拟合的过程,而逻辑回归是一个分类的过程,逻辑回归可以用于多分类,一般用在二分类的模型中。对于二维特征,只需要用一根直线进行分割,对于三维特征,需要用一个面进行分割,对于更多维的特征,就很难想象了,这里,我们只讨论二维特征。

二、数学原理

1、sigmoid函数:
在这里插入图片描述
2、对于线性边界的情况,边界形式如下:
在这里插入图片描述
3、构造预测函数为:
在这里插入图片描述
4、hθ(x)函数的值有特殊的含义,它表示结果取1的概率,因此对于输入x分类结果为类别1和类别0的概率分别为:
在这里插入图片描述
5、输出y(标签值0或1)类别的概率可以用以下公式表示:
在这里插入图片描述
举个例子,假设h(x) = 0.01,则表示y=0的概率为0.99,y=1的概率为0.01,这就要看训练集中y的值了,

6、取似然函数,就是对每组预测概率之间的乘积,乘积越大,则损失越小:
在这里插入图片描述
我们要改变参数theta,使得每组数据预测正确的概率值尽可能地大,乘积也就尽可能地大
7、对上式取对数,单调性没有改变,我觉得这种操作是为了更好地求导,得到如下式子:
在这里插入图片描述
8、损失函数一般习惯于取最小值,所以在最大值(上式)取负数就是最小值了,然后对m组数据取平均,除以m就是损失函数:
在这里插入图片描述
9、对theta求梯度如下:
在这里插入图片描述
10、使用梯度下降法更新参数,梯度下降法首先针对的凸函数,这样才能得到全局最优解。梯度下降法的设计和实现都很简单,但是效率很低。这里提下其他几种参数更新方法:Momentum、AdaGrad、Adam,感兴趣的可以查阅资料。梯度下降法如下:
在这里插入图片描述
11、逻辑回归原理参考

三、编程测试

环境:window10+pycharm2017.3+python3.6.6

import numpy as np
import matplotlib.pyplot as plt
"""
函数说明:梯度下降求最优值
Parameters:
    feature  --m*n
    lable    --m*1
    maxCycle --最大迭代次数
    alpha    --学习率
Returns:
    最优参数值
"""
def lr_train_bgd(feature, lable, maxCycle, alpha):
    # feature: m*n
    n = np.shape(feature)[1]  # 每组数据的特征个数
    m = np.shape(feature)[0]  # 多少组数据
    w = np.ones(n).reshape(n, 1)  #初始化权重
    i = 0
    while i < maxCycle:
        i += 1
        x = np.dot(feature, w)
        sigmoid = sig(x)  # m*1
        error = lable - sigmoid
        if i % 50 == 0:
            print("损失值: " + str(i) + ": " + str(error_rate(sigmoid, lable)))
        # 梯度为: gradient := -np.dot(feature.T, error)/m ;  w := w - gradient
        # feature.T: n*m  error:m*1   w: n*1
        w = w + alpha * np.dot(feature.T, error) / m
    return w

#计算损失值
"""
函数说明:计算loss或误差率
Parameters:
    sigmoid  --经过sigmoid转换的值
    lable    --标签数据
Returns:
    返回误差率
"""
def error_rate(sigmoid, lable):
    m = np.shape(sigmoid)[0] #特征条数
    sum = 0.
    for i in range(m):
        if sigmoid[i, 0] > 0 and (1 - sigmoid[i, 0] > 0):
            sum -= + lable[i, 0] * np.log(sigmoid[i, 0]) + (1 - lable[i, 0]) * np.log(1 - sigmoid[i, 0])
    return sum/m

"""
函数说明:将值映射到0-1上,使用了sigmoid函数
Parameters:
    X  --待变换的值或矩阵
Returns:
    返回 X的sigmoid值
"""
def sig(X):
    return 1./(1 + np.exp(-X))

"""
函数说明:加载数据集
Parameters:
    无
Returns:
    返回 feature 和 lable
"""
def loadData():
    feature = []
    lable = []
    fr = open('set.txt')
    lines = fr.readlines()
    for line in lines:
        lineArr = line.strip().split()
        feature.append([1.0, lineArr[0], lineArr[1]])
        lable.append([lineArr[-1]])
    return np.array(feature, dtype='float64'), np.array(lable, dtype='float64')

"""
函数说明:显示结果
Parameters:
    weights --训练得到的参数
    feature --特征数据
    lable   --标签数据
Returns:
    无
"""
def display(feature, lable, weights):
    xclass0 = []
    yclass0 = []
    xclass1 = []
    yclass1 = []
    for i in range(np.shape(lable)[0]):
        if lable[i] == 1:
            xclass0.append(feature[i, 1])
            yclass0.append(feature[i, 2])
        else:
            xclass1.append(feature[i, 1])
            yclass1.append(feature[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)  # 添加subplot
    ax.scatter(xclass0, yclass0, s=10, c='red', marker='s', alpha=.5)  # 绘制正样本
    ax.scatter(xclass1, yclass1, s=20, c='green', alpha=.5)  # 绘制负样本
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[0] - weights[1] * x) / weights[2]
    ax.plot(x, y)
    plt.title('BestFit')  # 绘制title
    plt.xlabel('X1')
    plt.ylabel('X2')  # 绘制label
    plt.show()

if __name__ == '__main__':
    feature, lable = loadData()
    w = lr_train_bgd(feature, lable, 5000, 0.2)
    print(w)
    display(feature, lable, w)


set,txt文件的数据格式形如:
-0.017612 14.053064 0
-1.395634 4.662541 1
-0.752157 6.538620 0
-1.322371 7.152853 0
0.423363 11.054677 0
0.406704 7.067335 1

损失值: 0.09733279544154633
权重:
[[11.23640427]
[ 1.00910356]
[-1.53621881]]

测试截图如下:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值