逻辑回归揭秘: 从分类原理到机器学习实践

这篇具有很好参考价值的文章主要介绍了逻辑回归揭秘: 从分类原理到机器学习实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

逻辑回归 (Logistic Regression) 尽管名字中带有 “回归” 两个字, 但主要是用来解决分类问题, 尤其是二分类问题. 逻辑回归的核心思想是: 通过将线性回归的输出传递给一个激活函数 (Activation Function) 比如 Sigmoid 函数) 将连续值转化为 0 到 1 之间的概率值, 在根据阈值 (Threshold) 对概率进行分类.

逻辑回归揭秘: 从分类原理到机器学习实践,2024 Python 最新基础教程,# 机器学习,机器学习,逻辑回归,分类

逻辑回归应用领域

逻辑回归 (Logistic Regression) 在许多领域有着广泛的应用, 包括但不限于:

  • 医学: 用于疾病预测
  • 金融: 信用评分, 评估某人违约的风险
  • 营销: 预测客户是否购买某个产品, 或是否点击某个广告
  • 社交网络: 预测用户相位, 例如是否接收好友请求或是否为垃圾信息

随着我们对数据的理解不断加深, 尤其是在设计分类任务时, 逻辑回归往往是我们首先尝试的算法. 相较于其他算法, 逻辑回归有着非常高的计算效率, 且背后的数学原理简单明了.

逻辑回归 vs 线性回归

在机器学习中, 线性回归 (Linear Regression) 和逻辑回归是最基础的算法. 尽管两个算法的名字十分相似, 但是工作原理和用途上有着很大的差异. 为了更深入的理解两者之间的差异, 我们从下面几个维度来展开讨论.

基本定义

  • 线性回归 (Linear Regression): 线性回归用于估计一个或多个自变量与因变量的线性关系, 用于回归任务
  • 逻辑回归 (Logistic Regression): 逻辑回归估算事件发生的概率, 用于分类任务

输出类型

  • 线性回归 (Linear Regression): 线性回归输出的是连续值, 范围是 − ∞ ∼ + ∞ -\infty\sim +\infty +
  • 逻辑回归 (Logistic Regression): 逻辑回归输出的是概率值, 范围是 0-1

函数关系

  • 线性回归 (Linear Regression): 线性回归关系是线性的, 使用恒等链接函数
  • 逻辑回归 (Logistic Regression): 逻辑回归关系是 S 形的 (Sigmoid) 函数

误差计算

  • 线性回归 (Linear Regression): 线性回归使用均方误差 (MSE) 来计算模型误差
  • 逻辑回归 (Logistic Regression): 逻辑回归使用对数损失函数 (Logarithmic Loss Function) 来计算模型误差

使用场景

  • 线性回归 (Linear Regression): 线性回归的目标是预测一个连续的值, 例如房价, 温度等
  • 逻辑回归 (Logistic Regression): 逻辑回归的目标是分类, 特别是二分类, 例如垃圾邮件检测, 疾病诊断等

数据分布

  • 线性回归 (Linear Regression): 要求自变量和因变量具有线性关系, 且误差应呈现正态分布 (Normal Distribution). 此外书籍中不能存在重共线性, 异方差性和自相关
  • 逻辑回归 (Logistic Regression): 不需要因变量和自变量之间存在线性关系, 每个自变量与 log(odds) 之间存在线性关系. 此外, 逻辑回归还假设观察值之间是独立的

逻辑回归的数学原理

在我们深入研究逻辑回归 (Logistic Regression) 之前, 理解其背后的数学原理至关重要. 通过理解原理, 我们可以更好的理解算法, 还可以帮助我们在实际应用中做出明智的决策.

Sigmoid 函数

逻辑回归的核心是 Sigmoid 函数, 也称为 Logistic 函数. 通过 Sigmoid 函数, 我们可以将任何实数映射到 0-1 之间.

逻辑回归揭秘: 从分类原理到机器学习实践,2024 Python 最新基础教程,# 机器学习,机器学习,逻辑回归,分类
sigmoid 公式:
S ( z ) = 1 1 + e − z S(z) = \frac{1}{1 + e^{-z}} S(z)=1+ez1

  • z 为输入的线性组合

z 的公式:
z = w 0 + w 1 x 1 + w 2 x 2 + w 3 x 3 + . . . + w n x n z = w_0 + w_1x_1 + w_2x_2 + w_3x_3 + ... + w_nx_n z=w0+w1x1+w2x2+w3x3+...+wnxn

  • 当 z 趋于正无穷时, S(z) 趋近于 1
  • 当 z 趋于负无穷时, S(z) 趋近于 0
  • 当 z=0 时, S(z) = 0.5

Sigmoid 的 S 形曲线非常适用于二分类问题, 因为 Sigmoid 可以产生的输出看做是属于某个类别的概率.

Sigmoid 函数在 Python 中的实现:

import numpy as np

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

多数几率

逻辑回归涉及到一个重要的概念, 对数几率 (Log-Odds). 对数几率是事件发生概率与事件不发生概率之间的对数比率.

l o g i t ( p ) = l o g ( p 1 − p ) logit(p) = log(\frac{p}{1-p}) logit(p)=log(1pp)

其中, p 是事件发生的概率 (Probability). 我们的目标是建立解释变量和对数几率之间的关系.

似然函数

为了估计逻辑回归模型中的参数, 我们需要使用似然函数 (Likelihood Function). 给定一组参数, 依然函数描述了数据观测到的概率.

似然函数与概率:

  • 似然: 给定某一观测到数据集, 我们试图估计某一参数 (如硬币出现正面的概率) 的可能性.
  • 概率: 给定某一参数值 (例如一个硬币出现正反面的概率), 我们计算特定情况下观察到某一数据集的概率. 举个栗子: 抛硬币, 正反面出现的概率为 0.5, 我们可以计算连续抛投 5 词都是正面的概论, 即 P ( 5 正面 ∣ p ) = ( 0.5 ) 5 = 0.03125 P(5 正面 | p) = (0.5)^5 = 0.03125 P(5正面p)=(0.5)5=0.03125
  • 似然 vs 概率:
    • 函数角度: 似然是关于参数的函数, 给定观测到的数据; 概率是关于数据的函数, 给定固定的参数值
    • 归一化: 似然的总和并不一定为 1, 不是一个真正的概率分布; 概率所有可能的事件总和总是等于 1
    • 观点: 似然描述了给定已经发生的某事件下, 不同情景 (模型参数) 的可能; 概率描述了未来发生某件事情的可能性

似然函数公式:
L ( θ ∣ x ) = P ( X = x ∣ θ ) L(\theta|x) = P(X=x|\theta) L(θx)=P(X=xθ)

  • θ \theta θ: 模型参数
  • X X X: 随机变量
  • x x x: 观察到的数据
  • P ( X = x ∣ θ ) P(X=x|\theta) P(X=xθ): 在给定参数 θ \theta θ下观测到数据 x x x的概率

最大似然估计, 似然函数在统计学中一个主要应用是最大似然估计 (MLE). 目标是找到能使似然函数最大化的参数值. 公式:

θ ˆ = a r g    m a x    L ( θ ∣ x ) \^\theta = arg\; max\; L(\theta|x) θˆ=argmaxL(θx)

  • θ ˆ \^\theta θˆ为模型参数的最佳估计值

为什么要使用似然函数:

  • 似然函数为我们提供了一个框架来评估模型参数的不同可能值对观察数据的拟合程度. 最大似然函数估计为我们提供了一个一致性和渐进无偏的估计方法, 即样本量越大, MLE 会月接近真实参数值

逻辑回归损失函数

逻辑回归 (Logistic Regression) 用于解决二分类 (Binary Classification) 问题, 主要用于目标是预测给定输入的输出类别为 1 (True) 的概率. 为了衡量模型的预测值 ( y ˆ \^y yˆ Predict) 与实际类别标签之间的差异, 我们需要一个损失函数. 逻辑回归蚕蛹的损失函数通常被称为对数损失 (Log Loss) 或交叉熵损失 (Cross Entropy Loss).

对数损失函数:
J ( w , b ) = − y l o g ( y ˆ ) − ( 1 − y ) l o g ( 1 − y ˆ ) J(w, b) = -ylog(\^y)- (1-y)log(1-\^y) J(w,b)=ylog(yˆ)(1y)log(1yˆ)

  • y: 是类别标签 (0 或 1)
  • y ˆ \^y yˆ: 是模型预测值

对数损失函数考虑了模型预测值的概率和实际类别之间的所有可能的差异:

  • 当实际类别等于 1 时 (y=1): 损失函数就是 − l o g ( y ˆ ) -log(\^y) log(yˆ). 如果 y ˆ \^y yˆ 越接近 1, 那么损失值将越接近 0. 反之 y ˆ \^y yˆ 越接近 0, 损失值将越大
  • 当实际类别等于 1 时 (y=0): 损失函数就是 − l o g ( 1 − y ˆ ) -log(1-\^y) log(1yˆ). 如果 y ˆ \^y yˆ 越接近 0, 那么损失值将越接近 0. 反之 y ˆ \^y yˆ 越接近 1, 损失值将越大

注: 交叉熵损失和对数损失在二分类问题下是等价的.

正则化

正则化 (Regularization) 是机器学习中一个的一个重点. 正则化通过在模型损失函数中添加一定的 “惩罚” 项, 来限制模型的复杂度以提高模型的泛化能力 (Generalization Ability) 和避免过拟合 (Overfitting). 在逻辑回归中, 我们常常会用到 L1 和 L2 正则化来实现.

L1 正则化

L1 正则化 (Lasso 正则化):
J L 1 = J + λ ∑ i = 1 n ∣ w i ∣ J_{L1} = J + \lambda \sum\limits_{i=1}^{n}|w_i| JL1=J+λi=1nwi

  • J J J: 原始的损失函数
  • w i w_i wi: 模型参数
  • λ \lambda λ: 正则化参数

L1 正则化倾向于产生一些权重为 0 的特征 (Feature), 这意味着模型中某些特征可能完全被忽略, 从而实现了特征选择.

L2 正则化

L2 正则化 (Ridge 正则化):
J L 1 = J + λ ∑ i = 1 n w i 2 J_{L1} = J + \lambda \sum\limits_{i=1}^{n}w_i^2 JL1=J+λi=1nwi2

  • J J J: 原始的损失函数
  • w i w_i wi: 模型参数
  • λ \lambda λ: 正则化参数

与 L1 正则化不同, L2 正则化不会使权重完全为 0, 但它会尽量使它们小, 这有助于防止任何单一特征对预测结果产生过大的影响, 从而使模型更加稳健.

选择合适的正则化:

  • 选择 L1 或 L2 正则化 (或者它们的组合, Elastic Net) 取决于我们需要解决什么问题. 如果只有几个特征是重要的, 那么 L1 正则化可能更合适, 因为它会导致稀疏的模型. 而如果所有特征都有意义, 但我们希望模型不要过于以来任何单一特征, 那么 L2 正则可能是更好的选择.

L1 vs L2 实例

假设我们有一个拥有 10 个特征的数据集, 但是其中只有 3 个是真正有意义的, 及特征中含有许多冗余特征. 在这种情况下, 我们就需要用到 L1 正则化, 因为 L1 正则化可以帮我们将那些不重要的特征的权重将为 0.

先讲一下 sklearn 生成模拟数据的格式:

sklearn.datasets.make_classification(n_samples=100, n_features=20, *, n_informative=2, n_redundant=2, n_repeated=0, n_classes=2, n_clusters_per_class=2, weights=None, flip_y=0.01, class_sep=1.0, hypercube=True, shift=0.0, scale=1.0, shuffle=True, random_state=None)

参数:

  • n_samples: 生成的数据数量
  • n_features: 数据的特征个数
  • n_informative: 信息特征的个数 (最重要的特征)
  • n_redundant: 冗余特征的个数
  • random_state: 随机状态 (随机数种子)

例子:

"""
@Module Name: 逻辑回归 正则化.py
@Author: CSDN@我是小白呀
@Date: October 18, 2023

Description:
逻辑回归 正则化
"""
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss, accuracy_score

# 生成模拟数据, 长度1000, 特征10, 其中有用特征3, 冗余特征7
X, y = make_classification(n_samples=1000, n_features=10, n_informative=3, n_redundant=7, random_state=8)

# 输出数据维度
print("特征维度:", X.shape)  # (1000, 10)
print("标签维度:", y.shape)  # (1000, )

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

# 使用L1正则化
l1_model = LogisticRegression(penalty='l1', solver='liblinear')
l1_model.fit(X_train, y_train)


# 使用L2正则化
l2_model = LogisticRegression(penalty='l2', solver='liblinear')
l2_model.fit(X_train, y_train)

# 对比权重
print("L1正则化的特征权重:\n{}".format(l1_model.coef_))
print("L2正则化的特征权重:\n{}".format(l2_model.coef_))

# 对比模型效果
l1_pred = l1_model.predict(X_test)
l2_pred = l2_model.predict(X_test)

print("L1 逻辑回归误差:", log_loss(y_test, l1_pred))
print("L2 逻辑回归误差:", log_loss(y_test, l2_pred))
print("L1 逻辑回归 acc:", accuracy_score(y_test, l1_pred))
print("L2 逻辑回归 acc:", accuracy_score(y_test, l2_pred))

输出结果:

特征维度: (1000, 10)
标签维度: (1000,)
L1正则化的特征权重:
[[ 0.          0.          0.         -0.66172034  0.          0.
   0.         -0.75254448 -0.27951727  0.41781586]]
L2正则化的特征权重:
[[-0.14042143 -0.21016038  0.12523401 -0.43610954  0.05762657  0.08849344
  -0.19145278 -0.51859205 -0.42032689  0.5046308 ]]
L1 逻辑回归误差: 9.901243835463227
L2 逻辑回归误差: 10.016373090112928
L1 逻辑回归 acc: 0.7133333333333334
L2 逻辑回归 acc: 0.71

标准化

标准化 (Standardization) 常用与预处理数据, 特别是在使用需要考虑特征尺度的机器学习算法, 例如: 支持向量机, 逻辑回归, K-近邻.

逻辑回归揭秘: 从分类原理到机器学习实践,2024 Python 最新基础教程,# 机器学习,机器学习,逻辑回归,分类

为什么要标准化?

机器学习算法对特征的尺度和分布较为敏感. 当特征的尺度 (范围) 相差很大时, 那些范围较大的特可能会主导算法的行为, 导致模型性能不佳.

如何进行标准化?

标准化的主要思想是对特征数据进行缩放, 使其均值为 0, 标准差为 1.

标准化公式:

z = x − μ σ z = \frac{x - \mu}{\sigma} z=σxμ

  • z z z: 原始特征值
  • μ \mu μ: 特征均值
  • σ \sigma σ: 特征标准差

sklearn 中进行标准化:

from sklearn.preprocessing import StandardScaler

# 原始数据
data = [[0, 1], [2, 3], [4, 5]]
print(data)

# 标准化
scaler = StandardScaler()
scaler.fit(data)
data = scaler.transform(data)
print(data)

输出结果:

[[0, 1], [2, 3], [4, 5]]
[[-1.22474487 -1.22474487]
 [ 0.          0.        ]
 [ 1.22474487  1.22474487]]

逻辑回归预测乳腺癌, 不进行标准化:

Classification Report:
               precision    recall  f1-score   support

           0       0.92      0.96      0.94        47
           1       0.97      0.94      0.95        67

    accuracy                           0.95       114
   macro avg       0.94      0.95      0.95       114
weighted avg       0.95      0.95      0.95       114

进行标准化:

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

梯度下降

梯度下降 (Gradient Descent) 是一个用于优化函数的迭代方法. 在机器学习 (Machine Learning) 和深度学习 (Deep Learning) 中, 我们常用梯度下降来最小化 (最大化) 损失函数, 进而找到模型的最优参数.

工作原理

梯度下降的核心思想很简单: 找到损失函数的斜率 (梯度), 然后沿着斜率的反方向更新模型的参数, 逐步减小损失.

逻辑回归揭秘: 从分类原理到机器学习实践,2024 Python 最新基础教程,# 机器学习,机器学习,逻辑回归,分类

梯度下降的公式

公式:
w n e x t = w − l r × ∂ l o s s ∂ w w_{next} = w - lr\times \frac{\partial loss}{\partial w} wnext=wlr×wloss

  • w n e x t w_{next} wnext: 是梯度下降过程中的下一个权重
  • lr: Learning Rate 学习率
  • ∂ l o s s ∂ w \frac{\partial loss}{\partial w} wloss: 误差函数的导数

下面我们来推导一下:
我们已知: M S E = 1 n ∑ i = 1 n ( y i − y ˆ i ) 2 y = w 0 + w 1 x 1 MSE = \frac{1}{n}\sum\limits_{i=1}^{n}(y_i - \^y_i)^2\\y = w_0 + w_1x_1 MSE=n1i=1n(yiyˆi)2y=w0+w1x1

在梯度下降中, 我们的目标是调整模型参数 (权重和偏置, w 和 b 或 w0) 以最小化损失函数, 所以我们需要对模型参数 (w 和 w0) 求偏导:

w1 (权重) 求导:
∂ M S E ∂ w 1 = 1 n ∑ i = 1 n ( w 0 + w 1 x 1 ) 2 d w = 2 n ∑ i = 1 n x ( w 0 + w 1 x 1 ) \frac{\partial MSE}{\partial w_1} = \frac{1}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1)^2dw \\=\frac{2}{n}\sum\limits_{i=1}^{n}x(w_0 + w_1x_1) w1MSE=n1i=1n(w0+w1x1)2dw=n2i=1nx(w0+w1x1)

w0 (偏置) 求导:
∂ M S E ∂ w 0 = 1 n ∑ i = 1 n ( w 0 + w 1 x 1 ) 2 d w = 2 n ∑ i = 1 n ( w 0 + w 1 x 1 ) \frac{\partial MSE}{\partial w_0} = \frac{1}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1)^2dw \\=\frac{2}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1) w0MSE=n1i=1n(w0+w1x1)2dw=n2i=1n(w0+w1x1)

如果有 w2, w3 以此类推, 这边我就不写了.

计算新的权重, 将上面的导数代入梯度下降公式, 我们可以得到:
w 1 n e x t = w 1 − l r × ∂ l o s s ∂ w 1 = w 1 − l r × 2 n ∑ i = 1 n x ( w 0 + w 1 x 1 ) w_{1next} = w_1 - lr\times \frac{\partial loss}{\partial w_1} \\=w_1 - lr\times\frac{2}{n}\sum\limits_{i=1}^{n}x(w_0 + w_1x_1) w1next=w1lr×w1loss=w1lr×n2i=1nx(w0+w1x1)

同理:
w 0 n e x t = w 0 − l r × ∂ l o s s ∂ w 0 = w 1 − l r × 2 n ∑ i = 1 n ( w 0 + w 1 x 1 ) w_{0next} = w_0 - lr\times \frac{\partial loss}{\partial w_0} \\=w_1 - lr\times\frac{2}{n}\sum\limits_{i=1}^{n}(w_0 + w_1x_1) w0next=w0lr×w0loss=w1lr×n2i=1n(w0+w1x1)

在代码中:

# 计算w的导, w的导 = 2x(wx+b-y)
 w_gradient += (2 / N) * x * ((w_current * x + b_current) - y)

# 计算b的导, b的导 = 2(wx+b-y)
b_gradient += (2 / N) * ((w_current * x + b_current) - y)

梯度下降的变种

  • 批量梯度下降 (BGD, Batch Gradient Descent): 每次使用这个训练集来计算梯度
  • 随机梯度下降 (SGD, Stochastic Gradient Descent): 每次只使用一个样本来计算梯度
  • 小批量梯度下降 (Mini-Batch Gradient Descent): 使用一个小批量的样本来计算梯度

学习率

寻找山谷的最低点, 也就是我们的目标函数终点 (什么样的参数能使得目标函数达到极值点)

下山分几步走呢?

  1. 找到当前最合适的方向
  2. 走一小步
  3. 按照方向与步伐去更新我们的参数

学习率 (learning_rate): 对结果影响较大, 越小越好.

数据批次 (batch_size): 优先考虑内存和效率, 批次大小是次要的.

逻辑回归揭秘: 从分类原理到机器学习实践,2024 Python 最新基础教程,# 机器学习,机器学习,逻辑回归,分类
选择适当的学习率非常重要:

  • 太小的学习率: 收敛速度慢
  • 太大的学习率: 会错过最小值, 或梯度爆炸

常见的操作有:

  • 学习率衰减或学习率退火 (Learning Rate Decay 或 Cosine Annealing), 即学习率随着迭代次数逐渐减小

前向传播 vs 反向传播

前向传播 (Forward Propagation) 和反向传播是深度学习 (Deep Learning) 中训练神经网络 (Neural Network) 的一个概念. 但是今天我乐意, 所以就来给大家讲一讲, 不喜欢欢迎来打我.

逻辑回归 (Logistic Regression) 可以被视为一个单层神经网络, 所以前向传播和反向传播的概念也适用.

前向传播

前向传播 (Forward Propagation) 是指从输入层传递到输出层的信息流. 在这个过程中我们计算每一层的输出值知道最后的预测值.

对于逻辑回归 (Logistic Regression) 而言, 逻辑回归的单层神经网络的前向传播可以描述为以下几步:

  1. 计算线性部分: 给定输入特征 X X X 和权重 w w w (以及偏置 b b b), 我们计算 z = w X + b z = wX + b z=wX+b
  2. 激活函数: 将上一步的结果 z z z 传递给 Sigmoid 激活函数, 得到预测值 y ˆ = σ ( z ) \^y = \sigma(z) yˆ=σ(z)

反向传播

反向传播 (Backward Propagation) 是通过计算损失函数对于每个参数梯度来更新模型的参数. 这些梯度可以告诉我们如何调整参数以最小化损失.

对于逻辑回归, 反向传播的过程可以描述为以下几步:

  1. 计算误差: 计算 y − y ˆ y - \^y yyˆ, 即真实值和预测值之间的差
  2. 计算梯度: 计算损失函数 L L L 相对于权重 w w w 和偏置 b b b 的梯度. 具体来说, 就是求对于权重 w w w 和偏置 b b b 的偏导. 计算梯度 (Gradient) 的目的是找到一个方向, 沿着方向调整参数使得损失减少
  3. 更新参数: 使用上一步计算所得的梯度来更新权重和偏置. 我们使用学习率 (Learning Rate) 来控制更新的步长

在神经网络中, 这个过程更加复杂, 因为我们需要从输出层开始, 一层一层的回到输入层, 计算每一层的梯度. 但基本思想是一样的, 即计算损失梯度, 并使用这些梯度来更新网络中的权重和偏置. 前向传播为我们提供了模型的预测值, 反向传播为我们提供了更新模型参数的方法, 从而改进模型的预测能力.

手把手计算回归

使用简单的线性回归模型 y = w x + b y=wx+b y=wx+b来拟合给定的数据.

数据:

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

模型初始参数:

  • w = 0
  • b = 0

目标: 最小化均方误差 (MSE)
1 n ∑ i = 1 n ( y − ( w x + b ) ) \frac{1}{n}\sum\limits_{i=1}^{n}(y - (wx + b)) n1i=1n(y(wx+b))

前向传播

前向传播计算:

对于 x 1 = 1 x_1 = 1 x1=1, 预测结果为:
y ˆ 1 = w × x 1 + b = 0 × 1 + 0 = 0 \^y_1 = w \times x_1 + b = 0 \times 1 + 0 = 0 yˆ1=w×x1+b=0×1+0=0
真实值 y 1 = 2 y_1 = 2 y1=2, 所以误差为 e 1 = y 1 − y ˆ 1 = 2 e_1 = y_1 - \^y_1 = 2 e1=y1yˆ1=2

以此类推:

  1. 对于 x 1 = 1 x_1 = 1 x1=1:
    • y ˆ 1 = w × x 1 + b = 0 \^y_1 = w \times x_1 + b = 0 yˆ1=w×x1+b=0
    • e 1 = y 1 − y ˆ 1 = 2 e_1 = y_1 - \^y_1 = 2 e1=y1yˆ1=2
  2. 对于 x 2 = 2 x_2 = 2 x2=2:
    • y ˆ 2 = w × x 2 + b = 0 \^y_2 = w \times x_2 + b = 0 yˆ2=w×x2+b=0
    • e 2 = y 2 − y ˆ 2 = 4 e_2 = y_2 - \^y_2 = 4 e2=y2yˆ2=4
  3. 对于 x 3 = 3 x_3 = 3 x3=3:
    • y ˆ 3 = w × x 3 + b = 0 \^y_3 = w \times x_3 + b = 0 yˆ3=w×x3+b=0
    • e 3 = y 3 − y ˆ 3 = 6 e_3 = y_3 - \^y_3 = 6 e3=y3yˆ3=6
  4. 对于 x 4 = 4 x_4 = 4 x4=4:
    • y ˆ 4 = w × x 4 + b = 0 \^y_4 = w \times x_4 + b = 0 yˆ4=w×x4+b=0
    • e 4 = y 4 − y ˆ 4 = 8 e_4 = y_4 - \^y_4 = 8 e4=y4yˆ4=8
  5. 对于 x 5 = 5 x_5 = 5 x5=5:
    • y ˆ 5 = w × x 5 + b = 0 \^y_5 = w \times x_5 + b = 0 yˆ5=w×x5+b=0
    • e 5 = y 5 − y ˆ 5 = 10 e_5 = y_5 - \^y_5 = 10 e5=y5yˆ5=10

反向传播

MSE 的偏导为:
∂ M S E ∂ w = − 2 n ∑ i = 1 n x ( y − ( w x + b ) ) \frac{\partial MSE}{\partial w} = -\frac{2}{n}\sum\limits_{i=1}^{n}x(y - (wx + b)) wMSE=n2i=1nx(y(wx+b))
∂ M S E ∂ b = − 2 n ∑ i = 1 n ( y − ( w x + b ) ) \frac{\partial MSE}{\partial b} =- \frac{2}{n}\sum\limits_{i=1}^{n}(y - (wx + b)) bMSE=n2i=1n(y(wx+b))

代入 x 1 = 1 x_1 = 1 x1=1 y 1 = 2 y_1 = 2 y1=2:

∂ M S E ∂ w = − 2 × 1 × 2 = − 4 \frac{\partial MSE}{\partial w} = -2 \times1 \times2 = -4 wMSE=2×1×2=4
∂ M S E ∂ b = = − 2 × 2 = − 4 \frac{\partial MSE}{\partial b} = = -2 \times2 = -4 bMSE==2×2=4

这是一个数据的梯度, 对于整个数据, 我们需要依次计算 x 1 x_1 x1 x 5 x_5 x5, 然后求平均:

∂ M S E ∂ w = − 2 5 × [ ( 1 × 2 ) + ( 2 × 4 ) + ( 3 × 6 ) + ( 4 × 8 ) + ( 5 × 10 ) ] = − 2 5 × 110 = − 44 \frac{\partial MSE}{\partial w} \\= \frac{-2}{5} \times[(1 \times 2) + (2 \times 4) + (3 \times 6) + (4 \times 8) + (5 \times 10)] \\= \frac{-2}{5} \times 110 \\= -44 wMSE=52×[(1×2)+(2×4)+(3×6)+(4×8)+(5×10)]=52×110=44

∂ M S E ∂ b = − 2 5 × ( 2 + 4 + 6 + 8 + 10 ) = − 2 5 × 30 = − 12 \frac{\partial MSE}{\partial b} \\= \frac{-2}{5} \times(2+4+6+8+10) \\= \frac{-2}{5} \times 30 \\= -12 bMSE=52×(2+4+6+8+10)=52×30=12

参数更新

参数更新公式:
w n e w = w o l d − L e a r n i n g R a t e × ∂ l o s s ∂ w w_{new} = w_{old} - LearningRate\times \frac{\partial loss}{\partial w} wnew=woldLearningRate×wloss

b n e w = b o l d − L e a r n i n g R a t e × ∂ l o s s ∂ b b_{new} = b_{old} - LearningRate\times \frac{\partial loss}{\partial b} bnew=boldLearningRate×bloss

代入 ∂ M S E ∂ w = − 44 \frac{\partial MSE}{\partial w} = -44 wMSE=44 ∂ M S E ∂ b = − 12 \frac{\partial MSE}{\partial b} = -12 bMSE=12:

w n e w = 0 − 0.01 × ∂ l o s s ∂ w = 0 − 0.01 × − 44 = 0.44 w_{new} = 0 - 0.01 \times \frac{\partial loss}{\partial w} = 0 - 0.01 \times -44 = 0.44 wnew=00.01×wloss=00.01×44=0.44

b n e w = 0 − 0.01 × ∂ l o s s ∂ b = 0 − 0.01 × − 12 = 0.12 b_{new} = 0 - 0.01 \times \frac{\partial loss}{\partial b} = 0 - 0.01 \times -12 = 0.12 bnew=00.01×bloss=00.01×12=0.12

这样我们就完成了一次迭代. 为了得到更准确的权重, 我们需要迭代多次对模型进行收敛. 经过多次得带, 我们会发现 w w w 趋近于 2, b b b 趋近于 0.

第 1 次迭代后: w=0.44, b=0.12
第 2 次迭代后: w=0.776, b=0.2112
第 3 次迭代后: w=1.032608, b=0.280416
第 4 次迭代后: w=1.22860928, b=0.3328512
第 5 次迭代后: w=1.3783441663999998, b=0.3724776192
第 6 次迭代后: w=1.4927597926399998, b=0.402327416832
第 7 次迭代后: w=1.5802129932492799, b=0.42471528093696004
第 8 次迭代后: w=1.6470832178782207, b=0.44140819572326406
第 9 次迭代后: w=1.6982404182016162, b=0.45375503873610556
第 10 次迭代后: w=1.7374022238730944, b=0.4627855128692865
第 11 次迭代后: w=1.7674066038488565, b=0.4692856691795151
第 12 次迭代后: w=1.7904200108513373, b=0.4738555595649934
第 13 次迭代后: w=1.8080962748901435, b=0.4769532477226133
第 14 次迭代后: w=1.8216978995509552, b=0.47892840627475247
第 15 次迭代后: w=1.83218865727326, b=0.4800479641762001
第 16 次迭代后: w=1.8403042748225709, b=0.48051568545628054
第 17 次迭代后: w=1.8466063932342285, b=0.4804871152578007
第 18 次迭代后: w=1.8515237598072303, b=0.48008098935859095
第 19 次迭代后: w=1.8553836732881241, b=0.47938794398298534
第 20 次迭代后: w=1.8584359885257578, b=0.4784771647060382
第 21 次迭代后: w=1.8608714411677287, b=0.47740146210037193
第 22 次迭代后: w=1.862835636384806, b=0.47620114638830074
第 23 次迭代后: w=1.8644397275968507, b=0.47490698527744635
第 24 次迭代后: w=1.8657685684088967, b=0.4735424619160864
第 25 次迭代后: w=1.8668869356439743, b=0.4721254985732309
第 26 次迭代后: w=1.8678442798879062, b=0.4706697724631278
第 27 次迭代后: w=1.8686783519647792, b=0.46918572022059085
第 28 次迭代后: w=1.8694179713192922, b=0.4676813046982923
第 29 次迭代后: w=1.8700851393471505, b=0.4661626003251689
第 30 次迭代后: w=1.8706966526712672, b=0.4646342399578365

实战

逻辑回归预测乳腺癌

"""
@Module Name: 逻辑回归 乳腺癌.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
逻辑回归 乳腺癌
"""
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 加载数据
data = load_breast_cancer()
X = data.data
y = data.target

# 调试输出数据基本信息
print("输出特征:", X[:5])
print("输出标签:", y[:5])

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 训练
clf = LogisticRegression(random_state=42)
clf.fit(X_train, y_train)

# 预测
y_pred = clf.predict(X_test)

# 模型评估
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)

print("acc:", accuracy)
print("\n混淆矩阵:\n", conf_matrix)
print("\nClassification Report:\n", report)

输出结果:

输出特征: [[1.799e+01 1.038e+01 1.228e+02 1.001e+03 1.184e-01 2.776e-01 3.001e-01
  1.471e-01 2.419e-01 7.871e-02 1.095e+00 9.053e-01 8.589e+00 1.534e+02
  6.399e-03 4.904e-02 5.373e-02 1.587e-02 3.003e-02 6.193e-03 2.538e+01
  1.733e+01 1.846e+02 2.019e+03 1.622e-01 6.656e-01 7.119e-01 2.654e-01
  4.601e-01 1.189e-01]
 [2.057e+01 1.777e+01 1.329e+02 1.326e+03 8.474e-02 7.864e-02 8.690e-02
  7.017e-02 1.812e-01 5.667e-02 5.435e-01 7.339e-01 3.398e+00 7.408e+01
  5.225e-03 1.308e-02 1.860e-02 1.340e-02 1.389e-02 3.532e-03 2.499e+01
  2.341e+01 1.588e+02 1.956e+03 1.238e-01 1.866e-01 2.416e-01 1.860e-01
  2.750e-01 8.902e-02]
 [1.969e+01 2.125e+01 1.300e+02 1.203e+03 1.096e-01 1.599e-01 1.974e-01
  1.279e-01 2.069e-01 5.999e-02 7.456e-01 7.869e-01 4.585e+00 9.403e+01
  6.150e-03 4.006e-02 3.832e-02 2.058e-02 2.250e-02 4.571e-03 2.357e+01
  2.553e+01 1.525e+02 1.709e+03 1.444e-01 4.245e-01 4.504e-01 2.430e-01
  3.613e-01 8.758e-02]
 [1.142e+01 2.038e+01 7.758e+01 3.861e+02 1.425e-01 2.839e-01 2.414e-01
  1.052e-01 2.597e-01 9.744e-02 4.956e-01 1.156e+00 3.445e+00 2.723e+01
  9.110e-03 7.458e-02 5.661e-02 1.867e-02 5.963e-02 9.208e-03 1.491e+01
  2.650e+01 9.887e+01 5.677e+02 2.098e-01 8.663e-01 6.869e-01 2.575e-01
  6.638e-01 1.730e-01]
 [2.029e+01 1.434e+01 1.351e+02 1.297e+03 1.003e-01 1.328e-01 1.980e-01
  1.043e-01 1.809e-01 5.883e-02 7.572e-01 7.813e-01 5.438e+00 9.444e+01
  1.149e-02 2.461e-02 5.688e-02 1.885e-02 1.756e-02 5.115e-03 2.254e+01
  1.667e+01 1.522e+02 1.575e+03 1.374e-01 2.050e-01 4.000e-01 1.625e-01
  2.364e-01 7.678e-02]]
输出标签: [0 0 0 0 0]
acc: 0.9649122807017544

混淆矩阵:
 [[45  2]
 [ 2 65]]

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

逻辑回归 鸢尾花

"""
@Module Name: 逻辑回归 鸢尾花.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
逻辑回归 鸢尾花
"""
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 加载数据
data = load_iris()
X = data.data
y = data.target

# 调试输出数据基本信息
print("输出特征:", X[:5])
print("输出标签:", y[:5])

# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# 标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 训练
clf = LogisticRegression(random_state=42)
clf.fit(X_train, y_train)

# 预测
y_pred = clf.predict(X_test)

# 模型评估
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)

print("acc:", accuracy)
print("\n混淆矩阵:\n", conf_matrix)
print("\nClassification Report:\n", report)

输出结果:

输出特征: [[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]
输出标签: [0 0 0 0 0]
acc: 1.0

混淆矩阵:
 [[11  0  0]
 [ 0 13  0]
 [ 0  0  6]]

Classification Report:
               precision    recall  f1-score   support

           0       1.00      1.00      1.00        11
           1       1.00      1.00      1.00        13
           2       1.00      1.00      1.00         6

    accuracy                           1.00        30
   macro avg       1.00      1.00      1.00        30
weighted avg       1.00      1.00      1.00        30

手搓逻辑回归

"""
@Module Name: 手把手教你实现逻辑回归.py
@Author: CSDN@我是小白呀
@Date: October 19, 2023

Description:
手把手教你实现逻辑回归
"""
class LogisticRegression:
    def __init__(self, learning_rate=0.01, num_iterations=1000):
        """
        初始化参数
        :param learning_rate: 学习率
        :param num_iterations: 迭代次数
        """
        self.learning_rate = learning_rate
        self.num_iterations = num_iterations
        self.weights = None
        self.bias = 0

    def _sigmoid(self, z):
        """
        sigmoid 激活函数
        :param z: 值
        :return: 0-1概率
        """
        return 1 / (1 + self._exp(-z))

    def _exp(self, value):
        # 实现指数函数, 为了防止溢出
        if value.any() < -100:
            return 0.0
        else:
            return 2.718281828459045 ** value

    def fit(self, X, y):
        """
        训练模型
        :param X: 特征
        :param y: 标签
        :return:
        """
        num_samples, num_features = X.shape
        self.weights = [0] * num_features

        for _ in range(self.num_iterations):
            model_output = self._predict(X)

            # 计算梯度
            d_weights = (1 / num_samples) * (X.T.dot(model_output - y))
            d_bias = (1 / num_samples) * sum(model_output - y)

            # 更新权重和偏置
            self.weights -= self.learning_rate * d_weights
            self.bias -= self.learning_rate * d_bias

    def predict(self, X):
        """
        预测
        :param X: 特征
        :return: 预测值
        """
        linear_model_output = X.dot(self.weights) + self.bias
        return [1 if i > 0.5 else 0 for i in self._sigmoid(linear_model_output)]

    def _predict(self, X):
        linear_model_output = X.dot(self.weights) + self.bias
        return self._sigmoid(linear_model_output)

if __name__ == '__main__':
    from sklearn.datasets import load_breast_cancer
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

    # 加载数据
    data = load_breast_cancer()
    X = data.data
    y = data.target

    # 调试输出数据基本信息
    print("输出特征:", X[:5])
    print("输出标签:", y[:5])

    # 分割数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

    # 标准化
    scaler = StandardScaler()
    X_train = scaler.fit_transform(X_train)
    X_test = scaler.transform(X_test)

    # 训练
    clf = LogisticRegression()
    clf.fit(X_train, y_train)

    # 预测
    y_pred = clf.predict(X_test)

    # 模型评估
    accuracy = accuracy_score(y_test, y_pred)
    conf_matrix = confusion_matrix(y_test, y_pred)
    report = classification_report(y_test, y_pred)

    print("acc:", accuracy)
    print("\n混淆矩阵:\n", conf_matrix)
    print("\nClassification Report:\n", report)

输出结果:文章来源地址https://www.toymoban.com/news/detail-786306.html

输出特征: [[1.799e+01 1.038e+01 1.228e+02 1.001e+03 1.184e-01 2.776e-01 3.001e-01
  1.471e-01 2.419e-01 7.871e-02 1.095e+00 9.053e-01 8.589e+00 1.534e+02
  6.399e-03 4.904e-02 5.373e-02 1.587e-02 3.003e-02 6.193e-03 2.538e+01
  1.733e+01 1.846e+02 2.019e+03 1.622e-01 6.656e-01 7.119e-01 2.654e-01
  4.601e-01 1.189e-01]
 [2.057e+01 1.777e+01 1.329e+02 1.326e+03 8.474e-02 7.864e-02 8.690e-02
  7.017e-02 1.812e-01 5.667e-02 5.435e-01 7.339e-01 3.398e+00 7.408e+01
  5.225e-03 1.308e-02 1.860e-02 1.340e-02 1.389e-02 3.532e-03 2.499e+01
  2.341e+01 1.588e+02 1.956e+03 1.238e-01 1.866e-01 2.416e-01 1.860e-01
  2.750e-01 8.902e-02]
 [1.969e+01 2.125e+01 1.300e+02 1.203e+03 1.096e-01 1.599e-01 1.974e-01
  1.279e-01 2.069e-01 5.999e-02 7.456e-01 7.869e-01 4.585e+00 9.403e+01
  6.150e-03 4.006e-02 3.832e-02 2.058e-02 2.250e-02 4.571e-03 2.357e+01
  2.553e+01 1.525e+02 1.709e+03 1.444e-01 4.245e-01 4.504e-01 2.430e-01
  3.613e-01 8.758e-02]
 [1.142e+01 2.038e+01 7.758e+01 3.861e+02 1.425e-01 2.839e-01 2.414e-01
  1.052e-01 2.597e-01 9.744e-02 4.956e-01 1.156e+00 3.445e+00 2.723e+01
  9.110e-03 7.458e-02 5.661e-02 1.867e-02 5.963e-02 9.208e-03 1.491e+01
  2.650e+01 9.887e+01 5.677e+02 2.098e-01 8.663e-01 6.869e-01 2.575e-01
  6.638e-01 1.730e-01]
 [2.029e+01 1.434e+01 1.351e+02 1.297e+03 1.003e-01 1.328e-01 1.980e-01
  1.043e-01 1.809e-01 5.883e-02 7.572e-01 7.813e-01 5.438e+00 9.444e+01
  1.149e-02 2.461e-02 5.688e-02 1.885e-02 1.756e-02 5.115e-03 2.254e+01
  1.667e+01 1.522e+02 1.575e+03 1.374e-01 2.050e-01 4.000e-01 1.625e-01
  2.364e-01 7.678e-02]]
输出标签: [0 0 0 0 0]
acc: 0.9649122807017544

混淆矩阵:
 [[45  2]
 [ 2 65]]

Classification Report:
               precision    recall  f1-score   support

           0       0.96      0.96      0.96        47
           1       0.97      0.97      0.97        67

    accuracy                           0.96       114
   macro avg       0.96      0.96      0.96       114
weighted avg       0.96      0.96      0.96       114

到了这里,关于逻辑回归揭秘: 从分类原理到机器学习实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【机器学习】鸢尾花分类-逻辑回归示例

    功能: 这段代码演示了如何使用逻辑回归对鸢尾花数据集进行训练,并将训练好的模型保存到文件中。然后,它允许用户输入新的鸢尾花特征数据,使用保存的模型进行预测,并输出预测结果。 步骤概述: 加载数据和预处理: 使用 Scikit-Learn 中的 datasets 模块加载鸢尾花数据

    2024年02月10日
    浏览(42)
  • 机器学习算法(一): 基于逻辑回归的分类预测

    逻辑回归的介绍 逻辑回归(Logistic regression,简称LR)虽然其中带有\\\"回归\\\"两个字,但逻辑回归其实是一个 分类 模型,并且广泛应用于各个领域之中。虽然现在深度学习相对于这些传统方法更为火热,但实则这些传统方法由于其独特的优势依然广泛应用于各个领域中。 而对于

    2024年01月15日
    浏览(49)
  • 【白话机器学习的数学】读书笔记(3)学习分类(感知机、逻辑回归)

    1.分类的目的 找到一条线把白点和黑点分开。这条直线是使 权重向量成为法线向量 的直线。(解释见下图) 直线的表达式为: ω ⋅ x = ∑ i = 1 n ω i ⋅ x i = 0 omega·x = sum_{i=1}^nomega_i · x_i = 0 ω ⋅ x = i = 1 ∑ n ​ ω i ​ ⋅ x i ​ = 0 ω omega ω 是权重向量 权重向量就是我们想要知

    2024年01月18日
    浏览(54)
  • 【AI底层逻辑】——篇章5(上):机器学习算法之回归&分类

    目录 引入 一、何为机器学习 1、定规则和学规则 2、算法的定义

    2024年02月16日
    浏览(56)
  • 机器学习基础之《回归与聚类算法(4)—逻辑回归与二分类(分类算法)》

    一、什么是逻辑回归 1、逻辑回归(Logistic Regression)是机器学习中的一种分类模型,逻辑回归是一种分类算法,虽然名字中带有回归,但是它与回归之间有一定的联系。由于算法的简单和高效,在实际中应用非常广泛 2、叫回归,但是它是一个分类算法 二、逻辑回归的应用场

    2024年02月07日
    浏览(54)
  • 机器学习实战:Python基于Logistic逻辑回归进行分类预测(一)

    1.1 Logistic回归的介绍 逻辑回归( Logistic regression ,简称 LR )是一种经典的二分类算法,它将输入特征与一个sigmoid函数进行线性组合,从而预测输出标签的概率。该算法常被用于预测离散的二元结果,例如是/否、真/假等。 优点: 实现简单。Logistic回归的参数可以用极大似然

    2024年02月08日
    浏览(42)
  • 机器学习(10) 逻辑回归:多元分类(Multi-class classification)

    对于数据集中存在多个类别的分类问题,我们可以采用一种叫做 One-vs-rest 的方法,将其转化成二元分类的问题,然后再进行解决。 前面的是对于二元分类问题,应该如何去处理其预测函数、代价函数和梯度下降算法。 但是多元的分类才是生活常见的情况。 例如对于邮件,我

    2024年02月02日
    浏览(52)
  • 机器学习实验1——朴素贝叶斯和逻辑回归分类Adult数据集

    基于Adult数据集,完成关于收入是否大于50K的逻辑回归分类、朴素贝叶斯模型训练、测试与评估。 认识数据 14个特征变量如下 1个目标变量:Income:50K 或 50K 填充缺失值(“ ?”) 统计各类型数据缺失个数如下,这三种缺失数据类型均为离散型(discrete),因此采用众数填充较

    2024年01月23日
    浏览(50)
  • 机器学习-逻辑回归:从技术原理到案例实战

    在本篇文章中,我们对逻辑回归这一经典的机器学习算法进行了全面而深入的探讨。从基础概念、数学原理,到使用Python和PyTorch进行的实战应用,本文旨在从多个角度展示逻辑回归的内在机制和实用性。 关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品

    2024年02月05日
    浏览(42)
  • 机器学习:逻辑回归模型算法原理(附案例实战)

    作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍 📜📜📜如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!💪 订阅专栏案

    2024年01月20日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包