Lesson 8.1 决策树的核心思想与建模流程

news2024/11/18 10:07:04

文章目录

  • 一、借助逻辑回归构建决策树
    • 1. 决策树实例
    • 2. 决策树知识补充
      • 2.1 决策树简单构建
      • 2.2 决策树的分类过程
      • 2.3 决策树模型本质
      • 2.4 决策树的树生长过程
      • 2.5 树模型的基本结构
  • 二、决策树的分类与流派
    • 1. ID3(Iterative Dichotomiser 3) 、C4.5、C5.0 决策树
    • 2. CART 决策树
    • 3. CHAID 树

  • 与此前的聚类算法类似,树模型也同样不是一个模型,而是一类模型的概称。
  • 树模型不仅运算效率高、模型判别能力强、而且原理简单过程清晰、可解释性强,是机器学习领域内为数不多的白箱模型。
  • 并且就树模型本身的功能来说,除了能够同时进行分类和回归预测外,还能够产出包括特征重要性、连续变量分箱指标等重要附加结论,而在集成学习中,最为常用的基础分类器也正是树模型。
  • 正是这些优势,使得树模型成为目前机器学习领域最为重要的模型之一。

一、借助逻辑回归构建决策树

1. 决策树实例

  • 那到底什么是树模型?接下来我们简单介绍树模型建模的基本思想 。
  • 尽管树模型作为经典模型,发展至今已是算法数量众多、流派众多,但大多数树模型的基本思想其实是相通的,我们可以用一句话来解释树模型的模型形态和建模目标,那就是:挖掘有效分类规则并以树状形式呈现。
  • 接下来我们就以一个简单实例进行说明,我们借助此前所学的基本建模知识,尝试复现决策树的基本分类思想。
  • 在最开始,我们先导入常用的模块。
# 科学计算模块
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
  • 在 Lesson 6.5 节中,我们曾围绕鸢尾花数据集构建了多分类逻辑回归模型并且采用网格搜索对其进行最优超参数搜索,其基本过程如下:
# 数据准备
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=24)

# 模型训练# 实例化模型
clf = LogisticRegression(max_iter=int(1e6), solver='saga')
# 构建参数空间
param_grid_simple = {'penalty': ['l1', 'l2'], 'C': [1, 0.5, 0.1, 0.05, 0.01]}
# 构建网格搜索评估器
search = GridSearchCV(estimator=clf, param_grid=param_grid_simple)# 模型训练
search.fit(X_train, y_train)
#GridSearchCV(estimator=LogisticRegression(max_iter=1000000, solver='saga'),
#             param_grid={'C': [1, 0.5, 0.1, 0.05, 0.01], 'penalty': ['l1', 'l2']})

search.best_params_
#{'C': 1, 'penalty': 'l1'}

search.best_estimator_.coef_
#array([[ 0.        ,  0.        , -3.47337669,  0.        ],
#       [ 0.        ,  0.        ,  0.        ,  0.        ],
#       [-0.55511761, -0.34237661,  3.03227709,  4.12148646]])

search.best_estimator_.intercept_
#array([ 11.85884734,   2.65291107, -14.51175841])
  • 我们发现,在参数组取值为 {‘C’: 1, ‘penalty’: ‘l1’} 的情况下,三个逻辑回归方程中,第一个方程只包含一个系数,也就是说明第一个方程实际上只用到了原数据集的一个特征,第二个方程自变量系数均为 0、基本属于无用方程,而只有第三个方程自变量系数都不是 0、看起来比较正常。
  • 我们知道,对于多分类问题,逻辑回归所构建的模型方程实际上是每个方程对应预测一个类别,而由于总共只有三个类别,因此是允许存在一个类别的预测方程失效的,只要剩下的两个类别能够各自完成对应类别的预测,则剩下的样本就属于第三类。
  • 此处我们需要重点关注的是第一个方程,该方程只有一个非零系数,其背后含义是模型只借助特征矩阵中的第三个特征,就很好的将第一类鸢尾花和其他鸢尾花区分开了。
  • 我们进一步观察数据和第三个特征对于第一个类别的分类结果:
iris = load_iris(as_frame=True)
iris.data
#	sepal length (cm)	sepal width (cm)	petal length (cm)	petal width (cm)
#0	5.1	3.5	1.4	0.2
#1	4.9	3.0	1.4	0.2
#2	4.7	3.2	1.3	0.2
#3	4.6	3.1	1.5	0.2
#4	5.0	3.6	1.4	0.2
#...	...	...	...	...
#145	6.7	3.0	5.2	2.3
#146	6.3	2.5	5.0	1.9
#147	6.5	3.0	5.2	2.0
#148	6.2	3.4	5.4	2.3
#149	5.9	3.0	5.1	1.8
#150 rows × 4 columns

t = np.array(iris.target)
t[50:]
#array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

# 将2、3类划归为一类
t[50:] = 1
t
#array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

# 此处提取第3、4个特征放置二维空间进行观察,用第三个特征和其他特征组合也是类似
d = np.array(iris.data.iloc[:, 2: 4])

plt.scatter(d[:, 0], d[:, 1], c=t)
plt.plot(np.array([2.5]*25), np.arange(0, 2.5, 0.1), 'r--')

在这里插入图片描述

  • 我们发现,确实可以通过第三个特征(横坐标)很好的区分第一类(紫色点簇)和其他两类(黄色点簇),也就是说,从分类结果来看,我们能够简单通过一个分类规则来区分第一类鸢尾花和其他两类.
  • 例如从上图可以看出,我们可以以 petal length (cm) <= 2.5 作为分类条件,当分类条件满足时,鸢尾花属于第一类,否则就属于第二、三类。至此我们集完成了对上述数据集的初步分类,基本分类情况可以通过下图来进行表示:

在这里插入图片描述

  • 当然围绕上述未分类的二、三类鸢尾花数据,我们能否进一步找到类似刚才的分类规则对其进行有效分类呢?
  • 当然此处由于我们希望分类规则能够尽可能简洁,我们力求找出根据某一个特征的取值划分就能对数据集进行有效分类的方法,这时我们可以考虑先利用逻辑回归的 l 1 l1 l1 正则化挑选出对二、三类分类最有分类效力的特征(也就是最重要的特征)。
  • 然后根据只有一个特征系数不为 0 的带 l 1 l1 l1 正则化的逻辑回归建模结果、找到决策边界,而该决策边界就是依据该单独特征划分 Iris 二、三类子数据的最佳方法。我们可以通过下述代码实现:
# 提取待分类的子数据集
X = np.array(iris.data)[t == 1]
y = np.array(iris.target)[t == 1]
  • 接下来,我们构建一个包含 l 1 l1 l1 正则化的逻辑回归模型,并通过不断调整 C 的取值、通过观察参数系数变化情况来挑选最重要的特征:
C_l = np.linspace(1, 0.1, 100)

coef_l = []for C in C_l:
    clf = LogisticRegression(penalty='l1', C=C, max_iter=int(1e6), solver='saga').fit(X, y)
    coef_l.append(clf.coef_.flatten())

ax = plt.gca()
ax.plot(C_l, coef_l)
ax.set_xlim(ax.get_xlim()[::-1])
plt.xlabel('C')
plt.ylabel('weights')
Text(0, 0.5, 'weights')

在这里插入图片描述

coef_l
  • 不难看出,在对鸢尾花数据集的二、三分类的子数据集进行分类时,仍然还是第三个特征会相对重要,因此我们根据上述结果,构建一个正则化项为 l 1 l1 l1、C 取值为 0.2 的逻辑回归模型进行训练,此时由于其他三个特征的参数都被归零,因此该模型训练过程实际上就相当于带入第三个特征进行建模:
clf = LogisticRegression(penalty='l1', C=0.2, max_iter=int(1e6), solver='saga').fit(X, y)

clf.coef_, clf.intercept_
#(array([[0.        , 0.        , 2.84518611, 0.        ]]),
# array([-13.88186328]))

clf.score(X, y)
#0.93
  • 此时模型准确率为 93%,同样,如果构建一个只包含第三、四个特征的特征空间,此时上述逻辑回归建模结果的决策边界为 x=b,其中 b 的取值如下:
b = 13.88186328 / 2.84518611
b
#4.87907038179657
  • 我们可以通过可视化的方法观察此时特征空间中样本分布情况,以及 x=b 的决策边界的分类效果:
plt.plot(X[:, 2][y==1], X[:, 3][y==1], 'ro')
plt.plot(X[:, 2][y==2], X[:, 3][y==2], 'bo')
plt.plot(np.array([b]*20), np.arange(0.5, 2.5, 0.1), 'r--')

在这里插入图片描述

  • 当然,我们也可以简单验算下 x=b 的决策边界是否是模型真实的分类边界:
y_pred = clf.predict(X)

plt.scatter(X[:, 2], X[:, 3], c=y_pred)
plt.plot(np.array([b]*20), np.arange(0.5, 2.5, 0.1), 'r--')

在这里插入图片描述

  • 注意,在确定第一个分类条件时我们没有直接根据逻辑回归的线性方程计算决策边界的主要原因是彼时逻辑回归方程是在 mvm 分类规则下的三个分类方程,其中每个方程其实都会一定程度上受到其他方程影响,导致决策边界无法直接通过方程系数进行计算。
  • 尽管 x=b 分类边界的准确率不足 100%,但其仍然不失为一个不错的分类规则,即分类条件为 petal length (cm) <= 4.879,当分类条件满足时,鸢尾花属于第二类、不满足时鸢尾花属于第三类。
  • 根据此分类条件进行的分类准确率为 93%。我们可以将围绕鸢尾花子数据集进行二、三类的分类过程进行如下方式表示:

在这里插入图片描述

  • 至此,我们就根据两个简单的分类规则,对鸢尾花数据集进行了有效划分,此时整体准确率为:
1-(y != y_pred).sum() / 150
#0.9533333333333334

2. 决策树知识补充

2.1 决策树简单构建

  • 而上述整个过程,我们是通过带正则化项的逻辑回归模型挖掘出的两个分类规则,并且这两个分类规则呈现递进的关系,也就是一个分类规则是在另一个分类规则的分类结果下继续进行分类,最终这两个分类规则和对应划分出来的数据集呈现出树状,而带有不同层次分类规则的模型,其实就是决策树模型,也就是说通过上面一系列的操作,我们就已经成功构建了一个决策树模型。

2.2 决策树的分类过程

  • 对于上述已经构建好的一个决策树来说,当对新数据进行判别时,任意进来一条数据我们都可以自上而下进行分类,先根据 petal length (cm) <= 2.5 判断是否属于第一类,如果不满足条件则不属于第一类,此时进一步考虑 petal length (cm) <= 4.879 是否满足条件,并据此判断是属于第二类还是第三类。
  • 当然,目前主流的决策树并不是依据逻辑回归来寻找分类规则,但上述构建决策树模型的一般过程和核心思想和目前主流的决策树模型并无二致,因此我们可以围绕上述过程进行进一步总结。

2.3 决策树模型本质

  • 当决策树模型构建好了之后,实际上一个决策树就是一系列分类规则的叠加,换而言之,决策树模型的构建从本质上来看就是在挖掘有效的分类规则,然后以树的形式来进行呈现。

2.4 决策树的树生长过程

  • 在整个树的构建过程中,我们实际上是分层来对数据集进行划分的,每当定下一个分类规则后,我们就可以根据是否满足分类规则来对数据集进行划分,而后续的分类规则的挖掘则进一步根据上一层划分出来的子数据集的情况来定,逐层划分数据集、逐数据集寻找分类规则再划分数据集,实际上就就是树模型的生长过程。
  • 这个过程实际上也是一个迭代计算过程(上一层的数据集决定有效规律的挖掘、而有效规律的挖掘)。而停止生长的条件,我们也可以根据继续迭代对结果没有显著影响这个一般思路来构建。

2.5 树模型的基本结构

  • 当然,在已经构建了决策树之后,我们也能够对一个树模型的内部结构来进行说明。
  • 对上述决策树来说,我们可以将其看成是点(数据集)和线构成的一个图结构(准确来说应该是一种有向无环图),而对于任何一个图结构,我们都能够通过点和线来构建对其的基本认知。
  • 对于决策树来说,我们主要将借助边的方向来定义不同类型点,首先我们知道如果一条边从 A 点引向 B 点,则我们这条边对于 A 点来说是出边、对于 B 点来说是入边,A 节点是 B 节点的父节点,据此我们可以将决策树中所有的点进行如下类别划分:
  • (1) 节点(root node):没有入边,但有零条或者多条出边的点;
  • (2) 内部点(internal node):只有一条入边并且有两条或多条出边的点;
  • (3) 叶节点(leaf node):只有入边但没有出边的点;
  • 因此,我们知道在一次次划分数据集的过程中,原始的完整数据集对应着决策树的根节点,而根结点划分出的子数据集就构成了决策树中的内部节点,同时迭代停止的时候所对应的数据集,其实就是决策树中的叶节点。
  • 并且在上述二叉树(每一层只有两个分支)中,一个父节点对应两个子节点。并且根据上述决策树的建模过程不难理解,其实每个数据集都是由一系列分类规则最终划分出来的,我们也可以理解成每个节点其实都对应着一系列分类规则,例如上述 E 节点实际上就是 petal length (cm) <= 2.5 和 petal length (cm) <= 4.879 同时为 False 时划分出来的数据集。

二、决策树的分类与流派

  • 正如此前所说,树模型并不是一个模型,而是一类模型。需要知道的是,尽管树模型的核心思想都是源于一种名为贪心算法的局部最优求解算法,但时至今日,树模型已经有数十种之多,并且划分为多个流派。目前主流的机器学习算法类别可划分如下:

1. ID3(Iterative Dichotomiser 3) 、C4.5、C5.0 决策树

  • ID3(Iterative Dichotomiser 3) 、C4.5、C5.0 决策树是最为经典的决策树算法、同时也是真正将树模型发扬光大的一派算法。
  • 最早的 ID3 决策树由 Ross Quinlan 在 1975 年(博士毕业论文中)提出,至此也奠定了现在决策树算法的基本框架——确定分类规则判别指标、寻找能够最快速降低信息熵的方式进行数据集划分(分类规则提取),不断迭代直至收敛。
  • 而 C4.5 则是 ID3 的后继者,C4.5 在 ID3 的基础上补充了一系列基础概念、同时也优化了决策树的算法流程,一方面使得现在的树模型能够处理连续变量(此前的 ID3 只能处理分类变量),同时也能够一定程度提高树模型的生长速度,而 C4.5 也是目前最为通用的决策树模型的一般框架,后续尽管有其他的决策树模型诞生,但大都是在 C4.5 的基本流程上进行略微调整或者指标修改。
  • 此外,由于 C4.5 开源时间较早,这也使得在过去的很长一段时间内,C4.5 都是最通用的决策树算法。当然在此后,Ross Quinlan 又公布了 C5.0 算法,进一步优化了运行效率和预测流程,通过一系列数据结构的调整使得其能够更加高效的利用内存、并提高执行速度。

2. CART 决策树

  • CART 全称为 Classification and Regression Trees,即分类与回归决策树,同时也被称为 C&RT 算法,在 1984 年由 Breiman、Friedman、Olshen 和 Stone 四人共同提出。
  • CART 树和 C4.5 决策树的构造过程非常类似,但拓展了回归类问题的计算流程(此前 C4.5 只能解决分类问题),并且允许采用更丰富的评估指标来指导建模流程,并且,最关键的是,CART 算法其实是一个非常典型的机器学习算法,在早期 CART 树的训练过程中,就是通过划分训练集和验证集(或者测试集)来验证模型结果、并进一步据此来调整模型结构。
  • 当然,除此以外,CART 树还能够用一套流程同时处理离散变量和连续变量、能够同时处理分类问题和回归问题。
  • 此处我们也可以参考 sklearn 中对于 ID3、C4.5 和 CART 树的对比描述:

在这里插入图片描述

  • 需要注意的是,sklearn 中也并非实现的是完全的 CART 树,通过相关评估器参数的调整,sklearn 中也能实现 CART 树的建模流程 + C4.5 的决策树生长指标这种混合模型。

3. CHAID 树

  • CHAID 是 Chi-square automatic interaction detection 的简称,由 Kass 在 1975 年提出,如果说 CART 树是一个典型的机器学习算法,那么 CHAID 树就是一个典型的统计学算法。
  • 从该算法的名字就能看出,整个决策树其实是基于卡方检验(Chi-square)的结果来构建的,并且整个决策树的建模流程(树的生长过程)及控制过拟合的方法(剪枝过程)都和 C4.5、CART 有根本性的区别,例如 CART 都只能构建二叉树,而 CHAID 可以构建多分枝的树(注:C4.5 也可以构建多分枝的树)。
  • 例如 C4.5 和 CART 的剪枝都是自下而上(Bottom-up)进行剪枝,也被称为修剪法(Pruning Technique),而 CHAID 树则是自上而下(Top-Down)进行剪枝,也被称为盆栽法(Bonsai Technique)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

minio安装配置和使用(一)

minio官网https://www.minio.org.cn 从官网获得安装文件。官网提供了Binary、RPM、DEB三种方式安装minio。 Binary方式我在我的测试环境中没有测试通过&#xff0c;按官网方式下载执行会报错如下&#xff1a; 查了下这个错误提示&#xff0c;似乎跟内存有关。 改用RPM方式安…

HCIP第一个实验

实验要求与实验拓扑子网划分分析将骨干链路看成一个整体&#xff0c;路由器后的2个环回地址先看成一个&#xff0c;最后再进行拆分。计算得出&#xff0c;一共需要划分为6个子网段&#xff0c;取三位。再将每一条网段&#xff0c;按照题目要求进行划分最后完成子网划分。子网划…

进行嵌入式C语言编程调试的通用办法

总结了一下调试我们嵌入式C程序的一些基本的办法和思想&#xff0c;供大家学习参考&#xff1a; 打印日志&#xff1a;在代码中添加打印语句&#xff0c;输出变量值、函数调用等信息&#xff0c;以便在程序运行时观察程序执行情况。 断点调试&#xff1a;在代码中添加断点&…

【编程实践】用 go 语言实现 B+ 树

文章目录 用 go 语言实现 B+ 树定义 B+ 树的结构B+ 树的插入操作函数B+ 树的查找小结用 go 语言实现 B+ 树 B+ 树是一种平衡的查找树,它可以有效组织存储大量的键值对,从而支持快速的插入和查找操作。 Go 语言可以用来实现 B+ 树,实现的思路是:首先,定义 B+ 树的结构,其…

【Linux】安装Linux操作系统具体步骤

1). 选择创建新的虚拟机 2). 选择"典型"配置 3). 选择"稍后安装操作系统(S)" 4). 选择"Linux"操作系统,"CentOS7 64位"版本 5). 设置虚拟机的名称及系统文件存放路径 6). 设置磁盘容量 7). 自定义硬件信息 8). 启动上述创建的新虚拟机…

【C++初阶】list的使用

大家好我是沐曦希&#x1f495; 文章目录一、前言二、构造三、迭代器四、增删查改1.头插头删2.尾插尾删3.查找和插入4.删除五、其他成员函数1.排序和去重2.splice和remove3.resize一、前言 list本质是带头双向循环链表&#xff0c;本文只对list的一些常用接口进行说明&#xf…

Qt creator中操作QAction加入QToolBar

背景&#xff1a;个人笔记。我之前没有系统化学习过任何资料&#xff0c;使用很多工具都是按需出发&#xff0c;直接上手&#xff0c;遇到问题再研究的。所以会有一些弯路。本文言语中难免有对个人情绪的生动描述&#xff0c;希望不要影响读者心情&#xff0c;这只是我学习过程…

前端网络安全

什么是同源策略同源指的是&#xff1a;协议、端口号、域名必须一致。他是浏览器的一个用于隔离潜在恶意文件的重要安全机制。限制了从同一个源加载的文档或脚本&#xff0c;与另一个源的资源进行交互。同源策略主要限制了三个方面&#xff1a;当前域下的js脚本不能够访问其他域…

waf和web应用防火墙的区别

waf和web应用防火墙有什么区别?相信这两个词大家都不陌生&#xff0c;特别是做互联网行业的小伙伴们。对于waf和web应用防火墙&#xff0c;这两个名词的理解应该都很清楚。但是很多小伙伴们不知道WAF防火墙与Web防火墙有什么区别&#xff0c;它们之间的区别在哪里&#xff0c;…

Spring Cloud(微服务)学习篇(七)

Spring Cloud(微服务)学习篇(七) 1.使用代码的方式实现流量限制规则 1.1 变更SentinelController类 1.1.1 加入的代码 //流控限制 (一个或多个资源限流), postConstruct注解的作用是保证项目一启动就会加载,// 一个rule就是一个规则PostConstructpublic void FlowRule(){Li…

【C++】string的成员函数、成员常量和非成员函数

目录 string 1. string的成员函数 1.1 构造、析构和赋值运算符重载 1.1.1 构造函数 1.1.2 析构函数 1.1.3 赋值运算符重载 1.2 迭代器 1.3 容量 1.4 元素访问 1.4.1 遍历方法 1.5 修改器 1.6 字符串操作 2. string的成员常量 3. string的非成员函数 string 以下…

javaEE 初阶 — 应用层中的 DNS 协议(域名解析系统)

文章目录什么是域名1. 如何建立 域名 与 IP 的对应关系2. 域名的分级什么是域名 域名也就是平常所说的网址&#xff0c;比如 www.baidu.com。 其实网络上的服务器要访问这个网址&#xff0c;需要的是 IP 地址。、 但是 IP 地址比较拗口不方便记忆&#xff0c;于是就有使用一些…

单向非循环链表

1、顺序表遗留问题 1. 中间/头部的插入删除&#xff0c;时间复杂度为O(N) 2. 增容需要申请新空间&#xff0c;使用malloc、realloc等函数拷贝数据&#xff0c;释放旧空间。会有不小的消耗。 3. 当我们以2倍速度增容时&#xff0c;势必会有一定的空间浪费。例如当前容量为100&a…

IDEA这些配置,简单高效

优化导包配置配置路径&#xff1a;File-> settings -> Editor -> General -> Auto ImportAdd unambiguous imports on the fly&#xff1a;自动导包Optimize imports on th fly (for current project)&#xff1a;自动删除无用包代码提示取消大小写配置路径&#x…

AOP(概念和原理)

文章目录1. AOP&#xff08;概念&#xff09;2. AOP&#xff08;底层原理&#xff09;2.1 AOP底层使用动态代理&#xff08;两种&#xff09;2.2 AOP 底层使用哪种代理方式 &#xff1f;3. AOP相关概念3.1 AOP术语4. AOP操作4.1 基于AspectJ实现AOP操作4.2 切点表达式4.3 基于A…

6 分布式事务简介

分布式事务简介 概念 基础概念&#xff1a;事务ACID * A&#xff08;Atomic&#xff09;&#xff1a;原子性&#xff0c;构成事务的所有操作&#xff0c;要么都执行完成&#xff0c;要么全部不执行&#xff0c;不可能出现部分成功部分失 败的情况。 * C&#xff08;Consisten…

嵌入式和Python(一):python环境搭建的详细步骤

目录 ● 安装python ① 更新软件列表 ② 安装编译python需要用到的环境 ③ 下载python源码 ④ 解压源码包 ⑤ 配置 ⑥ 编译 ⑦ 安装 ● 建立软连接 说明 ① 删除原来的软连接 ② 在/usr/bin/目录创建软连接python&#xff0c;定向/usr/local/bin/python3.9 ③ 检查…

Java面向对象:多态特性的学习

本文介绍了Java面向对象多态特性, 多态的介绍. 多态的实现条件–1.发生继承.2.发生重写(重写与重载的区别)3.向上转型与向下转型.4.静态绑定和动态绑定5. 实现多态 举例总结多态的优缺点 避免在构造方法内调用被重写的方法… Java面向对象:多态特性的学习一.什么是多态?二.多态…

MATLAB | 如何将colormap中心点置为0值处?

本期讲有一些绘图时正负部分需要分开赋予颜色&#xff0c;这时候双向colormap的中心对应的可能并不是数值0&#xff0c;该咋办&#xff0c;就比如下面的情况&#xff1a; 事先说明&#xff0c;为了绘图好看&#xff0c;本文中全部示例都在代码最后用了以下这个简单函数进行修饰…

库到底是个啥?为啥要链接,链接库的本质又是个啥?

目录 前言 一、库是个啥&#xff1f; ①最开始的库是用来解决啥问题&#xff1f; ②库的基本构成 ③动态库与静态库 二、如何生成库 0、相关知识 ①生成静态库 ②生成动态库 三、库的使用 ①修改环境变量 ②拷贝.so文件到系统共享库路径下, 一般指/usr/lib ③ldconfig 配置/etc…