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 类型字段在隐藏数组中索引其每个项目,这允许独立于索引…...
English Learning - Day53 作业打卡 2023.2.7 周二
English Learning - Day53 作业打卡 2023.2.7 周二引言1. 我必须承认,我之前学习没你用功。have to VS must2. 这跟我想得一样简单。3. 生活并不像它看上去那么顺风顺水,但也不会像我们想象得那么难。Look VS seem4. 你比去年高多了。5. 你关心你的工作胜…...
SpringMVC--注解配置SpringMVC、SpringMVC执行流程
注解配置SpringMVC 使用配置类和注解代替web.xml和SpringMVC配置文件的功能 创建初始化类,代替web.xml 在Servlet3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类, 如果找到的话就用它来配置Servle…...
JavaScript中数组常用的方法
文章目录前言常用数组方法1、 join( )2、push()与 pop()3、shift()与 unshift()4、sort()5、reverse()6、slice(ÿ…...
ModuleNotFoundError: No module named ‘pip‘
项目场景:pip 错误 Traceback (most recent call last): File "E:\KaiFa\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "E:\KaiFa\Python\Python38\lib\runpy.py&qu…...
ROS2 入门应用 发布和订阅(C++)
ROS2 入门应用 发布和订阅(C)1. 创建功能包2. 创建源文件2.1. 话题发布2.2. 话题订阅3. 添加依赖关系4. 添加编译信息4.1. 添加搜索库4.2. 增加可执行文件4.3. 增加可执行文件位置5. 编译和运行1. 创建功能包 在《ROS2 入门应用 工作空间》中已创建和加…...
XSS漏洞,通过XSS实现网页挂马
**今天讲下通过XSS实现网页挂马~*,目的是了解安全方面知识,提升生活网络中辨别度 原理: 实验分为两部分: 1、通过Kali linux,利用MS14_064漏洞,制作一个木马服务器。存在该漏洞的用户一旦通过浏览器访问木…...
家政服务小程序实战教程09-图文卡片
小程序还有一类需求就是展示服务的列表,我们这里用图文卡片组件来实现,我们先要添加一个标题,使用网格布局来实现 第一列添加一个文本组件,第二列添加一个图标组件 修改文本组件的文本内容,设置外边距 设置第二列的样式…...
国内唯一一部在CentOS下正确编译安装和使用RediSearch的教程
开篇 Redis6开始增加了诸多激动人心的模块,特别是:RedisJSON和RediSearch。这两个模块已经完全成熟了。它们可以直接使用我们的生产上的Redis服务器来做全文搜索(二级搜索)以取得更廉价的硬件成本、同时在效率上竟然超过了Elastic…...
前端对于深拷贝和浅拷贝的应用和思考
浅拷贝 浅拷贝 : 浅拷贝是指对基本类型的值拷贝,以及对对象类型的地址拷贝。它是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据。最简单直接的浅拷贝就…...
Java基础常见面试题(三)
String 字符型常量和字符串常量的区别? 形式上: 字符常量是单引号引起的一个字符,字符串常量是双引号引起的若干个字符; 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算;字符串常量代表一个地址值…...
可以做烟的网站吗/网站如何注册
专业技术资格申报受理日期 本报讯 (记者李雅琼)近日,省人事厅对职称评审制度进行调整,取得国家职称外语等级考试合格证书的人员,在申报对应档次专业技术资格时,不受有效期限制。 省人事厅的通知称,8月15日至9…...
简约wordpress/市场调研报告范文
SQL文里因为包含单引号,所以在输出的时候需要特殊处理。 awk中的printf里面要输出单引号是:一个单引号反斜杠两个单引号 例: 假如csv文件格式:input.csv csv文件内容 1,Robert 出力的sql文:output.sql 而有表aaa.tbl_name 里面有两列…...
网站什么做才会更吸引客户/qq刷赞网站推广快速
3373-00-0|6-羟基-1,2,3,4-四氢喹啉/别名5-羟基-1,2,3,4-四氢喹啉 | 1,2,3,4-四氢-6-羟基喹啉 Cas:3373-00-0 中文名:6-羟基-1,2,3,4-四氢喹啉 英文名:1,2,3,4-tetrahydroquinolin-6-o 中文别名:5-羟基-1,2,3,4-四氢喹啉 | 1,2,3,4-四氢-6-羟基喹啉 物理化学性质 密度:1.10.1…...
网站后台fpt/百度怎么推广广告
struts2中 显示日期 <td><s:date name"codDate" format"yyyy-MM-dd" /></td> //以下的写法是错误的,不可以加id,如果加了将不能显示.<td><s:date name"codDate" id"xxxx" format"yy…...
wordpress修改绑定域名/百度信息
elementui中有个隐藏的组件,就是element官网使用的滚动条,tree 左右滑动滚动条 ①首先全局引入element,import ElementUI from element-ui; import ElementUI from element-uiVue.use(ElementUI)②页面代码如下1 <template>2 <div…...
电子商务网站建设视频教程/深度搜索
情况描述 jenkins所在的服务器安装了apidoc,且apidoc -v可以得到返回信息。 但是在jenkins的exce shell时候执行apidoc -v就会报错apidoc: command not found解决办法 在jenkins所在的服务器上执行whereis apidoc查询它的安装目录。 jenkins中exec shell的时候使用…...