stacking和blending的区别

看到网上有很多关于BlendingStacking有什么区别的讨论,但感觉并没有说到点子上,最近在国外看了一篇比较好的博客,简洁明了地贴出了代码和讨论,所以我在这里总结一下。

直接说,其实Blending和Stacking基本上是一样的,除了有一点不同,Blending它在训练基础模型base model的时候,并没有使用kfold方法(Stacking使用了Kfold),而是拿了一部分数据,比如说20%的数据,这部分数据不加入基础模型的训练,而是在基础模型都训练好了以后,去预测这部分没有参与训练的数据得到预测概率,然后以各个模型的预测概率作为最终模型的特征。

image

相关代码如下:

from sklearn.model_selection import train_test_split
class BlendingAveragedModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, base_models, meta_model, holdout_pct=0.2, use_features_in_secondary=False):
        self.base_models = base_models
        self.meta_model = meta_model
        self.holdout_pct = holdout_pct
        self.use_features_in_secondary = use_features_in_secondary
        
    def fit(self, X, y):
        self.base_models_ = [clone(x) for x in self.base_models]
        self.meta_model_ = clone(self.meta_model)
        
        X_train, X_holdout, y_train, y_holdout = train_test_split(X, y, test_size=self.holdout_pct)
                
        holdout_predictions = np.zeros((X_holdout.shape[0], len(self.base_models)))
        for i, model in enumerate(self.base_models_):
            model.fit(X_train, y_train)
            y_pred = model.predict(X_holdout)
            holdout_predictions[:, i] = y_pred
        if self.use_features_in_secondary:
            self.meta_model_.fit(np.hstack((X_holdout, holdout_predictions)), y_holdout)
        else:
            self.meta_model_.fit(holdout_predictions, y_holdout)
            
        return self
    
    def predict(self, X):
        meta_features = np.column_stack([
            model.predict(X) for model in self.base_models_
        ])
        if self.use_features_in_secondary:
            return self.meta_model_.predict(np.hstack((X, meta_features)))
        else:
            return self.meta_model_.predict(meta_features)

Blending的好处就是训练时间缩短,这个比较好理解,毕竟拿了一部分数据出来做holdout,在前面训练基模型的时候就只用了较少的数据,在后面训练meta模型的时候holdout数据量又不大,自然总体上时间要加快。但坏处也比较明显,主要体现在holdout数据量少这个问题上。一个是前面在训练基模型的时候用的数据量比stacking少,第二个是在训练meta模型的时候holdout数据量少,可能会造成meta模型对于holdout数据的过拟合,第三个是因为holdout数据和训练数据不一样,自然会比使用kfold的stacking方式要精度更低。

stacking相当于是按照n折对数据迭代划分,每次划分都有n-1份数据作为训练集,1份数据作为预测后的结果,更新到特征当中。经过n次后,那么就会产生最终的预测分数,当然有很多数据都是重复使用的,这样的好处就是数据量充足,能够充分利用数据,精度也会更高,坏处就是可能会造成信息泄露的问题,因为在kfold当中除了第一轮以外都是拿着用来训练好的模型去预测之前用来训练这个模型的数据,会有这个风险。

第一轮迭代

image

第二轮迭代

image

代码如下:

class StackingAveragedModels(BaseEstimator, RegressorMixin, TransformerMixin):
    def __init__(self, base_models, meta_model, n_folds=5, use_features_in_secondary=False):
        self.base_models = base_models
        self.meta_model = meta_model
        self.n_folds = n_folds
        self.use_features_in_secondary = use_features_in_secondary
        
    def fit(self, X, y):
        """Fit all the models on the given dataset"""
        self.base_models_ = [list() for x in self.base_models]
        self.meta_model_ = clone(self.meta_model)
        kfold = KFold(n_splits=self.n_folds, shuffle=True, random_state=42)
        
        # Train cloned base models and create out-of-fold predictions
        out_of_fold_predictions = np.zeros((X.shape[0], len(self.base_models)))
        for i, model in enumerate(self.base_models):
            for train_index, holdout_index in kfold.split(X, y):
                instance = clone(model)
                self.base_models_[i].append(instance)
                instance.fit(X[train_index], y[train_index])
                y_pred = instance.predict(X[holdout_index])
                out_of_fold_predictions[holdout_index, i] = y_pred
        
        if self.use_features_in_secondary:
            self.meta_model_.fit(np.hstack((X, out_of_fold_predictions)), y)
        else:
            self.meta_model_.fit(out_of_fold_predictions, y)
            
        return self
    
    def predict(self, X):
        meta_features = np.column_stack([
            np.column_stack([model.predict(X) for model in base_models]).mean(axis=1)
            for base_models in self.base_models_ ])
        if self.use_features_in_secondary:
            return self.meta_model_.predict(np.hstack((X, meta_features)))
        else:
            return self.meta_model_.predict(meta_features)

参考资料

A guide to Ensemble Learning - Towards Data Science

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、数据量比较大的时候,svm和lr哪个更快? svm适用于相对稀疏的数据,所以xgb的效果比svm要好。面试官也...
    DaiMorph阅读 2,314评论 0 0
  • 一般来说,通过融合多个不同的模型,可能提升机器学习的性能,这一方法在各种机器学习比赛中广泛应用,比如在kaggle...
    尘嚣看客阅读 19,586评论 3 19
  • 1.Voting 投票法针对分类模型,多个模型的分类结果进行投票,少数服从多数。除了公平投票外,还可以给投...
    ZAK_ML阅读 2,292评论 0 1
  • [TOC] About Trs 只是阅读过程中对其中一些进行注脚而已,更确切的内容还是英文原文来的清晰,有些翻译反...
    mrlevo520阅读 1,234评论 0 0
  • 同DataWhale一起组队学习:https://tianchi.aliyun.com/notebook-ai/d...
    612twilight阅读 1,038评论 0 2