模型融合之blending和stacking

1. blending

  • 需要得到各个模型结果集的权重,然后再线性组合。
"""Kaggle competition: Predicting a Biological Response.

Blending {RandomForests, ExtraTrees, GradientBoosting} + stretching to
[0,1]. The blending scheme is related to the idea Jose H. Solorzano
presented here:
http://www.kaggle.com/c/bioresponse/forums/t/1889/question-about-the-process-of-ensemble-learning/10950#post10950
‘‘‘You can try this: In one of the 5 folds, train the models, then use
the results of the models as ‘variables‘ in logistic regression over
the validation data of that fold‘‘‘. Or at least this is the
implementation of my understanding of that idea :-)

The predictions are saved in test.csv. The code below created my best
submission to the competition:
- public score (25%): 0.43464
- private score (75%): 0.37751
- final rank on the private leaderboard: 17th over 711 teams :-)

Note: if you increase the number of estimators of the classifiers,
e.g. n_estimators=1000, you get a better score/rank on the private
test set.

Copyright 2012, Emanuele Olivetti.
BSD license, 3 clauses.
"""

from __future__ import division
import numpy as np
import load_data
from sklearn.cross_validation import StratifiedKFold
from sklearn.ensemble import RandomForestClassifier, ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression

def logloss(attempt, actual, epsilon=1.0e-15):
    """Logloss, i.e. the score of the bioresponse competition.
    """
    attempt = np.clip(attempt, epsilon, 1.0-epsilon)
    return - np.mean(actual * np.log(attempt) +
                     (1.0 - actual) * np.log(1.0 - attempt))

if __name__ == ‘__main__‘:

    np.random.seed(0)  # seed to shuffle the train set

    n_folds = 10
    verbose = True
    shuffle = False

    X, y, X_submission = load_data.load()

    if shuffle:
        idx = np.random.permutation(y.size)
        X = X[idx]
        y = y[idx]

    skf = list(StratifiedKFold(y, n_folds))

    clfs = [RandomForestClassifier(n_estimators=100, n_jobs=-1, criterion=‘gini‘),
            RandomForestClassifier(n_estimators=100, n_jobs=-1, criterion=‘entropy‘),
            ExtraTreesClassifier(n_estimators=100, n_jobs=-1, criterion=‘gini‘),
            ExtraTreesClassifier(n_estimators=100, n_jobs=-1, criterion=‘entropy‘),
            GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=50)]

    print ("Creating train and test sets for blending.")

    dataset_blend_train = np.zeros((X.shape[0], len(clfs)))
    dataset_blend_test = np.zeros((X_submission.shape[0], len(clfs)))

    for j, clf in enumerate(clfs):
        print (j, clf)
        dataset_blend_test_j = np.zeros((X_submission.shape[0], len(skf)))
        for i, (train, test) in enumerate(skf):
            print ("Fold", i)
            X_train = X[train]
            y_train = y[train]
            X_test = X[test]
            y_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_submission)[:, 1]
        dataset_blend_test[:, j] = dataset_blend_test_j.mean(1)

    print()
    print( "Blending.")
    clf = LogisticRegression()
    clf.fit(dataset_blend_train, y)
    y_submission = clf.predict_proba(dataset_blend_test)[:, 1]

    print( "Linear stretch of predictions to [0,1]")
    y_submission = (y_submission - y_submission.min()) / (y_submission.max() - y_submission.min())

    print( "Saving Results.")
    tmp = np.vstack([range(1, len(y_submission)+1), y_submission]).T
    np.savetxt(fname=‘submission.csv‘, X=tmp, fmt=‘%d,%0.9f‘,
               header=‘MoleculeId,PredictedProbability‘, comments=‘‘)

2.stacking

  • stacking的核心:在训练集上进行预测,从而构建更高层的学习器。
  • stacking训练过程:

    1) 拆解训练集。将训练数据随机且大致均匀的拆为m份。

    2)在拆解后的训练集上训练模型,同时在测试集上预测。利用m-1份训练数据进行训练,预测剩余一份;在此过程进行的同时,利用相同的m-1份数据训练,在真正的测试集上预测;如此重复m次,将训练集上m次结果叠加为1列,将测试集上m次结果取均值融合为1列。

    3)使用k个分类器重复2过程。将分别得到k列训练集的预测结果,k列测试集预测结果。

    4)训练3过程得到的数据。将k列训练集预测结果和训练集真实label进行训练,将k列测试集预测结果作为测试集。

# -*- coding: utf-8 -*-
import numpy as np
from sklearn.model_selection import StratifiedKFold
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
import xgboost as xgb
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.linear_model import LogisticRegression

def load_data():
    pass

def stacking(train_x, train_y, test):
    """ stacking
    input: train_x, train_y, test
    output: test的预测值
    clfs: 5个一级分类器
    dataset_blend_train: 一级分类器的prediction, 二级分类器的train_x
    dataset_blend_test: 二级分类器的test
    """
    # 5个一级分类器
    clfs = [SVC(C = 3, kernel="rbf"),
            RandomForestClassifier(n_estimators=100, max_features="log2", max_depth=10, min_samples_leaf=1, bootstrap=True, n_jobs=-1, random_state=1),
            KNeighborsClassifier(n_neighbors=15, n_jobs=-1),
            xgb.XGBClassifier(n_estimators=100, objective="binary:logistic", gamma=1, max_depth=10, subsample=0.8, nthread=-1, seed=1),
            ExtraTreesClassifier(n_estimators=100, criterion="gini", max_features="log2", max_depth=10, min_samples_split=2, min_samples_leaf=1,bootstrap=True, n_jobs=-1, random_state=1)]

    # 二级分类器的train_x, test
    dataset_blend_train = np.zeros((train_x.shape[0], len(clfs)), dtype=np.int)
    dataset_blend_test = np.zeros((test.shape[0], len(clfs)), dtype=np.int)

    # 5个分类器进行8_folds预测
    n_folds = 8
    skf = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=1)
    for i,clf in enumerate(clfs):
        dataset_blend_test_j = np.zeros((test.shape[0], n_folds))  # 每个分类器的单次fold预测结果
        for j,(train_index,test_index) in enumerate(skf.split(train_x, train_y)):
            tr_x = train_x[train_index]
            tr_y = train_y[train_index]
            clf.fit(tr_x, tr_y)
            dataset_blend_train[test_index, i] = clf.predict(train_x[test_index])
            dataset_blend_test_j[:, j] = clf.predict(test)
        dataset_blend_test[:, i] = dataset_blend_test_j.sum(axis=1) // (n_folds//2 + 1)

    # 二级分类器进行预测
    clf = LogisticRegression(penalty="l1", tol=1e-6, C=1.0, random_state=1, n_jobs=-1)
    clf.fit(dataset_blend_train, train_y)
    prediction = clf.predict(dataset_blend_test)
    return prediction

def main():
    (train_x, train_y, test) = load_data()
    prediction = stacking(train_x, train_y, test)
    return prediction

if __name__ == "__main__":
    prediction = main()

ensemble model

比较简明的资源有:

上面的是以5折为例,如果是2折的话就更简单了!

-----------------------------------------------------分割线------------------------------------------------------------------

  • 以Kaggle的泰坦尼克号为例子
# out-of-Fold Prdictions
TrainingData = train.shape[0] # 891行
TestData = test.shape[0] # 418 行
# 5 折
kf = KFold(n_splits = 5, random_state = 2017)

# X_train, y_train, X_test表示原生的数据
def get_oof(clf, X_train, y_train, X_test):
    # oof_train对应于训练数据集TrainingData
    oof_train = np.zeros((TrainingData, ))  # 1 * 891型
    # oof_test对应于测试集TestData
    oof_test  = np.zeros((TestData, ))     # 1 * 418型
    # oof_test_skf对应于5折之后的所有predict作为新的TestData(测试集),只要最后对行(axis = 0)取平均就得到平均predict值Test Data
    oof_test_skf = np.empty((5, TestData))  # 5 * 418型

    for i, (train_index, test_index) in enumerate(kf.split(X_train)):
        # kf_X_train 表示train data每一折中用于训练的训练集(4份共有712个样本)
        kf_X_train = X_train[train_index] # 712 * 7  例如712 instances for each fold
        kf_y_train = y_train[train_index] # 712 * 1  例如712 instances for each fold
        #  kf_X_test 表示train data每一折中用于predict的数据集(也就是验证集validation data)
        kf_X_test  = X_train[test_index]  # 179 * 7  例如178 instances for each fold

        clf.train(kf_X_train, kf_y_train)  # 训练模型

        # 得到predict值(输出值)作为new feature输入用于第二层的训练
        # 一个base model 就对应于new feature的一列,此时的new feature有多少列取决于你第一层用了多少个base model
        oof_train[test_index] = clf.prdict(kf_X_test)  # 1 * 179 ===> will be 1 * 891 after 5 folds
        # 用TestData --这里X_test(测试集)用于预测
        oof_test_skf[i, :] = clf.predict(X_test)  # oof_test_skf[i, :],1 * 418 ===> will be 5 * 418 after 5 folds

    # 5折stacking结束后
    # 对测试集预测得到的predict值进行行(axis = 0)平均:  5 * 418 ===> 1 * 418
    oof_test[:] = oof_test_skf.mean(axis = 0)

    return oof_train.reshpae(-1, 1), oof_test.reshpae(-1, 1)
    # oof_train.reshpae(-1, 1): 891 * 1    oof_test.reshpae(-1, 1): 418 * 1

-------------------------------------------------补充----------------------------------------------

Udacity的几张图

原文地址:https://www.cnblogs.com/HongjianChen/p/9706806.html

时间: 2024-11-03 16:48:18

模型融合之blending和stacking的相关文章

谈谈模型融合之一 —— 集成学习与 AdaBoost

前言 前面的文章中介绍了决策树以及其它一些算法,但是,会发现,有时候使用使用这些算法并不能达到特别好的效果.于是乎就有了集成学习(Ensemble Learning),通过构建多个学习器一起结合来完成具体的学习任务.这篇文章将介绍集成学习,以及其中的一种算法 AdaBoost. 集成学习 首先先来介绍下什么是集成学习: 构建多个学习器一起结合来完成具体的学习任务,常可获得比单一学习器显著优越的泛化性能,对"弱学习器" 尤为明显(三个臭皮匠,顶个诸葛亮) 也称为Multi-Classif

task5 模型融合 打卡

5.1 模型融合目标 对于多种调参完成的模型进行模型融合. 完成对于多种模型的融合,提交融合结果并打卡. 5.2 内容介绍 模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式. 简单加权融合: 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean): 分类:投票(Voting) 综合:排序融合(Rank averaging),log融合 stacking/blending: 构建多层模型,并利用预测结果再拟合预测. boosting

多模型融合推荐算法

常见的多模型融合算法 多模型融合算法可以比单一模型算法有极为明显的效果提升.但是怎样进行有效的融合,充分发挥各个算法的长处?这里总结一些常见的融合方法: 1. 线性加权融合法 线性加权是最简单易用的融合算法,工程实现非常方便,只需要汇总单一模型的结果,然后按不同算法赋予不同的权重,将多个推荐算法的结果进行加权,即可得到结果: 是给用户(user)推荐商品(item)的得分, 是算法K的权重,是算法k得到的用户(user)对商品item的推荐得分.这种融合方式实现简单,但效果较差.因为线性加权的参

模型融合

一.Voting 模型融合其实也没有想象的那么高大上,从最简单的Voting说起,这也可以说是一种模型融合.假设对于一个二分类问题,有3个基础模型,那么就采取投票制的方法,投票多者确定为最终的分类. 二.Averaging 对于回归问题,一个简单直接的思路是取平均.稍稍改进的方法是进行加权平均.权值可以用排序的方法确定,举个例子,比如A.B.C三种基本模型,模型效果进行排名,假设排名分别是1,2,3,那么给这三个模型赋予的权值分别是3/6.2/6.1/6这两种方法看似简单,其实后面的高级算法也可

CS231n 卷积神经网络与计算机视觉 7 神经网络训练技巧汇总 梯度检验 参数更新 超参数优化 模型融合 等

前面几章已经介绍了神经网络的结构.数据初始化.激活函数.损失函数等问题,现在我们该讨论如何让神经网络模型进行学习了. 1 梯度检验 权重的更新梯度是否正确决定着函数是否想着正确的方向迭代,在UFLDL中我们提到过,计算时梯度公式如果计算错误是不容被察觉的,我们需要比较分析法得到梯度与数值法得到的梯度是否相似,下面是一些技巧: 1.1 centered formula 高等数学中我们知道导数的近似公式: df(x)dx=f(x+h)?f(x)h 以及下面的centered formula: df(

十大经典预测算法六---集成学习(模型融合算法)

模型融合算法概念 它不是具体的指某一个算法,而是一种把多个弱模型融合合并在一起变成一个强模型的思想 用模型融合算法的原因 1.单个模型容易过拟合,多个模型融合可以提高范化能力 2.单个模型预测能力不高,多个模型往往能提高预测能力 3.对于数据集过大或过小,可以分别进行划分和有放回的操作,产生不同的数据子集,然后通过数据子集训练不同的分类模型,最终合并成一个大的分类器 4.对于多个异构的特征集的时候,很难进行融合,可以考虑每个数据集构建一个分类模型,然后将多个模型融合 5.模型融合算法成功的关键在

Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合)

http://www.cnblogs.com/fiercex/p/7927804.html fiercex 路漫漫其修远兮,吾将上下而求索 Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合) 这是在kaggle上的一个练习比赛,使用的是ImageNet数据集的子集.注意,mxnet版本要高于0.12.1b2017112.下载数据集. train.zip test.zip labels然后解压在data文件夹下 1. 数据 1.1 整理数据 将解压后的数据整理成Gluon能够读取

谈谈模型融合之二 —— 随机森林

前言 上篇文章介绍了集成学习的相关概念以及基于 Boosting的 AdaBoost,这篇文章将介绍基于模型融合的另一种方式 Bagging 的算法,随机森林(Random Forest).(上篇公式敲的太累了这篇就来个简单的缓解缓解) 随机森林 算法思想 我们先来看看这个算法的名字,可以拆分开为两部分,随机和森林.森林我们很容易可以想到,就是有很多棵树,即由多颗决策树组成.那么随机指的是什么呢?这里我们来看看 Bagging 的思想了. 首先先说说自助采样(Bootstrap Sanpling

基于BERT的多模型融合借鉴

本次介绍假新闻赛道一第一名的构建思路,大家一起学习下 任务描述 文本是新闻信息的主要载体,对新闻文本的研究有助于虚假新闻的有效识别.虚假新闻文本检测,具体任务为:给定一个新闻事件的文本,判定该事件属于真实新闻还是虚假新闻.该任务可抽象为NLP领域的文本分类任务,根据新闻文本内容,判定该新闻是真新闻还是假新闻.针对该任务,本文采用BERT-Finetune.BERT-CNN-Pooling.BERT-RCN-Pooling的多种结构进行融合,在输入上引入字词结合的形式,另外充分利用假新闻的关键词特