【手搓深度学习算法】用逻辑回归分类Iris数据集-线性数据篇

本文介绍逻辑回归算法对线性的Iris数据集进行分类。阐述逻辑斯蒂回归原理、与线性回归异同,用基础Python和NumPy实现代码,还引入SciPy库的minimize函数优化梯度下降,比较前后准确率差异,后续将总结其在非线性数据集的应用。

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

用逻辑回归分类Iris数据集-线性数据篇

前言

逻辑斯蒂回归是一种广泛使用的分类方法,它是基于条件概率密度函数的最大似然估计的。它的主要思想是将输入空间划分为多个子空间,每个子空间对应一个类别。在每个子空间内部,我们假设输入变量的取值与类别标签的概率成正比。

在逻辑斯蒂回归中,我们首先通过数据进行线性回归,得到的结果再通过sigmoid函数转化为概率,这样就可以得到每个类别的概率。然后,我们可以通过设置一个阈值,如果概率大于阈值,我们就认为这个样本属于这个类别,否则就属于其他类别。这就是逻辑斯蒂回归的基本原理。

逻辑斯蒂回归在现实生活中有很多应用,比如垃圾邮件分类、疾病诊断等。它可以处理非线性关系,而且它的预测结果是概率,这对于处理分类问题非常有用。

在深度学习中,逻辑斯蒂回归的作用主要体现在两个方面:一是作为一种基础的分类方法,它可以用于二分类问题,比如判断一个邮件是否为垃圾邮件;二是作为一种特征提取方法,它可以用于提取输入数据的特征,这些特征可以被其他深度学习模型使用。

本文介绍了逻辑回归算法的其中一种应用场景-对线性的多分类数据集进行分类,后续还将总结逻辑回归在非线性数据集中的应用方法。

本文首先使用基础python和numpy进行基础代码实现,然后引入一个科学计算库

from scipy.optimize import minimize

来优化梯度下降过程,并且比较前后的准确率差异

名词解释

回归

很多初学(复习)统计学或者深度学习算法的同学(包括我),对“回归”这个名词可能感觉有点疑惑,因为它既熟悉又陌生,熟悉是因为它在现实生活中也很常见,比如香港回归,澳门回归。。。,陌生的是当它跟统计学名词联系在一起,又会让人有点摸不着头脑,什么线性回归,逻辑斯蒂回归。。。,为此,我专门查找了相关资料,总结如下:

在统计学和深度学习中,“回归”这个术语的含义主要是关于预测一个连续的目标变量。这个目标变量可以是任何可以连续变化的东西,比如销售额、房价、股票价格等。在这种情况下,“回归”的意思是“倒推”或者“预测”。

在统计学中,我们使用回归分析来研究一个或多个自变量(即影响因素)与一个因变量(即我们想要预测的结果)之间的关系。例如,我们可能会使用回归分析来研究房价与房屋面积、位置、年份等因素的关系。在这种情况下,我们的目标是找到一个函数,这个函数可以根据这些因素预测房价。这就是“回归”的含义:我们是在“倒推”或者“预测”房价。

在深度学习中,我们也使用回归模型,但是这里的“回归”更多的是指预测一个连续的目标变量。例如,我们可能会使用深度学习的回归模型来预测一个物品的评分,或者预测一个人的年龄。在这种情况下,我们的目标是找到一个函数,这个函数可以根据一些输入特征预测这个连续的目标变量。这也是“回归”的含义:我们是在“倒推”或者“预测”这个连续的目标变量。

总的来说,无论是在统计学还是在深度学习中,“回归”的含义都是“倒推”或者“预测”一个连续的目标变量。这个目标变量可以是任何可以连续变化的东西,比如销售额、房价、股票价格、评分、年龄等。我们的目标是找到一个函数,这个函数可以根据一些输入特征预测这个连续的目标变量。

逻辑斯蒂回归和线性回归的异同点

逻辑斯蒂回归和线性回归都是回归分析的一种,但它们的主要区别在于处理的问题类型和输出结果的形式。

相同点

  1. 回归分析:逻辑斯蒂回归和线性回归都是回归分析的一种,它们都试图找到一个或多个自变量(即影响因素)与一个因变量(即我们想要预测的结果)之间的关系。

  2. 预测连续变量:逻辑斯蒂回归和线性回归都是用来预测连续变量的。在逻辑斯蒂回归中,我们通过sigmoid函数将线性回归的结果转化为概率,从而得到每个类别的概率。

不同点

  1. 处理问题类型:线性回归主要用于处理连续的目标变量,而逻辑斯蒂回归主要用于处理分类问题。

  2. 输出结果的形式:线性回归的输出结果是一个连续的值,而逻辑斯蒂回归的输出结果是一个概率值,通常用于二分类问题。

  3. 处理非线性关系:线性回归只能处理线性关系,而逻辑斯蒂回归可以处理非线性关系。

实现

工具函数

Sigmoid

Sigmoid函数是一种常用的激活函数,它将任意实数映射到0和1之间。Sigmoid函数的定义如下:

σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1

其中, x x x是输入, σ ( x ) \sigma(x) σ(x)是输出。

Sigmoid函数的图像如下(不平滑因为是我自己生成的。。。):
在这里插入图片描述

Sigmoid函数的主要特性包括:

  1. 单调递增:对于所有的 x x x σ ( x ) \sigma(x) σ(x)都是单调递增的。

  2. 输出范围在0和1之间:对于所有的 x x x 0 ≤ σ ( x ) ≤ 1 0 \leq \sigma(x) \leq 1 0σ(x)1

  3. 可微:Sigmoid函数是可微的,这使得它可以用于神经网络的反向传播算法。

def sigmoid(data):
    return 1 / (1+np.exp(-data))

逻辑斯蒂回归类

以下代码在名为"LogisticRegression"的类中

初始化

将传入的数据集和标签记录下来以便进一步处理,同时初始化权重矩阵

def __init__(self, data,labels) -> None:
        self.data = data
        self.labels = labels
        self.unique_labels = np.unique(labels) #取标签中的类的名称的集合
        self.num_examples = self.data.shape[0] #取数据集中样本的数量
        self.num_features = self.data.shape[1] #取数据集中的特征个数
        num_unique_labels = self.unique_labels.shape[0] #取标签中类的个数
        self.theta = np.zeros((num_unique_labels,self.num_features)) #初始化权重向量,因为我们是多分类,所以权重是 “分类数量 x 特征个数”的矩阵

训练函数

对每个可能的分类执行训练过程,因为逻辑斯蒂回归通常用于处理二分类问题,所以每次都将当前分类的标签置为“1”,其他分类的标签置为“0”

def train(self, lr = 0.01, max_iter = 1000):
    cost_histories = [] #记录损失历史记录,以便可视化
    for label_index, unique_label in enumerate(self.unique_labels): #对所有可能的分类进行遍历
        current_initial_theta = np.copy(self.theta[label_index].reshape(self.num_features, 1)) #复制对应的权重向量,以避免直接修改
        current_labels = (self.labels == unique_label).astype(float) #等于当前标签的置为1,否则为0
        (current_theta, cost_history) = LogisticRegression.gradient_descent(self.data, current_labels, current_initial_theta, max_iter) #执行梯度下降过程
        self.theta[label_index] = current_theta.T #记录当前分类最终的权重向量
        cost_histories.append(cost_history) #记录当前分类最终的损失历史记录
    return cost_histories, self.theta

梯度下降过程

在规定的迭代次数里执行梯度下降,每次权重向量都减去学习率乘以当前梯度,通过迭代优化模型的参数(也就是权重向量 θ \theta θ),使得模型的预测结果与真实标签之间的差异(也就是损失函数)最小。

gradient_descent 方法的主要任务是执行梯度下降的迭代过程。它接收五个参数:数据集 data、标签 labels、当前的初始权重向量 current_initial_theta、学习率 lr 和最大迭代次数 max_iter。在每次迭代中,它会调用 gradient_step 方法计算梯度,然后根据梯度更新权重向量。同时,它还会记录每次迭代后的损失值,以便于后续的可视化或者调试。

gradient_step 方法的主要任务是计算梯度。它接收三个参数:数据集 data、标签 labels 和当前的权重向量 theta。首先,它会计算预测值 predictions,然后计算预测值与真实标签之间的差异 label_diff。最后,它会计算梯度 gradients,并返回梯度的平均值。

在这里,梯度的计算公式为:

∇ θ J ( θ ) = 1 N ∑ i = 1 N ( h θ ( x ( i ) ) − y ( i ) ) x ( i ) \nabla_\theta J(\theta) = \frac{1}{N} \sum_{i=1}^{N} (h_\theta(x^{(i)}) - y^{(i)})x^{(i)} θJ(θ)=N1i=1N(hθ(x(i))y(i))x(i)

其中, N N N 是数据集的大小, h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i)) 是预测值, y ( i ) y^{(i)} y(i) 是真实标签, x (

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值