Lesson 6.5 机器学习调参基础理论与网格搜索

news2024/11/24 4:55:57

文章目录

  • 一、机器学习调参理论基础
    • 1. 机器学习调参目标及基本方法
    • 2. 基于网格搜索的超参数的调整方法
      • 2.1 参数空间
      • 2.2 交叉验证与评估指标
  • 二、基于 Scikit-Learn 的网格搜索调参
    • 1. sklearn 中网格搜索的基本说明
    • 2. sklearn 中 GridSearchCV 的参数解释
    • 3. sklearn 中 GridSearchCV 的使用方法
      • 3.1 GridSearchCV 评估器训练过程
      • 3.2 GridSearchCV 评估器结果查看

  • 在上一小节执行完手动调参之后,接下来我们重点讨论关于机器学习调参的理论基础,并且介绍 sklearn 中调参的核心工具—— GridSearchCV。
# 科学计算模块
import numpy as np
import pandas as pd
​
# 绘图模块
import matplotlib as mpl
import matplotlib.pyplot as plt
​
# 自定义模块
from ML_basic_function import *# Scikit-Learn相关模块
# 评估器类
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
​
# 实用函数
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

一、机器学习调参理论基础

  • 在利用 sklearn 进行机器学习调参之前,我们先深入探讨一些和调参相关的机器学习基础理论。
  • 尽管我们都知道,调参其实就是去寻找一组最优参数,但最优参数中的“最优”如何定义?面对模型中的众多参数又该如何“寻找”?
  • 要回答这些问题,我们就必须补充更加完整的关于机器学习中参数和调参的理论知识。

1. 机器学习调参目标及基本方法

  • 首先需要明确的一点,我们针对哪一类参数进行调参,以及围绕什么目的进行调参?
  • 参数与超参数
  • 根据此前对参数的划分,我们知道,影响机器学习建模结果的参数有两类,其一是参数,其二是超参数。
  • 其中参数的数值计算由一整套数学过程决定,在选定方法后,其计算过程基本不需要人工参与。
  • 因此我们经常说的模型调参,实际上是调整模型超参数
  • 超参数种类繁多,而且无法通过一个严谨的数学流程给出最优解,因此需要人工参与进行调节。
  • 而在围绕具体的机器学习评估器进行调参时,其实就是在调整评估器实例化过程中所涉及到的那些超参数,例如此前进行逻辑回归参数解释时的超参数。
  • 当然,这也是我们为什么需要对评估器进行如此详细的超参数的解释的原因之一。
参数解释
penalty正则化项
dual是否求解对偶问题*
tol迭代停止条件:两轮迭代损失值差值小于tol时,停止迭代
C经验风险和结构风险在损失函数中的权重
fit_intercept线性方程中是否包含截距项
intercept_scaling相当于此前讨论的特征最后一列全为1的列,当使用liblinear求解参数时用于捕获截距
class_weight各类样本权重*
random_state随机数种子
solver损失函数求解方法*
max_iter求解参数时最大迭代次数,迭代过程满足max_iter或tol其一即停止迭代
multi_class多分类问题时求解方法*
verbose是否输出任务进程
warm_start是否使用上次训练结果作为本次运行初始参数
l1_ratio当采用弹性网正则化时, l 1 l1 l1正则项权重,就是损失函数中的 ρ \rho ρ
  • 超参数调整目标
  • 那么紧接着的问题就是,超参数的调整目标是什么?是提升模型测试集的预测效果么?
  • 无论是机器学习还是统计模型,只要是进行预测的模型,其实核心的建模目标都是为了更好的进行预测,也就是希望模型能够有更好的预测未来的能力,换而言之,就是希望模型能够有更强的泛化能力。
  • 而在 Lesson 3 中我们曾谈到,机器学习类算法的可信度来源则是训练集和测试集的划分理论,也就是机器学习会认为,只要能够在模拟真实情况的测试集上表现良好,模型就能够具备良好的泛化能力。
  • 也就是说,超参数调整的核心目的是为了提升模型的泛化能力,而测试集上的预测效果只是模型泛化能力的一个具体表现,并且相比与一次测试集上的运行结果,其实借助交叉验证,能够提供更有效、更可靠的模型泛化能力的证明。
  • 交叉验证与评估指标
  • 如果需要获得更可靠的模型泛化能力的证明,则需要进行交叉验证,通过多轮的验证,来获得模型的更为一般、同时也更为准确的运行结果。当然,我们还需要谨慎的选择一个合适的评估指标对其进行结果评估。
  • 如何提升模型泛化能力
  • 如果拥有了一个更加可信的、用于验证模型是否具有泛化能力的评估方式之后,那么接下来的问题就是,我们应该如何提升模型泛化能力呢?
  • 当然,这其实是一个很大的问题,我们可以通过更好的选择模型(甚至是模型创新)、更好的特征工程、更好的模型训练等方法来提高模型泛化能力,而此处我们将要介绍的,是围绕某个具体的模型、通过更好的选择模型中的超参数,来提高模型的泛化能力。
  • 不过正如此前所说,超参数无法通过一个严谨的数学流程给出最优解,因此超参数的选择其实是经验 + 一定范围内枚举(也就是网格搜索)的方法来决定的。
  • 这个过程虽然看起来不是那么的 cooooool,但确实目前机器学习超参数选择的通用方式,并且当我们深入进行了解之后就会发现,尽管是经验 + 枚举,但经验的积累和枚举技术的掌握,其实也是机器学习水平的一种重要证明。

2. 基于网格搜索的超参数的调整方法

  • 在了解机器学习中调参的基础理论之后,接下来我们考虑一个更加具体的调参流程。
  • 实际上,尽管对于机器学习来说超参数众多,但能够对模型的建模结果产生决定性影响的超参数却不多,对于大多数超参数,我们都主要采用“经验结合实际”的方式来决定超参数的取值,如数据集划分比例、交叉验证的折数等等。
  • 而对于一些如正则化系数、特征衍生阶数等,则需要采用一个流程来对其进行调节。而这个流程,一般来说就是进行搜索与枚举,或者也被称为网格搜索(gridsearch)。
  • 所谓搜索与枚举,指的是将备选的参数一一列出,多个不同参数的不同取值最终将组成一个参数空间(parameter space),在这个参数空间中选取不同的值带入模型进行训练,最终选取一组最优的值作为模型的最终超参数。
  • 当然,正如前面所讨论的,此处“最优”的超参数,应该是那些尽可能让模型泛化能力更好的参数。
  • 在这个过程中,有两个核心问题需要注意,其一是参数空间的构成,其二是选取能够代表模型泛化能力的评估指标。接下来我们对其进行逐个讨论。

2.1 参数空间

  • 参数空间的定义
  • 所谓参数空间,其实就是我们挑选出来的、接下来需要通过枚举和搜索来进行数值确定的参数取值范围所构成的空间。
  • 例如对于逻辑回归模型来说,如果选择 penalty 参数和 C 来进行搜索调参,则这两个参数就是参数空间的不同维度,而这两个参数的不同取值就是这个参数空间中的一系列点。
  • 例如 (penalty=‘l1’, C=1)、(penalty=‘l1’, C=0.9)、(penalty=‘l2’, C=0.8) 等等,就是这个参数空间内的一系列点,接下来我们就需要从中挑选组一个最优组合。
  • 参数空间构造思路
  • 那么我们需要带入那些参数去构造这个参数空间呢?也就是我们需要选择那些参数进行调参呢?
  • 调参的目的是为了提升模型的泛化能力,而保证泛化能力的核心是同时控制模型的经验风险和结构风险(既不让模型过拟合也不让模型前拟合)。
  • 因此,对于逻辑回归来说,我们需要同时带入能够让模型拟合度增加、同时又能抑制模型过拟合倾向的参数来构造参数空间,即需要带入特征衍生的相关参数、以及正则化的相关参数。
  • 一个建模流程中的特征衍生的相关参数,也是可以带入同一个参数空间进行搜索的。

2.2 交叉验证与评估指标

  • 实际的超参数的搜索过程和我们上面讨论的模型结构风险一节中的参数选取过程略有不同,此前我们的过程是:先在训练集中训练模型,然后计算训练误差和泛化误差,通过二者误差的比较来观察模型是过拟合还是欠拟合(即评估模型泛化能力),然后再决定这些超参数应该如何调整。
  • 而在一个更加严谨的过程中,我们需要将上述“通过对比训练误差和测试误差的差异,来判断过拟合还是欠拟合”的这个偏向主观的过程变成一个更加客观的过程,即我们需要找到一个能够基于目前模型建模结果的、能代表模型泛化能力的评估指标。
  • 这即是模型建模流程更加严谨的需要,同时也是让测试集回归其本来定位的需要。
  • 评估指标选取
  • 而这个评估指标,对于分类模型来说,一般来说就是 ROC-AUC 或 F1-Score,并且是基于交叉验证之后的指标。
  • 我们通常会选取 ROC-AUC 或 F1-Score,其实也是因为这两个指标的敏感度要强于准确率(详见Lesson 5 中的讨论),并且如果需要重点识别模型识别 1 类的能力,则可考虑 F1-Score,其他时候更推荐使用 ROC-AUC。
  • 交叉验证过程
  • 而为何要进行交叉验证,则主要原因是超参数的调整也需要同时兼顾模型的结构风险和经验风险,而能够表示模型结构风险的,就是不带入模型训练、但是能够对模型建模结果进行评估并且指导模型进行调整的验证集上的评估结果。
  • 上述过程可以具体表示成如下步骤:
  • (1) 在训练集中进行验证集划分(几折待定);
  • (2) 带入训练集进行建模、带入验证集进行验证,并输出验证集上的模型评估指标;
  • (3) 计算多组验证集上的评估指标的均值,作为该超参数下模型最终表现。
  • 因此,在大多数情况下,网格搜索(gridsearch)都是和交叉验证(CV)同时出现的,这也是为什么 sklearn 中执行网格搜索的类名称为 GridSearchCV 的原因。
  • 另外需要强调的一点是,由于交叉验证的存在,此时测试集的作用就变成了验证网格搜索是否有效,而非去验证模型是否有效(此时模型是否有效由验证集来验证)。
  • 由于此时我们提交给测试集进行测试的,都是经过交叉验证挑选出来的最好的一组参数、或者说至少是在验证集上效果不错的参数(往往也是评估指标比较高的参数)。
  • 而此时如果模型在测试集上运行效果不好、或者说在测试集上评估指标表现不佳,则说明模型仍然还是过拟合,之前执行的网格搜索过程并没有很好的控制住模型的结构风险,据此我们需要调整此前的调参策略,如调整参数空间、或者更改交叉验证策略等。
  • 当然,如果是对网格搜索的过程比较自信,也可以不划分测试集,直接带入全部数据进行模型训练。

二、基于 Scikit-Learn 的网格搜索调参

  • 在了解机器学习调参基础理论之后,接下来我们来借助 sklearn 中的相关工具,来执行更加高效的调参工作。

1. sklearn 中网格搜索的基本说明

  • 由于网格搜索确定超参数的过程实际上帮助进行模型筛选,因此我们可以在 sklearn 的 model_selection 模块查找相关内容。
  • 要学习 sklearn 中的网格搜索相关功能,最好还是从查阅官网的说明文档开始,我们可以在 sklearn 的 User Guide 的 3.2 节中我们能看到关于网格搜索的相关内容。
  • 首先介绍官网给出的相关说明:

在这里插入图片描述

  • 该说明文档开宗明义的介绍了网格搜索根本目的是为了调整超参数(Hyper-parameters),也就是评估器(estimators)中的参数,每个评估器中的参数可以通过 .get_params() 的方法来查看,并且建议配合交叉验证来执行。
  • 同时,该说明文档重点指出了网格搜索中的核心要素,分别是:评估器、参数空间、搜索策略、交叉验证以及评估指标。
  • 其中参数空间、交叉验证以及评估指标我们都在此前介绍过了,而根据下文的介绍,sklearn 中实际上是集成了两种不同的进行参数搜索的方法,分别是 GridSearchCVRandomizedSearchCV

在这里插入图片描述

  • 尽管都是进行网格搜索,但两种方法还是各有不同,GridSearchCV 会尝试参数空间内的所有组合,而 RandomizedSearchCV 则会先进行采样再来进行搜索,即对某个参数空间的某个随机子集进行搜索。
  • 并且上文重点强调,这两种方法都支持先两两比对、然后逐层筛选的方法来进行参数筛选,即 HalvingGridSearchCV 和 HalvingRandomSearchCV方 法。
  • 当然,说明文档中也再次强调,由于 sklearn 的评估器中集成了非常多的参数,而并非所有参数都对最终建模结果有显著影响,因此为了不增加网格搜索过程计算量,推荐谨慎的构造参数空间,部分参数仍然以默认参数为主。
  • 在介绍完基本说明文档后,接下来我们尝试调用sklearn中集成的相关方法来进行建模试验。

2. sklearn 中 GridSearchCV 的参数解释

  • 接下来我们详细介绍 GridSearchCV 的相关参数,我们知道该方法的搜索策略是“全搜索”,即对参数空间内的所有参数进行搜索,该方法在 model_selection 模块下,同样也是以评估器形式存在,我们可以通过如下方式进行导入:
from sklearn.model_selection import GridSearchCV
  • 不难发现该评估器的参数主体就是此前介绍的评估器、参数空间、交叉验证以及评估指标,我们对该评估器的完整参数进行解释:
GridSearchCV?
NameDescription
estimator调参对象,某评估器
param_grid参数空间,可以是字典或者字典构成的列表,稍后介绍参数空间的创建方法
scoring评估指标,支持同时输出多个参数
n_jobs设置工作时参与计算的CPU核数
iid交叉验证时各折数据是否独立,该参数已在0.22版中停用,将在0.24版中弃用,此处不做介绍
refit挑选评估指标和最佳参数,在完整数据集上进行训练
cv交叉验证的折数
verbose输出工作日志形式
pre_dispatch多任务并行时任务划分数量
error_score当网格搜索报错时返回结果,选择’raise’时将直接报错并中断训练过程,其他情况会显示警告信息后继续完成训练
return_train_score在交叉验证中是否显示训练集中参数得分
  • 整体来看,上面的主要参数分为三类,分别是核心参数、评估参数和性能参数。
  • 核心参数
  • 所谓性能参数,也就是涉及评估器训练(fit)的最核心参数,也就是 estimator 参数和 param_grid 参数,同时也是实例化评估器过程中最重要的参数。
  • 评估参数
  • 所谓评估参数,指的是涉及到不同参数训练结果评估过程方式的参数,主要是 scoring、refit 和 cv三个参数。
  • 当然这三个参数都不是必要参数,但这三个参数却是直接决定模型结果评估过程、并且对最终模型参数选择和模型泛化能力提升直观重要的三个参数。
  • 这三个参数各自都有一个默认值,我们先解释在默认值情况下这三个参数的运作方式,然后在下一个应用阶段讨论如何对这三个参数进行修改。
  • 首先是关于 scoring 参数的选取,scoring 表示选取哪一项评估指标来对模型结果进行评估。
  • 而根据参数说明文档我们知道,在默认情况下 scoring 的评估指标就是评估器的 .score 方法默认的评估指标,对于逻辑回归来说也就是准确率。
  • 也就是说在默认情况下如果是围绕逻辑回归进行网格搜索,则默认评估指标是准确率。
  • 此外,scoring 参数还支持直接输入可调用对象(评估函数)、代表评估函数运行方式的字符串、字典或者 list。
  • 而 refit 参数则表示选择一个用于评估最佳模型的评估指标,然后在最佳参数的情况下整个训练集上进行对应评估指标的计算。
  • 而 cv 则是关于交叉验证的相关参数,默认情况下进行 5 折交叉验证,并同时支持自定义折数的交叉验证、输入交叉验证评估器的交叉验证、以及根据指定方法进行交叉验证等方法。当然此组参数有非常多的设计方法,我们将在下一个应用阶段进行进一步的详解。
  • 性能参数
  • 第三组则是关于网格搜索执行性能相关的性能参数,主要包括 n_jobs 和 pre_dispatch 参数两个,用于规定调用的核心数和一个任务按照何种方式进行并行运算。
  • 在网格搜索中,由于无需根据此前结果来确定后续计算方法,所以可以并行计算。
  • 在默认情况下并行任务的划分数量和 n_jobs 相同。当然,这组参数的合理设置能够一定程度提高模型网格搜索效率。
  • 但如果需要大幅提高执行速度,建议使用 RandomizedSearchCV、或者使用 Halving 方法来进行加速。

3. sklearn 中 GridSearchCV 的使用方法

  • 在了解了 GridSearchCV 的基本方法之后,接下来我们以逻辑回归在鸢尾花数据集上建模为例,来尝试使用 GridSearchCV 方法进行网格调参,并同时介绍网格搜索的一般流程:

3.1 GridSearchCV 评估器训练过程

  • Step 1. 创建评估器
  • 首先我们还是需要实例化一个评估器,这里可以是一个模型、也可以是一个机器学习流,网格搜索都可以对其进行调参。此处我们先从简单入手,尝试实例化逻辑回归模型并对其进行调参。
# 数据导入
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=24)

clf = LogisticRegression(max_iter=int(1e6), solver='saga')
  • 此处将 solver 设置成 saga,也是为了方便后续同时比较 l 1 l1 l1 正则化和 l 2 l2 l2 正则化时无需更换求解器。
clf.get_params()
#{'C': 1.0,
# 'class_weight': None,
# 'dual': False,
# 'fit_intercept': True,
# 'intercept_scaling': 1,
# 'l1_ratio': None,
# 'max_iter': 1000000,
# 'multi_class': 'auto',
# 'n_jobs': None,
# 'penalty': 'l2',
# 'random_state': None,
# 'solver': 'saga',
# 'tol': 0.0001,
# 'verbose': 0,
# 'warm_start': False}
  • Step 2. 创建参数空间
  • 接下来,我们就需要挑选评估器中的超参数构造参数空间。
  • 这里需要注意的是,我们需要挑选能够控制模型拟合度的超参数来进行参数空间的构造,例如挑选类似 verbose、n_jobs 等此类参数构造参数是毫无意义的。
  • 此处我们挑选 penalty 和 C 这两个参数来进行参数空间的构造。
  • 参数空间首先可以是一个字典:
param_grid_simple = {'penalty': ['l1', 'l2'],
                     'C': [1, 0.5, 0.1, 0.05, 0.01]}
  • 其中,字典的 Key 用参数的字符串来代表不同的参数,对应的 Value 则用列表来表示对应参数不同的取值范围。
  • 也就是字典的 Key 是参数空间的维度,而 Value 则是不同纬度上可选的取值。而后续的网格搜索则是在上述参数的不同组合中挑选出一组最优的参数取值。
  • 当然,由于如此构造方法,此处自然会衍生出一个新的问题,那就是如果某个维度的参数取值对应一组新的参数,应该如何处理?
  • 例如,对于逻辑回归来说,如果 penalty 参数中选择弹性网参数,则会衍生出一个新的参数 l1_ratio,如果我们还想考虑 penalty 参数选取 elasticnet 参数,并且同时评估 l1_ratio 取不同值时模型效果,则无法将上述参数封装在一个参数空间内。
  • 因为当 penalty 取其他值时 l1_ratio 并不存在。为了解决这个问题,我们可以创造多个参数空间(字典),然后将其封装在一个列表中,而该列表则表示多个参数空间的集成。
  • 例如上述问题可以进行如下表示:
param_grid_ra = [
    {'penalty': ['l1', 'l2'], 'C': [1, 0.5, 0.1, 0.05, 0.01]}, 
    {'penalty': ['elasticnet'], 'C': [1, 0.5, 0.1, 0.05, 0.01], 'l1_ratio': [0.3, 0.6, 0.9]}
]
  • 即可表示网格搜索在 l1+1、l1+0.5…空间与 elasticnet+1+0.3、elasticnet+1+0.6…空间同时进行搜索。
  • Step 3. 实例化网格搜索评估器
  • 和 sklearn 中其他所有评估器一样,网格搜索的评估器的使用也是先实例化然后进行对其进行训练。
  • 此处先实例化一个简单的网格搜索评估器,需要输入此前设置的评估器和参数空间。
search = GridSearchCV(estimator=clf,
                      param_grid=param_grid_simple)
  • Step 4. 训练网格搜索评估器
  • 同样,我们通过fit方法即可完成评估器的训练。
search.fit(X_train, y_train)
#GridSearchCV(estimator=LogisticRegression(max_iter=1000000, solver='saga'),
#             param_grid={'C': [1, 0.5, 0.1, 0.05, 0.01],
#                         'penalty': ['l1', 'l2']})
  • 需要知道的是,所谓的训练网格搜索评估器,本质上是在挑选不同的参数组合进行逻辑回归模型训练,而训练完成后相关结果都保存在 search 对象的属性中。

3.2 GridSearchCV 评估器结果查看

  • 此处我们先介绍关于网格搜索类的所有属性和方法,再来查看挑选其中重要属性的结果进行解读。
NameDescription
cv_results_交叉验证过程中的重要结果
best_estimator_最终挑选出的最优
best_score_在最优参数情况下,训练集的交叉验证的平均得分
best_params_最优参数组合
best_index_CV过程会对所有参数组合标号,该参数表示最优参数组合的标号
scorer在最优参数下,计算模型得分的方法
n_splits_交叉验证的折数
  • best_estimator_:训练完成后的最佳评估器
  • 实际上返回的就是带有网格搜索挑选出来的最佳参数(超参数)的评估器。
search.best_estimator_
#LogisticRegression(C=1, max_iter=1000000, penalty='l1', solver='saga')
  • 上述评估器就相当于一个包含最佳参数的逻辑回归评估器,可以调用逻辑回归评估器的所有属性:
# 查看参数
search.best_estimator_.coef_
#array([[ 0.        ,  0.        , -3.47349066,  0.        ],
#       [ 0.        ,  0.        ,  0.        ,  0.        ],
#       [-0.55506614, -0.34227663,  3.03238721,  4.12147362]])

# 查看训练误差、测试误差
search.best_estimator_.score(X_train,y_train), search.best_estimator_.score(X_test,y_test)
#(0.9732142857142857, 0.9736842105263158)

# 查看参数
search.best_estimator_.get_params()
#{'C': 1,
# 'class_weight': None,
# 'dual': False,
# 'fit_intercept': True,
# 'intercept_scaling': 1,
# 'l1_ratio': None,
# 'max_iter': 1000000,
# 'multi_class': 'auto',
# 'n_jobs': None,
# 'penalty': 'l1',
# 'random_state': None,
# 'solver': 'saga',
# 'tol': 0.0001,
# 'verbose': 0,
# 'warm_start': False}
  • best_score_:最优参数时交叉验证平均得分
search.best_score_
#0.9644268774703558
  • 在默认情况下(未修改网格搜索评估器中评估指标参数时),此处的 score 就是准确率。此处有两点需要注意:
  • 其一:该指标和训练集上整体准确率不同,该指标是交叉验证时验证集准确率的平均值,而不是所有数据的准确率;
  • 其二:该指标是网格搜索在进行参数挑选时的参照依据。
  • 其他属性方法测试
search.cv_results_

search.best_params_
#{'C': 1, 'penalty': 'l1'}

search.best_index_
#0

# 等价于search.best_estimator_.score
search.score(X_train,y_train), search.score(X_test,y_test)
#(0.9732142857142857, 0.9736842105263158)

search.n_splits_
#5

search.refit_time_
#0.07661604881286621
  • 至此,我们就执行了一个完整的网格搜索的调参过程。
  • 但该过程大多只使用了默认参数在小范围内进行的运算,如果我们希望更换模型评估指标、并且在一个更加完整的参数范围内进行搜索,则需要对上述过程进行修改,并更近一步掌握关于评估器中 scoring 参数和 refit 参数的相关使用方法,相关内容我们将在后续的文章当中进行详细讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

漏洞扫描器之AWVS

数据来源 01 漏洞扫描器及AWVS介绍 》漏洞扫描 》常见漏洞扫描工具 网络上公布的付费的或者免费的漏洞扫描工具、脚本多种多样。 √ 针对某类漏洞的:sql注入(sqlmap)、weblogic(weblogicscan) √ 针对某类CMS的: wordpress( wpscan)、 …

数据分析到底该怎么学呢?讲真,真不难!

这几年,“数据分析”是很火啊,在这个数据驱动一切的时代,数据挖掘和数据分析就是这个时代的“淘金”,懂数据分析、拥有数据思维,往往成了大厂面试的加分项。 比如通过数据分析,我们可以更好地了解用户画像…

CSS 重新认识 !important 肯定有你不知道的

重新认识 !important 影响级联规则 与 animation 和 transition 的关系级联层cascade layer内联样式!important 与权重 !important 与简写属性!important 与自定义变量!important 最佳实践 在开始之前, 先来规范一下文中的用于, 首先看 W3C 中关于 CSS 的一些术语定义吧. 下图…

微信小程序如何获取用户信息

自我介绍我是IT果果日记,微信公众号请搜索 IT果果日记一个普通的技术宅,定期分享技术文章,欢迎点赞、关注和转发,请多关照。微信小程序用户基本信息有哪些?除了基本信息,微信还会提供openId和unionId&#…

微服务项目简介

项目简介 项目模式 电商模式:市面上有5种常见的电商模式,B2B、B2C、 C2B、 C2C、O2O; 1、B2B模式 B2B (Business to Business),是指 商家与商家建立的商业关系。如:阿里巴巴 2、B2C 模式 B2C (Business to Consumer), 就是我们经常看到的供…

6个月软件测试培训出来后的感悟 —— 写给正在迷茫是否要转行或去学软件测试的学弟们

本人刚从某培训机构学习结束,现在已经上班一个月了。这篇文章我不会说太多的知识点,或噱人去培训机构学习的话语,仅作为一个普通打工者的身份,来写给那些对于软件测试未来发展、薪资待遇等不清楚的正在为家庭,解决信用…

2023年中国数字化活动行业专题报告

易观:2023年2月,易观发布《2023年中国数字化活动行业专题报告》。报告主要分析了中国数字化活动市场发展背景与现状,数字化活动厂商的主要商业模式及其运作模式,典型案例,未来发展趋势洞察等。同时,易观分析…

网上流量卡可靠吗,网上的这些大流量卡你知道是怎么来的吗?

网上怎么这么多五花八门的流量卡,这些大流量卡是怎么来的你都知道吗?所谓的大流量卡,是因为每个省份为了拉新用户所自行包装的产品,一般是在在基础套餐上增加了一些流量包和充值送话费活动,然后得出来一个产品套餐&…

【动态规划】01背包问题(滚动数组 + 手画图解)

01背包除了可以用形象的二维动态数组表示外,还可以使用空间复杂度更低的一维滚动数组。 目录 文章目录 前言 一、滚动数组的基本理解 二、确定dp及其下标含义 三、确定递推公式 四、确定初始化 五、确定遍历顺序 1.用物品(正序)遍历背…

【刷题篇】链表(上)

前言🌈前段时间我们学习了单向链表和双向链表,本期将带来3道与链表相关的OJ题来巩固对链表的理解。话不多说,让我们进入今天的题目吧!🚀本期的题目有:反转单链表、链表的中间结点、合并两个有序链表反转单链…

XCP实战系列介绍09-基于Vehicle Spy进行XCP测量步骤详解

本文框架 1.概述2. 基于SPY进行测量步骤2.1 建立ECU和vspy3通信2.2 DAQ数据设置2.3 测量变量的记录2.3.1 需要记录变量的选择2.3.2 Log保存3. 在MEP中观测变量3.1 添加观测变量3.2 实时更新变量的值1.概述 在介绍了ASAP2 Editor进行A2l文件的生成,及如何使用Vehicle Spy进行X…

点云深度学习系列博客(五): Point Transformer方法概述

在上一篇博客《注意力机制原理概述》中,我们介绍了注意力机制的基本原理以及一些技术细节。基于注意力机制的深度学习模型在起初设计时,针对的是NLP问题。包括词元分析,翻译等语言处理任务,注意力机制能够训练超大规模数据&#x…

活动星投票午间修身自习室制作在线投票投票制作网页

“午间修身自习室”网络评选投票_免费小程序投票推广_小程序投票平台好处手机互联网给所有人都带来不同程度的便利,而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票,对于运营及推广来说找一个合适的投票小程序能够提高工…

SpringBoot整合(三)SpringBoot发送邮件

使用SpringBoot发送邮件 邮件发送其实是一个非常常见的需求,用户注册,找回密码等地方,都会用到,Spring Boot 中对于邮件发送,提供了相关的自动化配置类,使得邮件发送变得非常容易。 1、前置工作 目前国内…

[SSD固态硬盘技术 9] FTL详解

了解硬件特性有助于我们针对特性进行进一步的探索与优化。为了使闪存成为存储数据的友好介质,我们需要一种机制:将更新的信息写入新的空页,然后将 所有后续读取请求转移到其新地址确保新编程的页面均匀分布在所有可用闪存中,以便均…

【Python入门第五天】Python 变量

创建变量 变量是存放数据值的容器。 与其他编程语言不同,Python 没有声明变量的命令。 首次为其赋值时,才会创建变量。 实例 x 10 y "Bill" print(x) print(y)运行实例 变量不需要使用任何特定类型声明,甚至可以在设置后更改…

Jupyter 使用Anaconda 虚拟环境内核

Anaconda 虚拟环境中使用Jupyter Notebook 安装好Anaconda之后,进入Anaconda Prompt,创建虚拟环境,env_name是创建的环境的名字。 conda creat -n env_name python3.9等虚拟环境搭建好之后,激活环境。 conda activate env_name…

网络流与图(一)

线性规划问题是运筹学最基本的问题,我们已经学过不少的解决方法,今天继续学习针对线性规划问题的另一种高效算法——网络流问题(network flow problem)1网络流模型为了更好介绍该算法来龙去脉,与以往一样,从…

MongoDB 删除文档

MongoDB 删除文档 MongoDB remove() 、deleteMany()、deleteOne()函数是用来移除集合中的数据。 remove()删除文档 remove() 方法的基本语法格式如下所示&#xff1a; db.collection.remove(<query>,<justOne> ) 如果你的 MongoDB 是 2.6 版本以后的&#xff0c…

filter及backdrop-filter属性详解

filter属性详解 filter 属性定义了元素(通常是<img>)的可视效果(例如&#xff1a;模糊与饱和度)。 filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia() | url();下面运用…