集成学习综合教程

一、前置知识

一个分类器的分类准确率在60%-80%,即:比随机预测略好,但准确率却不太高,我们可以称之为 "弱分类器" ,比如CART(classification and regression tree 分类与回归树)。
反之,如果分类精度90%以上,则是强分类器。

二、高级集成技术

1.堆叠(stacking)

它使用多个模型(决策树、knn、svm)的预测来构建 新模型 。该 新模型 用于对测试集进行 预测
第一步:把训练集分成10份

第二步:基础模型(假设是决策树)在其中9份上拟合,并对第10份进行预测。
第三步:对训练集上的每一份如此做一遍。

第四步:然后将基础模型(此处是决策树)拟合到整个训练集上。
第五步:使用此模型,在测试集上进行预测。

第六步:对另一个基本模型(比如knn)重复步骤2到4,产生对训练集和测试集的另一组预测。

第七步:训练集预测被用作构建新模型的特征。
第八步:该新模型用于对测试预测集(test prediction set,上图的右下角)进行最终预测。

示例代码:
我们首先定义一个函数来对n折的训练集和测试集进行预测。此函数返回每个模型对训练集和测试集的预测。
def Stacking(model,train,y,test,n_fold):
folds=StratifiedKFold(n_splits=n_fold,random_state=1)
test_pred=np.empty((test.shape[0],1),float)
train_pred=np.empty((0,1),float)
for train_indices,val_indices in folds.split(train,y.values):
x_train,x_val=train.iloc[train_indices],train.iloc[val_indices]
y_train,y_val=y.iloc[train_indices],y.iloc[val_indices]
model.fit(X=x_train,y=y_train)
train_pred=np.append(train_pred,model.predict(x_val))
test_pred=np.append(test_pred,model.predict(test))
return test_pred.reshape(-1,1),train_pred
现在我们将创建两个基本模型:决策树和knn。
model1 = tree.DecisionTreeClassifier(random_state=1)
test_pred1 ,train_pred1=Stacking(model=model1,n_fold=10, train=x_train,test=x_test,y=y_train)
train_pred1=pd.DataFrame(train_pred1)
test_pred1=pd.DataFrame(test_pred1)
model2 = KNeighborsClassifier()
test_pred2 ,train_pred2=Stacking(model=model2,n_fold=10,train=x_train,test=x_test,y=y_train)
train_pred2=pd.DataFrame(train_pred2)
test_pred2=pd.DataFrame(test_pred2)
创建第三个模型,逻辑回归,在决策树和knn模型的预测之上。
df = pd.concat([train_pred1, train_pred2], axis=1)
df_test = pd.concat([test_pred1, test_pred2], axis=1)
model = LogisticRegression(random_state=1)
model.fit(df,y_train)
model.score(df_test, y_test)
为了简化上面的解释,我们创建的堆叠模型只有两层。决策树和knn模型建立在零级,而逻辑回归模型建立在第一级。其实可以随意的在堆叠模型中创建多个层次。

2.混合

混合遵循与堆叠相同的方法,但仅使用来自训练集的一个留出(holdout)/验证集来进行预测。换句话说,与堆叠不同,预测仅在留出集上进行。留出集和预测用于构建在测试集上运行的模型。以下是混合过程的详细说明:
第一步:原始训练数据被分为训练集合验证集。

第二步:在训练集上拟合模型。
第三步:在验证集和测试集上进行预测。

第四步:验证集及其预测用作构建新模型的特征。
第五步:该新模型用于对测试集和元特征(meta-features)进行最终预测。
示例代码:
我们将在训练集上建立两个模型,决策树和knn,以便对验证集进行预测。
model1 = tree.DecisionTreeClassifier()
model1.fit(x_train, y_train)
val_pred1=model1.predict(x_val)
test_pred1=model1.predict(x_test)
val_pred1=pd.DataFrame(val_pred1)
test_pred1=pd.DataFrame(test_pred1)
model2 = KNeighborsClassifier()
model2.fit(x_train,y_train)
val_pred2=model2.predict(x_val)
test_pred2=model2.predict(x_test)
val_pred2=pd.DataFrame(val_pred2)
test_pred2=pd.DataFrame(test_pred2)
结合元特征和验证集,构建逻辑回归模型以对测试集进行预测。
df_val=pd.concat([x_val, val_pred1,val_pred2],axis=1)
df_test=pd.concat([x_test, test_pred1,test_pred2],axis=1)
model = LogisticRegression()
model.fit(df_val,y_val)
model.score(df_test,y_test)

3.bagging !

结合 多个模型的结果来获得泛化的结果。
Bootstrapping是一种采样技术,我们有放回的从原始数据集上创建观察子集,子集的大小与原始集的大小相同。
**Bagging(或Bootstrap Aggregating)**技术使用这些子集(包)来获得分布的完整概念(完备集)。为bagging创建的子集的大小也可能小于原始集。
第一步:从原始数据集有放回的选择观测值来创建多个子集。
第二步:在每一个子集上创建一个 基础模型(弱模型)。
第三步:这些模型同时运行,彼此独立。
第四步:通过 组合所有模型的预测来确定最终预测。

4.Boosting !!

在我们进一步讨论之前,这里有另一个问题:如果 第一个模型错误地预测了某一个数据点,然后接下来的模型(可能是所有模型),将预测组合起来会提供更好的结果吗?Boosting就是来处理这种情况的。
Boosting是一个顺序过程,每个后续模型都会尝试 纠正先前模型的错误。后续的模型依赖于之前的模型。接下来一起看看boosting的工作方式:
第一步:从原始数据集创建一个子集。
第二步:最初,所有数据点都具有相同的权重。
第三步:在此子集上创建基础模型。
第四步:该模型用于对整个数据集进行预测。
第五步:使用实际值和预测值计算误差。
第六步: 预测错误的点获得更高的权重
第七步:创建另一个模型并对数据集进行预测( 此模型尝试更正先前模型中的错误)。
第八步:类似地,创建多个模型,每个模型校正先前模型的错误。
第九步:最终模型(强学习器)是所有模型(弱学习器)的 加权平均值
因此,boosting算法结合了许多弱学习器来形成一个强学习器。单个模型在整个数据集上表现不佳,但它们在数据集的某些部分上表现很好。因此,每个模型实际上提升了集成的整体性能。

三、具体算法

1.Bagging meta-estimator

适用于分类和回归。
示例代码:
from sklearn.ensemble import BaggingClassifier
from sklearn import tree
model = BaggingClassifier(tree.DecisionTreeClassifier(random_state=1))
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.75135135135135134
回归问题示例代码:
from sklearn.ensemble import BaggingRegressor
model = BaggingRegressor(tree.DecisionTreeRegressor(random_state=1))
model.fit(x_train, y_train)
model.score(x_test,y_test)
算法中用到的参数:
base_estimator

  • 定义了在随机子集上拟合所用的基础估计器
  • 没有指明时,默认使用决策树

n_estimators

  • 创建的基础估计器数量
  • 要小心微调这个参数,因为数字越大运行时间越长,相反太小的数字可能无法提供最优结果

max_samples

  • 该参数控制子集的大小
  • 它是训练每个基础估计器的最大样本数量

max_features

  • 控制从数据集中提取多少个特征
  • 它是训练每个基础估计器的最大特征数量

n_jobs

  • 同时运行的job数量
  • 将这个值设为你系统的CPU核数
  • 如果设为-1,这个值会被设为你系统的CPU核数

random_state

  • 定义了随机分割的方法。当两个模型的random_state值一样时,它们的随机选择也一样
  • 如果你想对比不同的模型,这个参数很有用。

2.Bagging--随机森林

随机森林中的基础估计器是 决策树 。与bagging meta-estimator不同,随机森林随机选择一组特征,这些特征用于决定决策树的每个节点处的最佳分割。

随机森林的具体步骤如下:
第一步:从原始数据集(Bootstrapping)创建随机子集。
第二步:在决策树中的每个节点处,仅考虑一组随机特征来决定最佳分割。
第三步:在每个子集上拟合决策树模型。
第四步:通过对所有决策树的预测求平均来计算最终预测。
注意:随机林中的决策树可以构建在数据和特征的子集上。特别地,sklearn中的随机森林使用所有特征作为候选,并且候选特征的随机子集用于在每个节点处分裂。
总而言之,随机森林随机选择数据点和特征,并构建多个树(森林)。
示例代码:
from sklearn.ensemble import RandomForestClassifier
model= RandomForestClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.77297297297297296
你可以通过在随机林中使用model.feature_importances_来查看特征重要性。
for i, j in sorted(zip(x_train.columns, model.feature_importances_)):
print(i, j)
结果如下:
ApplicantIncome 0.180924483743
CoapplicantIncome 0.135979758733
Credit_History 0.186436670523
Property_Area_Urban 0.0167025290557
Self_Employed_No 0.0165385567137
Self_Employed_Yes 0.0134763695267
回归问题示例代码:
from sklearn.ensemble import RandomForestRegressor
model= RandomForestRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)
参数:
n_estimators

  • 定义随机森林中要创建的决策树数量
  • 通常,越高的值会让预测更强大更稳定,但是过高的值会让训练时间很长

criterion

  • 定义了分割用的函数
  • 该函数用来衡量使用每个特征分割的质量从而选择最佳分割

max_features

  • 定义了每个决策树中可用于分割的最大特征数量
  • 增加最大特征数通常可以改善性能,但是一个非常高的值会减少各个树之间的差异性

max_depth

  • 随机森林有多个决策树,此参数定义树的最大深度

min_samples_split

  • 用于在尝试拆分之前定义叶节点中所需的最小样本数
  • 如果样本数小于所需数量,则不分割节点

min_samples_leaf

  • 定义了叶子节点所需的最小样本数
  • 较小的叶片尺寸使得模型更容易捕获训练数据中的噪声

max_leaf_nodes

  • 此参数指定每个树的最大叶子节点数
  • 当叶节点的数量变得等于最大叶节点时,树停止分裂

n_jobs

  • 这表示并行运行的作业数
  • 如果要在系统中的所有核心上运行,请将值设置为-1

random_state

  • 此参数用于定义随机选择
  • 它用于各种模型之间的比较

**3.**AdaBoost

自适应增强或AdaBoost是最简单的boosting算法之一。通常用决策树来建模。创建多个顺序模型,每个模型都校正上一个模型的错误。AdaBoost为错误预测的观测值分配权重,后续模型来正确预测这些值。
以下是执行AdaBoost算法的步骤:
第一步:最初,数据集中的所有观察值都具有相同的权重。
第二步:在数据子集上建立一个模型。
第三步:使用此模型,可以对整个数据集进行预测。
第四步:通过比较预测值和实际值来计算误差。
第五步:在创建下一个模型时,会给预测错误的数据点赋予更高的权重。
第六步:可以使用误差值确定权重。例如,误差越大,分配给观察值的权重越大。
第七步:重复该过程直到误差函数没有改变,或达到估计器数量的最大限制。
示例代码:
from sklearn.ensemble import AdaBoostClassifierfrom sklearn.ensemble import AdaBoostClassifier
model = AdaBoostClassifier(random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.81081081081081086
回归问题示例代码:
from sklearn.ensemble import AdaBoostRegressor
model = AdaBoostRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)
参数:
base_estimators

  • 它用于指定基础估计器的类型,即用作基础学习器的机器学习算法

n_estimators

  • 它定义了基础估计器的数量
  • 默认值为10,但可以设为较高的值以获得更好的性能

learning_rate

  • 此参数控制估计器在最终组合中的贡献
  • 在learning_rate和n_estimators之间需要进行权衡

max_depth

    • 定义单个估计器的最大深度
    • 调整此参数以获得最佳性能

n_jobs

  • 指定允许使用的处理器数
  • 将值设为-1,可以使用允许的最大处理器数量

random_state

  • 用于指定随机数据拆分的整数值
  • 如果给出相同的参数和训练数据,random_state的确定值将始终产生相同的结果

4.Gradient Boosting(梯度提升GBM)

Gradient Boosting或GBM是另一种集成机器学习算法,适用于回归和分类问题。GBM使用boosting技术,结合了许多弱学习器,以形成一个强大的学习器。回归树用作基础学习器,每个后续的树都是基于前一棵树计算的错误构建的。
我们将使用一个简单的例子来理解GBM算法。我们会使用以下数据预测一群人的年龄:

第一步:假设平均年龄是数据集中所有观测值的预测值。
第二步:使用该平均预测值和年龄的实际值来计算误差:

第三步:使用上面计算的误差作为目标变量创建树模型。我们的目标是找到最佳分割以最小化误差。
第四步:该模型的预测与预测1相结合:

第五步:上面计算的这个值是新的预测。
第六步:使用此预测值和实际值计算新误差:

第七步:重复步骤2到6,直到最大迭代次数(或误差函数不再改变)
示例代码:
from sklearn.ensemble import GradientBoostingClassifier
model= GradientBoostingClassifier(learning_rate=0.01,random_state=1)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.81621621621621621
回归问题示例代码:
from sklearn.ensemble import GradientBoostingRegressor
model= GradientBoostingRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)
参数:
min_samples_split

  • 定义考虑被拆分的节点中所需的最小样本数(或观察值数)
  • 用于控制过配合。较高的值会阻止模型学习关系,这种关系可能对为一棵树选择的特定样本高度特定

min_samples_leaf

  • 定义终端或叶节点中所需的最小样本数
  • 一般来说,应该为不平衡的分类问题选择较低的值,因为少数群体占大多数的地区将非常小

min_weight_fraction_leaf

  • 与min_samples_leaf类似,但定义为观察总数的一个比例而不是整数

max_depth

  • 树的最大深度。
  • 用于控制过拟合,因为更高的深度将让模型学习到非常特定于某个样本的关系
  • 应该使用CV进行调整

max_leaf_nodes

  • 树中终端节点或叶子的最大数量
  • 可以用于代替max_depth。由于创建了二叉树,因此深度'n'将产生最多2 ^ n个叶子
  • 如果它被定义,则GBM会忽略max_depth

max_features

  • 搜索最佳拆分时要考虑的特征数量。这些特征将被随机选择。
  • 作为一个经验法则,特征总数的平方根效果很好,但我们可以尝试直到特征总数的30-40%。
  • 较高的值可能导致过度拟合,但通常取决于具体情况。

5 XGBoost

XGBoost(extreme Gradient Boosting)是梯度提升算法的高级实现。实践证明,XGBoost是一种高效的ML算法,广泛应用于机器学习竞赛和黑客马拉松。 XGBoost具有很高的预测能力,几乎比其他梯度提升技术快10倍。它还包括各种正规化,可减少过拟合并提高整体性能。因此,它也被称为"正则化提升"技术。

让我们看看XGBoost为何比其他技术更好:
正则化:

  • 标准GBM实现没有像XGBoost那样的正则化
  • 因此,XGBoost还有助于减少过拟合

并行处理:

  • XGBoost实现并行处理,并且比GBM更快
  • XGBoost还支持Hadoop上的实现

高灵活性:

  • XGBoost允许用户自定义优化目标和评估标准,为模型添加全新维度

处理缺失值:

  • XGBoost有一个内置的例程来处理缺失值

树剪枝:

  • XGBoost先进行分割,直到指定的max_depth,然后开始向后修剪树并删除没有正向增益的分割

内置交叉验证:

  • XGBoost允许用户在提升过程的每次迭代中运行交叉验证,因此很容易在一次运行中获得精确的最佳提升迭代次数

示例代码:
由于XGBoost会自行处理缺失值,因此你不必再处理。你可以跳过上述代码中缺失值插补的步骤。如下展示了如何应用xgboost:
import xgboost as xgb
model=xgb.XGBClassifier(random_state=1,learning_rate=0.01)
model.fit(x_train, y_train)
model.score(x_test,y_test)
0.82702702702702702
回归问题示例代码:
import xgboost as xgb
model=xgb.XGBRegressor()
model.fit(x_train, y_train)
model.score(x_test,y_test)
参数:
nthread

  • 这用于并行处理,应输入系统中的核心数
  • 如果你希望在所有核心上运行,请不要输入此值。该算法将自动检测

eta

  • 类似于GBM中的学习率
  • 通过缩小每一步的权重,使模型更加健壮

min_child_weight

  • 定义子节点中所有观察值的最小权重和
  • 用于控制过拟合。较高的值会阻止模型学习关系,这种关系可能高度特定于为某个树所选的具体样本

max_depth

  • 它用于定义最大深度
  • 更高的深度将让模型学习到非常特定于某个样本的关系

max_leaf_nodes

  • 树中终端节点或叶子的最大数量
  • 可以用来代替max_depth。由于创建了二叉树,因此深度'n'将产生最多2 ^ n个叶子
  • 如果已定义,则GBM将忽略max_depth

gamma

  • 仅当产生的分割能给出损失函数的正向减少时,才分割节点。Gamma指定进行分割所需的最小损失减少量。
  • 使算法保守。值可能会根据损失函数而有所不同,因此应进行调整

subsample

  • 与GBM的子样本相同。表示用于每棵树随机采样的观察值的比例。
  • 较低的值使算法更加保守并防止过拟合,但是太小的值可能导致欠拟合。

colsample_bytree

  • 它类似于GBM中的max_features
  • 表示要为每个树随机采样的列的比例

6.Light GBM

在讨论Light GBM如何工作之前,先理解为什么在我们有如此多其他算法时(例如我们上面看到的算法)我们还需要这个算法。当数据集非常大时,Light GBM会击败所有其他算法。与其他算法相比,Light GBM在较大的数据集上运行所需的时间较短。

LightGBM是一个梯度提升框架,它使用基于树的算法并遵循逐叶子的方式(leaf-wise),而其他算法以逐层级(level-wise)模式工作。下图帮助你更好地理解二者差异:


逐叶子方式可能在较小的数据集上导致过拟合,但可以通过使用'max_depth'参数来避免这种情况。你可以在本文中阅读有关Light GBM及其与XGB比较的更多信息。
示例代码:
import lightgbm as lgb
train_data=lgb.Dataset(x_train,label=y_train)
#define parameters
params = {'learning_rate':0.001}
model= lgb.train(params, train_data, 100)
y_pred=model.predict(x_test)
for i in range(0,185):
if y_pred[i]>=0.5:
y_pred[i]=1
else:
y_pred[i]=0
0.81621621621621621
回归问题示例代码:
import lightgbm as lgb
train_data=lgb.Dataset(x_train,label=y_train)
params = {'learning_rate':0.001}
model= lgb.train(params, train_data, 100)
from sklearn.metrics import mean_squared_error
rmse=mean_squared_error(y_pred,y_test)**0.5
参数:
num_iterations

  • 它定义了要执行的提升迭代次数

num_leaves

  • 此参数用于设置要在树中形成的叶子数
  • 在Light GBM的情况下,由于拆分是按逐叶子方式而不是深度方式进行的,因此num_leaves必须小于2 ^(max_depth),否则可能导致过拟合

min_data_in_leaf

  • 非常小的值可能导致过拟合
  • 它也是处理过拟合的最重要的参数之一

max_depth

  • 它指定树可以生长到的最大深度或级别
  • 此参数的值非常高可能会导致过拟合

bagging_fraction

  • 它用于指定每次迭代使用的数据比例
  • 此参数通常用于加速训练

max_bin

  • 定义特征值将被分桶的最大分箱数
  • 较小的max_bin值可以节省大量时间,因为它在离散分箱中存储特征值,这在计算开销上是便宜的

7.CatBoost

处理类别型变量是一个繁琐的过程,尤其是你有大量此类变量时。当你的类别变量有很多标签(即它们是高度基数)时,对它们执行one-hot编码会指数级的增加维度,会让数据集的使用变得非常困难。
CatBoost可以自动处理类别型变量,并且不需要像其他机器学习算法那样进行大量数据预处理。这篇文章详细解释了CatBoost。
示例代码:
CatBoost算法有效地处理类别型变量。因此,无需对变量执行one-hot编码。只需加载文件,估算缺失值,就可以了:
from catboost import CatBoostClassifier
model=CatBoostClassifier()
categorical_features_indices = np.where(df.dtypes != np.float)[0]
model.fit(x_train,y_train,cat_features=([ 0, 1, 2, 3, 4, 10]),eval_set=(x_test, y_test))
model.score(x_test,y_test)
0.80540540540540539
回归问题示例代码:
from catboost import CatBoostRegressor
model=CatBoostRegressor()
categorical_features_indices = np.where(df.dtypes != np.float)[0]
model.fit(x_train,y_train,cat_features=([ 0, 1, 2, 3, 4, 10]),eval_set=(x_test, y_test))
model.score(x_test,y_test)
参数:
loss_function

  • 定义用于训练的度量标准

iterations

  • 可以构建最多多少棵树
  • 树的最终数量可能小于或等于此数字

learning_rate

  • 定义学习率
  • 用于减少梯度步骤

border_count

  • 它指定数值型特征的拆分数
  • 它类似于max_bin参数

depth

  • 定义树的深度

random_seed

  • 此参数类似于我们之前看到的'random_state'参数
  • 它是一个整数值,用于定义训练的随机种子

结语

集成模型可以指数级地提升模型的性能,有时可以成为第一名和第二名之间的决定因素!在本文中,我们介绍了各种集成学习技术,并了解了这些技术如何应用于机器学习算法。此外,我们在贷款预测数据集上运用了算法。

相关推荐
GIOTTO情20 分钟前
媒介宣发的技术革命:Infoseek如何用AI重构企业传播全链路
大数据·人工智能·重构
阿里云大数据AI技术29 分钟前
云栖实录 | 从多模态数据到 Physical AI,PAI 助力客户快速启动 Physical AI 实践
人工智能
小关会打代码36 分钟前
计算机视觉进阶教学之颜色识别
人工智能·计算机视觉
IT小哥哥呀42 分钟前
基于深度学习的数字图像分类实验与分析
人工智能·深度学习·分类
机器之心1 小时前
VAE时代终结?谢赛宁团队「RAE」登场,表征自编码器或成DiT训练新基石
人工智能·openai
机器之心1 小时前
Sutton判定「LLM是死胡同」后,新访谈揭示AI困境
人工智能·openai
大模型真好玩1 小时前
低代码Agent开发框架使用指南(四)—Coze大模型和插件参数配置最佳实践
人工智能·agent·coze
jerryinwuhan1 小时前
基于大语言模型(LLM)的城市时间、空间与情感交织分析:面向智能城市的情感动态预测与空间优化
人工智能·语言模型·自然语言处理
落雪财神意1 小时前
股指10月想法
大数据·人工智能·金融·区块链·期股
中杯可乐多加冰1 小时前
无代码开发实践|基于业务流能力快速开发市场监管系统,实现投诉处理快速响应
人工智能·低代码