精华内容
下载资源
问答
  • 针对当前电力公司面临的专变用户电费回收风险,提出一种基于Stacking模型融合的专变用户电费回收风险识别方法。对专变用户数据进行特征处理、特征构造与特征筛选,从样本分布和特征属性上优化模型的泛化性能;利用...
  • 为了提高光伏发电输出功率的预测精度和可靠性,本文提出一种基于Stacking模型融合的光伏发电功率预测方法.选取某光伏电站温度、湿度、辐照度等历史实测数据为研究对象,在将光伏发电功率数据进行特征交叉以及基于...
  • 为了解决失压故障识别维度单一和终端漏报误报的问题,采用比较研究法,在前人使用机器学习算法解决故障识别问题的基础上,结合真实计量数据,构建失压关键指标,提出了一种基于Stacking模型融合的计量故障监测算法。...
  • 为此,提出一种基于极限梯度提升(XGBoost)与Stacking模型融合的短期母线负荷预测方法。基于XGBoost建立多个母线负荷预测元模型,组合构成Stacking模型融合的元模型层,连接一个XGBoost模型对元模型进行融合,整体...
  • Stacking 模型融合讲解

    万次阅读 2018-05-01 16:25:14
    stacking 模型融合 Stacking模型融合的一个重要的方法,几乎每个数据科学竞赛的前几名都会使用,接下来我主要是介绍stacking的原理。相信大家看很多stacking的资料都会看到下面的这个图:这个图很形象,他具体是...

    stacking 模型融合

        Stacking是模型融合的一个重要的方法,几乎每个数据科学竞赛的前几名都会使用,接下来我主要是介绍stacking的原理。

    相信大家看很多stacking的资料都会看到下面的这个图:



    这个图很形象,他具体是这样做的,

    首先我们将训练集使用kfold切分为k分,每一分包括一个验证集和测试集,每次取其中k-1分训练,另外的1分用来验证,stacking是这样做的,比如对于集成的第一个模型,clf1,我们使用kfold交叉验证,那么可以得到kclf1模型,模型的类型是一样的,但是模型里面学到的参数不一样,因为他们的训练集是不一样的,对与每一折的训练,我们还有一个验证集啊,那么我们用训练得到的模型在验证集合上做一次预测,你想,因为这个时候我们的验证集是不是只有1分,也就是只有train_set_number/k个样本(train_set_number表示训练样本的个数),但是这只是一折啊,我们还有k折,每一折我们都会在验证集上预测,所以最终对于clf1在验证集上得到是不是train_set_number个结果,不用担心是没有重复的,因为你是kflod

    是不是每一折的验证集样本都不会相同,也就是没有哪个样本同时出现在两个验证集上,这样下来,我们就得到第一级的结果,也是train_set_number个结果。然后在每一折上,我们在测试集上做一次预测,那么kclf1模型预测k次得到了k个结果,也就是每一个样本预测结果有k个,我们就取一下平均,看到是取平均,这样取完平均以后每一个样本在clf1模型上就得到一个预测结果。这只是一个模型的过程,因为我们需要集成很多个模型,那么我重复n个模型,做法和上面是一样的,假设我们有n个模型,那么请问我们stacking第一层出来,在验证集上得到的结果特征是什么维度?应该就是训练样本的个数行(train_set_number),列数就是n吧,因为n个模型啊,这就是我们对第一层结果的一个特征堆叠方法,这样第一层出来的结果又可以作为特征训练第二层,第二层任然可以使用stacking多个模型,或者直接接一个模型用于训练,然后直接预测。那么同样,对于测试集第一层出来的维度是不是(test_set_number,n),也就是测试集样本的行数,这样是不是可以用第二层训练的模型在这个上面预测,得到我们最后的结果。这个就是stacking的整个过程。

    然后我们看一段stacking的代码:


    stack_model = [svm,lr,nn,xgb,lgb]  ## 这个地方我是简写,实际这样训练会报错,需要自己导库,定义分类器
    ## train_data 表示训练集,train_label 表示训练集的标签,test_data表示训练集
    ntrain = train_data.shape[0]  ## 训练集样本数量
    ntest = test_data.shape[0]   ## 测试集样本数量
    train_stack = np.zeros(ntrain,n) ##  n表示n个模型
    test_stack = np.zeros(ntest,n) ##
    
    kf = kfold.split(train_data, train_label)
    
    for i,model in enumerate(stack_model):
        for j, (train_fold, validate) in enumerate(kf):
                    X_train, X_validate, label_train, label_validate = \
                        train_data[train_fold, :], train_data[validate, :], train_label[train_fold], train_label[validate]
                    
                    model.fit(X_train,label_train)
                    train_stack[validate,i] = model.predict(X_validate)
                    test_stack[:,i] = model.predict(test_data)
                    
    ### 假设就只有两层,那么最后预测:
    
    final_model  = xgb()  ## 假设第二层我们还是用xgb吧,这个地方也是简写,仅仅表示这个地方是xgb模型
    final_model.fit(train_stack,train_label)
    
    pre = final_model.predict(test_stack)  
    这就是整个stacking的过程,自己写一个也不是很难,重点是理解,下一次我分享常用的stack的python库。
    展开全文
  • 模型融合的一个重要的方法,几乎每个数据科学竞赛的前几名都会使用,接下来我主要是介绍 stacking 的原理。 相信大家看很多 stacking 的资料都会看到下面的这个图: 这个图很形象,他具体是这样做的, 构造...

    640?wx_fmt=gif

    向AI转型的程序员都关注了这个号👇👇👇

    机器学习AI算法工程  公众号: datayx

    集成学习

      Ensemble learning 中文名叫做集成学习,它并不是一个单独的机器学习算法,而是将很多的机器学习算法结合在一起,我们把组成集成学习的算法叫做“个体学习器”。在集成学习器当中,个体学习器都相同,那么这些个体学习器可以叫做“基学习器”。

      个体学习器组合在一起形成的集成学习,常常能够使得泛化性能提高,这对于“弱学习器”的提高尤为明显。弱学习器指的是比随机猜想要好一些的学习器。

      在进行集成学习的时候,我们希望我们的基学习器应该是好而不同,这个思想在后面经常体现。 “好”就是说,你的基学习器不能太差,“不同”就是各个学习器尽量有差异。

      集成学习有两个分类,一个是个体学习器存在强依赖关系、必须串行生成的序列化方法,以Boosting为代表。另外一种是个体学习器不存在强依赖关系、可同时生成的并行化方法,以Bagging和随机森林(Random Forest)为代表。

     

    Stacking 的基本思想

      将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

      上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

      在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

    640?wx_fmt=png

    过程1-3 是训练出来个体学习器,也就是初级学习器。

    过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。

    过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

    如果想要预测一个数据的输出,只需要把这条数据用初级学习器预测,然后将预测后的结果用次级学习器预测便可。

     


    访问AI图谱 技术分享社区 

    https://loveai.tech


    Stacking的实现

      最先想到的方法是这样的,

      1:用数据集D来训练h1,h2,h3...,

      2:用这些训练出来的初级学习器在数据集D上面进行预测得到次级训练集。

      3:用次级训练集来训练次级学习器。

      但是这样的实现是有很大的缺陷的。在原始数据集D上面训练的模型,然后用这些模型再D上面再进行预测得到的次级训练集肯定是非常好的。会出现过拟合的现象。

    Stacking是模型融合的一个重要的方法,几乎每个数据科学竞赛的前几名都会使用,接下来我主要是介绍stacking的原理。

    相信大家看很多stacking的资料都会看到下面的这个图:

    640?wx_fmt=jpeg

    这个图很形象,他具体是这样做的,

    640?wx_fmt=png

    构造stacking类

    事实上还可以构造一个stacking的类,它拥有fit和predict方法

    640?wx_fmt=png


    阅读过本文的人还看了以下:

    不断更新资源

    深度学习、机器学习、数据分析、python

     搜索公众号添加: datayx  

    640?wx_fmt=jpeg

    长按图片,识别二维码,点关注

    访问AI图谱  

    https://loveai.tech

    640?wx_fmt=png

    640?wx_fmt=png

    展开全文
  • 学习笔记(八)使用stacking模型融合

    千次阅读 2018-11-26 16:14:02
    学习笔记(八)使用stacking模型融合 x_temp = np.array(datafinal) y_temp = np.array(data_train) """ 1.3 数据集的切分 "&...

    数据是金融数据,我们要做的是预测贷款用户是否会逾期,表格中,status是标签:0表示未逾期,1表示逾期。
    Misson1 - 构建逻辑回归模型进行预测
    Misson2 - 构建SVM和决策树模型进行预测
    Misson3 - 构建xgboost和lightgbm模型进行预测
    Mission4 - 记录五个模型关于precision,rescore,f1,auc,roc的评分表格,画出auc和roc曲线图
    Mission5 - 关于数据类型转换以及缺失值处理(尝试不同的填充看效果)以及你能借鉴的数据探索
    Mission6 - 交叉验证和网格搜索调参
    Mission7 - stacking 融合模型。

    数据准备

    数据的预处理见前面:https://blog.csdn.net/zhangyunpeng0922/article/details/84346663
    但此处将前面处理好的数据转换成数组形式,并用自己写的split来切分数据集。(因为不知道什么原因调用scikit里面的train_test_split的函数切分后会出现空值????)
    切分函数

    def split(x,y,test_ratic=0.2,seed=None):
        assert x.shape[0]==y.shape[0]
        assert 0.0<=test_ratic <=1.0
    
        if seed:
            np.random.seed(seed)
        shuffle_index = np.random.permutation(len(x))  ##乱序排列
        test_size = int(len(x) * test_ratic)
        test_index = shuffle_index[:test_size]
        train_index = shuffle_index[test_size:]
    
        x_train = x[train_index]
        y_train = y[train_index]
    
        x_test = x[test_index]
        y_test = y[test_index]
    
        return x_train,y_train,x_test,y_test
    

    数据切分和数据的归一化

    x_temp = np.array(datafinal)
    y_temp = np.array(data_train)
    
    """
    1.3 数据集的切分
    """
    import sys 
    sys.path.append("F:PYCharm\PYcode")
    from  machine_learning.model_selection  import split
    
    x_train,y_train,x_test,y_test = split(x_temp, y_temp,test_ratic=0.3)
    
    """
    1.4标准化数据,方差为1,均值为零
    """
    standardScaler = StandardScaler()
    X_train_fit = standardScaler.fit_transform(x_train)
    X_test_fit = standardScaler.transform(x_test)
    

    模型的初始化

    根据前一个任务的调参所得的相对来说较好的参数来初始化模型。

    log_reg = LogisticRegression(C=0.1, penalty='l1')
    lsvc = SVC(C=5, gamma=0.001)
    dtc = DecisionTreeClassifier(max_depth=3)
    xgbc_model = XGBClassifier(learning_rate=0.05, max_depth=3)
    lgbm_model = LGBMClassifier(learning_rate=0.1, max_depth=3)
    

    使用stacking进行模型融合

    1. 使用 mlxtend.classifier中的StackingClassifier

    安装;打开,命令提示符。pip install mlxtend;

    clfs = {
        'log_reg': LogisticRegression(C=0.1, penalty='l1'),
        'lsvc': SVC(C=5, gamma=0.001),
        'dtc': DecisionTreeClassifier(max_depth=3),
        
        'xgbc_model':XGBClassifier(learning_rate=0.05, max_depth=3),
        'lgbm_model':LGBMClassifier(learning_rate=0.1, max_depth=3)
    }
    log_reg_clf = clfs["log_reg"]
    lsvc_clf = clfs["lsvc"]
    dtc_clf = clfs["dtc"]
    xgbc_model_clf = clfs["xgbc_model"]
    lgbm_model_clf = clfs["lgbm_model"]
    
    sclf = StackingClassifier(classifiers=[log_reg_clf, lsvc_clf, dtc_clf,xgbc_model_clf, lgbm_model_clf],
                                meta_classifier=log_reg_clf)
    sclf.fit(X_train_fit, y_train)
    pre_train = sclf.predict(X_test_fit)
    

    结果如下:
    在这里插入图片描述
    结果与前面相比有一些提升:之前的结果

    2. 参考网络上的stacking代码

    stack_model = [log_reg,lsvc,dtc,xgbc_model,lgbm_model]  ## 这个地方我是简写,实际这样训练会报错,需要自己导库,定义分类器
    ## train_data 表示训练集,train_label 表示训练集的标签,test_data表示训练集
    ntrain = X_train_fit.shape[0]  ## 训练集样本数量
    ntest = X_test_fit.shape[0]   ## 测试集样本数量
    train_stack = np.zeros((ntrain,5)) ##  n表示n个模型
    test_stack = np.zeros((ntest,5)) ##
    kf = KFold(n_splits=5) 
    #kf = KFold.split(X_train_fit, y_train)
    kf2 = kf.split(X_train_fit, y_train)
    for i,model in enumerate(stack_model):
        for j,(train_fold, validate) in enumerate(kf2):
                    
                    X_train_kf, X_validate, label_train, label_validate = X_train_fit[train_fold, :], X_train_fit[validate, :], y_train[train_fold], y_train[validate]
                    print(label_train)
                    model.fit(X_train_kf,label_train)
                    train_stack[validate,i] = model.predict(X_validate)
                    test_stack[:,i] = model.predict(X_test_fit)
    final_model = XGBClassifier(learning_rate=0.05, max_depth=3)
    final_model.fit(train_stack,y_train)
     
    pre = final_model.predict(test_stack)
    score = final_model.score(test_stack, y_test)
    

    结果:
    在这里插入图片描述
    结果与前面相比有一些提升:之前的结果

    总结

    1. 调用scikit里面的train_test_split的函数切分后会出现空值,导致模型无法继续运行。
    2. 对stacking的原理与运用了解的不深。
    3. 感觉前面的调参和数据处理并没有做的很好,导致后面的融合之类地感觉没有太大的提升。

    参考文章

    1. stackClassifier
    2. 模型融合方法概述
    3. 集成学习中的 stacking 以及python实现
    展开全文
  • stacking模型融合

    千次阅读 多人点赞 2020-04-04 20:16:00
    模型融合 模型融合的方法 简单加权融合: 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean); 分类:投票(Voting) 综合:排序融合(Rank averaging),log融合 stacking/...

    模型融合

    模型融合的方法

    1. 简单加权融合:

      • 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);
      • 分类:投票(Voting)
      • 综合:排序融合(Rank averaging),log融合
    2. stacking/blending:

      • 构建多层模型,并利用预测结果再拟合预测。
    3. boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):

      • 多树的提升方法

    stacking相关理论介绍

    1. 什么是 stacking

    简单来说 stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wHQRdyI9-1586002387196)(stacking流程图.png)]

    将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

    上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

    在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

    1. stacking的工作方式
      在这里插入图片描述

    引自西瓜书(机器学习)

    • 过程1-3 是训练出来个体学习器,也就是初级学习器。
    • 过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。
    • 过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

    3)Stacking的方法讲解

    首先,我们先从一种“不那么正确”但是容易懂的Stacking方法讲起。

    Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking.假设我们有2个基模型 Model1_1、Model1_2 和 一个次级模型Model2

    Step 1. 基模型 Model1_1,对训练集train训练,然后用于预测 train 和 test 的标签列,分别是P1,T1

    在这里插入图片描述

    训练后的模型 Model1_1 分别在 train 和 test 上预测,得到预测标签分别是P1,T1

    Step 2. 基模型 Model1_2 ,对训练集train训练,然后用于预测train和test的标签列,分别是P2,T2

    在这里插入图片描述

    训练后的模型 Model1_2 分别在 train 和 test 上预测,得到预测标签分别是P2,T2

    Step 3. 分别把P1,P2以及T1,T2合并,得到一个新的训练集和测试集train2,test2.

    在这里插入图片描述

    再用 次级模型 Model2 以真实训练集标签为标签训练,以train2为特征进行训练,预测test2,得到最终的测试集预测的标签列 Y P r e Y_{Pre} YPre

    这就是我们两层堆叠的一种基本的原始思路想法。在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。

    Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法。

      1. 次级模型尽量选择简单的线性模型
      1. 利用K折交叉验证

    K-折交叉验证:
    训练:
    在这里插入图片描述
    预测:
    在这里插入图片描述

    代码示例

    回归\分类概率-融合:

    1)简单加权平均,结果直接融合

    ## 生成一些简单的样本数据,test_prei 代表第i个模型的预测值
    test_pre1 = [1.2, 3.2, 2.1, 6.2]
    test_pre2 = [0.9, 3.1, 2.0, 5.9]
    test_pre3 = [1.1, 2.9, 2.2, 6.0]
    
    # y_test_true 代表第模型的真实值
    y_test_true = [1, 3, 2, 6] 
    
    import numpy as np
    import pandas as pd
    
    ## 定义结果的加权平均函数
    def Weighted_method(test_pre1,test_pre2,test_pre3,w=[1/3,1/3,1/3]):
        Weighted_result = w[0]*pd.Series(test_pre1)+w[1]*pd.Series(test_pre2)+w[2]*pd.Series(test_pre3)
        return Weighted_result
    
    from sklearn import metrics
    # 各模型的预测结果计算MAE
    print('Pred1 MAE:',metrics.mean_absolute_error(y_test_true, test_pre1))
    print('Pred2 MAE:',metrics.mean_absolute_error(y_test_true, test_pre2))
    print('Pred3 MAE:',metrics.mean_absolute_error(y_test_true, test_pre3))
    
    Pred1 MAE: 0.1750000000000001
    Pred2 MAE: 0.07499999999999993
    Pred3 MAE: 0.10000000000000009
    
    ## 根据加权计算MAE
    w = [0.3,0.4,0.3] # 定义比重权值
    Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w)
    print('Weighted_pre MAE:',metrics.mean_absolute_error(y_test_true, Weighted_pre))
    
    Weighted_pre MAE: 0.05750000000000027
    

    可以发现加权结果相对于之前的结果是有提升的,这种我们称其为简单的加权平均。
    还有一些特殊的形式,比如mean平均,median平均

    ## 定义结果的加权平均函数
    def Mean_method(test_pre1,test_pre2,test_pre3):
        Mean_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).mean(axis=1)
        return Mean_result
    Mean_pre = Mean_method(test_pre1,test_pre2,test_pre3)
    print('Mean_pre MAE:',metrics.mean_absolute_error(y_test_true, Mean_pre))
    
    Mean_pre MAE: 0.06666666666666693
    
    ## 定义结果的加权平均函数
    def Median_method(test_pre1,test_pre2,test_pre3):
        Median_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).median(axis=1)
        return Median_result
    Median_pre = Median_method(test_pre1,test_pre2,test_pre3)
    print('Median_pre MAE:',metrics.mean_absolute_error(y_test_true, Median_pre))
    
    Median_pre MAE: 0.07500000000000007
    

    2) Stacking融合(回归):

    from sklearn import linear_model
    
    def Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,test_pre1,test_pre2,test_pre3,model_L2= linear_model.LinearRegression()):
        model_L2.fit(pd.concat([pd.Series(train_reg1),pd.Series(train_reg2),pd.Series(train_reg3)],axis=1).values,y_train_true)
        Stacking_result = model_L2.predict(pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).values)
        return Stacking_result
    
    ## 生成一些简单的样本数据,test_prei 代表第i个模型的预测值
    train_reg1 = [3.2, 8.2, 9.1, 5.2]
    train_reg2 = [2.9, 8.1, 9.0, 4.9]
    train_reg3 = [3.1, 7.9, 9.2, 5.0]
    # y_test_true 代表第模型的真实值
    y_train_true = [3, 8, 9, 5] 
    
    test_pre1 = [1.2, 3.2, 2.1, 6.2]
    test_pre2 = [0.9, 3.1, 2.0, 5.9]
    test_pre3 = [1.1, 2.9, 2.2, 6.0]
    
    # y_test_true 代表第模型的真实值
    y_test_true = [1, 3, 2, 6] 
    
    model_L2= linear_model.LinearRegression()
    Stacking_pre = Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,
                                   test_pre1,test_pre2,test_pre3,model_L2)
    print('Stacking_pre MAE:',metrics.mean_absolute_error(y_test_true, Stacking_pre))
    
    Stacking_pre MAE: 0.04213483146067476
    

    可以发现模型结果相对于之前有进一步的提升,这是我们需要注意的一点是,对于第二层Stacking的模型不宜选取的过于复杂,这样会导致模型在训练集上过拟合,从而使得在测试集上并不能达到很好的效果。

    分类模型融合:

    对于分类,同样的可以使用融合方法,比如简单投票,Stacking…

    from sklearn.datasets import make_blobs
    from sklearn import datasets
    from sklearn.tree import DecisionTreeClassifier
    import numpy as np
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.ensemble import VotingClassifier
    from xgboost import XGBClassifier
    from sklearn.linear_model import LogisticRegression
    from sklearn.svm import SVC
    from sklearn.model_selection import train_test_split
    from sklearn.datasets import make_moons
    from sklearn.metrics import accuracy_score,roc_auc_score
    from sklearn.model_selection import cross_val_score
    from sklearn.model_selection import StratifiedKFold
    

    1)Voting投票机制:

    Voting即投票机制,分为软投票和硬投票两种,其原理采用少数服从多数的思想。

    iris = datasets.load_iris()
    
    x=iris.data
    y=iris.target
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
    
    clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.7,
                         colsample_bytree=0.6, objective='binary:logistic')
    clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,
                                  min_samples_leaf=63,oob_score=True)
    clf3 = SVC(C=0.1, gamma='auto')
    
    # 硬投票
    eclf = VotingClassifier(estimators=[('xgb', clf1), ('rf', clf2), ('svc', clf3)], voting='hard')
    for clf, label in zip([clf1, clf2, clf3, eclf], ['XGBBoosting', 'Random Forest', 'SVM', 'Ensemble']):
        scores = cross_val_score(clf, x, y, cv=5, scoring='accuracy')
        print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
    
    Accuracy: 0.96 (+/- 0.02) [XGBBoosting]
    Accuracy: 0.33 (+/- 0.00) [Random Forest]
    Accuracy: 0.95 (+/- 0.03) [SVM]
    Accuracy: 0.95 (+/- 0.03) [Ensemble]
    
    '''
    软投票:和硬投票原理相同,增加了设置权重的功能,可以为不同模型设置不同权重,进而区别模型不同的重要度。
    '''
    x=iris.data
    y=iris.target
    x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)
    
    clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.8,
                         colsample_bytree=0.8, objective='binary:logistic')
    clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,
                                  min_samples_leaf=63,oob_score=True)
    clf3 = SVC(C=0.1, probability=True, gamma='auto')
    
    # 软投票
    eclf = VotingClassifier(estimators=[('xgb', clf1), ('rf', clf2), ('svc', clf3)], voting='soft', weights=[4, 1, 1])
    clf1.fit(x_train, y_train)
    
    for clf, label in zip([clf1, clf2, clf3, eclf], ['XGBBoosting', 'Random Forest', 'SVM', 'Ensemble']):
        scores = cross_val_score(clf, x, y, cv=5, scoring='accuracy')
        print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
    
    Accuracy: 0.96 (+/- 0.02) [XGBBoosting]
    Accuracy: 0.33 (+/- 0.00) [Random Forest]
    Accuracy: 0.95 (+/- 0.03) [SVM]
    Accuracy: 0.96 (+/- 0.02) [Ensemble]
    

    2)分类的Stacking\Blending融合:

    stacking是一种分层模型集成框架。

    以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为训练集进行再训练,从而得到完整的stacking模型, stacking两层模型都使用了全部的训练数据。

    '''
    5-Fold Stacking
    '''
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.ensemble import ExtraTreesClassifier,GradientBoostingClassifier
    import pandas as pd
    #创建训练的数据集
    data_0 = iris.data
    data = data_0[:100,:]
    
    target_0 = iris.target
    target = target_0[:100]
    
    #模型融合中使用到的各个单模型
    clfs = [LogisticRegression(solver='lbfgs'),
            RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=5)]
     
    #切分一部分数据作为测试集
    X, X_predict, y, y_predict = train_test_split(data, target, test_size=0.3, random_state=0)
    
    dataset_blend_train = np.zeros((X.shape[0], len(clfs)))
    dataset_blend_test = np.zeros((X_predict.shape[0], len(clfs)))
    
    #5折stacking
    n_splits = 5
    skf = StratifiedKFold(n_splits)
    skf = skf.split(X, y)
    
    for j, clf in enumerate(clfs):
        #依次训练各个单模型
        dataset_blend_test_j = np.zeros((X_predict.shape[0], len(clfs)))
        for i, (train, test) in enumerate(skf):
            #5-Fold交叉训练,使用第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]
        #对于测试集,直接用这交叉验证训练的模型的预测值均值作为新的特征。
        dataset_blend_test[:, j] = dataset_blend_test_j.mean(1)
        print("val auc Score: %f" % roc_auc_score(y_predict, dataset_blend_test[:, j]))
    
    clf = LogisticRegression(solver='lbfgs')
    clf.fit(dataset_blend_train, y)
    y_submission = clf.predict_proba(dataset_blend_test)[:, 1]
    
    print("Val auc Score of Stacking: %f" % (roc_auc_score(y_predict, y_submission)))
    
    
    val auc Score: 1.000000
    val auc Score: 0.500000
    val auc Score: 0.500000
    val auc Score: 0.500000
    val auc Score: 0.500000
    Val auc Score of Stacking: 1.000000
    

    Blending,其实和Stacking是一种类似的多层模型融合的形式

    其主要思路是把原始的训练集先分成两部分,比如70%的数据作为新的训练集,剩下30%的数据作为测试集。

    在第一层,我们在这70%的数据上训练多个模型,然后去预测那30%数据的label,同时也预测test集的label。

    在第二层,我们就直接用这30%数据在第一层预测的结果做为新特征继续训练,然后用test集第一层预测的label做特征,用第二层训练的模型做进一步预测

    其优点在于:

    • 1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)
    • 2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集

    缺点在于:

    • 1.使用了很少的数据(第二阶段的blender只使用training set10%的量)
    • 2.blender可能会过拟合
    • 3.stacking使用多次的交叉验证会比较稳健
      ‘’’
    '''
    Blending
    '''
     
    #创建训练的数据集
    #创建训练的数据集
    data_0 = iris.data
    data = data_0[:100,:]
    
    target_0 = iris.target
    target = target_0[:100]
     
    #模型融合中使用到的各个单模型
    clfs = [LogisticRegression(solver='lbfgs'),
            RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            #ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=5)]
     
    #切分一部分数据作为测试集
    X, X_predict, y, y_predict = train_test_split(data, target, test_size=0.3, random_state=2020)
    
    #切分训练数据集为d1,d2两部分
    X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=2020)
    dataset_d1 = np.zeros((X_d2.shape[0], len(clfs)))
    dataset_d2 = np.zeros((X_predict.shape[0], len(clfs)))
     
    for j, clf in enumerate(clfs):
        #依次训练各个单模型
        clf.fit(X_d1, y_d1)
        y_submission = clf.predict_proba(X_d2)[:, 1]
        dataset_d1[:, j] = y_submission
        #对于测试集,直接用这k个模型的预测值作为新的特征。
        dataset_d2[:, j] = clf.predict_proba(X_predict)[:, 1]
        print("val auc Score: %f" % roc_auc_score(y_predict, dataset_d2[:, j]))
    
    #融合使用的模型
    clf = GradientBoostingClassifier(learning_rate=0.02, subsample=0.5, max_depth=6, n_estimators=30)
    clf.fit(dataset_d1, y_d2)
    y_submission = clf.predict_proba(dataset_d2)[:, 1]
    print("Val auc Score of Blending: %f" % (roc_auc_score(y_predict, y_submission)))
    
    val auc Score: 1.000000
    val auc Score: 1.000000
    val auc Score: 1.000000
    val auc Score: 1.000000
    val auc Score: 1.000000
    Val auc Score of Blending: 1.000000
    

    3)分类的Stacking融合(利用mlxtend):

    
    
    import warnings
    warnings.filterwarnings('ignore')
    import itertools
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    import matplotlib.gridspec as gridspec
    
    from sklearn import datasets
    from sklearn.linear_model import LogisticRegression
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.naive_bayes import GaussianNB 
    from sklearn.ensemble import RandomForestClassifier
    from mlxtend.classifier import StackingClassifier
    
    from sklearn.model_selection import cross_val_score
    from mlxtend.plotting import plot_learning_curves
    from mlxtend.plotting import plot_decision_regions
    
    # 以python自带的鸢尾花数据集为例
    iris = datasets.load_iris()
    X, y = iris.data[:, 1:3], iris.target
    
    clf1 = KNeighborsClassifier(n_neighbors=1)
    clf2 = RandomForestClassifier(random_state=1)
    clf3 = GaussianNB()
    lr = LogisticRegression()
    sclf = StackingClassifier(classifiers=[clf1, clf2, clf3], 
                              meta_classifier=lr)
    
    label = ['KNN', 'Random Forest', 'Naive Bayes', 'Stacking Classifier']
    clf_list = [clf1, clf2, clf3, sclf]
    
    fig = plt.figure(figsize=(10,8))
    gs = gridspec.GridSpec(2, 2)
    grid = itertools.product([0,1],repeat=2)
    
    clf_cv_mean = []
    clf_cv_std = []
    for clf, label, grd in zip(clf_list, label, grid):
            
        scores = cross_val_score(clf, X, y, cv=3, scoring='accuracy')
        print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))
        clf_cv_mean.append(scores.mean())
        clf_cv_std.append(scores.std())
            
        clf.fit(X, y)
        ax = plt.subplot(gs[grd[0], grd[1]])
        fig = plot_decision_regions(X=X, y=y, clf=clf)
        plt.title(label)
    
    plt.show()
    
    Accuracy: 0.91 (+/- 0.01) [KNN]
    Accuracy: 0.93 (+/- 0.05) [Random Forest]
    Accuracy: 0.92 (+/- 0.03) [Naive Bayes]
    Accuracy: 0.95 (+/- 0.03) [Stacking Classifier]
    

    在这里插入图片描述

    可以发现 基模型 用 ‘KNN’, ‘Random Forest’, ‘Naive Bayes’ 然后再这基础上 次级模型加一个 ‘LogisticRegression’,模型测试效果有着很好的提升。

    一些其它方法:

    将特征放进模型中预测,并将预测结果变换并作为新的特征加入原有特征中再经过模型预测结果 (Stacking变化)

    (可以反复预测多次将结果加入最后的特征中)

    def Ensemble_add_feature(train,test,target,clfs):
        
        # n_flods = 5
        # skf = list(StratifiedKFold(y, n_folds=n_flods))
    
        train_ = np.zeros((train.shape[0],len(clfs*2)))
        test_ = np.zeros((test.shape[0],len(clfs*2)))
    
        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(train,target)
            y_train = clf.predict(train)
            y_test = clf.predict(test)
    
            ## 新特征生成
            train_[:,j*2] = y_train**2
            test_[:,j*2] = y_test**2
            train_[:, j+1] = np.exp(y_train)
            test_[:, j+1] = np.exp(y_test)
            # print("val auc Score: %f" % r2_score(y_predict, dataset_d2[:, j]))
            print('Method ',j)
        
        train_ = pd.DataFrame(train_)
        test_ = pd.DataFrame(test_)
        return train_,test_
    
    
    from sklearn.model_selection import cross_val_score, train_test_split
    from sklearn.linear_model import LogisticRegression
    clf = LogisticRegression()
    
    data_0 = iris.data
    data = data_0[:100,:]
    
    target_0 = iris.target
    target = target_0[:100]
    
    x_train,x_test,y_train,y_test=train_test_split(data,target,test_size=0.3)
    x_train = pd.DataFrame(x_train) ; x_test = pd.DataFrame(x_test)
    
    #模型融合中使用到的各个单模型
    clfs = [LogisticRegression(),
            RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
            ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
            GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=5)]
    
    New_train,New_test = Ensemble_add_feature(x_train,x_test,y_train,clfs)
    
    clf = LogisticRegression()
    # clf = GradientBoostingClassifier(learning_rate=0.02, subsample=0.5, max_depth=6, n_estimators=30)
    clf.fit(New_train, y_train)
    y_emb = clf.predict_proba(New_test)[:, 1]
    
    print("Val auc Score of stacking: %f" % (roc_auc_score(y_test, y_emb)))
    
    Method  0
    Method  1
    Method  2
    Method  3
    Method  4
    Val auc Score of stacking: 1.000000
    
    展开全文
  • 利用stacking模型融合,并做预测

    千次阅读 2019-01-09 20:58:27
    利用stacking模型融合,并做预测 导入的包 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 引入用到的分类...
  • 在学习过程中感谢@贝尔塔的模型融合方法,以及如何在 Kaggle 首战中进入前 10%这篇文章(作者是章凌豪)。对于两位提供的信息,感激不尽。同时还有Kaggle上一些关于ensemble的文章和代码,比如这篇...
  • 机器学习中的Stacking模型融合

    万次阅读 2018-06-04 18:10:56
    最近学习了模型融合的方法,遇到了Stacking的方法来解决模型融合的问题,因此做了以下总结。 1.Stacking是什么? Stacking简单理解就是讲几个简单的模型,一般采用将它们进行K折交叉验证输出预测结果,然后将每...
  • stacking 模型融合

    千次阅读 2017-06-21 08:57:37
    结合策略 假定集成包含T个基学习器,其中h_i在示例x上的输出为h_i(x). 对于数值型的输出,最常见的结合策略是averaging.分为simple averaging 和 weighted averaging....Stacking是学习法的典型代表。
  • 1 def stacking_first(train, train_y, test): 2 savepath = './stack_op{}_dt{}_tfidf{}/'.format(args.option, args.data_type, args.tfidf) 3 os.makedirs(savepath, exist_ok=True) ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,290
精华内容 1,316
关键字:

stacking模型融合