Lesson 6.6 多分类评估指标的 macro 和 weighted 过程 Lesson 6.7 GridSearchCV 的进阶使用方法
文章目录
- 一、多分类评估指标的 macro 和 weighted 过程
- 1. 多分类 F1-Score 评估指标
- 2. 多分类 ROC-AUC 评估指标
- 二、借助机器学习流构建全域参数搜索空间
- 三、优化评估指标选取
- 1. 高级评估指标的选用方法
- 2. 同时输入多组评估指标
- 四、优化后建模流程
- 在正式讨论关于网格搜索的进阶使用方法之前,我们需要先补充一些关于多分类问题的评估指标计算过程。
- 在此前的内容中,我们曾经介绍过分类模型在解决多分类问题时的不同策略,同时也介绍过二分类问题的更高级评估指标,如 F1-Score 和 ROC-AUC 等。
- 接下来我们将详细讨论关于多分类预测结果在 F1-Socre 和 ROC-AUC 中的评估过程,以及 在sklearn 中如何调用函数进行计算。
# 科学计算模块
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 GridSearchCV
# 实用函数
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 数据准备
from sklearn.datasets import load_iris
一、多分类评估指标的 macro 和 weighted 过程
1. 多分类 F1-Score 评估指标
- 首先导入和 F1-Score 相关的评估指标计算函数。
from sklearn.metrics import precision_score,recall_score,f1_score
- 然后简单查看相关说明文档,发现这几组和混淆矩阵相关的评估指标基本是共用了一套参数命名,并且大多数参数其实都是作用于多分类问题,对于二分类问题,我们可以简单调用相关函数直接计算:
y_true = np.array([1, 0, 0, 1, 0, 1])
y_pred = np.array([1, 1, 0, 1, 0, 1])precision_score(y_true, y_pred), recall_score(y_true, y_pred), f1_score(y_true, y_pred)
#(0.75, 1.0, 0.8571428571428571)precision_score?
- 具体参数含义解释如下:
| Name | Description |
|---|---|
| y_true | 数据集真实标签 |
| y_pred | 标签预测结果 |
| labels | 允许以列表形式输入其他形态的标签,一般不进行修改 |
| pos_label | positive类别标签 |
| average | 多分类时指标计算方法 |
| sample_weight | 不同类别的样本权重 |
| zero_division | 当分母为0时返回结果 |
- 其中,需要重点介绍多分类问题时 average 参数不同取值时的计算方法。
- 此处以 recall 为例进行计算,重点介绍当 average 取值为 ‘macro’、‘micro’ 和 ‘weighted’ 的情况,其他指标也类似,例如有简单多分类问题如下:

- 我们令 1 类标签为 0、2 类标签为 1、3 类标签为 2,则上述数据集真实标签为:
y_true = np.array([0, 1, 2, 2, 0, 1, 1, 2, 0, 2])
- 并且最终分类预测结果为:
y_pred = np.array([0, 1, 0, 2, 2, 1, 2, 2, 0, 2])
- 据此我们可以构造多分类混淆矩阵如下:

- 据此我们可以计算三个类别的 TP 和 FN:
tp1 = 2
tp2 = 2
tp3 = 3fn1 = 1
fn2 = 1
fn3 = 1
- 接下来有两种计算 recall 的方法,其一是先计算每个类别的 recall,然后求均值:
re1 = 2/3
re2 = 2/3
re3 = 3/4np.mean([re1, re2, re3])
#0.6944444444444443
- 这也就是 average 参数取值为 macro 时的计算结果:
recall_score(y_true, y_pred, average='macro')
#0.6944444444444443
- 当然,如果上述手动实现过程不求均值,而是根据每个类别的数量进行加权求和,则就是参数 average 参数取值为 weighted 时的结果:
re1 * 3/10 + re2 * 3/10 + re3 * 4/10
#0.7recall_score(y_true, y_pred, average='weighted')
#0.7
- 当然,还有另外一种计算方法,那就是先计算整体的 TP 和 FN,然后根据整体 TP 和 FN 计算 recall:
tp = tp1 + tp2 + tp3
fn = fn1 + fn2 + fn3tp / (tp+fn)
#0.7
- 该过程也就是 average 参数取值 micro 时的计算结果:
recall_score(y_true, y_pred, average='micro')
#0.7
- 对于上述三个不同参数的选取,首先如果是样本不平衡问题(如果是要侧重训练模型判别小类样本的能力的情况下)、则应排除 weighted 参数,以避免赋予大类样本更高的权重。
- 除此以外,在大多数情况下这三个不同的参数其实并不会对最后评估器的选取结果造成太大影响,只是在很多要求严谨的场合下需要说明多分类的评估结果的计算过程,此时需要简单标注下是按照何种方法进行的计算。
- 不过,如果是混淆矩阵中相关指标和 ROC-AUC 指标放在一起讨论,由于新版 sklearn 中 ROC-AUC 本身不支持在多分类时按照 micro 计算、只支持 macro 计算,因此建议混淆矩阵的多分类计算过程也选择 macro 过程,以保持一致。
- 不过值得注意的是,还有一种观点,尽管 micro 和 macro 方法在混淆矩阵相关指标的计算过程中差别不大,在 ROC-AUC 中,macro 指标并不利于非平衡样本的计算(混淆矩阵中可以通过 positive 的类别选择来解决这一问题),需要配合 OVR 分类方法才能够有所改善。
2. 多分类 ROC-AUC 评估指标
- 接下来继续讨论关于多分类的 ROC-AUC 评估指标的相关问题:
from sklearn.metrics import roc_auc_score
- 能够发现,roc_auc_score 评估指标函数中大多数参数都和此前介绍的混淆矩阵中评估指标类似。
- 接下来我们简单尝试使用 ROC-AUC 函数进行评估指标计算,根据 ROC-AUC 的计算流程可知,此处我们需要在 y_pred 参数位中输入模型概率预测结果:
y_true = np.array([1, 0, 0, 1, 0, 1])
y_pred = np.array([0.9, 0.7, 0.2, 0.7, 0.4, 0.8])roc_auc_score(y_true, y_pred)
#0.9444444444444444
- 当然,如果我们在 y_pred 参数中输入分类结果,该函数也能计算出最终结果:
y_true = np.array([1, 0, 0, 1, 0, 1])
y_pred = np.array([1, 1, 0, 1, 0, 1])roc_auc_score(y_true, y_pred)
#0.8333333333333334
- 不过,此时模型会默认预测标签为 0 的概率结果为 0.4、预测标签为 1 的概率预测结果为 0.6,即上述结果等价于:
y_true = np.array([1, 0, 0, 1, 0, 1])
y_pred = np.array([0.6, 0.6, 0.4, 0.6, 0.4, 0.6])roc_auc_score(y_true, y_pred)
#0.8333333333333334
- 即计算过程会默认模型概率预测结果更差。
- 接下来详细解释 ROC-AUC 中其他参数:
roc_auc_score?
| Name | Description |
|---|---|
| max_fpr | fpr最大值,fpr是roc曲线的横坐标 |
| multi_class | 分类器在进行多分类时进行的多分类问题处理策略 |
- 此处需要注意的是关于 multi_class 参数的选择。
- 一般来说 sklearn 中的 multi_class 参数都是二分类器中用于解决多元分类问题时的参数(如逻辑回归)。
- 由于 ROC-AUC 需要分类结果中的概率来完成最终计算,因此需要知道概率结果对应分类标签——即到底是以 OVO 还是 OVR 模式在进行多分类,因此如果是进行多分类 ROC-AUC 计算时,需要对其进行明确说明。
- 不过对于多分类逻辑回归来说,无论是 OVR 还是 MVM 策略,最终分类结果其实都可以看成是 OVR 分类结果,因此如果是多分类逻辑回归计算 ROC-AUC ,需要设置 multi_class 参数为 OVR 。
- 同时由于根据 ROC-AUC 的函数参数说明可知,在 multi_class 参数取为 OVR 时,average 参数取值为 macro 时能够保持一个较高的偏态样本敏感性,因此对于 ROC-AUC 来说,大多数时候 average 参数建议取值为 macro。
- 总结一下,对于 ROC-AUC 进行多分类问题评估时,建议选择的参数组合是 OVR/OVO+macro,而 OVR/OVO 的参数选择需要根据具体的多分类模型来定,如果是围绕逻辑回归多分类评估器来进行结果评估,则建议 ROC-AUC 和逻辑回归评估器的 multi_class 参数都选择 OVR。
- 在新版的 sklearn 中, ROC-AUC 函数的multi_class参数已不支持 micro 参数,面对多分类问题,该参数只能够在 macro 和 weighted 中进行选择。
- 接下来我们简单测算 average 参数中 macro 和 weighted 的计算过程。还是围绕上述数据集进行计算:

- 据此我们可以计算每个类别单独的 ROC-AUC 值:
y_true_1 = np.array([1, 0, 0, 0, 1, 0, 0, 0, 1, 0])
y_pred_1 = np.array([0.8, 0.2, 0.5, 0.2, 0.3, 0.1, 0.3, 0.3, 0.9, 0.3])r1 = roc_auc_score(y_true_1, y_pred_1)
r1
#0.8809523809523809y_true_2 = np.array([0, 1, 0, 0, 0, 1, 1, 0, 0, 0])
y_pred_2 = np.array([0.2, 0.6, 0.3, 0, 0.2, 0.8, 0.2, 0.3, 0, 0.1])r2 = roc_auc_score(y_true_2, y_pred_2)
r2
#0.8571428571428571y_true_3 = np.array([0, 0, 1, 1, 0, 0, 0, 1, 0, 1])
y_pred_3 = np.array([0, 0.2, 0.2, 0.8, 0.5, 0.1, 0.5, 0.4, 0.1, 0.6])r3 = roc_auc_score(y_true_3, y_pred_3)
r3
#0.8125
- 此时 r1、r2、r3 的均值如下:
np.mean([r1, r2, r3])
#0.8501984126984127
- 该结果应当和 macro+multi_class 参数计算结果相同
y_pred = np.concatenate([y_pred_1.reshape(-1, 1), y_pred_2.reshape(-1, 1), y_pred_3.reshape(-1, 1)], 1)
y_pred
#array([[0.8, 0.2, 0. ],
# [0.2, 0.6, 0.2],
# [0.5, 0.3, 0.2],
# [0.2, 0. , 0.8],
# [0.3, 0.2, 0.5],
# [0.1, 0.8, 0.1],
# [0.3, 0.2, 0.5],
# [0.3, 0.3, 0.4],
# [0.9, 0. , 0.1],
# [0.3, 0.1, 0.6]])y_true = np.array([0, 1, 2, 2, 0, 1, 1, 2, 0, 2])roc_auc_score(y_true, y_pred, average='macro', multi_class='ovr')
#0.8501984126984127
- 当然,如果 ROC-AUC 函数的参数是 OVR+weighted,则计算结果过程验证如下:
r1 * 3/10 + r2 * 3/10 + r3 * 4/10
#0.8464285714285713roc_auc_score(y_true, y_pred, average='weighted', multi_class='ovr')
#0.8464285714285713
- 至此,我们就能够较为清楚的了解关于 F1-Score 和 ROC-AUC 评估指标在调用 sklearn 中相关函数解决多分类问题评估的具体方法。
二、借助机器学习流构建全域参数搜索空间
- 在 Lesson 6.5 中我们已经完整总结了机器学习调参的基本理论,同时介绍了 sklearn 中网格搜索(GridSearchCV)评估器的参数及基本使用方法。
- 我们将进一步介绍网格搜索的进阶使用方法,并同时补充多分类问题评估指标在 sklearn 中实现的相关方法,然后围绕 Lesson 6.4 中提出的问题给出一个基于网格搜索的解决方案。
- 首先是关于评估器全参数的设置方法。
- 在此前的实验中,我们只是保守的选取了部分我们觉得会对模型产生比较大影响的超参数来构建参数空间,但在实际场景中,调参应该是纳入所有对模型结果有影响的参数进行搜索、并且是全流程中的参数来进行搜索。
- 也就是说我们设置参数的空间的思路不应该更加“激进”一些,首先是对逻辑回归评估器来说,应该是排除无用的参数外纳入所有参数进行调参,并且就逻辑回归模型来说,往往我们需要在模型训练前进行特征衍生以增强模型表现。
- 因此我们应该先构建一个包含多项式特征衍生的机器学习流、然后围绕这个机器学习流进行参数搜索,这才是一个更加完整的调参过程。
- 首先,仿造 Lesson 6.4 中展示过程创造数据集如下:
np.random.seed(24)
X = np.random.normal(0, 1, size=(1000, 2))
y = np.array(X[:,0]+X[:, 1]**2 < 1.5, int)np.random.seed(24)
for i in range(200):y[np.random.randint(1000)] = 1y[np.random.randint(1000)] = 0plt.scatter(X[:, 0], X[:, 1], c=y)

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, random_state = 42)
- 然后开始构造机器学习流。
# 构造机器学习流
pipe = make_pipeline(PolynomialFeatures(), StandardScaler(), LogisticRegression(max_iter=int(1e6)))# 查看参数
pipe.get_params()# 构造参数空间
param_grid = [{'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['l1'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__solver': ['saga']}, {'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['l2'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__solver': ['lbfgs', 'newton-cg', 'sag', 'saga']},{'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['elasticnet'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__l1_ratio': np.arange(0.1, 1, 0.1).tolist(), 'logisticregression__solver': ['saga']}
]
三、优化评估指标选取
1. 高级评估指标的选用方法
- 根据此前介绍,如果需要更好的验证模型本身泛化能力,建议使用 F1-Score 或者 ROC-AUC,当然调整网格搜索过程的模型评估指标过程其实并不难理解,核心就是修改 scoring 参数取值。
- 但由于涉及到在参数中调用评估函数,因此需要补充一些关于常用分类评估指标在 sklearn 中的函数使用方法,以及不同评估指标函数在不同参数取值时在网格搜索评估器中的调用方法。
GridSearchCV?
- 从评估器的说明文档中能够看出,scoring 参数最基础的情况下可以选择输入 str(字符串)或者 callable(可调用)对象,也就是可以输入指代某个评估过程的字符串(一个字符串代表不同参数取值下的某评估函数),或者直接输入某评估指标函数(或者通过 make_score 函数创建的函数),来进行模型结果的评估。
- 当然,也可以在该参数位上直接输入一个字典或者 list,其中,如果是字典的话字典的 value 需要是 str(字符串)或者 callable(可调用)对象。
- 由于 sklearn 中的评估指标函数一般都是有多个不同参数,而不同参数代表不同的计算过程,因此这些评估指标函数作为参数输入网格搜索评估器中的时候,必须通过“某种方式”确定这些参数取值.
- 因此就有了如下方法,即通过字符串对应表来查看不同字符串所代表的不同参数取值下的评估指标函数,如下所示:

- 不难看出,在网格搜索中输出评估指标参数,和调用评估指标函数进行数据处理还是有很大的区别。
- 例如,
metrics.roc_auc_score函数能够同时处理多分类问题和二分类问题,但如果作为参数输入到网格搜索中,roc_auc参数只能指代metrics.roc_auc_score函数的二分类功能. - 如果需要进行多分类,则需要在 scoring 参数中输入
roc_auc_ovr、roc_auc_ovo或者roc_auc_ovr_weighted、roc_auc_ovo_weighted。 - 我们先简单尝试在 scoring 中输入字符串的基本操作,然后在深入解释 ROC-AUC 评估指标的使用方法。
- 同时,该参数列表也可以通过如下方式获得:
import sklearn
sorted(sklearn.metrics.SCORERS.keys())from sklearn.metrics import roc_auc_scoreroc_auc_score?
- 例如字符串 roc_auc_ovr 就代表 roc_auc_score 函数中 multi_class 参数取值为 ovr 时的计算流程。
- 也就是说,当网格搜索的 scoring 参数取值为字符串 roc_auc_ovr 时,就代表调用了 multi_class=`ovr`、而其他参数选用默认参数的 roc_auc_score 函数作为模型评估函数。
GridSearchCV(estimator=pipe,param_grid=param_grid,scoring='roc_auc_ovr')
- 当然,scoring 参数还支持直接输入可调用对象,即支持输入经过 make_scorer 函数转化之后的评估指标函数:
from sklearn.metrics import make_scoreracc = make_scorer(roc_auc_score)GridSearchCV(estimator=pipe,param_grid=param_grid,scoring=acc)
- 但此时我们无法修改评估指标函数的默认参数。
- 值得注意的是,此处 make_scorer 函数实际上会将一个简单的评估指标函数转化为评估器结果评估函数。
- 对于评估指标函数来说,只需要输入标签的预测值和真实值即可进行计算,例如:
accuracy_score([1, 1, 0], [1, 1, 1])
#0.6666666666666666
- 而评估器结果评估函数,则需要同时输入评估器、特征矩阵以及对应的真实标签,其执行过程是先将特征矩阵输入评估器、然后将输出结果和真实标签进行对比:
acc = make_scorer(accuracy_score)acc(search.best_estimator_, X_train, y_train)
#0.9732142857142857search.score(X_train, y_train)
#0.9732142857142857
- 而在网格搜索或者交叉验证评估器中,只支持输入经过 make_scorer 转化后的评估指标函数。
2. 同时输入多组评估指标
- 当然,有的时候我们可能需要同时看不同参数下多项评估指标的结果,此时我们就可以在 scoring 中输入列表、元组或者字典,当然字典对象会较为常用。
- 例如如果我们需要同时选用 roc-auc 和 accuracy 作为模型评估指标,则需要创建如下字典:
scoring = {'AUC': 'roc_auc', 'Accuracy': make_scorer(accuracy_score)}
- 然后将其作为参数传入网格搜索评估器内:
GridSearchCV?search = GridSearchCV(estimator=clf,param_grid=param_grid_simple, scoring=scoring, refit='Accuracy')
- 当然,roc-auc 指标也可以用 make_score 来传输,accuracy 也可以用字符串形式来传输,即来上述多评估指标的字典等价于:
{'AUC': make_scorer(roc_auc_score), 'Accuracy': 'accuracy'}
#{'AUC': make_scorer(roc_auc_score), 'Accuracy': 'accuracy'}
- 不过,需要注意的是,尽管此时网格搜索评估器将同时计算一组参数下的多个评估指标结果并输出,但我们只能选取其中一个评估指标作为挑选超参数的依据,而其他指标尽管仍然会计算,但结果只作参考。
- 而 refit 参数中输入的评估指标,就是最终选择参数的评估指标
- 尽管网格搜索支持依据不同的评估指标进行参数搜索,但最终选择何种参数,可以参考如下依据:
- 有明确模型评估指标的
- 在很多竞赛或者项目算法验收环节,可能都会存在较为明确的模型评估指标,例如模型排名根据 f1-score 计算结果得出等。在该情况下,应当尽量选择要求的评估指标。
- 没有明确模型评估指标的
- 但是,如果没有明确的评估指标要求,则选择评估指标最核心的依据就是尽可能提升/确保模型的泛化能力。
- 此时,根据 Lesson 5 中对各评估指标的讨论结果,如果数据集的各类别并没有明确的差异,在算力允许的情况下,应当优先考虑 roc-auc。
- 而如果希望重点提升模型对类别 1(或者某类别)的识别能力,则可以优先考虑 f1-score 作为模型评估指标。
四、优化后建模流程
- 接下来,依据上述优化后的过程,来执行网格搜索。完整流程如下:
- (1) 构造机器学习流
#构造机器学习流
pipe = make_pipeline(PolynomialFeatures(), StandardScaler(), LogisticRegression(max_iter=int(1e6)))
- (2) 构造包含多个评估器的机器学习流的参数空间
# 构造参数空间
param_grid = [{'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['l1'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__solver': ['saga']}, {'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['l2'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__solver': ['lbfgs', 'newton-cg', 'sag', 'saga']},{'polynomialfeatures__degree': np.arange(2, 10).tolist(), 'logisticregression__penalty': ['elasticnet'], 'logisticregression__C': np.arange(0.1, 2, 0.1).tolist(), 'logisticregression__l1_ratio': np.arange(0.1, 1, 0.1).tolist(), 'logisticregression__solver': ['saga']}
]
- (3) 实例化网格搜索评估器
- 考虑到实际参数空间较大,网格搜索需要耗费较长时间,此处使用单一指标 roc 作为参数选取指标进行搜索:
search = GridSearchCV(estimator=pipe,param_grid=param_grid, scoring='roc_auc', n_jobs=5)
- (4) 执行训练
search.fit(X_train, y_train)
- (5) 查看结果
search.best_score_
#0.7879905483853072search.best_params_
#{'logisticregression__C': 0.2,
# 'logisticregression__penalty': 'l1',
# 'logisticregression__solver': 'saga',
# 'polynomialfeatures__degree': 3}
- 需要注意的是,上述 best_score_ 属性查看的结果是在 roc-auc 评估指标下,默认五折交叉验证时验证集上的 roc-auc 的平均值。
- 但如果我们对训练好的评估器使用 .socre 方法,查看的仍然是 pipe 评估器默认的结果评估方式,也就是准确率计算结果:
search.best_estimator_.score(X_train,y_train)
#0.7857142857142857search.best_estimator_.score(X_test,y_test)
#0.7866666666666666
- 验证准确率计算结果:
accuracy_score(search.best_estimator_.predict(X_train), y_train)
#0.7857142857142857accuracy_score(search.best_estimator_.predict(X_test), y_test)
#0.7866666666666666
- (6) 结果分析
- 最终模型结果准确率在 78% 上下。当然,如果只看模型准确率结果,我们发现该结果相比 Lesson 6.4 中结果较差(Lesson 6.4 中测试集最高得分达到 0.8)。
- 但是,该模型相比 Lesson 6.4 中模型来看,该模型基本没有过拟合隐患(测试集分数甚至高于训练集),因此该模型在未来的使用过程中更有可能能够确保一个稳定的预测输出结果(泛化能力更强)。这也是交叉验证和 roc-auc 共同作用的结果。
- 当然,如果有明确要求根据准确率判断模型效果,则上述过程应该选择准确率,同时如果算力允许,也可以近一步扩大搜索空间(Lesson 6.4 中 0.8 的准确率就是在 15 阶多项式特征衍生基础上进行的运算)。
- 至此,我们就完成了在实验数据上的建模调优。
相关文章:
Lesson 6.6 多分类评估指标的 macro 和 weighted 过程 Lesson 6.7 GridSearchCV 的进阶使用方法
文章目录一、多分类评估指标的 macro 和 weighted 过程1. 多分类 F1-Score 评估指标2. 多分类 ROC-AUC 评估指标二、借助机器学习流构建全域参数搜索空间三、优化评估指标选取1. 高级评估指标的选用方法2. 同时输入多组评估指标四、优化后建模流程在正式讨论关于网格搜索的进阶…...
基于 Python 实时图像获取及处理软件图像获取;图像处理;人脸识别设计 计算机毕设 附完整代码+论文 +报告
界面结果:图像获取;图像处理;人脸识别 程序结构设计 图形用户界面设计与程序结构设计是互为表里的。或者说,程序结构设计是软件设计最本质、最核心的内容。徒有界面而内部逻辑结构混乱的软件一无是处。 Windows 操作系统是一款图形化的操作系统,相比于早期的计算机使用的命…...
前后端RSA互相加解密、加签验签、密钥对生成(Java)
目录一、序言二、关于PKCS#1和PKCS#8格式密钥1、简介2、区别二、关于JSEncrypt三、关于jsrsasign四、前端RSA加解密、加验签示例1、相关依赖2、cryptoUtils工具类封装3、测试用例五、Java后端RSA加解密、加验签1、CryptoUtils工具类封装2、测试用例六、前后端加解密、加验签交互…...
基于Java+SpringBoot+Vue前后端分离学生宿舍管理系统设计与实现
博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建、毕业项目实战、项目定制✌ 博主作品:《微服务实战》专栏是本人的实战经验总结,《S…...
前端高频面试题—JavaScript篇(二)
💻前端高频面试题—JavaScript篇(二) 🏠专栏:前端面试题 👀个人主页:繁星学编程🍁 🧑个人简介:一个不断提高自我的平凡人🚀 🔊分享方向…...
【微信小游戏开发笔记】第二节:Cocos开发界面常用功能简介
Cocos开发界面常用功能简介 本章只介绍微信小游戏开发时常用的功能,其他功能不常用,写多了记不住(其实是懒 -_-!): 层级管理器,用于操作各个节点。资源管理器,用于操作各种文件资源。场景编辑…...
3分钟,学会了一个调试CSS的小妙招
Ⅰ. 作用 用于调试CSS , 比控制台添更加方便,不需要寻找 ;边添加样式,边可以查看效果,适合初学者对CSS 的理解和学习; Ⅱ. 快速实现(两边) ① 显示这个样式眶 给 head 和 style 标签添加一个…...
【项目精选】基于jsp的健身俱乐部会员系统
点击下载源码 社会可行性 随着社会的发展和计算机技术的进步,人类越来越依赖于信息化的管理系统,这种系统能更加方便的获得信息以及处理信息。人们都改变了过去的思维,开始走向了互联网的时代,在 可行性小结 本章在技术可行性上…...
java注解
1. Java注解(Annotation) 2. Java注解分类 3. JDK基本注解 4. JDK元注解 5. 注解分类 6. 自定义注解开发 7. 提取Annotation信息 8. 注解处理器 9. 动态注解处理器(spring aop方式) 1. Java注解(Annotation) Java注解是附加在代码中的一些元信息,用于…...
移动测试相关
一、环境搭建 准备工作: (python、pycharm安装配置好) 1、Java SDK 安装配置 Java Downloads | Oracle 下载安装后配置系统环境变量:JAVA_HOME(jdk根目录路径)和path(jdk根目录下的bin目录路径…...
SIGIR22:User-controllable Recommendation Against Filter Bubbles
User-controllable Recommendation Against Filter Bubbles 摘要 推荐系统经常面临过滤气泡的问题:过度推荐基于用户特征以及历史交互的同质化项目。过滤气泡将会随着反馈循环增长,缩小了用户兴趣。现有的工作通常通过纳入诸如多样性和公平性等准确性之…...
Python中的进程线程
文章目录前言多进程与多线程基本概念多进程multiprocessing 类对象进程池subprocess模块进程间通信多线程threading实现线程操作线程共享所有变量线程锁参考资料前言 又花了点时间学习了一下Python中的多线程与多进程的知识点,梳理一下供复习参考 多进程与多线程 …...
python(8):使用conda update更新conda后,anaconda所有环境崩溃----问题没有解决,不要轻易更新conda
文章目录0. 教训1. 问题:使用conda update更新conda后,anaconda所有环境崩溃1.1 问题描述1.2 我搜索到的全网最相关的问题----也没有解决3 尝试流程记录3.1 重新安装pip3.2 解决anaconda编译问题----没成功0. 教训 (1) 不要轻易使用conda update更新conda----我遇到…...
c++11 标准模板(STL)(std::multimap)(四)
定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...
乐观锁及悲观锁
目录 1.乐观锁 (1).定义 (2).大体流程 (3).实现 (4).总结 2.悲观锁 (1).定义 (2).大体流程 (3).实现 (4).缺点 (5).总结 1.乐观锁 (1).定义 乐观锁在操作数据时非常乐观,认为别的线程不会同时修改数据所以不会上锁,但是在更新的时候会判断一…...
常见的锁策略
注意: 接下来讲解的锁策略不仅仅是局限于 Java . 任何和 "锁" 相关的话题, 都可能会涉及到以下内容. 这些特性主要是给锁的实现者来参考的.普通的程序猿也需要了解一些, 对于合理的使用锁也是有很大帮助的. 1.乐观锁 vs 悲观锁 悲观锁: (认为出现锁冲…...
springboot学习(八十) springboot中使用Log4j2记录分布式链路日志
在分布式环境中一般统一收集日志,但是在并发大时不好定位问题,大量的日志导致无法找出日志的链路关系。 可以为每一个请求分配一个traceId,记录日志时,记录此traceId,从网关开始,依次将traceId记录到请求头…...
10种ADC软件滤波方法及程序
10种ADC软件滤波方法及程序一、10种ADC软件滤波方法1、限幅滤波法(又称程序判断滤波法)2、中位值滤波法3、算术平均滤波法4、递推平均滤波法(又称滑动平均滤波法)5、中位值平均滤波法(又称防脉冲干扰平均滤波法&#x…...
第五章:Windows server加域
加入AD域:教学视频:https://www.bilibili.com/video/BV1xM4y1D7oL/?spm_id_from333.999.0.0首先我们选择一个干净的,也就是新建的没动过的Windows server虚拟机。我们将DNS改成域的ip地址,还要保证它们之间能ping的通,…...
Elasticsearch:获取 nested 类型数组中的所有元素
在我之前的文章 “Elasticsearch: object 及 nested 数据类型” 对 nested 数据类型做了一个比较详细的介绍。在实际使用中,你在构建查询时肯定会遇到一些问题。根据官方文档介绍,nested 类型字段在隐藏数组中索引其每个项目,这允许独立于索引…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...
