主流树模型讲解、行列抽样、特征重要性梳理总结

本文旨在总结一下常见树模型的行、列抽样特点以及特征重要性的计算方式,也会带着过一遍算法基本原理,一些细节很容易忘记啊。

主要是分类回归两类任务,相信能搜索这篇文章的你,应该对树模型有一定的了解。

可以搜索 总结 ,直接定位到要讲的重点,跳过算法基础讲解的部分。

一、早期历史

1.1 决策树核心算法

ID3算法(1986年):只能用来分类,使用的分裂准则是信息增益,用分裂前的entropy - child leaf的entropy。

假设样本总共有m个类别,每个类别在当前结点的概率p_k,则信息熵计算如下。

$Entrophy = -\sum_1^m p_k\log{p_k}$

遍历特征,特征必须是离散值,不能处理连续值,本质上是个大的if then else,容易过拟合,比较老了都不用这个了,但这个是入门基础。

C4.5:是对ID3的改进,①可以处理连续值,就是将某个特征排序,取两个数的中间值来划分;②将信息增益改为信息增益比,避免有些特征取值很多,分裂时容易有倾向性;

【机器学习(三)】机器学习中:信息熵,信息增益,信息增益比,原理,案例,代码实现。-CSDN博客

 这篇文章讲的挺清楚的;

这两个算法是老黄历了,只能分类,并非可以是多叉树,是基础,但实际上我们根本不会用这些。


Cart树(classification and regression tree):是二叉树,看名字就知道,既可以分类又可以回归,属于重大革新了。

分类问题中,采用gini系数作为不纯度来计算分裂收益,找到两个叶子结点gini系数之和最小的划分方式,等同于父节点gini - 两个子节点gini 之差最大,这样鸡贼地避免了对数运算,加快了速度;

在回归中,就是MSE均方差作为分裂计算标准,准确点说,是squared error之差,看取哪个特征哪一个点,能让划分的两个子类,误差较之前减少最多。

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0.00001,0.999999 , 10000)
entropy = -x*np.log2(x) - (1-x)*np.log2(1-x)
gini = 2*x*(1-x)plt.plot(x,entropy, label='entropy',color='purple',alpha=0.5)
plt.plot(x,gini, label='gini',color='blue',alpha=0.5)plt.title('two class entropy & gini sum plt')
plt.xticks(np.arange(0,1.1,0.1))
plt.axvline(0.5,color='black',linestyle='--',alpha=0.2)
plt.legend()
plt.show()

可以看到,这两个计算方式的图像的性质基本相同,如果一个叶子里含有两类,那就是没完全区分,一个的比例是p另一个就是1-p,如果只剩一类就是0;

虽然基尼系数简单好用,但相对于信息熵,还是准确率方面是稍微差那么一点的,譬如二分类,对比两个划分点位,带来的信息增益VS基尼不纯度减少,采用两种计算方式,在两个点位,用同一种计算方式差别很小的情况下,可能不同的计算方式会选择不同的划分点位,退一万步来讲,又计算简单又准,咋不上天呢?不然xgboost和之后树模型为何还是使用了logloss,有兴趣的可以深入研究下两者区别。

1.2 发展路线

bagging和boosting和stacking

决策树本身只是一棵树,在后续的发展中,基本是往bagging和boosting两条路发展,stacking这种混合模式就不在本文讨论范围中;

本文准备了两组数据,一个是自带的乳腺癌,一个是波士顿零元购房价数据,相信大家都很熟悉;

2.bagging-随机森林

bagging算法主要是随机森林和极限森林两种:

2.1随机森林分类(RandomForestClassifier)

在sklearn.ensemble里有分类、回归和RandomTreesEmbedding,其中Embedding基本用来将数据变成高维的One-Hot矩阵,再喂给其他模型,本文不讨论这么广;

所有参数如下:

ccp_alpha Classifier(n_estimators=100, *,criterion='gini', # {"gini", "entropy", "log_loss"}, default="gini"# entropy应该是可多分类也可二分类# log_loss应该是只能二分类max_depth=None,    #int, default=None,最大深度,默认直到世界的尽头min_samples_split=2, # 父节点可分裂,要求的最少样本数# int为个数,float为占总数的比例min_samples_leaf=1,  # 孩子节点最少样本数,同父亲一样int\floatmin_weight_fraction_leaf=0.0, # float,默认0即不设置,可忽视# 叶子结点最少的权重数合计比例# 不设sample_weight等同结点样本占比# 如设,比如二分类不平衡,将少数样本权重比例设为10# 则可控制要往下分裂所需的最小权重之和# 用得少,不如用其他参数,不平衡数据实在难崩再考虑max_features='sqrt', # {"sqrt", "log2", None}, int or float, default="sqrt"max_leaf_nodes=None, # int,最大叶子节点数,默认None不限制min_impurity_decrease=0.0, # 往下分裂所需不纯度减少要求,注意看说明文档公式# 还有个当前结点占总体数量的比例# 说实话这参数,不太好控制# 除非效果太差或追求极致,一般不用这个控过拟合bootstrap=True,            # bool, default=True,默认对样本放回抽样# 基本绝对会抽到重复的,这是随机森林行抽样的特色# False则每棵树用全部样本# 所以随机森林要么不放回会有重复,要么全部样本oob_score=False,           # 见下文n_jobs=None,               # 默认None只开一核,无脑-1全核即可random_state=None,         # 固定种子,则多次运行行列抽样等可固定对比verbose=0,                 # 0->不输出日志,n->迭代n次输一次warm_start=False,          # 默认重新训练模型,为真则当传入新数据fit# 可以继续新增树,之前的树可保留class_weight=None,         # 一般样本不平衡时考虑用,注意多分类传入方式# 解释文档说的很清楚{"balanced", "balanced_subsample"}# balanced则将少数样本按占比的反比提升# balanced_subsample是按抽的样本中的比例而不是总体比例调整ccp_alpha=0.0,             # 类似L2或者xgboost的gamma Tree 参数,详见下max_samples=None,          # 必须要bootstrap为True,因为False则用全样本# None则从所有m个样本中放回抽m个# int,float则为最大个数、比例# 均为不放回抽样,都有重复的# 因为不放回抽样本就有很多没抽到,一般不用这个monotonic_cst=None,        # 单调性约束,跟特征数相同的列表# 比如有个特征越高,分类越趋向于1,则设为1# 0则无约束,-1则表示负相关# 在一起情况下,应该能提升准确率# 感觉没啥用,直接换算法来得快一些
)

单独说明:

bootstrap:如果默认放回抽样,假设有m个样本,则每个样本被抽到的概率为1/m,要抽m次(等于样本总数),则有的样本会重复,有的样本会没有被抽到,这是绝对会发生的,极限情况下,可证明约有36.8%的样本没被抽到,即为Out Of Bag袋外数据。

$P = {\lim_{m \to \infty}}(1-\frac{1}{m})^m = \frac{1}{e} \approx0.368$

oob_score:是否用袋外数据对模型进行评分,前提是开了bootstrap,分类默认是accuracy,也可以传个函数进去。

有些参数,应该是后期更新加进去的,因为我的版本应该比较新。

ccp_alpha:在复杂度(单颗树的叶子节点数)和不纯度减少\MSE减少中,取最小值,附带链接!

决策树后剪枝算法(一)代价复杂度剪枝CPP-CSDN博客

2.2随机森林回归(RandomForestRegressor)

只看跟分类的区别,因为分类问题往往难一些;

RandomForestRegressor(criterion='squared_error',    # default="squared_error"# {"squared_error", "absolute_error", "friedman_mse", "poisson"}oob_score=False, # 默认用R方,即sklearn.metrics.r2_score)

仔细猛地一看,与分类只有两个区别:

①criterion:分裂标准默认是SSE(sum of squaerd error),跟MSE一个道理,乘了样本数,假如左、右叶子结点的SSE比父结点少,即可分裂,当然是找分裂增益最大的那个啦,说MSE是不太准确的,难道写代码的时候,先求个平均再乘个总数,这不是有病么,所以肯定是直接求平方和;一般不会用绝对值的L1_loss,因为求导分两种情况并且导数为正负1,难顶。

friedman_mse,相当于调整了一下,有点F1-score的感觉。

# friedman_mse 
diff = mean_left - mean_rightimprovement = (n_left * n_right) * diff**2 / (n_left + n_right)

poisson ,应该是2\sum_{i=1}^n(y_i\log(\frac{y_i}{\hat{y_i}})-(y_i-\hat{y_i})),泊松偏差则是适用于一个特殊场景的(泊松分布是正整数的分布),当需要预测的标签全部为正整数时,标签的分布可以被认为是类似于泊松分布的。 正整数预测在实际应用中非常常见,比如预测点击量、预测客户/离职人数、预测销售量等。

②oob_score:用的R方

$R^2 = 1-\frac{\sum_{i=1}^n (y_i - \hat{y_i})^2}{\sum_{i=1}^n (y_i - \bar{y_i})^2}$

R方一般会在0到1之间,但假如万一出其不意一不留神模型极其之差,可为负数,R方越接近1越好,基本跟MSE是一个道理;

重要属性:

挑几个重要点的

oob_score_, 返回accuracy或者R方,必须在参数里先把oob_score设为真;

oob_decision_function_,返回袋外数据的预测结果,实测过就是oob_score_的源数据;

比如二分类问题,样本m个,每次不放回抽样,基本有三四成样本没被抽到,此时第一棵树训练出来了,可以得到这三四成的预测结果,综合n颗树,可以投票得到一个结果。

model.oob_decision_function_,跟model.predict(所有训练data_x)的结果肯定不同,理解了随机森林抽样和袋外验证的原理,就很容易知其原因。

feature_importances_,返回特征重要性,按不纯度减少(看你选的哪个criterion)或者MSE(SSE--sum squared error)减少,所有树的所有分裂结点先累加,再归一化,可以看到所有的feature_importances_加和为1;

亦有一种说法是,特征重要性还有第二种计算方式,用袋外数据,随机打乱某特征列,看对结果造成的误差大小,判断重要性,也有很多文章阐述了这个事实,但我在sklearn里好像没有什么参数能指定用哪种方式计算。

不过也不太需要深究,

what the fu**,I didn`t plan to write things about the parameters.but As the writing progresses,I got fu**ing stuck in thest sh*t until all done.还写得很全...

总结:

随机森林,行抽样,默认bootstrap=True是放回的,大概会有36.8%的数据不会被抽到,同时你还可以搞事情,用max_samples限制抽样的总次数,这样会有更多数据没被抽到,也可强行指定用全部数据,bootstrap = False。

列抽样,取开根号、log2或者指定数字、比例或全部,分类中默认用sqrt开根号,回归默认用全部特征;

但随机森林列抽样跟xgboost之类的不同,是在每次分裂的时候,才开始选指定数量的列,而xgboost等是在建树的时候就已经先选定了那些列,当前树的分裂过程中,不会再抽,即每棵树一开始就定死了那些列,随机森林每次分裂都抽(翻出去可查证)

特征重要性,不纯度减少、MSE减少,结果是归一化的,关于打乱特征计算重要性的方法,sklearn中未见参数可指定用哪种方式计算,个人认为就是按criterion的减少计算的,但这也不重要啦。

这个obb_score是个创意,直接不用分train和test了,本身抽样就留出了快四成。

一般碰到一个数据集,不知道哪个特征重要,丢给随机森林跑一遍总没错,一来快,二来模型方差不高,堪称居家旅行、数据狗必会。

 

2.3决策树--漏了补上

其实是应该先说决策树,但懒得改编号了,随机森林说白了就是多个决策树;

from sklearn.tree import DecisionTreeClassifier,DecisionTreeRegressor
# 只说跟随机森林不同的,但是逻辑顺序反了,懒得改了
DecisionTreeClassifier(splitter='best',criterion='gini'
)# {"best", "random"}, default="best"
# {"gini", "entropy", "log_loss"}, default="gini"# 回归问题
DecisionTreeRegressor(*,criterion='squared_error',# {"squared_error", "friedman_mse", "absolute_error", "poisson"}, # default="squared_error"max_features=None, # 默认是全部特征,分类基本都是开根号
)

splitter:

best不难理解,正常是这样,遍历所有特征所有阈值,查找最佳分裂点;
random:中文网上难找到具体答案,出去查阅了下:

一种说法是,会先找到分裂增益最大的点,选定这个特征,在这个特征中不选最佳的阈值,选个其他的,控制过拟合;

第二种是单纯随便挑一个特征的一个阈值,直接进行分裂;

第三种是极限森林的玩法,每个特征都先随便选一个阈值,再对比哪个最好,选定这个相对最好的;关于这个随便,亦有人试验循环很多次,阈值的挑选会选择最佳阈值的附近值,大部分会选择最佳特征的最佳阈值附近,有点均值上下一两个标准差的感觉,也会选择非最佳特征的非最佳值,但总体占比少一些,很少会选非常边缘的值,有点正态分布靠中间位置的意思。

众说纷纭,但目前第三种说法,比较占优,个人也认同,如果有大佬精通,请批评指正。

总结:

没有行抽样,因为就一棵树,毕竟行抽样是随机森林是在决策树上改进添加的;

列抽样:可选取sqrt、log2或者指定数字、比例或全部,分类回归默认用全部特征;

同时warm_start,bootstrap,oob_score,n_jobs这些需要bagging多棵树的东西都没有,因为懒得改顺序,其实应该先说决策树参数,再讲随机森林增加了哪些内容。

特征重要性:criterion减少值并归一化

2.4极限树--漏了补上

查看参数,同决策树一模一样,将splitter设为best,即启用决策树,用random即极限树,我猜测之前可能是有区别的,决策树就是best,极限树就是random,后期有改动,将两个功能合并了。

总结:

单颗极限树和单颗决策树,现在区别仅在一个splitter设置上,没有行抽样,默认使用了全部行,列抽样和随机森林一样,特征重要性也是根据criterion计算;

2.5 极限森林

经查,同随机森林参数完全一样,不过内部的特征分裂点选择,不能像单颗树一样随意切换,单颗树导包导错了,换个splitter一样用,森林则不行。

极限森林这种random选择阈值的方式,可以减小模型总体的方差,代价是偏差会略微高一点,可能在交叉验证中,极限森林会取得更好的平均成绩。

如何理解不选最佳分裂阈值,模型方差还会小呢:比如判定一个人是否有钱,选定了一个特征,每月银行卡入账的金额,随机森林可能选了每月>10万,极限森林可能选了>50万,有的人虽然入账多,他可能工作性质就这样,搞销售、跑业务请吃请和,经常进货倒货,这样的人并不一定非常富有,而月入账50万的,是假富人的概率更低。虽然在训练数据集上,每个都分得不够仔细,但树多了,对新加入的陌生数据集,预测的总体误差很可能减少,毕竟开宝马7系不一定真有钱,但开帕加尼风之子很难说他没钱。

总结:

极限森林行采样:稍微不同,默认bootstrap=False,毕竟分裂点不是最佳,故用全部行,当然可以设置bootstrap=True再叠加一个max_samples,就变成了有放回的行抽样;

列抽样:同随机森林,分类默认sqrt,回归默认全部特征;

特征重要性:同随机森林,criterion减少值并归一化

因为默认bootstrap=False,则袋外数据结果obb_score默认也是False

3.boosting

基本是adboost、GBDT、xgboost、lightgbm、catboost之类的

3.1AdaBoost算法

是boosting,基本是用来进行分类的,使用指数损失函数,单纯地分类来说,准确率是挺高的,回归使用的是中位数,一般不会有人用来回归,缺点是计算比较慢,是真的慢龟速,毕竟涉及到太多对数和指数运算。

损失函数:比较特殊,是集成学习里较少使用的指数损失函数。

$Loss=argmin \sum_{i=1}^m e^{-y_i*f(x_i)}$

二分类大概原理:

①先搞一棵树,计算分类错误率:错误率必须小于0.5,如果大于则反转预测结果即可小于0.5

$e_t=\sum_{i=1}^m(\hat{y_i} \neq y_i)/m$

②计算这棵树的权重: 可知错误率越低,权重越高,反之错误越多,权重就低;

$\alpha_t = \frac{1}{2}\ln(\frac{1-e_t}{e_t})$

③更新每个样本的权重:第一棵树分类错的,就增加权重,分对的就降低权重;

$w_{i+1} =w_i* e^{-\alpha_t y_i f(x_i)}/\sum w_{i+1} $

如果预测对:则y_i * f(x_i) = 1 ,指数上面是负数,会变小;

如果预测错误:则y_i * f(x_i) = -1 ,指数上面是正数,会变大;

由于每个样本权重都变化了,新的权重要归一化。

④循环往复,直到达到设定的树的棵树,或者最后一棵树能全部预测正确;

⑤最终结果:

$H(x) = sign(\sum_{t=1}^T learning\_rate * \alpha_t*H_t(x))$

很多公式都忘记打上学习率了,虽然默认学习率是1。

一般要自己先搞一个基学习器,不然默认DecisionTreeClassifier(max_depth=1)有点低,大部分情况下base_estimator都是决策树。

可以证明训练误差是以指数的速度下降的:https://www.cnblogs.com/liuwu265/p/4692347.html

算法内部最后的预测概率代码实现跟原理公式写的有点区别:

每棵树预测概率*树权重加和-->除以权重之和归一化-->一般将第一个标签变成-1-->再对-1和1的概率预测相加(记为p)-->-1和1的概率为[-p,p],最终进行sigmoid。

多分类时:每棵树的权重计算公式有点变化;不会降低预测正确样本的权重,仅增加预测错误样本权重,再归一化,也相当于变相一增一减,有兴趣可以研究下两种算法SAMME和SAMME.R的区别;

其实没必要搞这么清楚,最终也是殊途同归。

回归:略

总结:

由于要使用基学习器,而基学习器基本都是决策树,行列的抽样,又回到了决策树那一套模式上了;

特征重要性,也是基于每棵树给的值计算,adaboost对每个学习器,根据错误率计算每棵树的权重,那么计算特征重要性的时候,有加权吗?经过查找很多资料发现,并没有任何文章提及加权的事,个人认为就是单纯的每棵树相加,再归一化。

3.2 GBDT

梯度提升树,CART回归树,分类也是用的回归的均方差,不停地拟合残差,最终预测结果为F(x)=f(0)+learning_rate*f(x),准确率基本是优于随机森林的,GBDT主要是降低模型的偏差,而随机森林降低模型的方差,说人话就是GBDT过拟合重一些但更准确,随机森林没那么准但预测没见过的数据集(特征不能很多超过训练数据集范围)可能总体误差更小。

二分类中:可选损失函数为log_loss(默认值,一般基本都用这个),exponential指数损失,选指数就变成了adaboost;

难点可能是分类问题中,如何计算叶子结点的权重weight(叶子结点算出的值),因为很难算,用的是泰勒公式一阶、二阶导求极值代替。

详见:https://zhuanlan.zhihu.com/p/89549390

# 只考虑和随机森林不一样的参数
GradientBoostingClassifier(*,loss='log_loss', # {'log_loss', 'exponential'}, default='log_loss'subsample=1.0, # 不放回抽样,跟随机森林不同criterion='friedman_mse', # {'friedman_mse', 'squared_error'}, default='friedman_mse'# 分裂增益的计算公式 validation_fraction=0.1,# 留出用来验证的数据集比例,要先设early_stop才可用# 虽然可不用分训练、验证数据集,自带一个不错的功能# 但一般我们习惯手动CVn_iter_no_change=None, # early_stop的迭代次数tol=0.0001,  # 如果总体损失降低没有tol下限高,则不迭代了ccp_alpha=0.0, # 同决策树、随机森林的正则参数
)

多分类:构造n_class个二分类器,用one_vs_rest,最终将K个类预测的结果,用softmax进行归一化。

详细请看大神文章:深入理解GBDT多分类算法 - 知乎 (zhihu.com)

回归:

GradientBoostingRegressor(loss='squared_error',#  可选{'squared_error', 'absolute_error', 'huber', 'quantile'}# 见下文criterion='friedman_mse',# 可选{'friedman_mse', 'squared_error'}# 分裂增益计算,同分类alpha=0.9,# 如损失函数选了huber\quantile则可使用,见下文
)

比较值得注意的是损失函数,squared_error默认方差,比较容易理解;absolute_error绝对值差,由于导数为+1或者-1,一般较少用;剩下两个huber和quantile见下图

回归总体简单很多,就是下一棵树,拟合上一棵树的残差,叶子结点预测值是样本均值,最终乘个学习率即可。

总结:

GBDT行抽样,分类回归默认都是全部样本如果指定了比例,则不放回抽样,变成了一种随机梯度提升树 (Stochastic Gradient Boosting Tree, SGBT),一般用GBDT,先留出验证集,训练集就用全部行,或者交叉验证。

列抽样:不同的是分类回归默认都是用所有特征,可选的同随机森林,GBDT就是要算到极致,行变少了、列不选全,怎么算到底,当然你也可以选择只用一部分。

特征重要性:按照每个特征带来的criterion减少值计算的,也是归一化的结果,criterion有friedman_mse和squared_error两种,故重要性的计算方式也有两种。

GBDT单纯按算法原理,会过拟合,但默认值,在学习率、最大深度、等方面设得比较稳健,再加上人为设置行、列抽样,故没有那么严重的过拟合,一般要交叉验证,要调参,设置各种剪枝参数。

GBDT 性能强于随机森林,这句话基本没错,不然为什么后面的都用GBDT作为基础。

3.3 XGBOOST-eXtreme Gradient Boosting tree

xgboost是2014年提出的,极致梯度提升树,分类回归都是cart回归树,现在的xgboost经过偷偷地不断更新,已经涵盖了很多功能,比如可以使用直方图计算,可以进行梯度采样,可以特征互相绑定,可以直接支持类别特征(需要手动指定),这些我记得很多都是lightgbm、catboost的东西。

这些新增功能,在很多原理文章中,可能都找不到描述

xgboost参数太多,而且新增很多,我曾写过一篇,但也不全,原理参数方面略。

总结:

行采样:subsample,每棵树不放回抽样,一般是个0.5~0.9之类的浮点;在用gpu_hist的时候,还可以像lightgbm一样梯度采样。

列采样:colsample_bytree,每棵树生成之时就抽相应的比例的特征,跟随机森林不同,随机森林是每次分裂的时候抽,而xgboost这棵树在生成的时候,抽了哪些特征就定下来。同时还在colsample_bylevel,colsample_bynode这些二级、三级列抽样参数。

特征重要性:
 
‘weight’: the number of times a feature is used to split the data across all trees.

简单来说,就是在子树模型分裂时,用到的特征次数。这里计算的是所有的树。
‘gain’: the average gain across all splits the feature is used in.

特征在作为划分属性时gain的平均值
‘cover’: the average coverage across all splits the feature is used in.

这个是cover是略有不明白的,按照解释,是使用某个特征进行分裂所影响到的样本数量,可以计算父节点或者左右两个子节点,毕竟结果是一样的。亦有一种说法,是两个特征分裂产生的子节点二阶导之和,回归问题中,二阶导为1没毛病,但分类问题中,二阶导是sigmoid(1-sigmoid),这一样就与回归计算结果肯定不同;个人比较支持第一种说法
‘total_gain’: the total gain across all splits the feature is used in.

不算平均算总数,由于一般都会进行列抽样,在计算平均时,用到的列次数很可能不同,所以结果会与'gain'有区别,这个计算方式同随机森林、GBDT比较像,因为最终也会进行归一化。
‘total_cover’: the total coverage across all splits the feature is used in.

同上。

xgboost一般都习惯用原生train方法,快,但缺点①是参数字典要自己写,基本得翻一下,不然谁记得那么多名字。②无法用gridsearch之类的调参,自带的CV只能寻找既定参数下的最佳迭代次数,但往往我们都需要批量或者分小批调参。

不过sklearn版的,好像进行了更新,速度也不错,用sklearn的也行。

3.4 lightgbm

参数方面可参考一个帅逼写的,自认为写的还是比较全的,花了不少时间看原文。LightGbm参数案例详解、参数讲解全又多-CSDN博客

总结:

行采样:subsample控制比例,subsample_freq 设置隔多少次迭代再重新采样行。

如果data_sample_strategy设为goss,则会用单边梯度采样,不可用行抽样和行抽样间隔,但是可以用列抽样。

还可以进行正负样本采样比例设置。

列抽样:colsample_bytree(原生方法里叫feature_fraction),feature_fraction_bynode子节点列采样比例,有两个,xgboost里是三个;

lightgbm绝对会用直方图,所以force_row_wise和force_col_wise绝对会用一个,如果自己不设,模型会都试一下看哪个快帮你定,建议参考使用场景说明。

特征重要性:有两个,大厂搞的东西,往往会削减那些花里胡哨的东西,我觉得两个差不多就够了。

The type of feature importance to be filled into ``feature_importances_``.

If 'split', result contains numbers of times the feature is used in a model.

If 'gain', result contains total gains of splits which use the feature.

3.5 catboost

参考:

决策树三种算法比较(ID3、C4.5、CART)_三种决策树算法的区别-CSDN博客

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

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

相关文章

老鼠后五毒也来凑热闹!网红食品惊现「壁虎头」,胖东来已下架…

上周,老鼠有点忙,比如其连续被曝出,出现在了方便面知名品牌的调料包、知名连锁餐饮品牌的黄焖鸡饭中。‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 在小柴「被「添加」进方便面、黄焖鸡饭?老鼠最近忙疯了……」这篇文章的评论区,柴油…

计算机视觉与面部识别:技术、应用与未来发展

引言 在当今数字化时代,计算机视觉技术迅速发展,成为人工智能领域的一个重要分支。计算机视觉旨在让机器理解和解释视觉信息,模拟人类的视觉系统。它在各行各业中发挥着重要作用,从自动驾驶汽车到智能监控系统,再到医疗…

Python:对常见报错导致的崩溃的处理

Python的注释: mac用cmd/即可 # 注释内容 代码正常运行会报以0退出,如果是1,则表示代码崩溃 age int(input(Age: )) print(age) 如果输入非数字,程序会崩溃,也就是破坏了程序,终止运行 解决方案&#xf…

贪心算法(三) ---cmp_to_key, 力扣452,力扣179

目录 cmp_to_key 比较函数 键函数 cmp_to_key 的作用 使用 cmp_to_key 代码解释 力扣452 ---射气球 题目 分析 代码 力扣179 ---最大数 题目 分析 代码 cmp_to_key 在Python中,cmp_to_key 是一个函数,它将一个比较函数转换成一个键函数…

Problems retrieving the embeddings data form OpenAI API Batch embedding job

题意:从OpenAI API批量嵌入作业中检索嵌入数据时遇到问题 问题背景: I have to embed over 300,000 products description for a multi-classification project. I split the descriptions onto chunks of 34,337 descriptions to be under the Batch e…

Nginx优化、防盗链

目录 Nginx优化 隐藏版本信息 网站缓存 日志切割 超时时间 更改进程数 网页压缩 防盗链 在使用源码软件包安装过Nginx服务,具体步骤看上一篇文章 功能模块位置 在Nginx的解压目录下的auto目录内的options文件可以查看Nginx可以安装的功能模块 [rootlocal…

数据结构初阶-单链表

链表的结构非常多样,以下情况组合起来就有8种(2 x 2 x 2)链表结构: 而我们主要要熟悉的单链表与双向链表的全称分别为:不带头单向不循环链表,带头双向循环链表,当我们对这两种链表熟悉后&#x…

重生之我们在ES顶端相遇第5章-常用字段类型

思维导图 前置 在第4章,我们提到了 keyword(一笔带过)。在本章,我们将介绍 ES 的字段类型。全面的带大家了解 ES 各个字段类型的使用场景。 字段类型 ES 支持以下字段类型(仅介绍开发中常用,更多内容请自…

AI App Store-AI用户评价-多维度打分对比pk-AI社区

C端用户、创作者、AI达人们在选择众多国内外AI厂商的服务时候往往感到一头雾水,那么多功能接近的AI应用(智能对话类、文档总结类、文生图、AI搜索引擎) 究竟在不同用户需求场景下表现怎么样。大部分人如果有需求都会所有平台都尝试一遍,比如一个博主生成…

C++自定义字典树结构

代码 #include <iostream> using namespace std;class TrieNode { public:char data;TrieNode* children[26];bool isTerminal;TrieNode(char ch){data ch;for (int i 0; i < 26; i){children[i] NULL;}isTerminal false;} }; class Trie { public:TrieNode* ro…

基于区块链技术的中药饮片代煎配送服务与监管平台

业务背景 近年来&#xff0c;随着公众对中医药青睐有加&#xff0c;中药代煎服务作为中医药现代化的重要一环&#xff0c;在全国各地蓬勃兴起。鉴于传统煎煮方式的繁琐耗时&#xff0c;医疗机构纷纷转向与第三方中药饮片企业合作&#xff0c;采用集中代煎模式。这些第三方煎药中…

Proactor模型

文章目录 概述1. 异步I/O操作2. 事件通知3. 事件处理函数4. 事件循环5. 多线程支持6. 非阻塞I/O7. 可扩展性8. 错误处理9. 资源管理10. 编程复杂性11. 应用场景流程图 结论 概述 Proactor模型是一种基于异步I/O操作的事件驱动编程模型&#xff0c;主要用于处理并发的I/O事件&a…

冒泡排序(数组作为函数参数)

什么是冒泡排序&#xff1f; 冒泡排序&#xff08;Bubble Sort&#xff09;也是一种简单直观的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换&#xff0c;…

docker--容器数据进行持久化存储的三种方式

文章目录 为什么Docker容器需要使用持久化存储1.什么是Docker容器&#xff1f;2.什么是持久化存储&#xff1f;3.为什么Docker容器需要持久化存储&#xff1f;4.Docker如何实现持久化存储&#xff1f;(1)、Docker卷(Volumes)简介适用环境:使用场景:使用案例: (2)、绑定挂载&…

pycharm+pytorch2.3.1安装

成功运行 Anaconda简介 Anaconda 就是可以便捷获取包且对包能够进行管理&#xff0c;同时对环境可以统一管理的发行版本。Anaconda包含了conda、Python在内的超过180个科学包及其依赖项。 Anaconda安装 去官网地址下载 Download Anaconda Distribution | Anaconda​www.ana…

SpringBoot启动原理详解

透彻理解SpringBoot启动原理&#xff08;一&#xff09; 一张Spring启动顺序图我们对Spring启动原理有多少理解呢一起看一下Spring有那些扩展点和启动过程有关通过打印日志学习Spring的执行顺序实例化和初始化的区别Spring重要扩展点的启动顺序1.BeanFactoryPostProcessor2.实例…

python3.10.4——Windows环境安装

python下载官网&#xff1a;https://www.python.org/downloads/ 如果安装在C盘&#xff0c;需要右键→选择“以管理员身份运行” 勾选2个按钮&#xff0c;选择自定义安装 全部选择&#xff0c;点击Next 更改安装路径 命令行检查python是否安装成功&#xff1a; 出现版本号说明…

内存泄漏详解

文章目录 什么是内存泄漏内存泄漏的原因排查及解决内存泄漏避免内存泄漏及时释放资源设置合理的变量作用域及时清理不需要的对象避免无限增长避免内部类持有外部类引用使用弱引用 什么是内存泄漏 内存泄漏是指不使用的对象持续占有内存使得内存得不到释放&#xff0c;从而造成…

【Hot100】LeetCode—416. 分割等和子集

目录 题目1- 思路2- 实现⭐152. 乘积最大子数组——题解思路 3- ACM 实现 题目 原题连接&#xff1a;416. 分割等和子集 1- 思路 理解为背包问题 思路&#xff1a; 能否将均分的子集理解为一个背包&#xff0c;比如对于 [1,5,11,5]&#xff0c;判断能否凑齐背包为 11 的容量…

面试场景题系列--(1)如果系统的 QPS 突然提升 10 倍该怎么设计?--xunznux

1. 如果系统的 QPS 突然提升 10 倍该怎么设计&#xff1f; 1.1 硬件的扩展微服务的拆分 如果所有的业务包括交易系统、会员信息、库存、商品等等都夹杂在一起&#xff0c;当流量一旦起来之后&#xff0c;单体架构的问题就暴露出来了&#xff0c;机器挂了所有的业务就全部无法…