Ensemble Learning-基于集成学习的模型融合-Python实现

Wisdom of the crowds == ensemble machine learning

1 Ensemble Learning-模型融合

通过对多个单模型融合以提升整体性能。

1.1 Voting

投票制即为,投票多者为最终的结果。例如一个分类问题,多个模型投票(当然可以设置权重)。最终投票数最多的类为最终被预测的类。

1.2 Averaging

Averaging即所有预测器的结果平均。

  • 回归问题,直接取平均值作为最终的预测值。(也可以使用加权平均)
  • 分类问题,直接将模型的预测概率做平均。(or 加权)

加权平均,其公式如下:

∑ i = 1 n W e i g h t i ∗ P i \sum\limits_{i=1}^{n} {Weight_i}*{P_i} i=1nWeightiPi

其中 n n n表示模型的个数, W e i g h t i Weight_i Weighti表示该模型权重, P i P_i Pi表示模型i的预测概率值。

例如两个分类器,XGBoost(权重0.4)和LightGBM(权重0.6),其预测概率分别为:0.75、0.5,那么最终的预测概率,(0.4 * 0.75+0.6 * 0.5)/(0.4+0.6)=0.6

模型权重也可以通过机器学习模型学习得到

1.3 Ranking

Rank的思想其实和Averaging一致,但Rank是把排名做平均,对于AUC指标比较有效。

个人认为其实就是Learning to rank的思想,可以来优化搜索排名。具体公式如下:

∑ i = 1 n W e i g h t i R a n k i \sum\limits_{i=1}^{n}\frac{Weight_i}{Rank_i} i=1nRankiWeighti

其中 n n n表示模型的个数, W e i g h t i Weight_i Weighti表示该模型权重,所有权重相同表示平均融合。 R a n k i Rank_i Ranki表示样本在第i个模型中的升序排名。它可以较快的利用排名融合多个模型之间的差异,而不需要加权融合概率。

1.4 Binning

将单个模型的输出放到一个桶中。参考pdf paperGuocong Song

1.5 Bagging

使用训练数据的不同随机子集来训练每个 Base Model,最后每个 Base Model 权重相同,分类问题进行投票,回归问题平均。

随机森林就用到了Bagging,并且具有天然的并行性。

1.6 Boosting

Boosting是一种迭代的方法,每一次训练会更关心上一次被分错的样本,比如改变被错分的样本的权重的Adaboost方法。还有许多都是基于这种思想,比如Gradient Boosting等。

经典问题:随机森林、Adaboost、GBDT、XGBoost的区别是什么?(面试常常被问)

1.7 Stacking

在这里插入图片描述

图片来自Wille的博客

从上图可以看出,类似交叉验证。

  1. 将数据集分为K个部分,共有n个模型。

  2. for i in xrange(n):

    ​ for i in xrange(k):

    ​ 用第i个部分作为预测,剩余的部分来训练模型,获得其预测的输出作为第i部分的新特征。

    ​ 对于测试集,直接用这k个模型的预测值均值作为新的特征。

  3. 这样k次下来,整个数据集都获得了这个模型构建的New Feature。n个模型训练下来,这个模型就有n个New Features。

  4. 把New Features和label作为新的分类器的输入进行训练。然后输入测试集的New Features输入模型获得最终的预测结果。

1.8 Blending

Blending直接用不相交的数据集用于不同层的训练。

以两层的Blending为例,训练集划分为两部分(d1,d2),测试集为test。

  1. 第一层:用d1训练多个模型,讲其对d2和test的预测结果作为第二层的New Features。
  2. 第二层:用d2的New Features和标签训练新的分类器,然后把test的New Features输入作为最终的预测值。

2 融合的条件

  • **Base Model 之间的相关性要尽可能的小。**这就是为什么非 Tree-based Model 往往表现不是最好但还是要将它们包括在 Ensemble 里面的原因。Ensemble 的 Diversity 越大,最终 Model 的 Bias 就越低。
  • **Base Model 之间的性能表现不能差距太大。**这其实是一个 Trade-off,在实际中很有可能表现相近的 Model 只有寥寥几个而且它们之间相关性还不低。但是实践告诉我们即使在这种情况下 Ensemble 还是能大幅提高成绩。

3 Python实现

下面只实现了一些常用的融合方法,其他的类推。

3.1 Stacking

'''5折stacking'''
n_folds = 5
skf = list(StratifiedKFold(y, n_folds))
for j, clf in enumerate(clfs):
    '''依次训练各个单模型'''
    dataset_blend_test_j = np.zeros((X_predict.shape[0], len(skf)))
    for i, (train, test) in enumerate(skf):
        '''使用第i个部分作为预测,剩余的部分来训练模型,获得其预测的输出作为第i部分的新特征。'''
        X_train, y_train, X_test, y_test = X[train], y[train], X[test], y[test]
        clf.fit(X_train, y_train)
        y_submission = clf.predict_proba(X_test)[:, 1]
        dataset_blend_train[test, j] = y_submission
        dataset_blend_test_j[:, i] = clf.predict_proba(X_predict)[:, 1]
    '''对于测试集,直接用这k个模型的预测值均值作为新的特征。'''
    dataset_blend_test[:, j] = dataset_blend_test_j.mean(1)

'''融合使用的模型'''
clf = GradientBoostingClassifier(learning_rate=0.02, subsample=0.5, max_depth=6, n_estimators=30)
clf.fit(dataset_blend_train, y)
y_submission = clf.predict_proba(dataset_blend_test)[:, 1]

完整代码见:GitHub_ensemble_stacking

3.2 Blending

下面是一个两层的Blending的实现

'''切分训练数据集为d1,d2两部分'''
X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=2017)
dataset_blend_train = np.zeros((X_d2.shape[0], len(clfs)))
dataset_blend_test = np.zeros((X_predict.shape[0], len(clfs)))

for j, clf in enumerate(clfs):
    '''依次训练各个单模型'''
    # print(j, clf)
    '''使用第1个部分作为预测,第2部分来训练模型,获得其预测的输出作为第2部分的新特征。'''
    # X_train, y_train, X_test, y_test = X[train], y[train], X[test], y[test]
    clf.fit(X_train, y_train)
    y_submission = clf.predict_proba(X_test)[:, 1]
    dataset_blend_train[:, j] = y_submission
    '''对于测试集,直接用这k个模型的预测值作为新的特征。'''
    dataset_blend_test[:, j] = clf.predict_proba(X_predict)[:, 1]
    print("val auc Score: %f" % roc_auc_score(y_predict, dataset_blend_test[:, j]))

'''融合使用的模型'''
# clf = LogisticRegression()
clf = GradientBoostingClassifier(learning_rate=0.02, subsample=0.5, max_depth=6, n_estimators=30)
clf.fit(dataset_blend_train, y_test)
y_submission = clf.predict_proba(dataset_blend_test)[:, 1]

完整代码见:GitHub_ensemble_blending

Reference

  1. HUMAN ENSEMBLE LEARNING
  2. https://mlwave.com/kaggle-ensembling-guide/
  3. https://dnc1994.com/2016/04/rank-10-percent-in-first-kaggle-competition/
  4. https://zhuanlan.zhihu.com/p/25836678
  • 43
    点赞
  • 262
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
集成学习是一种通过组合多个基本模型来提高预测准确性的机器学习方法。下面是一个使用Python实现集成学习模型的示例代码: ```python # 导入所需的库 from sklearn.ensemble import VotingClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.neighbors import KNeighborsClassifier from sklearn.svm import SVC from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据集 iris = load_iris() X, y = iris.data, iris.target # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 定义基本模型 model1 = DecisionTreeClassifier() model2 = KNeighborsClassifier() model3 = SVC() # 定义集成学习模型 ensemble_model = VotingClassifier(estimators=[('dt', model1), ('knn', model2), ('svm', model3)], voting='hard') # 训练集成学习模型 ensemble_model.fit(X_train, y_train) # 在测试集上进行预测 y_pred = ensemble_model.predict(X_test) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print("准确率:", accuracy) ``` 在上面的代码中,我们使用了三个基本模型:决策树分类器(DecisionTreeClassifier)、K近邻分类器(KNeighborsClassifier)和支持向量机分类器(SVC)。然后,我们使用VotingClassifier来定义集成学习模型,其中estimators参数指定了基本模型的名称和实例,voting参数指定了投票策略('hard'表示多数表决)。最后,我们使用fit方法训练集成学习模型,并使用predict方法在测试集上进行预测,最后计算准确率。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百川AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值