python学智能算法(八)|决策树
【1】引言
前序学习进程中,已经对KNN邻近算法有了探索,相关文章链接为:
python学智能算法(七)|KNN邻近算法-CSDN博客
但KNN邻近算法有一个特点是:它在分类的时候,不能知晓每个类别内事物的具体面貌,只能获得类别,停留在事物的表面。
为了进一步探索事物的内在特征,就需要学习新的算法。
本篇文章就是在KNN的基础上学习新算法:决策树。
【2】原理分析
在学习决策树执之前,需要先了解香农熵。
本科学控制课,老师讲到香农熵,那时候啥也不懂,以为就是个普通公式,多年以后,看到这三个字难免感慨当年太过幼稚。
【2.1】香农熵
香农熵比较简单,从数学层面上看就是对数求和。
这是香农熵的求解代码:
import numpy as np
from math import log #引入log()函数求对数# 定义一个嵌套列表
def creatDataset():# dataset是一个嵌套列表dataset=[[1,1,'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]# lables也是一个列表labels=['no surfacing','flippers']return dataset,labels# calcShannonEnt是具体的香农熵求解函数
def calcShannonEnt(dataset):# numEntries获得了dataset列表的行数numEntries=len(dataset)# labelcounts是一个空的字典labelcounts={}# for函数的意义是,对于dataset里面的每一行都会执行循环操作for feature in dataset:# currentlabel 取到了feature的最后一个元素currentlabel=feature[-1]# 由于labelcounts是一个空字典,labelcounts.keys()在第一次运行的时候不会指向任何标签,所以会被直接添加# currentlabel是每一行dataset的最后一列,也就是最后一个元素# if函数实际上进行了同类项合并工作if currentlabel not in labelcounts.keys():# 给以currentlabel为标签的项目赋值0labelcounts[currentlabel]=0# 只要currentlabel和labelcounts.keys()存储的元素一致,就给以currentlabel为标签的项目赋值加1labelcounts[currentlabel]+=1# 定义香农熵的初始值=0ShannonEnt=0.0# 由于labelcounts是字典,所以可以用key访问字典的项目for key in labelcounts:# 计算值为浮点数# 用key指向的项目对应的数量比上总数prob=float(labelcounts[key])/numEntries# 香农熵就是频数乘以以2为底的频数的对数,然后还要取负值# 取负值是因为,频数小于1,所以对数小于0,一旦取负值就获得了正数ShannonEnt-=prob*log(prob,2)return ShannonEnt
dataset,labels=creatDataset()
ShannonEnt=calcShannonEnt(dataset)
print('ShannonEnt=',ShannonEnt)
整体代码非常简单,总结起来就是一个公式:
代码中需要注意的是:dataset是一个嵌套列表,labelcounts是一个字典。
【2.2】数据集划分
数据集划分,目的是找出某些关键特征后,将其删除。
# 定义一个嵌套列表
def creatDataset():# dataset是一个嵌套列表dataset=[[1,1,'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]# lables也是一个列表labels=['no surfacing','flippers']return dataset,labels# splitdataset把一些列因素直接删除后输出
def splitdataset(dataset, axis, value):# 创建一个新的列表retdataset = []# 对于dataset的每一行for featvec in dataset:# if第axis列的数据刚好和value相等if featvec[axis] == value:# reducedfeature先获取索引从第0个到axis-1的元素,一共axis个reducedfeatvec = featvec[:axis]# reducedfeature继续获取索引从第axis+1开始的所有元素# reducedfeature后面再获取从第axis+2个开始一直到最后一个元素reducedfeatvec.extend(featvec[axis + 1:])# retdataset存储了reducedfeature# retdataset中刚好没有位置索引为axis的元素# retdataset中刚好没有第axis+1个元素retdataset.append(reducedfeatvec)return retdatasetdataset, labels = creatDataset()
retdataset = splitdataset(dataset, 0,1)
retdataset1 = splitdataset(dataset, 1,1)
retdataset2 = splitdataset(dataset, 1,0)
print("retdataset:", retdataset)
print("retdataset1:", retdataset1)
print("retdataset2:", retdataset2)
数据集划分只用了一个for循环加if判断就能实现,划分的原理是:对于每一行元素,如果指定列的元素和指定数据相等,就把这个相等的元素挑出去,然后把这行数据剩下的部分添加到一个新的列表里;如果指定列的元素和指定数据不相等,这一行数据会直接略过。
上述代码运行的效果是:
retdataset: [[1, 'yes'], [1, 'yes'], [0, 'no']]
retdataset1: [[1, 'yes'], [1, 'yes'], [0, 'no'], [0, 'no']]
retdataset2: [[1, 'no']]
【2.3】特征选择
数据集划分后,序言按照制定的特征作为依据,判断这个特征指向的样本对应的香农熵。
要想理解特征选择的意义,需要把前面的香农熵计算和数据集划分子函数都一起写进来:
from math import log # 引入log()函数求对数def creatDataset():# dataset是一个嵌套列表dataset=[[1,1,'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]# lables也是一个列表labels=['no surfacing','flippers']return dataset,labels# calcShannonEnt是具体的香农熵求解函数
# 实际上calcShannonEnt是dataset最后一列的香农熵
def calcShannonEnt(dataset):# numEntries获得了dataset列表的行数numEntries = len(dataset)# labelcounts是一个空的字典labelcounts = {}# for函数的意义是,对于dataset里面的每一行都会执行循环操作for feature in dataset:# currentlabel 取到了feature的最后一个元素currentlabel = feature[-1]# 由于labelcounts是一个空字典,labelcounts.keys()在第一次运行的时候不会指向任何标签,所以会被直接添加# currentlabel是每一行dataset的最后一列,也就是最后一个元素# if函数实际上进行了同类项合并工作if currentlabel not in labelcounts.keys():# 给以currentlabel为标签的项目赋值0labelcounts[currentlabel] = 0# 只要currentlabel和labelcounts.keys()存储的元素一致,就给以currentlabel为标签的项目赋值加1labelcounts[currentlabel] += 1# 定义香农熵的初始值=0ShannonEnt = 0.0# 由于labelcounts是字典,所以可以用key访问字典的项目for key in labelcounts:# 计算值为浮点数# 用key指向的项目对应的数量比上总数prob = float(labelcounts[key]) / numEntries# 香农熵就是频数乘以以2为底的频数的对数,然后还要取负值# 取负值是因为,频数小于1,所以对数小于0,一旦取负值就获得了正数ShannonEnt -= prob * log(prob, 2)return ShannonEnt# splitdataset把一些列因素直接删除后输出
def splitdataset(dataset, axis, value):# 创建一个新的列表retdataset = []# 对于dataset的每一行for featvec in dataset:# if第axis列的数据刚好和value相等if featvec[axis] == value:# reducedfeature先获取索引从第0个到axis-1的元素,一共axis个reducedfeatvec = featvec[:axis]# reducedfeature继续获取索引从第axis+1开始的所有元素# reducedfeature后面再获取从第axis+2个开始一直到最后一个元素reducedfeatvec.extend(featvec[axis + 1:])# retdataset存储了reducedfeature# retdataset中刚好没有位置索引为axis的元素# retdataset中刚好没有第axis+1个元素retdataset.append(reducedfeatvec)return retdataset# choosebestfeaturetosplit计算的香农熵对象元素是dataset最后一列对应的元素
def choosebestfeaturetosplit(dataset):# 对dataset第0行求长度,获得列数,然后再减去1numfeatures = len(dataset[0]) - 1# 调用函数calcShannonEnt获得dataset的香农熵baseentroy = calcShannonEnt(dataset)# 定义一个常数bestinfogain = 0.0# 定义一个常数bestfeature = -1# 对于numfeatures中的每一个数# numfeatures比dataset的列数少一个for i in range(numfeatures):# 对于每一行在dataset中的元素,按照列位置索引为i的形式提取# 每一行位置索引为i的元素赋值给featlist# 这个嵌套列表,因为for的存在,把dataset每一行和位置索引为i的元素赋值给featlist# featlist存储的元素数量和dataset的函数一致# featlist作为列表没有提前预定义,此处定义这个量和定义如何取值一起出现featlist = [example[i] for example in dataset]# set是一个内置函数,将featlist这个列表转化为集合# 集合具有合并同类项的作用,重复的元素只会保留一个uniquevals = set(featlist)# 定义一个常数newentropy = 0.0# 对于uniquevals中的每一个值# uniquevals执行过程中,相当于把整个dataset计算获得的uniquevals进行遍历# value是uniquevals中的具体元素,也是列位置索引为i的dataset取到的值for value in uniquevals:# 调用splitdataset对dataset进行子集划分# 子集划分的列数和获得uniquevals的列数一致,value是uniquevals的存储值# subdataset不会是空值subdataset = splitdataset(dataset, i, value)# 获取每一个元素的香农熵# 需要注意的是,在每一个i的取值范围内,都会执行subdataset操作# subdataset是按照列元素进行的集合划分# 这个prob实际上是针对列元素展开的,有多少列,就会有多少次prob计算# prob实际上代表的是subdataset行数和dataset行数的比例prob = len(subdataset) / float(len(dataset))# 更新香农熵# calcShannonEnt(subdataset)计算了subdataset的最后一列的香农熵# newtropy是prob这个比例和对应香农熵的乘积newentropy += prob * calcShannonEnt(subdataset)# 获得香农熵的变化量# baseentroy是dataset的香农熵# newtropy是第i列元素为特征进行集合划分之后,对新集合开展的香农熵计算和新集合数量比例的乘积infogain = baseentroy - newentropy# 如果变化量超过阈值if (infogain > bestinfogain):# 新变化=变化量bestinfogain = infogain# 给bestfeature赋值ibestfeature = ireturn bestfeaturedataset, labels = creatDataset()
ShannonEnt=calcShannonEnt(dataset)
print('ShannonEnt=',ShannonEnt)
bestfeature=choosebestfeaturetosplit(dataset)
print('bestfeature=',bestfeature)
但在前面理解的基础上,可以先记住两条原则:
- 香农熵是以一行数据列表的最后一列为计算依据,开展的对数运算;
- 数据计划分时,会把特征这个依据从一行数据列表中删除。
而为了理解特征选择子函数choosebestfeaturetosplit(dataset),需要把这个函数分作三部分。
【2.3.1】准备部分
# 对dataset第0行求长度,获得列数,然后再减去1numfeatures = len(dataset[0]) - 1# 调用函数calcShannonEnt获得dataset的香农熵baseentroy = calcShannonEnt(dataset)# 定义一个常数bestinfogain = 0.0# 定义一个常数bestfeature = -1
准备部分获得一些备用值:
numfeatures = len(dataset[0]) - 1,对应的是dataset列表的列数-1;
baseentroy = calcShannonEnt(dataset),是对dataset计算香农熵;
bestinfogain = 0.0和bestfeature = -1都是直接赋值。
【2.3.2】特征值提取
# 对于numfeatures中的每一个数# numfeatures比dataset的列数少一个for i in range(numfeatures):# 对于每一行在dataset中的元素,按照列位置索引为i的形式提取# 每一行位置索引为i的元素赋值给featlist# 这个嵌套列表,因为for的存在,把dataset每一行和位置索引为i的元素赋值给featlist# featlist存储的元素数量和dataset的函数一致# featlist作为列表没有提前预定义,此处定义这个量和定义如何取值一起出现featlist = [example[i] for example in dataset]# set是一个内置函数,将featlist这个列表转化为集合# 集合具有合并同类项的作用,重复的元素只会保留一个uniquevals = set(featlist)# 定义一个常数newentropy = 0.0# 对于uniquevals中的每一个值# uniquevals执行过程中,相当于把整个dataset计算获得的uniquevals进行遍历# value是uniquevals中的具体元素,也是列位置索引为i的dataset取到的值
在特征值提取部分,featlist通过嵌套for循环来提取了特征,然后通过set函数做了合并同类型操作。
featlist本质上是对dataset的列数据进行了提取,然后再合并同类项。
注意newtropy在每列特征值获得后,初始值都是0.0。
【2.3.3】特征值香农熵
for value in uniquevals:# 调用splitdataset对dataset进行子集划分# 子集划分的列数和获得uniquevals的列数一致,value是uniquevals的存储值# subdataset不会是空值subdataset = splitdataset(dataset, i, value)# 获取每一个元素的香农熵# 需要注意的是,在每一个i的取值范围内,都会执行subdataset操作# subdataset是按照列元素进行的集合划分# 这个prob实际上是针对列元素展开的,有多少列,就会有多少次prob计算# prob实际上代表的是subdataset行数和dataset行数的比例prob = len(subdataset) / float(len(dataset))# 更新香农熵# calcShannonEnt(subdataset)计算了subdataset的最后一列的香农熵# newtropy是prob这个比例和对应香农熵的乘积newentropy += prob * calcShannonEnt(subdataset)
在获得特征值之后,以每一个特征值为依据,对取得特征值的列进行数据集划分。
也就是在某列取得特征值,这一列的数据就会被提取出来参与数据集划分。
对于每一个特征值对应的数据集,都要依据最后一列元素计算香农熵,然后这个香农熵还要和每个数据集行数占整个dataset行数的比例相乘。实际上,每个数据集的行数就代表了这个特征值在dataset的第i列中出现的次数。
需要注意的是,newentropy需要把第i列获得的所有特征值对应的数据集的香农熵都算一遍再叠加在一起。
【2.3.4】特征值香农熵变化量
# 获得香农熵的变化量# baseentroy是dataset的香农熵# newtropy是第i列元素为特征进行集合划分之后,对新集合开展的香农熵计算和新集合数量比例的乘积infogain = baseentroy - newentropy
这一步相对来说比较简单,用整个数据集dataset的香农熵减去特征值数据集的香农熵,获得一个当前熵增益。
【2.3.5】最佳熵增益
if (infogain > bestinfogain):# 新变化=变化量bestinfogain = infogain# 给bestfeature赋值ibestfeature = i
如果当前熵增益>最佳熵增益,就把当前熵增益赋值给最佳熵增益,记录此时特征值在dataset中的列数。
总体而言,对于最佳列数的选择,是对dataset除最后一列之外的每一列元素都进行特征值选择,再计算香农熵后做出的选择。
当它们偏离dataset香农熵越远,被选中的概率越大。
【2.4】多数表决
def majoritycnt(classlist):# classcount是一个空字典classcount = {}for vote in classlist:# classlist是一个外部导入的参数# 从if条件来看,classlist也是一个字典# 对于classlist字典里的每一个键if vote not in classcount.keys():# 如果classlist里的键和clssscount里的键不一样# classcount字典里的vote键赋值0classcount[vote] = 0# 如果classlist里的键和clssscount里的键一样# classcount字典里的vote键值+1classcount[vote] += 1# Python 3中字典的iteritems()方法已被items()方法取代sortedclasscount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)return sortedclasscount[0][0]
对于多数表决部分,相对比较简单,整体上是一个排序的目标。
整个函数的输入参数其实也是列表,需要计算出列表中有多少个键值,然后对键值进行从大到小的排序即可,整个函数只返回最大值。
【2.5】获得决策树
def creattree(dataset, labels):# 对dataset中的最后一列取值# classlist是一个列元素列表classlist = [example[-1] for example in dataset]# 修正判断条件的括号# classlist.count(classlist[0])获得的是classlist列元素的第一个元素出现的次数# len(classlist)是classlist的行数,等于dataset中样本的数量if classlist.count(classlist[0]) == len(classlist):return classlist[0]# dataset[0]代表的是列数,如果列数=1,就直接返回classlist代入majoritycnt()函数的值if len(dataset[0]) == 1:return majoritycnt(classlist)# bestfeat通过choosebestfeaturetosplit(dataset)函数取值bestfeat = choosebestfeaturetosplit(dataset)# bestfeatlabel通过labels[bestfeat]函数取值bestfeatlabel = labels[bestfeat]# mytree是一个空字典,字典的键为bestfeatlabel,键值暂时是一个空字典mytree = {bestfeatlabel: {}}# 从特征标签中删除bestfeaturedel (labels[bestfeat])# featvalues的取值是dataset中位置索引为bestfeat的行featvalues = [example[bestfeat] for example in dataset]# 合并同类项uniquevals = set(featvalues)# 对于每一项for value in uniquevals:# sublabels是一个lables的副本sublabels = labels[:]# 获得决策树mytree[bestfeatlabel][value] = creattree(splitdataset(dataset, bestfeat, value), sublabels)return mytree
获得决策树的部分相对复杂一些,下一篇文章对整体做结构分析,到时候详细说明。
此时的完整代码为:
import numpy as np
from math import log # 引入log()函数求对数
import operator# 定义一个嵌套列表
def creatDataset():# dataset是一个嵌套列表dataset = [[1, 1, 'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]# lables也是一个列表labels = ['no surfacing', 'flippers']return dataset, labels# calcShannonEnt是具体的香农熵求解函数
def calcShannonEnt(dataset):# numEntries获得了dataset列表的行数numEntries = len(dataset)# labelcounts是一个空的字典labelcounts = {}# for函数的意义是,对于dataset里面的每一行都会执行循环操作for feature in dataset:# currentlabel 取到了feature的最后一个元素currentlabel = feature[-1]# 由于labelcounts是一个空字典,labelcounts.keys()在第一次运行的时候不会指向任何标签,所以会被直接添加# currentlabel是每一行dataset的最后一列,也就是最后一个元素# if函数实际上进行了同类项合并工作if currentlabel not in labelcounts.keys():# 给以currentlabel为标签的项目赋值0labelcounts[currentlabel] = 0# 只要currentlabel和labelcounts.keys()存储的元素一致,就给以currentlabel为标签的项目赋值加1labelcounts[currentlabel] += 1# 定义香农熵的初始值=0ShannonEnt = 0.0# 由于labelcounts是字典,所以可以用key访问字典的项目for key in labelcounts:# 计算值为浮点数# 用key指向的项目对应的数量比上总数prob = float(labelcounts[key]) / numEntries# 香农熵就是频数乘以以2为底的频数的对数,然后还要取负值# 取负值是因为,频数小于1,所以对数小于0,一旦取负值就获得了正数ShannonEnt -= prob * log(prob, 2)return ShannonEntdataset, labels = creatDataset()
ShannonEnt = calcShannonEnt(dataset)
print('ShannonEnt=', ShannonEnt)# splitdataset把一些列因素直接删除后输出
def splitdataset(dataset, axis, value):# 创建一个新的列表retdataset = []# 对于dataset的每一行for featvec in dataset:# if第axis列的数据刚好和value相等if featvec[axis] == value:# reducedfeature先获取索引从第0个到axis-1的元素,一共axis个reducedfeatvec = featvec[:axis]# reducedfeature继续获取索引从第axis+1开始的所有元素# reducedfeature后面再获取从第axis+2个开始一直到最后一个元素reducedfeatvec.extend(featvec[axis + 1:])# retdataset存储了reducedfeature# retdataset中刚好没有位置索引为axis的元素retdataset.append(reducedfeatvec)return retdatasetdef choosebestfeaturetosplit(dataset):# 对dataset第0行求长度,获得列数,然后再减去1numfeatures = len(dataset[0]) - 1# 调用函数calcShannonEnt获得dataset的香农熵baseentroy = calcShannonEnt(dataset)# 定义一个常数bestinfogain = 0.0# 定义一个常数bestfeature = -1# 对于numfeatures中的每一个数# numfeatures比dataset的列数少一个for i in range(numfeatures):# 对于每一个在dataset中的元素,按照位置索引为i的形式提取featlist = [example[i] for example in dataset]# set是一个内置函数,将featlist这个列表转化为集合# 集合具有合并同类项的作用,重复的元素只会保留一个uniquevals = set(featlist)# 定义一个常数newentropy = 0.0# 对于uniquevals中的每一个值for value in uniquevals:# 调用splitdataset进行子集划分subdataset = splitdataset(dataset, i, value)# 获取每一个元素的香农熵prob = len(subdataset) / float(len(dataset))# 更新香农熵newentropy += prob * calcShannonEnt(subdataset)# 获得香农熵的变化量infogain = baseentroy - newentropy# 如果变化量查过阈值if (infogain > bestinfogain):# 新变化=变化量bestinfogain = infogain# 给bestfeature赋值ibestfeature = ireturn bestfeaturedef majoritycnt(classlist):# classcount是一个空字典classcount = {}for vote in classlist:# classlist是一个外部导入的参数# 从if条件来看,classlist也是一个字典# 对于classlist字典里的每一个键if vote not in classcount.keys():# 如果classlist里的键和clssscount里的键不一样# classcount字典里的vote键赋值0classcount[vote] = 0# 如果classlist里的键和clssscount里的键一样# classcount字典里的vote键值+1classcount[vote] += 1# Python 3中字典的iteritems()方法已被items()方法取代sortedclasscount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)return sortedclasscount[0][0]def creattree(dataset, labels):# 对dataset中的最后一列取值# classlist是一个列元素列表classlist = [example[-1] for example in dataset]# 修正判断条件的括号# classlist.count(classlist[0])获得的是classlist列元素的第一个元素出现的次数# len(classlist)是classlist的行数,等于dataset中样本的数量if classlist.count(classlist[0]) == len(classlist):return classlist[0]# dataset[0]代表的是列数,如果列数=1,就直接返回classlist代入majoritycnt()函数的值if len(dataset[0]) == 1:return majoritycnt(classlist)# bestfeat通过choosebestfeaturetosplit(dataset)函数取值bestfeat = choosebestfeaturetosplit(dataset)# bestfeatlabel通过labels[bestfeat]函数取值bestfeatlabel = labels[bestfeat]# mytree是一个空字典,字典的键为bestfeatlabel,键值暂时是一个空字典mytree = {bestfeatlabel: {}}# 从特征标签中删除bestfeaturedel (labels[bestfeat])# featvalues的取值是dataset中位置索引为bestfeat的行featvalues = [example[bestfeat] for example in dataset]# 合并同类项uniquevals = set(featvalues)# 对于每一项for value in uniquevals:# sublabels是一个lables的副本sublabels = labels[:]# 获得决策树mytree[bestfeatlabel][value] = creattree(splitdataset(dataset, bestfeat, value), sublabels)return mytree# 测试代码
dataset, labels = creatDataset()
tree = creattree(dataset, labels.copy())
print("决策树:", tree)
【3】总结
学习了决策树的基础知识。
相关文章:
python学智能算法(八)|决策树
【1】引言 前序学习进程中,已经对KNN邻近算法有了探索,相关文章链接为: python学智能算法(七)|KNN邻近算法-CSDN博客 但KNN邻近算法有一个特点是:它在分类的时候,不能知晓每个类别内事物的具…...
【经验】Orin系列Ubuntu远程桌面:VNC、NoMachine、URDC
1、VNC 1.1 Ubuntu端 1)安装VNC服务器 sudo apt install tigervnc-standalone-server2)安装xfce4 桌面 xfce4 用资源较GNOME ,KDE较少。适合老机器,轻量级桌面。与windows界面环境类似。 sudo apt install xfce4 xfce4-goodies也可以使用其它的桌面系统,可以使用如下命…...
【QT:控件】
目录 控件状态:编辑 geometry : window frame windowlcon: qrc机制 qrc的使用方式: window opacity cursor font: ToolTip focusPolicy: styleSheet: 按钮类控件: PushButton: 给按钮添加图标: 给按钮添加快捷键…...
Python(最新版)集成开发环境PyCharm下载安装详细教程
Python 下载和安装 1.进入Python官网 Download Python | Python.org,点击Downloads,这里以Windows为例 2.选择下载Python 3.13.2 Windows 64位的版本。注意:不能在Windows 7 或更早的版本上使用。 3.打开文件,会自动出现安装界…...
PyTorch 实现 Conditional DCGAN(条件深度卷积生成对抗网络)进行图像到图像转换的示例代码
以下是一个使用 PyTorch 实现 Conditional DCGAN(条件深度卷积生成对抗网络)进行图像到图像转换的示例代码。该代码包含训练和可视化部分,假设输入为图片和 4 个工艺参数,根据这些输入生成相应的图片。 1. 导入必要的库 import …...
【BERT和GPT的区别】
BERT采用完形填空(Masked Language Modeling, MLM)与GPT采用自回归生成(Autoregressive Generation)的差异,本质源于两者对语言建模的不同哲学导向与技术目标的根本分歧。这种选择不仅塑造了模型的架构特性,…...
PTA 7-12 排序
题目描述 给定 n 个(长整型范围内的)整数,要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下: 数据1:只有1个元素;数据2:11个不…...
uniapp 实现的步进指示器组件
采用 uniapp 实现的一款步进指示器组件,展示业务步骤进度等内容,对外提供“前进”、“后退”方法,让用户可高度自定义所需交互,适配 web、H5、微信小程序(其他平台小程序未测试过,可自行尝试) 可…...
大模型-提示词调优
什么是提示词 提示词(Prompt)在大模型应用中扮演着关键角色,它是用户输入给模型的一段文本指令 。简单来说,就是我们向大模型提出问题、请求或描述任务时所使用的文字内容。例如,当我们想让模型写一篇关于春天的散文&a…...
【k8s002】k8s健康检查与故障诊断
k8s健康检查与故障诊断 一、集群状态检查 检查节点健康状态 kubectl get nodes -o wide # 查看节点状态及基本信息 kubectl describe node <node-name> # 分析节点详细事件(如资源不足、网络异常) kubectl top nodes …...
统计数字字符个数(信息学奥赛一本通-1129)
【题目描述】 输入一行字符,统计出其中数字字符的个数。 【输入】 一行字符串,总长度不超过255。 【输出】 输出为1行,输出字符串里面数字字符的个数。 【输入样例】 Peking University is set up at 1898. 【输出样例】 4 【输出样例】 #in…...
CentOS 6 YUM源切换成国内yum源
由于 CentOS 6 已于 2020 年 11 月进入 EOL(End of Life),官方软件源已不再提供更新,因此你可能会遇到 yum makecache 命令失败的问题。以下是解决该问题的详细步骤: ### 解决方案 1. **备份原有 yum 源文件** bash …...
继承知识点—详细
一:普通写法 package extend_;public class Extends01 {public static void main(String[] args) {Pubil pubil new Pubil();pubil.name"小明";pubil.age18;pubil.testing();pubil.setScore(60);pubil.showInfo();System.out.println("-----------…...
设备管理VTY(Telnet、SSH)
实验目的:物理机远程VTY通过telnet协议登录AR1,ssh协议登录AR2和sw 注意配置Cloud1: 注意!!博主的物理机VMnet8--IP:192.168.160.1,所以AR1路由0/0/0端口才添加IP:192.168.160.3,每个…...
Linux 中 Git 使用指南:从零开始掌握版本控制
目录 1. 什么是 Git? Git 的核心功能: 2. Git 的安装 Ubuntu/Debian 系统: 验证安装: 3.gitee库 4. Git 的首次配置 配置用户名和邮箱: 查看配置: 5. Git 的基本使用 初始化仓库 添加文件到暂存区…...
Linux 中的 likely 和 unlikely
1. 源码 # define likely(x) __builtin_expect(!!(x), 1) # define unlikely(x) __builtin_expect(!!(x), 0) 实际上就是通过GCC 的内建函数 __builtin_expect() 进行编译优化: long __builtin_expect (long exp, long c) 该函数是告诉编译器:参…...
CSS -属性值的计算过程
目录 一、抛出两个问题1.如果我们学过优先级关系,那么请思考如下样式为何会生效2.如果我们学习过继承,那么可以知道color是可以被子元素继承使用的,那么请思考下述情景为何不生效 二、属性值计算过程1.确定声明值2.层叠冲突3.使用继承4.使用默…...
百度贴吧IP和ID是什么意思?怎么查看
在百度贴吧这一充满活力的网络社区中,IP和ID是两个频繁出现的概念。它们各自承载着不同的意义和作用,对于贴吧用户而言,了解这两个概念有助于更好地参与社区互动、保护个人隐私以及维护社区秩序。本文将详细解析百度贴吧中IP和ID的含义&#…...
SpiderX:专为前端JS加密绕过设计的自动化工具
SpiderX 一、工具概述 SpiderX是一款专为解决前端JS加密问题而设计的自动化绕过工具。在网络安全领域,随着前端加密技术的普及,传统的爬虫和自动化测试工具在面对复杂的JS加密时显得力不从心。SpiderX应运而生,旨在通过自动化手段高效绕过前…...
基于银河麒麟系统ARM架构安装达梦数据库并配置主从模式
达梦数据库简要概述 达梦数据库(DM Database)是一款由武汉达梦公司开发的关系型数据库管理系统,支持多种高可用性和数据同步方案。在主从模式(也称为 Master-Slave 或 Primary-Secondary 模式)中,主要通过…...
【AWS入门】AWS云计算简介
【AWS入门】AWS云计算简介 A Brief Introduction to AWS Cloud Computing By JacksonML 什么是云计算?云计算能干什么?我们如何利用云计算?云计算如何实现? 带着一系列问题,我将做一个普通布道者,引领广…...
适合企业内训的AI工具实操培训教程(37页PPT)(文末有下载方式)
详细资料请看本解读文章的最后内容。 资料解读:适合企业内训的 AI 工具实操培训教程 在当今数字化时代,人工智能(AI)技术迅速发展,深度融入到各个领域,AIGC(人工智能生成内容)更是成…...
【数据结构与算法】Java描述:第四节:二叉树
一、树的相关概念 编程中的树是模仿大自然中的树设计的,呈现倒立的结构,我们着重掌握 二叉树 。 1.1 基本概念: 结点的度:一个结点有几个子结点,度就是几; 如上图:A的度为3 树的度࿱…...
【一起来学kubernetes】14、StatefulSet使用详解
一、核心特性二、架构与组件三、生命周期管理四、典型应用场景**五、注意事项与最佳实践六、对比Deployment一、应用场景二、Pod管理三、部署与更新策略四、其他特性 七、常见问题八、拓展 前文中我们介绍了k8s中常用的一种控制器 Deployment,与之向对应的ÿ…...
Day5 结构体、文字显示与GDT/IDT初始化
文章目录 1. harib02b用例(使用结构体)2. harib02c用例3. harib02d用例(显示字符图案)3. harib02e用例(增加字符图案)4. harib02g用例4.1 显示字符串4.2 显示变量值 5. harib02h用例(显示鼠标&a…...
AI第一天 自我理解笔记--微调大模型
目录 1. 确定目标:明确任务和数据 2. 选择预训练模型 3. 数据预处理 (1) 数据清洗与格式化 (2) 划分数据集 (3) 数据加载与批处理 4. 构建微调模型架构 (1) 加载预训练模型 (2) 修改模型尾部(适配任务) (3) 冻结部分层(可…...
ClientAbortException问题分析
最近遇到一个问题,在设备采数据数据上报后频繁发生ClientAbortException异常,一种处理方案是ClientAbortException 问题分析-CSDN博客 一、ClientAbortException 的触发与影响 1. 定义与场景 ClientAbortException 是后端服务器(如 Tomc…...
系统思考全球化落地
感谢加密货币公司Bybit的再次邀请,为全球团队分享系统思考课程!虽然大家来自不同国家,线上学习的形式依然让大家充满热情与互动,思维的碰撞不断激发新的灵感。 尽管时间存在挑战,但我看到大家的讨论异常积极ÿ…...
【开原宝藏】30天学会CSS - DAY1 第一课
下面提供一个由浅入深、按步骤拆解的示例教程,让你能从零开始,逐步理解并实现带有旋转及悬停动画的社交图标效果。为了更简单明了,以下示例仅创建四个图标(Facebook、Twitter、Google、LinkedIn),并在每一步…...
钉钉项目报销与金蝶系统高效集成技术解析
钉钉报销【项目报销类】集成到金蝶付款单【画纤骨】的技术实现 在企业日常运营中,数据的高效流转和准确对接是提升业务效率的关键。本文将分享一个具体的系统对接集成案例:如何将钉钉平台上的项目报销数据无缝集成到金蝶云星空的付款单系统中。本次方案…...
