机器学习实战刻意练习-- Task 6 Adaboost

2023-12-07 05:10

本文主要是介绍机器学习实战刻意练习-- Task 6 Adaboost,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Week 4

AdaBoost(adaptive boosting【自适应 boosting】)

adaboost 运行过程

训练数据中的每个样本,并赋予其一个权重,这些权重构成了向量D。一开始,这些权重都初始化成相等值。首先在训练数据上训练出一个弱分类器并计算该分类器的错误率,然后在同一数据集上再次训练弱分类器。在分类器的第二次训练当中,将会重新调整每个样本的权重,其中第一次分对的样本的权重将会降低而第一次分错的样本的权重将会提高。为了从所有弱分类器中得到最终的分类结果,AdaBoost为每个分类器都分配了一个权重值alpha,这些alpha值是基于每个弱分类器的错误率进行计算的。

adaboost 工作原理

gzyl

Adaboost 的一般流程

收集数据:可以使用任意方法
准备数据:依赖于所使用的弱分类器类型,本章使用的是单层决策树,这种分类器可以处理任何数据类型。当然也可以使用任意分类器作为弱分类器,第2章到第6章中的任一分类器都可以充当弱分类器。作为弱分类器,简单分类器的效果更好。
分析数据:可以使用任意方法。
训练算法:AdaBoost 的大部分时间都用在训练上,分类器将多次在同一数据集上训练弱分类器。
测试算法:计算分类的错误率。
使用算法:通SVM一样,AdaBoost 预测两个类别中的一个。如果想把它应用到多个类别的场景,那么就要像多类 SVM 中的做法一样对 AdaBoost 进行修改。

AdaBoost 算法特点

优点:泛化(由具体的、个别的扩大为一般的)错误率低,易编码,可以应用在大部分分类器上,无参数调节。
缺点:对离群点敏感。
适用数据类型:数值型和标称型数据。
基于单层决策树构建弱分类器

单层决策树(decision stump,也称决策树桩)是一种简单的决策树。前面我们已经介绍了决策树的工作原理,接下来将构建一个单层决策树,而它仅基于单个特征来做决策。由于这棵树只有一次分裂过程,因此它实际上就是一个树桩。

代码实现
# 建立一个adaboost.py文件,加入下列代码:
from numpy import *def loadSimpData():""" 测试数据Returns:datMat       feature对应的数据集classLabels  feature对应的分类标签"""datMat = array([[1. , 2.1],[2. , 1.1],[1.3, 1. ],[1. , 1. ],[2. , 1. ]])classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]return datMat, classLabels
# 代码运行:
>>> import adaboost
>>> datMat, classLabels = adaboost.loadSimpData()
# 有了数据,接下来就可以通过构建多个函数来建立单层决策树。
# 第一个函数将用于测试是否有某个值小于或者大于我们正在测试的阈值。第二个函数则更加
# 复杂一些,它会在一个加权数据集中循环,并找到具有最低错误率的单层决策树。
# 下面列出伪代码:
'''
将最小错误率minError设为+∞ 
对数据集中的每一个特征(第一层循环):对每个步长(第二层循环): 对每个不等号(第三层循环): 建立一棵单层决策树并利用加权数据集对它进行测试 如果错误率低于minError,则将当前单层决策树设为最佳单层决策树 
返回最佳单层决策树
'''
# 下面开始构造函数
# 单层决策树生成函数
def stumpClassify(dataMat, dimen, threshVal, threshIneq):"""stumpClassify(将数据集,按照feature列的value进行 二分法切分比较来赋值分类)Args:dataMat    Matrix数据集dimen      特征列threshVal  特征列要比较的值Returns:retArray 结果集"""# 默认都是1retArray = ones((shape(dataMat)[0], 1))# dataMat[:, dimen] 表示数据集中第dimen列的所有值# threshIneq == 'lt'表示修改左边的值,gt表示修改右边的值# print '-----', threshIneq, dataMat[:, dimen], threshValif threshIneq == 'lt':retArray[dataMat[:, dimen] <= threshVal] = -1.0else:retArray[dataMat[:, dimen] > threshVal] = -1.0return retArraydef buildStump(dataArr, labelArr, D):"""buildStump(得到决策树的模型)Args:dataArr   特征标签集合labelArr  分类标签集合D         最初的样本的所有特征权重集合Returns:bestStump    最优的分类器模型minError     错误率bestClasEst  训练后的结果集"""# 转换数据dataMat = mat(dataArr)labelMat = mat(labelArr).T# m行 n列m, n = shape(dataMat)# 初始化数据numSteps = 10.0bestStump = {}bestClasEst = mat(zeros((m, 1)))# 初始化的最小误差为无穷大minError = inf# 循环所有的feature列,将列切分成 若干份,每一段以最左边的点作为分类节点for i in range(n):rangeMin = dataMat[:, i].min()rangeMax = dataMat[:, i].max()# print 'rangeMin=%s, rangeMax=%s' % (rangeMin, rangeMax)# 计算每一份的元素个数stepSize = (rangeMax-rangeMin)/numSteps# 例如: 4=(10-1)/2   那么  1-4(-1次)   1(0次)  1+1*4(1次)   1+2*4(2次)# 所以: 循环 -1/0/1/2for j in range(-1, int(numSteps)+1):# go over less than and greater thanfor inequal in ['lt', 'gt']:# 如果是-1,那么得到rangeMin-stepSize; 如果是numSteps,那么得到rangeMaxthreshVal = (rangeMin + float(j) * stepSize)# 对单层决策树进行简单分类,得到预测的分类值predictedVals = stumpClassify(dataMat, i, threshVal, inequal)# print predictedValserrArr = mat(ones((m, 1)))# 正确为0,错误为1errArr[predictedVals == labelMat] = 0# 计算 平均每个特征的概率0.2*错误概率的总和为多少,就知道错误率多高# 例如: 一个都没错,那么错误率= 0.2*0=0 , 5个都错,那么错误率= 0.2*5=1, 只错3个,那么错误率= 0.2*3=0.6weightedError = D.T*errArr'''dim            表示 feature列threshVal      表示树的分界值inequal        表示计算树左右颠倒的错误率的情况weightedError  表示整体结果的错误率bestClasEst    预测的最优结果'''# print ("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError))if weightedError < minError:minError = weightedErrorbestClasEst = predictedVals.copy()bestStump['dim'] = ibestStump['thresh'] = threshValbestStump['ineq'] = inequal# bestStump 表示分类器的结果,在第几个列上,用大于/小于比较,阈值是多少return bestStump, minError, bestClasEst# 代码运行:
>>> import adaboost
>>> D = mat(ones((5,1))/5)
>>> D
matrix([[0.2],[0.2],[0.2],[0.2],[0.2]])
>>> datMat, classLabels = adaboost.loadSimpData()
>>> adaboost.buildStump(datMat, classLabels, D)
split: dim 0, thresh 0.90, thresh ineqal: lt, the weighted error is 0.400
split: dim 0, thresh 0.90, thresh ineqal: gt, the weighted error is 0.600
split: dim 0, thresh 1.00, thresh ineqal: lt, the weighted error is 0.400
split: dim 0, thresh 1.00, thresh ineqal: gt, the weighted error is 0.600
split: dim 0, thresh 1.10, thresh ineqal: lt, the weighted error is 0.400
.....
split: dim 1, thresh 1.88, thresh ineqal: gt, the weighted error is 0.600
split: dim 1, thresh 1.99, thresh ineqal: lt, the weighted error is 0.400
split: dim 1, thresh 1.99, thresh ineqal: gt, the weighted error is 0.600
split: dim 1, thresh 2.10, thresh ineqal: lt, the weighted error is 0.600
split: dim 1, thresh 2.10, thresh ineqal: gt, the weighted error is 0.400
({'dim': 0, 'thresh': 1.3, 'ineq': 'lt'}, matrix([[0.2]]), array([[-1.],[ 1.],[-1.],[-1.],[ 1.]]))
>>> # 完整Adaboost算法的实现
# 整个实现的伪代码:
'''
对每次迭代:利用buildStump()函数找到最佳的单层决策树 将最佳单层决策树加入到单层决策树数组 计算alpha 计算新的权重向量D 更新累计类别估计值 
如果错误率等于0.0,则退出循环
'''
# 基于单层决策树的AdaBoost训练过程
def adaBoostTrainDS(dataArr, labelArr, numIt=40):"""adaBoostTrainDS(adaBoost训练过程放大)Args:dataArr   特征标签集合labelArr  分类标签集合numIt     实例数Returns:weakClassArr  弱分类器的集合aggClassEst   预测的分类结果值"""weakClassArr = []m = shape(dataArr)[0]# 初始化 D,设置每行数据的样本的所有特征权重集合,平均分为m份D = mat(ones((m, 1))/m)aggClassEst = mat(zeros((m, 1)))for i in range(numIt):# 得到决策树的模型bestStump, error, classEst = buildStump(dataArr, labelArr, D)# alpha 目的主要是计算每一个分类器实例的权重(加和就是分类结果)# 计算每个分类器的 alpha 权重值alpha = float(0.5*log((1.0-error)/max(error, 1e-16)))bestStump['alpha'] = alpha# store Stump Params in ArrayweakClassArr.append(bestStump)# print ("alpha=%s, classEst=%s, bestStump=%s, error=%s " % (alpha, classEst.T, bestStump, error))# 分类正确:乘积为1,不会影响结果,-1主要是下面求e的-alpha次方# 分类错误:乘积为 -1,结果会受影响,所以也乘以 -1expon = multiply(-1*alpha*mat(labelArr).T, classEst)# print ('\n')# print ('labelArr=', labelArr)# print ('classEst=', classEst.T)# print ('\n')# print ('乘积: ', multiply(mat(labelArr).T, classEst).T)# 判断正确的,就乘以-1,否则就乘以1, 为什么? 书上的公式。# print ('(-1取反)预测值expon=', expon.T)# 计算e的expon次方,然后计算得到一个综合的概率的值# 结果发现: 判断错误的样本,D对于的样本权重值会变大。D = multiply(D, exp(expon))D = D/D.sum()# print ("D: ", D.T)# print ('\n')# 预测的分类结果值,在上一轮结果的基础上,进行加和操作# print ('当前的分类结果:', alpha*classEst.T)aggClassEst += alpha*classEst# print ("叠加后的分类结果aggClassEst: ", aggClassEst.T)# sign 判断正为1, 0为0, 负为-1,通过最终加和的权重值,判断符号。# 结果为:错误的样本标签集合,因为是 !=,那么结果就是0 正, 1 负aggErrors = multiply(sign(aggClassEst) != mat(labelArr).T, ones((m, 1)))errorRate = aggErrors.sum()/mprint ("total error=%s " % (errorRate))if errorRate == 0.0:breakreturn weakClassArr, aggClassEst
# 代码运行:
>>> import adaboost
>>> datMat, classLabels = adaboost.loadSimpData()
>>> classifierArray = adaboost.adaBoostTrainDS(datMat, classLabels, 9)
alpha=0.6931471805599453, classEst=[[-1.  1. -1. -1.  1.]], bestStump={'dim': 0, 'thresh': 1.3, 'ineq': 'lt', 'alpha': 0.6931471805599453}, error=[[0.2]] labelArr= [1.0, 1.0, -1.0, -1.0, 1.0]
classEst= [[-1.  1. -1. -1.  1.]]乘积:  [[-1.  1.  1.  1.  1.]]
(-1取反)预测值expon= [[ 0.69314718 -0.69314718 -0.69314718 -0.69314718 -0.69314718]]
D:  [[0.5   0.125 0.125 0.125 0.125]]当前的分类结果: [[-0.69314718  0.69314718 -0.69314718 -0.69314718  0.69314718]]
叠加后的分类结果aggClassEst:  [[-0.69314718  0.69314718 -0.69314718 -0.69314718  0.69314718]]
total error=0.2 
alpha=0.9729550745276565, classEst=[[ 1.  1. -1. -1. -1.]], bestStump={'dim': 1, 'thresh': 1.0, 'ineq': 'lt', 'alpha': 0.9729550745276565}, error=[[0.125]] labelArr= [1.0, 1.0, -1.0, -1.0, 1.0]
classEst= [[ 1.  1. -1. -1. -1.]]乘积:  [[ 1.  1.  1.  1. -1.]]
(-1取反)预测值expon= [[-0.97295507 -0.97295507 -0.97295507 -0.97295507  0.97295507]]
D:  [[0.28571429 0.07142857 0.07142857 0.07142857 0.5       ]]当前的分类结果: [[ 0.97295507  0.97295507 -0.97295507 -0.97295507 -0.97295507]]
叠加后的分类结果aggClassEst:  [[ 0.27980789  1.66610226 -1.66610226 -1.66610226 -0.27980789]]
total error=0.2 
alpha=0.8958797346140273, classEst=[[1. 1. 1. 1. 1.]], bestStump={'dim': 0, 'thresh': 0.9, 'ineq': 'lt', 'alpha': 0.8958797346140273}, error=[[0.14285714]] labelArr= [1.0, 1.0, -1.0, -1.0, 1.0]
classEst= [[1. 1. 1. 1. 1.]]乘积:  [[ 1.  1. -1. -1.  1.]]
(-1取反)预测值expon= [[-0.89587973 -0.89587973  0.89587973  0.89587973 -0.89587973]]
D:  [[0.16666667 0.04166667 0.25       0.25       0.29166667]]当前的分类结果: [[0.89587973 0.89587973 0.89587973 0.89587973 0.89587973]]
叠加后的分类结果aggClassEst:  [[ 1.17568763  2.56198199 -0.77022252 -0.77022252  0.61607184]]
total error=0.0 
>>> classifierArray
([{'dim': 0, 'thresh': 1.3, 'ineq': 'lt', 'alpha': 0.6931471805599453}, {'dim': 1, 'thresh': 1.0, 'ineq': 'lt', 'alpha': 0.9729550745276565}, {'dim': 0, 'thresh': 0.9, 'ineq': 'lt', 'alpha': 0.8958797346140273}], matrix([[ 1.17568763],[ 2.56198199],[-0.77022252],[-0.77022252],[ 0.61607184]]))
>>> # 测试算法:基于 AdaBoost 的分类
# 现在,需要做的就只是将弱分类器的训练过程从程序中抽出来,然后应用到某个具体的实例上去。
# 每个弱分类器的结果以其对应的alpha值作为权重。所有这些弱分类器的结果加权求和就得到了最后的结果。
# Adaboost 分类函数
def adaClassify(datToClass,classifierArr):#构建数据向量或矩阵dataMatrix=mat(datToClass)#获取矩阵行数m=shape(dataMatrix)[0]#初始化最终分类器aggClassEst = mat(zeros((m,1)))#遍历分类器列表中的每一个弱分类器for i in range(len(classifierArr)):#每一个弱分类器对测试数据进行预测分类classEst = stumpClassify(dataMatrix, classifierArr[0][i]["dim"], classifierArr[0][i]["thresh"], classifierArr[0][i]["ineq"])#对各个分类器的预测结果进行加权累加aggClassEst += classifierArr[0][i]['alpha']*classEstprint('aggClassEst:',aggClassEst)#通过sign函数根据结果大于或小于0预测出+1或-1return sign(aggClassEst)
# 代码运行:
>>> import adaboost
>>> import importlib
>>> importlib.reload(adaboost)
<module 'adaboost' from 'C:\\Users\\dell\\Desktop\\机器学习实战资料\\第7章 AdaBoost\\adaboost.py'>
>>> datArr, labelArr = adaboost.loadSimpData()
>>> classifierArr = adaboost.adaBoostTrainDS(datArr, labelArr, 30)
......
>>> adaboost.adaClassify([0, 0], classifierArr)
aggClassEst: [[-0.69314718]]
aggClassEst: [[-1.66610226]]
matrix([[-1.]])
>>> adaboost.adaClassify([[5, 5], [0, 0]], classifierArr)
aggClassEst: [[ 0.69314718][-0.69314718]]
aggClassEst: [[ 1.66610226][-1.66610226]]
matrix([[ 1.],[-1.]])
>>> 
实战示例:在一个难数据集上应用 AdaBoost (马疝病的预测)
项目概述

预测患有疝气病的马的存活问题,这里的数据包括368个样本和28个特征,疝气病是描述马胃肠痛的术语,然而,这种病并不一定源自马的胃肠问题,其他问题也可能引发疝气病,该数据集中包含了医院检测马疝气病的一些指标,有的指标比较主观,有的指标难以测量,例如马的疼痛级别。另外,除了部分指标主观和难以测量之外,该数据还存在一个问题,数据集中有30%的值是缺失的。

开发流程
# 流程
'''
收集数据:提供的文本文件
准备数据:确保类别标签是+1和-1,而非1和0
分析数据:统计分析
训练算法:在数据上,利用 adaBoostTrainDS() 函数训练出一系列的分类器
测试算法:我们拥有两个数据集。在不采用随机抽样的方法下,我们就会对 AdaBoost 和 Logistic 回归的结果进行完全对等的比较
使用算法:观察该例子上的错误率。不过,也可以构建一个 Web 网站,让驯马师输入马的症状然后预测马是否会死去
'''
# 收集数据:提供的文本文件
训练数据:horseColicTraining.txt
测试数据:horseColicTest.txt# 准备数据:确保类别标签是+1和-1,而非1和0
# 自适应数据加载函数
# general function to parse tab -delimited floats
def loadDataSet(filename):#创建数据集矩阵,标签向量dataMat=[];labelMat=[]#获取特征数目(包括最后一类标签)#readline():读取文件的一行#readlines:读取整个文件所有行numFeat=len(open(filename).readline().split('\t'))#打开文件fr=open(filename)#遍历文本每一行for line in fr.readlines():lineArr=[]curLine=line.strip().split('\t')for i in range(numFeat-1):lineArr.append(float(curLine[i]))#数据矩阵dataMat.append(lineArr)#标签向量labelMat.append(float(curLine[-1]))return dataMat,labelMat
# 代码运行:
>>> import adaboost
>>> datArr, labelArr = adaboost.loadDataSet('horseColicTraining2.txt')
>>> classifierArr = adaboost.adaBoostTrainDS(datArr, labelArr, 10)
total error=0.2842809364548495 
......
total error=0.23076923076923078 
>>> testArr, testLabelArr = adaboost.loadDataSet('horseColicTest2.txt')
>>> prediction10 = adaboost.adaClassify(testArr, classifierArr)
aggClassEst: [[ 0.46166238][-0.46166238].....[ 0.46166238]]
aggClassEst: [[ 0.77414483][ 0.77414483].....[ 0.77414483]]
>>> errArr = mat(ones((67,1)))
>>> errArr[prediction10 != mat(testLabelArr) .T] .sum()
18.0
>>> # 分析数据:统计分析
'''
过拟合(overfitting, 也称为过学习)
-->发现测试错误率在达到一个最小值之后有开始上升,这种现象称为过拟合。
-->对于表现好的数据集,AdaBoost的测试错误率就会达到一个稳定值,并不会随着分类器的增多而上升。
'''# 训练算法:在数据上,利用 adaBoostTrainDS() 函数训练出一系列的分类器
# ROC曲线的绘制及AUC计算函数
def plotROC(predStrengths, classLabels):"""plotROC(打印ROC曲线,并计算AUC的面积大小)Args:predStrengths  最终预测结果的权重值classLabels    原始数据的分类结果集"""print('predStrengths=', predStrengths)print('classLabels=', classLabels)import matplotlib.pyplot as plt# variable to calculate AUCySum = 0.0# 对正样本的进行求和numPosClas = sum(array(classLabels)==1.0)# 正样本的概率yStep = 1/float(numPosClas)# 负样本的概率xStep = 1/float(len(classLabels)-numPosClas)# argsort函数返回的是数组值从小到大的索引值# get sorted index, it's reversesortedIndicies = predStrengths.argsort()# 测试结果是否是从小到大排列print('sortedIndicies=', sortedIndicies, predStrengths[0, 176], predStrengths.min(), predStrengths[0, 293], predStrengths.max())# 开始创建模版对象fig = plt.figure()fig.clf()ax = plt.subplot(111)# cursor光标值cur = (1.0, 1.0)# loop through all the values, drawing a line segment at each pointfor index in sortedIndicies.tolist()[0]:if classLabels[index] == 1.0:delX = 0delY = yStepelse:delX = xStepdelY = 0ySum += cur[1]# draw line from cur to (cur[0]-delX, cur[1]-delY)# 画点连线 (x1, x2, y1, y2)print(cur[0], cur[0]-delX, cur[1], cur[1]-delY)ax.plot([cur[0], cur[0]-delX], [cur[1], cur[1]-delY], c='b')cur = (cur[0]-delX, cur[1]-delY)# 画对角的虚线线ax.plot([0, 1], [0, 1], 'b--')plt.xlabel('False positive rate')plt.ylabel('True positive rate')plt.title('ROC curve for AdaBoost horse colic detection system')# 设置画图的范围区间 (x1, x2, y1, y2)ax.axis([0, 1, 0, 1])plt.show()
'''
发现:
alpha (模型权重)目的主要是计算每一个分类器实例的权重(加和就是分类结果)分类的权重值:最大的值= alpha 的加和,最小值=-最大值
D (样本权重)的目的是为了计算错误概率: weightedError = D.T*errArr,求最佳分类器样本的权重值:如果一个值误判的几率越小,那么 D 的样本权重越小
'''# 测试算法:我们拥有两个数据集。在不采用随机抽样的方法下,我们就会对 AdaBoost 和 Logistic 回归的结果进行完全对等的比较。
def adaClassify(datToClass, classifierArr):"""adaClassify(ada分类测试)Args:datToClass     多个待分类的样例classifierArr  弱分类器的集合Returns:sign(aggClassEst) 分类结果"""# do stuff similar to last aggClassEst in adaBoostTrainDSdataMat = mat(datToClass)m = shape(dataMat)[0]aggClassEst = mat(zeros((m, 1)))# 循环 多个分类器for i in range(len(classifierArr)):# 前提: 我们已经知道了最佳的分类器的实例# 通过分类器来核算每一次的分类结果,然后通过alpha*每一次的结果 得到最后的权重加和的值。classEst = stumpClassify(dataMat, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])aggClassEst += classifierArr[i]['alpha']*classEstreturn sign(aggClassEst)# 使用算法:观察该例子上的错误率。不过,也可以构建一个 Web 网站,让驯马师输入马的症状然后预测马是否会死去。
# 代码运行:
>>> import adaboost
>>> import importlib
>>> importlib.reload(adaboost)
<module 'adaboost' from 'C:\\Users\\dell\\Desktop\\机器学习实战资料\\第7章 AdaBoost\\adaboost.py'>
>>> datArr, labelArr = adaboost.loadDataSet('horseColicTraining2.txt')
>>> classifierArray, aggClassEst = adaboost.adaBoostTrainDS(datArr, labelArr, 10)
total error=0.2842809364548495 
.....
total error=0.23076923076923078 
>>> adaboost.plotROC(aggClassEst.T, labelArr)
predStrengths= [[-0.646419    0.53886223  0.91726555  0.21712009 -0.69768794  1.22181293
.....0.05809528 -0.65208904 -1.02662219  0.27123572  0.5606821 ]]
classLabels= [-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, .....1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0]
sortedIndicies= [[ 45  59 244 230 141  40 272  35 181  83 239 192  49 133  46 176 121 285
.....175 183 145 125  95 279 148  85 276  71 166 248  12  67 224 136 214 28321 142 202 257 115 293  77  29 191 153 116]] -1.2464795402559683 -1.5816013179942605 1.6934230616135448 1.9979704415630808
1.0 0.9917355371900827 1.0 1.0
......
2.4702462297909733e-15 2.4702462297909733e-15 0.005617977528087764 -2.123301534595612e-15
>>> 
# 输出的图像如下:

ashoavnskanc

备注

学习参考资料:
《机器学习实战》
https://github.com/apachecn/AiLearning/tree/master/docs/ml
https://github.com/apachecn/AiLearning/blob/master/src/py2.x/ml/7.AdaBoost/adaboost.py
https://github.com/Y1ran/Machine-Learning-in-Action-Python3
https://github.com/TrWestdoor/Machine-Learning-in-Action

这篇关于机器学习实战刻意练习-- Task 6 Adaboost的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/464589

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

Python实战之屏幕录制功能的实现

《Python实战之屏幕录制功能的实现》屏幕录制,即屏幕捕获,是指将计算机屏幕上的活动记录下来,生成视频文件,本文主要为大家介绍了如何使用Python实现这一功能,希望对大家有所帮助... 目录屏幕录制原理图像捕获音频捕获编码压缩输出保存完整的屏幕录制工具高级功能实时预览增加水印多平台支持屏幕录制原理屏幕

最新Spring Security实战教程之Spring Security安全框架指南

《最新SpringSecurity实战教程之SpringSecurity安全框架指南》SpringSecurity是Spring生态系统中的核心组件,提供认证、授权和防护机制,以保护应用免受各种安... 目录前言什么是Spring Security?同类框架对比Spring Security典型应用场景传统

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

OpenManus本地部署实战亲测有效完全免费(最新推荐)

《OpenManus本地部署实战亲测有效完全免费(最新推荐)》文章介绍了如何在本地部署OpenManus大语言模型,包括环境搭建、LLM编程接口配置和测试步骤,本文给大家讲解的非常详细,感兴趣的朋友一... 目录1.概况2.环境搭建2.1安装miniconda或者anaconda2.2 LLM编程接口配置2

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...