文章目录

  • 7 LightGBM
    • 7.1 概述
    • 7.2 LightGBM优化算法详解
      • 7.2.1 GOSS算法
      • 7.2.2 EFB算法
      • 7.2.3 Histogram算法
      • 7.2.4 Leaf-Wise策略
      • 7.2.5 直接支持类别型特征
      • 7.2.6 并行优化方法
      • 7.2.7 小结
    • 7.3 LightGBM的使用
      • 7.3.1 常用参数
      • 7.3.2 常用调参方法

7 LightGBM

7.1 概述

前面我们介绍了AdaBoost和GBDT这两种Boosting方法,它们已经在很多问题上发挥了强大的威力,也已经具有较好效率。但是,如今的数据集正在朝着样本数越来越巨大,特征维度也越来越高的方向发展,此时这两种传统的Boosting方法在效率和可扩展性上已经不能满足现在的需求了。主要原因是:传统的Boosting算法中的基学习器需要通过对所有样本点的每一个特征都进行扫描来计算信息增益,进而找到最佳的分割点,这在样本数和特征数巨大的情况下会相当耗时。为了解决传统Boosting方法在大样本、高纬度数据的环境下的耗时问题,微软团队提出了两种新的技术:基于梯度的单边采样(Gradient-based One-Side Sampling, GOSS)和互斥特征捆绑(Exclusive Feature Bundling, EFB)。下面简单介绍下这两种方法的原理。

  • GOSS:不再对所有的样本都计算信息增益,而是采取“保留所有大梯度样本,而对小梯度样本进行随机采样”的方式,减少了计算信息增益的样本数,降低了运算的复杂度,又不会对数据集的总体分布造成太大的破坏。这就是基于梯度的单边采样方法的基本思想。

  • EFB:将某些互斥性较大的特征捆绑成一个新的特征来降低特征的维度,使得找到最佳分割点的时间大大减少。互斥特征一般是针对高维度特征而言的,指的是几乎不会同时取非零值的一组(两个或两个以上)特征。具体示例如下表所示:

    样本x1\boldsymbol x_1x1​ 样本x2\boldsymbol x_2x2​ 样本x3\boldsymbol x_3x3​ 样本x4\boldsymbol x_4x4​ 样本x5\boldsymbol x_5x5​ 样本xm−1\boldsymbol x_{ m-1}xm−1​ 样本xm\boldsymbol x_mxm​
    特征f1f_1f1​ 1 3 0 0 8 0 5
    特征f2f_2f2​ 0 0 5 9 0 2 0

上表模拟了在大样本、高维度数据集中两个特征的分布情况,这两个特征就组成了一组互斥特征。在大样本、高维度数据集中,特征的分布一般都比较稀疏,也就是说会出现很多样本在某些特征上取0值的情况。我们通过一定的策略找到在所有的样本中都不会同时取非0值,或者同时取非0值的样本很少的多个特征,将它们捆绑成一个特征,这样可以在降低特征维度的同时又不会对数据集的分布造成太大的破坏。这就是互斥特征捆绑方法的思想。

​回顾前面介绍的GBDT算法,可以发现,GBDT算法在训练每棵提升树的时候有两种提供样本方式:第一种是为每棵树都提供所有的样本进行训练,第二种是采用子采样方式,按照固定比例无放回地取出一部分样本依次给每棵提升树训练。使用第一种方法会导致如下问题:当数据集样本数很多、特征维数很高的时候,为每棵树都提供所有数据集中的样本进行训练会非常耗时。为了解决这一问题,我们可以在GBDT算法的基础上使用GOSS和EFB这两种方法。通过GOSS方法对基决策树的训练样本进行灵活限制,再通过EFB方法对高维的特征空间进行降维,双管齐下,这样就能在很大程度上减少模型拟合数据集的时间,同时又不会降低准确率。我们将结合了GOSS方法和EFB方法的GBDT算法称为LightGBM算法。可以用如下公式通俗地表示:
LightGBM=GBDT+GOSS+EFBLightGBM=GBDT+GOSS+EFB LightGBM=GBDT+GOSS+EFB
这就是LightGBM算法的由来。

7.2 LightGBM优化算法详解

上一小节我们简要介绍了GOSS和EFB这两种算法的思路,并通过一条通俗的公式说明了LightGBM算法的来源 。本小节我们将对LightGBM中涉及的优化算法的细节进行阐述。

7.2.1 GOSS算法

前面我们介绍了AdaBoost算法,该算法的大体思想是:在每次迭代时更加注重上一次错分的样本点,增大上一次分错的样本的权重。虽然GBDT算法中并没有这种为分错样本增大权重的机制,但是由于GBDT是以样本的残差(即模型对样本的训练结果与标签值之间的差距)作为训练提升树的依据,所以GBDT算法可以根据每个样本的残差来判断模型对样本的拟合程度。在这里我们将残差称为梯度,那么按照梯度大小,数据集中的样本就分为大梯度样本和小梯度样本两种。

  • 大梯度样本一般是未经模型拟合或者模型欠拟合的样本,模型对这些样本训练偏差较大,所以这些样本是要在后续模型训练中重点关注的样本,应全部保留;
  • 小梯度样本一般是已经被模型拟合过、并且拟合得比较好的样本,模型对这些样本的训练误差较小,因此可以弱化对这些样本的训练,一个简单粗暴的办法就是直接抛弃掉这部分梯度较小的样本,但这样会对数据集的总体分布造成较大的破坏,所以还是不能完全忽略这部分样本,而是对这部分样本采取随机采样的方式。

GOSS算法对上面这两点进行了实现。具体如下:

设当前模型为modelmodelmodel,训练数据集为 III,迭代次数为ddd,大梯度样本的采样率为aaa,小梯度样本的采样率为bbb,损失函数为losslossloss,弱学习器的类型为LLL(一般为决策树)。

循环进行ddd轮迭代,循环体中的各个步骤如下:

  1. 获取modelmodelmodel对 III 中各个样本的训练梯度的绝对值,按照降序的顺序对所有样本进行排序;
  2. 在上述排序结果的基础上,选取前a×100%a×100\%a×100%的样本,组成一个大梯度样本子集;
  3. 在剩下(1−a)×100%(1-a)×100\%(1−a)×100%的样本中随机的选取b×(1−a)×100%b×(1-a)×100\%b×(1−a)×100%个样本,生成一个小梯度样本子集;
  4. 为小梯度样本子集中的每一个样本乘上一个权重系数1−ab\frac{1-a}{b}b1−a​;
  5. 将上面得到的大梯度样本子集和小梯度样本子集进行合并;
  6. 使用上一步得到的样本集对一个新的弱学习器LLL进行训练;

不断重复循环体中的步骤,直到达到规定的迭代次数ddd或者losslossloss收敛为止。

​ 从上面的步骤中可以看到,当a=0a=0a=0时,GOSS算法退化为随机采样算法;当a=1a=1a=1时,GOSS算法退化为传统的取所有训练样本对弱学习器进行训练的方法。训练出的模型精确度要高于随机采样算法。

GOSS算法具有如下优点:

  • 对样本进行采样增加了弱学习器的多样性,从而提升了模型的泛化能力;
  • 该算法几乎不会对数据集的分布造成破坏,同时又大幅度减少了每一轮迭代的训练样本数,所以该算法在保证了GBDT模型的精度不受损失的同时,又大大减少了GBDT模型对数据集的拟合时间。

7.2.2 EFB算法

前面我们已经简单介绍了EFB算法的原理,即将多个不同的特征按照互斥的程度划分为了更小的互斥捆绑数,从而实现了特征降维。但由于现实中的数据集很多是大样本、高维度的数据集,遍历所有特征在各个样本上的值尚且非常耗时了,更不用说为了匹配互斥特征还要进行重复遍历,所以找到各组互斥的特征并进行捆绑是一个NP-hard问题,即在多项式时间内不可能找到确切的解。为了解决这一问题,EFB算法在原有特征互斥判定方法的基础上进行了如下改进:用一个称为最大冲突数的参数来量化并限制同一个特征捆中总的互斥程度,我们允许特征之间存在少数样本不互斥,即允许存在某些特征对应的样本之间不同时取非零值。这样做放宽了特征互斥的条件,减少了特征捆绑数,从而进一步的提高了计算的有效性。理论上,使用该方法对模型准确率的影响程度为O([(1−γ)n]−23)O([(1-\gamma)n]^{-\frac{2}{3}})O([(1−γ)n]−32​),参数γ\gammaγ称为每个绑定的最大冲突率,用来量化不同特征之间的互斥程度。当γ\gammaγ取值较小时,可以在精确度和模型训练效率上获得很好的权衡。EFB算法实现该功能的具体步骤如下:

初始化各变量:构造一个带权图GGG,图中结点代表各个不同的特征,边的权值代表对应特征之间的互斥程度(冲突数),通过各个特征节点在图GGG中的度(即与特征节点相连的边数)降序排序所有特征,并按顺序加入到列表FeaturesFeaturesFeatures中。设特征数为FFF,特征捆中的最大冲突数为KKK,特征捆列表为bundlesbundlesbundles(如bundles[i]bundles[i]bundles[i]表示构建出的第iii捆特征,初始化状态下所有bundles[i]bundles[i]bundles[i]均为空),bundlesConflictsbundlesConflictsbundlesConflicts列表记录bundlesbundlesbundles中各个特征捆的当前总冲突数(如bundlesConflicts[i]bundlesConflicts[i]bundlesConflicts[i]表示第iii捆特征的总冲突数)。

接下来进行FFF次循环。循环体中的步骤如下:

  1. 遍历有序列表FeaturesFeaturesFeatures中的每个特征;
  2. 遍历bundlesbundlesbundles列表中的所有特征捆bundles[j]bundles[j]bundles[j],如果特征捆为空,则将当前特征Features[i]Features[i]Features[i]加入bundles[j]bundles[j]bundles[j]中;若特征捆不为空,则进行如下判断:
    • 如果加入新特征Features[i]Features[i]Features[i]后bundles[j]bundles[j]bundles[j]的总冲突数小于KKK,则将该特征加入bundles[j]bundles[j]bundles[j];
    • 如果加入之后大于KKK,则将新特征Features[i]Features[i]Features[i]加入下一个空的特征捆bundles[j+1]bundles[j+1]bundles[j+1]中。

不断重复上述步骤,直至遍历完所有特征,最终输出bundlesbundlesbundles。

上述算法的时间复杂度为O(n_features2)O(n\_features^2)O(n_features2)(n_featuresn\_featuresn_features为总的特征数),在特征维度不是很大时,这样的复杂度是可以接受的,但当样本维度较高时,这种方法就显得非常低效。对此,微软团队又提出的另外一种更加高效的算法:不再按照特征节点度的大小的降序来对特征进行排序,而是按特征中非零值数量的降序来对特征进行排序,因为非零值更多的特征通常会导致更高的冲突概率。通过这一点小小的改变,EFB算法的复杂度得到了进一步下降。

7.2.3 Histogram算法

我们通过EFB算法成功将所有特征拆分成了多个互斥的特征捆,但要怎么将同一特征捆中的所有特征合并起来呢?Lightgbm中使用直方图(Histogram)算法来合并互斥特征。直方图算法的直观示意图如下:

如图,该算法的基本思想为:

  1. 把连续的特征值离散化成kkk个整数,同时构造一个具有kkk个bins的直方图;
  2. 遍历所有特征的各个特征值数据,根据离散化后的值,在直方图中对应的bins部分进行累加求出统计量,这样的话,当遍历一次数据后,直方图累积了所有的特征统计量;
  3. 根据直方图的离散值,遍历寻找最优的分割点。

由于直方图算法的思想是存储离散的bins而不是连续的特征值,所以我们可以通过让互斥特征驻留在不同的bins中来构造特征捆。这可以通过在原始特征值的基础上增加适当的偏移量来实现。比如,假设我们有两个特征A和B,A的取值范围是[0,10),而B的取值范围是[0,20),我们可以通过给B增加偏移量10,使得B的取值范围变成[10, 30),这样就可以合并特征A和B的范围区间,形成取值范围为[0,30)的新特征来取代原来的A和B。使用直方图算法在规避了对特征进行排序、从而减小了损耗时间的同时,又实现了对互斥特征进行合并、从而实现了特征降维的目的,一举两得。

7.2.4 Leaf-Wise策略

在LightGBM算法之前,大部分以决策树为基学习器的集成学习方法(包括原始GBDT算法、XGBoost算法等)都是通过一种称为Level-Wise的策略来生成基决策树。这种生成策略的缺点是:对于同一深度的的所有节点都不加区分地进行分裂,使得很多分裂增益较低的节点也进行了分裂,从而带来了没必要的开销。示意图如下:

为了避免带来不必要的开销,LightGBM使用了一种称为Leaf-Wise的树生成策略。该策略的思路为:每次只从同一深度的所有节点中找到分裂增益最大的那一个节点进行分裂而不对其他节点进行分裂,如此循环,直到到达所设定的最大深度为止。示意图如下:

在分裂次数相同的情况下,相比使用Level-Wise策略,使用Leaf-Wise策略可以得到更好的精度。但是,当样本量较小的时候,Leaf-Wise很容易造成过拟合。 所以,可以通过调整LightGBM中的参数 max_depth 来限制树的最大深度,避免过拟合。

7.2.5 直接支持类别型特征

所谓类别型特征(Categorical features)是指其值是离散的集合且相互比较并无意义的变量,比如用户的ID、产品ID、颜色等。 这些变量无法在二叉决策树当中直接使用。 常规的做法是将这些类别变量通过预处理的方式转化成数值型变量再喂给模型,比如用一个或者若干个数值来代表一个类别型特征。目前广泛用于类别特征的处理方法是One-Hot编码:将原来的特征删除,然后对于每一个类别加一个0/1的用来指示是否含有该类别的数值型特征。使用这种处理方式有一个致命的缺点:在高势特征(也叫高数量类别特征,即对于某个类别型特征,不同值的数量非常多)当中,比如用户的ID,用这种编码方式生成的特征维数会非常巨大,造成维度灾难。

​ 在实际应用中,大多数机器学习算法模型都无法直接支持对类别特征的使用,一般需要把类别特征通过One-Hot编码的方式转化到高维的0/1 特征空间,这样做降低了机器学习模型拟合数据集的空间和时间的效率。而如果能直接使用类别特征,避开类别特征编码,那么就可以提升机器学习算法的整体效率。基于这个考虑,LightGBM实现了对类别特征的支持,也就是说,LightGBM模型支持对类别特征的直接读取,而不需要读取类别特征的One-Hot编码形式。这使得LightGBM模型的效率有了进一步的提升。

7.2.6 并行优化方法

LightGBM中还采用了并行优化方法,进一步提升了模型拟合的效率。它的并行优化方法是基于特征并行和数据并行这两种普通的并行方法进行改进的。这两种方法的主要思想如下:

  • 特征并行:使用多个不同的机器,分别在不同特征集合上寻找最优的分割点,然后再对所有机器结果进行同步,输出最优分割点;
  • 数据并行:让不同的机器先在本地各自构造特征直方图,然后进行全局合并,最后在合并的直方图上寻找最优分割点。

LightGBM针对这两种并行方法都做了优化:

  • 在特征并行方法中,各个机器均保存数据集中的全部数据,“各取所需”,避免因数据量不足造成不同机器数据分割结果的相互干扰;
  • 在数据并行方法中,使用一种称为分散规约 (Reduce scatter)的方法把直方图合并的任务分摊到不同的机器,减少了单个机器的计算负担,并利用直方图做差的方式减少了一半的通信量。

7.2.7 小结

1.7.2小节中我们介绍了LightGBM中所用到的优化算法,这些方法在原始GBDT算法的基础上大幅提升运算速度,同时保持了和原始GBDT算法几乎一致的准确率,从而解决了原始GBDT算法在大样本、高维度数据集上效率过慢的问题,这使得LightGBM算法在近两年来得到了广泛的应用。

7.3 LightGBM的使用

令人感到可惜的是,sklearn中并没有为用户提供调用LightGBM算法模型的接口,因为LightGBM是微软团队的研究成果,它们自己编写了一个独立的库供用户使用LightGBM算法。尽管如此,sklearn还是巧妙借鉴了LightGBM算法的思想,在GBDT算法的基础上进行了改进,设计出了基于直方图算法进行改进的GBDT算法,并提供了HistGradientBoostingClassifier和HistGradientBoostingRegressor这两个接口供用户使用,大大提升了GBDT模型在大样本数据集上的训练速度,使得用户可以轻松地将GBDT模型用于样本数10000个以上的数据集的训练。而完整的LightGBM算法过于复杂,导致其参数、属性、方法等有很多,故本书不再进行赘述,读者可以移步LightGBM的官方文档进行详细了解,下面仅列举出LightGBM中的常用参数,以及每个参数的所对应的调参场景。

7.3.1 常用参数

参数 含义 用法
max_depth 基决策树树的最大深度 当模型过拟合时,可以考虑降低 max_depth的值以限制最大深度
min_data_in_leaf 基决策树叶子节点所需要的最小样本数 默认值为20,模型过拟合时用
feature_fraction 使用bagging方法时特征子集的采样比例 指定boosting 方法为 random forest 时使用
bagging_fractions 使用bagging方法时样本的采样比例 用于加快训练速度,减小过拟合的风险
early_stopping_round 指定使用提前停止方法的迭代次数上限。如果在一次验证中模型对数据集的度量(如验证错误率、验证准确率等)在early_stopping_round轮迭代中中没有得到提高,模型将终止训练 减少因迭代次数过多造成计算资源的浪费
lambda 指定正则化系数 指定为0~1之间的实数,缓解过拟合
min_gain_to_split 指定基决策树分裂时所要求的最小gain(信息增益) 缓解过拟合
Task 模型对数据集的操作 指定为train表示对数据集进行拟合,指定为predict表示对数据进行预测
application 模型的用途 指定为regression表示完成回归任务,指定为binary表示完成二分类任务, 指定为multiclass表示完成多分类任务
num_boost_round 迭代次数 通常设置成100以上
learning_rate 学习率 常用 0.1, 0.001等较小值
num_leaves 基决策树节点数量 默认值为31(对应深度为5),取值应不大于 2max_depth2 ^{max\_depth}2max_depth, 超过此值会导致过拟合
save_binary 是否将数据集存储为二进制文件 这个参数为 true 时,则数据集被保存为二进制文件,下次读数据时速度会变快
max_bin 表示特征存入的最大bin数量 不得超过255
device 训练模型所用的设备 cpu | gpu
metric 损失函数

7.3.2 常用调参方法

1 针对 Leaf-Wise策略

  • 通过调整num_leaves参数来控制基决策树中节点的数量,进而控制树模型的复杂程度。一般情况下,若使用Level-Wise策略来生成基决策树,则可以设置该参数的值为 2max_depth2^{max\_depth}2max_depth。但如果要使用Leaf_Wise策略来优化模型的拟合效果,则num_leaves 的取值应小于 2max_depth2^{max\_depth}2max_depth;

  • 通过调整min_data_in_leaf参数来控制基决策树中每个节点所要求的最小样本数。该参数是处理Leaf-Wise 树过拟合问题中一个非常重要的参数。将该值设置得较大可避免基决策树的深度过深,,但设置得较大又有可能导致欠拟合,并且其取值不得超过训练数据集的总样本数 num_leaves。在实际应用中,应对该参数进行小心调整,调整的范围一般在几百到几千之间;

  • 通过调整max_depth参数显式地限制基决策树的的深度,以降低过拟合的风险。一般设置为5—10之间的整数。

2 针对更快的训练速度

  • 设置 bagging_fractionbagging_freq 参数以使用 bagging 方法;
  • 设置合适的feature_fraction 参数(表示特征子采样的比例);
  • 使用较小的 max_bin
  • 使用 save_binary ,用以在后续学习过程中加速对数据集的加载。

3 针对更好的准确率

  • 使用较大的 max_bin (学习速度可能变慢);

  • 使用较小的 learning_rate 和较大的 num_iterations

  • 使用较大的 num_leaves (可能导致过拟合);

  • 使用更大的训练数据集合。

4 缓解过拟合

  • 使用较小的 max_bin(默认值为255);

  • 使用较小的 num_leaves(默认为31);

  • 调整 min_data_in_leaf(默认为20)和 min_sum_hessian_in_leaf(默认为e−3e^{-3}e−3)的值;

  • 调整bagging_fraction (默认为1.0)和 bagging_freq (默认值为0,表示禁用bagging;将该值设置为kkk,表示每kkk次迭代执行一次bagging操作)的值以使用 bagging;

  • 调整 feature_fraction(默认为1.0)的值以调整特征子采样的比例;

  • 使用更大的训练数据;

  • 使用 lambda_l1(默认为0), lambda_l2 (默认为0)和 min_split_gain(默认为0,表示执行切分的最小增益)以执行正则化操作;

  • 尝试调低 max_depth 的值,以避免生成过深的树。

【集成学习系列教程5】LightGBM相关推荐

  1. OpenCV学习系列教程第五篇:测试和提高代码的效率

    Opencv-Python学习系列教程第五篇 来自opencv-python官方学习文档,本人谨做翻译和注释,以及一些自己的理解 本文由作者翻译并进行代码验证,转载请注明出处~ 官方文档请参阅:htt ...

  2. Python2爬虫学习系列教程

    http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己 ...

  3. Python爬虫学习系列教程

    大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把一些学习的笔记总结下来,还记录了一些自己实际写的一些小爬虫,在这里跟大家一同分享,希望对Python爬虫 ...

  4. Python爬虫学习系列教程-----------爬虫系列 你值的收藏

    静觅 » Python爬虫学习系列教程:http://cuiqingcai.com/1052.html 大家好哈,我呢最近在学习Python爬虫,感觉非常有意思,真的让生活可以方便很多.学习过程中我把 ...

  5. @data注解的作用_Java中注解学习系列教程-2

    在上一篇文章中,我们讲解了:Java中注解的定义.JDK中内置注解.第三方注解. 本文是注解系列教程中的第二篇.来看看今天主要内容: ​ 1:注解的分类 2:元注解说明 3:自定义注解声明 一:注解的 ...

  6. Python 爬虫学习 系列教程

    Python爬虫 --- 中高级爬虫学习路线 :https://www.cnblogs.com/Eeyhan/p/14148832.html 看不清图时,可以把图片保存到本地在打开查看... Pyth ...

  7. @excel 注解_Java中注解学习系列教程-3

    本文是<Java中注解学习系列教程>第三篇文章 在前两篇中我们学习了注解的定义.JDK内置注解.注解分类及自定义注解的写法. 本文咱们将学习: ​ 1:自定义注解一些说明 2:自定义注解怎 ...

  8. excel导出多重表头utils_Java中注解学习系列教程-4 使用自定义注解实现excel导出...

    本文是<Java中注解学习系列教程>第四篇文章也是小案例文章. 自定义注解小案例是:使用自定义注解实现excel导出. Excel导出分析: ​ 有表头.数据值.一般第一行是表头,从第二行 ...

  9. java excel 注解_Java中注解学习系列教程-5 excel导出优化初级阶段

    在上一篇文章中,我们实现了使用自定义注解导出Excel的小案例.但是有问题的.我们发现,如果对象属性中包含了date类型或者使用了枚举类.这个时候就会出问题.我们来看看问题所在: 是不是已经看到了结果 ...

最新文章

  1. 在绘制USB2.O设备接口差分线时,应注意以下几点要求:
  2. js网页返回页面顶部的小方法
  3. Netbackup 7.6新增功能和优势
  4. tp5分页不加载搜索参数
  5. ajax添加和删除数据,ajax 添加 更新 删除数据库
  6. Linux文档内容查询命令
  7. Strtus2标签s:url
  8. Android 使用数据库操作应用加锁、未加锁,列表展示效果
  9. 求两个数的最小公倍数(C语言)
  10. Ubuntu拼音打不了中文
  11. 裁员狂潮席卷硅谷:Meta史上最大规模裁员将至,英特尔被曝裁掉数千人
  12. CentOS 7 服务器密码忘记的解决办法
  13. Html Table 合并单元格
  14. 如何快速有效提升网站的百度排名
  15. 法规标准-ECE R79标准解读
  16. java全栈系列之JavaSE--数组的三种初始化方法及内存分析024
  17. 我在大厂写React学到了什么?性能优化篇
  18. QQ,MSN,skype,goolge TALK,雅虎通,贸易通,淘宝旺旺在线客服代码
  19. 段里仁:十论智能交通系统在我国的发展与应用
  20. 传感器原理与检测技术复习笔记第五章-电容式传感器

热门文章

  1. Ubuntu彻底卸载软件和清理磁盘空间
  2. matlab 三围温度,matlab 两个二维温度场平面如何通过插值立体重建三维温度场
  3. mt4查看虚拟服务器,查mt4服务器地址
  4. python turtle绘图蟒蛇
  5. 渗透测试的目标、思路
  6. Vue SPA工作原理
  7. 导电聚合物中热电效应转换原理
  8. mac电脑解压缩报错:错误22 无效的参数
  9. 【Python】星号与双星号
  10. matlab hold on 置顶,matlab中 hold on 与hold off的用法