【机器学习】决策树原理及scikit-learn使用

文章目录

  • 决策树详解
    • ID3 算法
    • C4.5算法
    • CART 算法
  • scikit-learn使用
    • 分类树
      • 剪枝参数
      • 重要属性和接口
    • 回归树
      • 重要参数,属性及接口
      • 交叉验证
      • 代码示例
    • 一维回归的图像绘制


决策树详解

决策树(Decision Tree)是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。

决策树由结点(node)和有向边(directed edge)组成。结点有两种:内部结点(internal node)和叶子结点(leaf node),其中内部结点表示一个特征或者属性,叶子结点表示一个类。

下图为是否为哺乳动物的二分类决策树:体温和胎生为特征,哺乳动物和非哺乳动物为类别。【可以看成if-else的结够,根据给定的数据,一路走下去,最后得出结论】

在这里插入图片描述原则上讲,任意一个数据集上的所有特征都可以被拿来分枝,特征上的任意节点又可以自由组合,所以一个数据集上可以发展出非常非常多棵决策树,其数量可达指数级。在这些树中,总有那么一棵树比其他的树分类效力都好,那样的树叫做”全局最优树“。

暴力搜索方法肯定行不通,时间复杂度太高。
机器学习研究者们开发了一些有效的算法,能够在合理的时间内构造出具有一定准确率的次最优决策树。这些算法基本都执行”贪心策略“,即通过局部的最优来达到我们相信是最接近全局最优的结果。

在学习算法之前,先了解几个概念:

  1. 信息熵:熵度量了事物的不确定性,越不确定的事物,它的熵就越大。
    随机变量X的熵的表达式如下:
    在这里插入图片描述

其中n代表X的n种不同的离散取值。而 p x i p_{x_i} pxi代表了X取值为i的概率,log为以2或者e为底的对数。

  1. 条件熵 (Conditional Entropy) H ( X ∣ Y ) H(X∣Y) H(XY) 表示在已知随机变量Y的条件下随机变量X的不确定性。

H ( X ∣ Y ) = ∑ j = 1 n p ( y i ) H ( X ∣ y i ) H(X|Y)=\sum_{j=1}^np(y_i)H(X|y_i) H(XY)=j=1np(yi)H(Xyi)

  1. 信息增益:特征A对训练数据集D的信息增益 I ( D , A ) I(D,A) I(D,A),定义为集合D的经验熵 H ( D ) H(D) H(D)与给定特征A在给定条件下D的经验条件熵 H ( D ∣ A ) H(D|A) H(DA)之差,即:

I ( D , A ) = H ( D ) − H ( D ∣ A ) I(D,A)=H(D)-H(D|A) I(D,A)=H(D)H(DA)

H ( D ∣ A ) H(D|A) H(DA)表示在特征A在给定条件下对数据集D进行分类的不确定性,二者之差即为信息增益,表示特征A使得数据集D的分类不确定性减少的程度。
显然,对于信息增益大的特征具有更强的分类能力。

  1. 具体计算示例:

在这里插入图片描述
构建最优树的算法:

ID3 算法

ID3算法的核心就是在决策树各个节点上应用信息增益准则选择特征,递归地构建决策树。

具体过程:-

  1. 输入:训练数据集D、特征集A、,阈值ϵ
  2. 输出: 决策树T

判断T是否需要选择特征生成决策树:

  • 若D中所有实例属于同一类,则T为单结点树,记录实例类别 C k C_k Ck,以此作为该结点的类标记,并返回T;
  • 若D中所有实例无任何特征(A=空集),则T为单结点树,记录D中实例个数最多类别 C k C_k Ck,以此作为该结点的类标记,并返回T ;

否则,计算A中各特征的信息增益,并选择信息增益最大的特征 A g A_g Ag;

  • A g A_g Ag的信息增益小于ϵ,则T为单结点树,记录D中实例个数最多类别 C k C_k Ck ,以此作为该结点的类标记,并返回T ;
  • 否则,按照 A g A_g Ag的每个可能值 a i a_i ai,将D分为若干非空子集 D i D_i Di,将 D i D_i Di中实例个数最多的类别作为标记,构建子结点,以结点和其子节点构成T,并返回T ;

i i i个子结点,以 D i D_i Di为训练集, A − A g A-A_g AAg为特征集合,递归地调用以上步骤,得到子树 T i T_i Ti并返回。

C4.5算法

D3算法有四个主要的不足,一是不能处理连续特征,第二个就是用信息增益作为标准容易偏向于取值较多的特征,最后两个是缺失值处理的问和过拟合问题。C4.5算法中改进了上述4个问题。

==信息增益作为标准容易偏向于取值较多的特征的问题。==我们引入一个信息增益比的变量 I R ( X , Y ) I_R(X,Y) IR(X,Y),它是信息增益和特征熵的比值。表达式如下:

I R ( D , A ) = I ( A , D ) H A ( D ) I_R(D,A)=\frac{I(A,D)}{H_A(D)} IR(D,A)=HA(D)I(A,D)

其中D为样本特征输出的集合,A为样本特征,对于特征熵 H A ( D H_A(D HA(D), 表达式如下:

H A ( D ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ l o g 2 ∣ D i ∣ ∣ D ∣ H_A(D)=-\sum_{i=1}^n\frac{|D_i|}{|D|}log_2\frac{|D_i|}{|D|} HA(D)=i=1nDDilog2DDi
其中n为特征A的类别数, D i D_i Di为特征A的第i个取值对应的样本个数。 ∣ D ∣ |D| D为样本个数。
特征数越多的特征对应的特征熵越大,它作为分母,可以校正信息增益容易偏向于取值较多的特征的问题。

算法流程同ID3,将信息增益换成信息增益比即可。

CART 算法

  1. ID3算法中我们使用了信息增益来选择特征,信息增益大的优先选择。
  2. C4.5算法中,采用了信息增益比来选择特征,以减少信息增益容易选择特征值多的特征的问题。
  3. CART分类树算法使用基尼系数来代替信息增益比,基尼系数代表了模型的不纯度,基尼系数越小,则不纯度越低,特征越好。【简化了运算,没有那么多对数运算】

具体的,在分类问题中,假设有K个类别,第k个类别的概率为 p k p_k pk, 则基尼系数的表达式为:
G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp^2_k Gini(p)=k=1Kpk(1pk)=1k=1Kpk2
对于个给定的样本D,假设有K个类别, 第k个类别的数量为 C k C_k Ck,则样本D的基尼系数表达式为:
G i n i ( D ) = 1 − ∑ k = 1 K ∣ C k ∣ ∣ D ∣ Gini(D)=1-\sum_{k=1}^K\frac{|C_k|}{|D|} Gini(D)=1k=1KDCk

二分类:
G i n i ( D ) = 2 p ( 1 − p ) Gini(D)=2p(1-p) Gini(D)=2p(1p)

对于样本D,如果根据特征A的某个值a,把D分成D1和D2两部分,则在特征A的条件下,D的基尼系数表达式为:

G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A)=\frac{|D_1|}{|D|}Gini(D_1)+\frac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)

CART既可以用于分类又可以用来回归,其中对回归树用平方误差最小化准则,对分类树用基尼指数最小化原则,进行特征选择,生成二叉树。下表列出了三种不同决策树算法的差别:
在这里插入图片描述CART生成分类树,是用基尼指数选择最优特征后,生成的二叉树:

在这里插入图片描述具体流程:

  1. 输入:训练数据集D、特征集A、阈值
  2. 输出:CART决策树T

从根节点出发,进行操作,构建二叉树;

结点处的训练数据集为D,计算现有特征对该数据集的基尼指数,并选择最优特征。

  • 在特征 A g A_g Ag下,对其可能取的每个值 a g a_g ag,根据样本点对 A g = a g A_g= a_g Ag=ag的测试为“是”或“否”,将D分割成 D 1 D_1 D1 D 2 D_2 D2两部分,计算 A g = a g A_g= a_g Ag=ag时的基尼指数。
  • 选择基尼指数最小的那个值作为该特征下的最优切分点。
  • 计算每个特征下的最优切分点,并比较在最优切分下的每个特征的基尼指数,选择基尼指数最小的那个特征,即最优特征。

根据最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。

分别对两个子结点递归地调用上述步骤,直至满足停止条件(比如结点中的样本个数小于预定阈值,或样本集的基尼指数小于预定阈值(样本基本属于同一类),或者没有更多特征),即生成CART决策树。

示例:
在这里插入图片描述在这里插入图片描述在这里插入图片描述基尼指数最小的是青年和老年,都可以作为最优划分点,总的年龄这个特征的基尼指数是:0.44,划分点为青年/老年。

在这里插入图片描述有工作这个特征的基尼指数是0.32,只有两个划分,不需要区分划分点了。

在这里插入图片描述有自己房子这个特征的基尼指数:0.27

在这里插入图片描述信贷情况的基尼指数是0.32,以一般为划分点

基尼指数从小到大排序:有自己房子0.27,有工作0.32,信贷情况0.32(一般),年龄0.44(青年/老年),越小的越好分类:

所以以有自己房子开始进行分类:
在这里插入图片描述在没有房子的条件下计算其他特征的基尼指数:
在这里插入图片描述很明显,有工作这个特征它的基尼指数肯定是等于0的,其他基尼指数都大于0,所以选择有工作进行划分:

在这里插入图片描述

CART生成回归树:
在这里插入图片描述在这里插入图片描述

CART决策树剪枝:

在这里插入图片描述阿拉法到


scikit-learn使用

sklearn.tree介绍
tree.DecisionTreeClassifier分类树
tree.DecisionTreeRegressor回归树
tree.export_graphviz将生成的决策树导出为DOT格式,画图专用
tree.ExtraTreeClassifier高随机版本的分类树
tree.ExtraTreeRegressor高随机版本的回归树

分类树

分类树核心代码:

from sklearn import tree #导入需要的模块
clf = tree.DecisionTreeClassifier()     #实例化
clf = clf.fit(X_train,y_train) #用训练集数据训练模型
result = clf.score(X_test,y_test) #导入测试集,从接口中调用需要的信息

DecisionTreeClassifier参数详解:
在这里插入图片描述简单示例:

导入的库

from sklearn import tree  # 决策树
from sklearn.datasets import load_wine # 酒的数据集
from sklearn.model_selection import train_test_split  # 把数据集分成训练集和测试集

打印看看白酒数据集:
在这里插入图片描述在这里插入图片描述可以通过pandas把数据集拼接一起:
在这里插入图片描述把数据集分成训练集和测试集,参数test_size表示测试集的比例

Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data, wine.target, test_size=0.3)

在这里插入图片描述
定义模型,开始训练,测试:

clf = tree.DecisionTreeClassifier(criterion='entropy')
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) # 返回预测的准确度accuracy
score

在这里插入图片描述
看一看模型给我们定义的决策树:

feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚','类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']import graphviz
dot_data = tree.export_graphviz(clf, feature_names=feature_name, class_names=['清酒', '雪梨', '贝尔摩德'], filled=True, rounded=True)
graph = graphviz.Source(dot_data)
graph  # graph.view()

注意如果pycharm能显示图片,而jupyter不能,报错找不到graphviz模块,可以试一下下面操作:在jupyter中执行conda install python-graphviz
在这里插入图片描述

在这里插入图片描述

  • 第一行:划分条件,脯氨酸是否小于760,是往左边走,不是往右边走。
  • 第二行:entropy,信息增益比,越大分类越好,越靠前。当entropy=0时,可以选出类别了。
  • sample: 样本数量。
  • value:每个类别的数量。
  • class:类别

决策树并不会选择全部特征可以通过feature_importances_来查看:
在这里插入图片描述在这里插入图片描述

scikit-learn在每次分枝时,不从使用全部特征,而是随机选取一部分特征,从中选取不纯度相关指标最优的作为分枝用的节点。这样,每次生成的树也就不同了,准确率也不一样,不希望每次结果不一样,需要添加参数random_state来控制随机性:

random_state用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,低维度的数据(比如鸢尾花数据集),随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来。

clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest) #返回预测的准确度
score

splitter也是用来控制决策树中的随机选项的,有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看),输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。

clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score

在这里插入图片描述

dot_data = tree.export_graphviz(clf,feature_names= feature_name,class_names=["琴酒","雪莉","贝尔摩德"],filled=True,rounded=True)
graph = graphviz.Source(dot_data)
graph

在这里插入图片描述随机性增加了,树变深了。

剪枝参数

在不加限制的情况下,一棵决策树会生长到衡量entropy的指标最优,或者没有更多的特征可用为止。这样的决策树往往会过拟合,这就是说,它会在训练集上表现很好,在测试集上却表现糟糕,我们需要使用剪枝参数来防止过拟合。

剪枝策略对决策树的影响巨大,正确的剪枝策略是优化
决策树算法的核心。sklearn为我们提供了不同的剪枝策略:

  • max_depth
    限制树的最大深度,超过设定深度的树枝全部剪掉
    这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效地限制过拟合。在集成算法中也非常实用。实际使用时,建议从=3开始尝试,看看拟合的效果再决定是否增加设定深度。

  • min_samples_leaf & min_samples_split 限定叶子节点
    min_samples_leaf限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本【对应图中simple值】,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生
    一般搭配max_depth使用,在回归树中有神奇的效果,可以让模型变得更加平滑。
    这个参数的数量设置得太小会引起过拟合,设置得太大就会阻止模型学习数据。
    一般来说,建议从=5开始使用。如果叶节点中含有的样本量变化很大,建议输入浮点数作为样本量的百分比来使用。同时,这个参数可以保证每个叶子的最小尺寸,可以在回归问题中避免低方差,过拟合的叶子节点出现。对于类别不多的分类问题,=1通常就是最佳选择
    min_samples_split限定,一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生。

clf = tree.DecisionTreeClassifier(criterion='entropy',random_state=30# ,splitter='random',max_depth=3,min_samples_leaf=10,min_samples_split=10)
clf = clf.fit(Xtrain, Ytrain)dot_data = tree.export_graphviz(clf,feature_names= feature_name,class_names=["琴酒","雪莉","贝尔摩德"],filled=True,rounded=True)
graph = graphviz.Source(dot_data)
graph

在这里插入图片描述我们对上面的几个参数进行调参,找准确率最高的:
在这里插入图片描述在这里插入图片描述

  • max_features & min_impurity_decrease
    一般max_depth使用,用作树的”精修“
    max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。和max_depth异曲同工,max_features是用来限制高维度数据的过拟合的剪枝参数,但其方法比较暴力,是直接限制可以使用的特征数量而强行使决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。如果希望通过降维的方式防止过拟合,建议使用PCA,ICA或者特征选择模块中的降维算法。
    min_impurity_decrease限制信息增益的大小,信息增益小于设定数值的分枝不会发生。

确认最优的剪枝参数
使用确定超参数的曲线来进行判断了,继续使用我们已经训练好的决策树模型clf。超参数的学习曲线,是一条以超参数的取值为横坐标,模型的度量指标为纵坐标的曲线,它是用来衡量不同超参数取值下模型的表现的线。在我们建好的决策树里,我们的模型度量指标就是score。

max_depth为例:

import matplotlib.pyplot as plt
test = []
for i in range(10):clf = tree.DecisionTreeClassifier(max_depth=i+1,criterion="entropy",random_state=30,splitter="random")clf = clf.fit(Xtrain, Ytrain)score = clf.score(Xtest, Ytest)test.append(score)
plt.plot(range(1,11),test,color="red",label="max_depth")
plt.legend()
plt.show()

在这里插入图片描述可以看到max_depth=4时,准确度最高。

  • class_weight & min_weight_fraction_leaf 【控制目标权重】
    完成样本标签平衡的参数。样本不平衡是指在一组数据集中,标签的一类天生占有很大的比例。比如说,在银行要判断“一个办了信用卡的人是否会违约”,就是是vs否(1%:99%)的比例。这种分类状况下,即便模型什么也不做,全把结果预测成“否”,正确率也能有99%。因此我们要使用class_weight参数对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给与数据集中的所有标签相同的权重。
    有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配min_weight_fraction_leaf这个基于权重的剪枝参数来使用。另请注意,基于权重的剪枝参数(例如min_weight_fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。

重要属性和接口

属性是在模型训练之后,能够调用查看的模型的各种性质。对决策树来说,最重要的是feature_importances_,能够查看各个特征对模型的重要性。

决策树最常用的接口:

  • fit
  • score
  • apply
  • predict
#apply返回每个测试样本所在的叶子节点的索引
clf.apply(Xtest)
#predict返回每个测试样本的分类/回归结果
clf.predict(Xtest)

回归树

DecisionTreeRegressor几乎所有参数,属性及接口都和分类树一模一样。需要注意的是,在回归树种,没有标签分布是否均衡的问题,因此没有class_weight这样的参数。

重要参数,属性及接口

criterion
回归树衡量分枝质量的指标,支持的标准有三种:
1)输入"mse"使用均方误差mean squared error(MSE),父节点和叶子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子节点的均值来最小化L2损失
2)输入“friedman_mse”使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差
3)输入"mae"使用绝对平均误差MAE(mean absolute error)
这种指标使用叶节点的中值来最小化L1损失属性中最重要的依然是feature_importances_,
接口依然是apply, fit, predict, score最核心。

交叉验证

交叉验证是用来观察模型的稳定性的一种方法,我们将数据划分为n份,依次使用其中一份作为测试集,其他n-1份作为训练集,多次计算模型的精确性来评估模型的平均准确程度。训练集和测试集的划分会干扰模型的结果,因此用交叉验证n次的结果求出的平均值,是对模型效果的一个更好的度量。在这里插入图片描述

代码示例

from sklearn.datasets import load_boston  # 波士顿房价数据集
from sklearn.model_selection import cross_val_score # 交叉验证
from sklearn.tree import DecisionTreeRegressor # 回归树
boston = load_boston()
regressor = DecisionTreeRegressor(random_state=0)
cross_val_score(regressor, boston.data, boston.target, cv=10, scoring = "neg_mean_squared_error") # 均方误差

一维回归的图像绘制

import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as pltrng = np.random.RandomState(1)
X = np.sort(5 * rng.rand(80,1), axis=0) # 创建80个(0,1)的随机数,扩大五倍,排序
y = np.sin(X).ravel()  # 降维ravel
y[::5] += 3 * (0.5 - rng.rand(16)) # 每个5个数,制造一个噪声regr_1 = DecisionTreeRegressor(max_depth=2) # 模型1
regr_2 = DecisionTreeRegressor(max_depth=5) # 模型2
regr_1.fit(X, y) # 模型1训练
regr_2.fit(X, y) # 模型2训练X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis] # 创建一组测试集 np.newaxis 增维
y_1 = regr_1.predict(X_test) # 预测 模型1
y_2 = regr_2.predict(X_test) # 预测 模型2plt.figure() # 画布
plt.scatter(X, y, s=20, edgecolor="black",c="darkorange", label="data") # 散点图
plt.plot(X_test, y_1, color="cornflowerblue",label="max_depth=2", linewidth=2) # 回归预测图1
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2) # 回归预测图2
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()

在这里插入图片描述如果树的最大深度(由max_depth参数控制)设置得太高,则决策树学习得太精细,它从训练数据中学了很多细节,包括噪声得呈现,从而使模型偏离真实的正弦曲线,形成过拟合。


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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法优选】 二分查找专题——贰

文章目录 😎前言🌲[山脉数组的峰顶索引](https://leetcode.cn/problems/peak-index-in-a-mountain-array/)🚩题目描述:🚩算法思路🚩代码实现: 🌴[寻找峰值](https://leetcode.cn/pro…

VUE3基础知识梳理

VUE3基础知识梳理 一、vue了解和环境搭建1.vue是什么:cn.vuejs.org/vuejs.org2.渐进式框架3.vue的版本4.vueAPI的风格5.准备环境5.1.创建vue项目5.2.vue的目录结构 二、vue3语法1.干净的vue项目2.模板语法2.1 文本插值2.2属性绑定2.3条件渲染2.4列表渲染2.5通过key管…

10、SpringBoot_测试用例

四、测试用例 1.准备工作 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><dependency><groupId>com…

ELK 处理 SpringCloud 日志

在排查线上异常的过程中&#xff0c;查询日志总是必不可缺的一部分。现今大多采用的微服务架构&#xff0c;日志被分散在不同的机器上&#xff0c;使得日志的查询变得异常困难。工欲善其事&#xff0c;必先利其器。如果此时有一个统一的实时日志分析平台&#xff0c;那可谓是雪…

2023年电工(初级)证考试题库及电工(初级)试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年电工&#xff08;初级&#xff09;证考试题库及电工&#xff08;初级&#xff09;试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#…

mysql面试题40:列值为null或者空字符串时,查询是否会用到索引?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:列值为null或者空字符串时,查询是否会用到索引? 当列的值为NULL时,查询可能会使用索引,但具体是否使用索引取决于数据库的优化器和查询条件。…

Compose 编译器版本和Kotlin版本对应关系

使用了最新的kotlin版本&#xff0c;compose报错&#xff0c;不兼容&#xff0c;在这里记录一下版本对应关系 值得注意的是Compose Kotlin 编译器扩展 (androidx.compose.compiler) 未关联到 Compose 库版本。相反&#xff0c;它会关联到 Kotlin 编译器插件的版本&#xff0c;…

【SoC FPGA】HPS启动过程

SoC HPS启动流程 Boot ROMPreloaderBoot Loader HPS的启动是一个多阶段的过程&#xff0c;每一个阶段都会完成对应的工作并且将下一个阶段的执行代码引导起来。每个阶段均负责加载下一个阶段。第一个软件阶段是引导 ROM&#xff0c;引导 ROM 代码查找并且执行称为预加载器的第 …

【ArcGIS】NDVI估算植被覆盖度FVC

NDVI计算 植被覆盖度计算 Step1&#xff1a;调出栅格计算器工具 1、首先打开软件&#xff0c;然后在操作页面点击&#xff0c;自定义工具栏中——自定义模式。 2、再点击窗口中的命令选项。 3、在窗口右上角处搜索“栅格计算”。 4、然后&#xff0c;直接将栅格计算器直接…

Linux C select 的学习

一. select 系统调用 1. 函数说明 #include <sys/select.h> #include <sys/time.h>int select(int nfds, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeval *timeout);nfds: 是一个整数值&#xff0c;是指集合中所有文件描述符的范围&#…

SpringBoot 接口 字节数组直接显示为图片

源码&#xff1a; import java.io.ByteArrayOutputStream; import javax.imageio.ImageIO; import org.springframework.web.bind.annotation.RequestMapping;/*** 获取二维码图像* 二维码支付** param price 金额* return 二维码图像* throws IOException IOException*/ Requ…

Windows Nginx 服务器部署(保姆级)

大家好 我是寸铁 不知道怎么部署Windows Nginx 服务器看过来 手把手带你部署服务器 将你的本地网页部署到服务器上 话不多说&#xff0c;直接上操作&#xff01;&#xff01;&#xff01; Windows Nginx服务器部署 进入下载地址&#xff1a; http://nginx.org/en/download.h…

stm32学习笔记:中断的应用:对射式红外传感器计次旋转编码器计次

相关API介绍 EXT配置API(stm32f10x exti.h&#xff09; NVIC 配置API (misc.h) 初始化的中断的步骤 第一步&#xff1a;配置RCC时钟&#xff0c;把涉及外设的时钟都打开 第二步&#xff1a;配置GPIO&#xff0c;设置为输入模式 第三步&#xff1a;配置AFIO&#xff0…

VsCode同时编译多个C文件

VsCode默认只能编译单个C文件&#xff0c;想要编译多个文件&#xff0c;需要额外进行配置 第一种方法 ——> 通过手动指定要编译的文件 g -g .\C文件1 .\C文件2 -o 编译后exe名称 例如我将demo.c和extern.c同时编译得到haha.exe g -g .\demo.c .\extern.c -o haha 第二种…

移动应用-Android开发基础\核心知识点

Android开发基础 知识点 1 介绍了解2 系统体系架构3 四大应用组件4 移动操作系统优缺点5 开发工具6 配置工具7 下载相关资源8JDK下载安装流程9配置好SDK和JDK环境10 第一个Hello word11 AS开发前常用设置12模拟器使用运行13 真机调试14 AndroidUI基础布局15 加载展示XML布局16…

dll动态链接库及ocx activex 控件regsvr32注册失败 解决方法(Win10)

一、错误提示说明&#xff1a; 1、regsvr32注册dll或ocx activex控件时提示模块 dll加载失败&#xff0c;请确保该二进制存储在指定的路径中&#xff0c;或者调试它以检查该二进制或相关的.dll文件是否有问题”。 检查了.dll文件路径也没有问题&#xff0c;在开发机器上是可以…

【Java 进阶篇】JavaScript三元运算符详解

JavaScript是一门广泛用于前端和后端开发的编程语言&#xff0c;具备强大的表达式和运算符。本篇博客将重点介绍JavaScript中的三元运算符&#xff0c;解释其语法、用法和示例。如果您是JavaScript初学者&#xff0c;或者希望更深入了解这门语言的运算符&#xff0c;那么这篇博…

适合自学的网络安全基础技能“蓝宝书”:《CTF那些事儿》

CTF比赛是快速提升网络安全实战技能的重要途径&#xff0c;已成为各个行业选拔网络安全人才的通用方法。但是&#xff0c;本书作者在从事CTF培训的过程中&#xff0c;发现存在几个突出的问题&#xff1a; 1&#xff09;线下CTF比赛培训中存在严重的 “最后一公里”问题 &#…

鉴源实验室 | AUTOSAR SecOC:保障汽车通信的安全

作者 | 沈平 上海控安可信软件创新研究院汽车网络安全组 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 在现代汽车行业中&#xff0c;随着电子控制单元&#xff08;ECUs&#xff09;的普及以及车与车之间通信的不断增加&#xff0c;确…

【Linux 安装Kibana 及 Es 分词器安装】

一、客户端Kibana安装 Kibana是一个开源分析和可视化平台&#xff0c;旨在与Elasticsearch协同工作。参考文档 1. 下载并解压缩Kibana 下载路径 选择的版本是和 ElasticSearch 对应&#xff08;7.17.3&#xff09; 下载后上传到Linux 系统中&#xff0c;并放在 /root/ 下&a…