精华内容
下载资源
问答
  • 当然,有很多方法可以提升模型的表现,包括特征工程、调参、模型融合等。在这篇文章中,主要介绍针对模型融合的实践内容,即对多个baseline按一定的方法进行“融合”以期达到指标的提升。以下是前面两篇文章的链接。...

    前面的两篇文章中,我们完成了文件内容提取、中文分词、机器学习模型构建等任务。现在,我们希望对得到的模型效果做出优化。当然,有很多方法可以提升模型的表现,包括特征工程、调参、模型融合等。在这篇文章中,主要介绍针对模型融合的实践内容,即对多个baseline按一定的方法进行“融合”以期达到指标的提升。以下是前面两篇文章的链接。

    最全NLP中文文本分类实践(上)——中文分词获取和Word2Vec模型构建

    最全NLP中文文本分类实践(中)——SVM和基于keras的TextCNN实现

    1 概念简介

    所谓模型融合,其实就是字面意思,通过融合多个不同的模型来提升性能。最容易理解的模型融合有针对分类问题的Voting和回归问题的Average。在其基础上有改进或稍微复杂的有Bagging,Boosting,Stacking等。

    • Voting

    用多个模型对样本进行分类,以“投票”的形式,投票最多者为最终的分类。

    • Average

    对不同模型得出的结果取平均或加权平均。

    • Bagging

    先利用多次有放回抽样生成不同的训练集训练出不同的模型,将这些模型的输出结果通过上述两种方法综合得到最终的结果。随机森林就是基于Bagging算法的一个典型例子。

    • Boosting

    一种迭代的方法,每一次训练的时候都更加关心分类错误的样例,给这些分类错误的样例增加更大的权重,下一次迭代的目标就是能够更容易辨别出上一轮分类错误的样例。最终将这些弱分类器进行加权相加。

    • Stacking

    本质上是分层的结构。第一层是k折交叉的训练集,针对于每一折,由除自己以外的其他的训练数据训练出模型,并以此模型对这一折进行预测。按照此流程进行k次之后,我们得到了用不同模型预测训练集标签的结果,按顺序罗列之后作为第二层的训练集。再用k次训练的模型预测测试集标签,将得到的结果除以k取平均,作为第二层的测试集。随后,我们再用另一个模型去训练第二层的训练集并预测第二层的测试集,获取对原始的测试集的预测结果进行评估。

    Stacking

    这一部分的内容概念可能用语言描述起来不太好理解,我是通过以下链接进行更直观的认知的。有需要的同学可以去加深一下理解认识。

    【机器学习】模型融合方法概述

    在本次实践中,我主要应用的是Voting和Stacking两种模型融合的方法,也将在下文中分别展开。

    2 Voting实现

    在此之前,我们先需要有几个预先存好的模型。最好是奇数个,这样不会出现特别多的平票的情况。我使用了5个模型进行voting,分别是TextCNN,以及5个和10个epochs分别训练出来的Word2Vec模型下,各自的SVM和神经网络分类器。

    #模型融合
    import joblib
    import h5py
    from tensorflow.keras.models import load_model
    
    #导入五个提前保存好的模型
    cnnmodel = load_model('textcnn.h5')
    svm1model = joblib.load("download_w2v_svm.m")
    svm2model = joblib.load("download_w2v_10epochs_svm.m")
    nn1model = joblib.load("download_w2v_nn.m")
    nn2model = joblib.load("download_w2v_10epochs_nn.m")
    
    #由于CNN模型和其他分类器模型所产生的标签格式是不一致的
    #因此需要应用不同的测试集特征格式,并将预测结果进行统一
    y_cnnpred = cnnmodel.predict(X_testcnn, batch_size=64,
                                  verbose=0, steps=None,
                                  callbacks=None, max_queue_size=10,
                                  workers=1, use_multiprocessing=False)
    y_svm1pred = svm1model.predict_proba(X_testclf)
    y_svm2pred = svm2model.predict_proba(X_testclf)
    y_nn1pred = nn1model.predict_proba(X_testclf)
    y_nn2pred = nn2model.predict_proba(X_testclf)
    
    #获取one-hot标签形式
    y_cnnpred = np.rint(y_cnnpred)
    y_nn1pred = np.rint(y_nn1pred)
    y_nn2pred = np.rint(y_nn2pred)
    y_svm1pred = np.rint(y_svm1pred)
    y_svm2pred = np.rint(y_svm2pred)
    
    #加和投票
    y_ensemble = y_cnnpred + y_svm1pred + y_svm2pred + y_nn1pred + y_nn2pred
    y_pred_ensemble = y_ensemble.argmax(axis=1)
    
    #Confusion Matrix and report
    print(confusion_matrix(y_test, y_pred_ensemble))
    print(classification_report(y_test, y_pred_ensemble, digits=4))
    

    最终,该融合模型可以达到了90.77%的准确率和88.57%的macro f1,这在我目前的所有模型中达到最好的效果,也比上一节只是用SVM分类器多个指标提高了1%以上。

    3 Stacking实现

    拿下了目前为止的最优模型表现,我们一鼓作气向Stacking方法前进。Stacking在原理上其实没有很难理解,实现上也不是特别复杂。当然,我个人对这个方法所能达到的效果还是有些怀疑,虽然是应用交叉验证进行了模型融合,但是双层的训练结构其实也会一定程度上会造成错误的累加。虽然初衷是降低泛化的误差,但是略显复杂的模型结构也容易造成过拟合。简单进行了一些思考和预估之后,开始实践。

    def get_stacking(clf,X_train,y_train,X_test,n_folds):
        """
        x_train, y_train, x_test 的值应该为numpy里面的数组类型 numpy.ndarray .
        """
        #初始化
        train_num, test_num = X_train.shape[0], X_test.shape[0]
        second_level_train_set = np.zeros((train_num,))
        second_level_test_set = np.zeros((test_num,))
        test_nfolds_sets = np.zeros((test_num, n_folds))
        #创建k折数据
        skf = StratifiedKFold(n_splits=n_folds)
    
        for i,(train_index, test_index) in enumerate(skf.split(X_train,y_train)):
            X_tra, y_tra = X_train[train_index], y_train[train_index]
            X_tst, y_tst =  X_train[test_index], y_train[test_index]
    
            clf.fit(X_tra, y_tra)
            #获得第二层训练集
            second_level_train_set[test_index] = clf.predict(X_tst)
            test_nfolds_sets[:,i] = clf.predict(X_test)
        #获得第二层测试集,取平均
        second_level_test_set[:] = test_nfolds_sets.mean(axis=1)
        return second_level_train_set, second_level_test_set
    

    get_stacking()是针对一个模型进行k折交叉验证。和刚才的Voting方法相同,我们同样导入所需要的的模型。

    import joblib
    
    rfmodel = joblib.load("download_w2v_rf.m")
    svm1model = joblib.load("download_w2v_svm.m")
    svm2model = joblib.load("download_w2v_10epochs_svm.m")
    nn1model = joblib.load("download_w2v_nn.m")
    nn2model = joblib.load("download_w2v_10epochs_nn.m")
    
    train_sets = []
    test_sets = []
    for clf in [rfmodel, svm1model, svm2model, nn1model, nn2model]:
        train_set, test_set = get_stacking(clf, X_train, y_train, X_test,n_folds=5)
        train_sets.append(train_set)
        test_sets.append(test_set)
    
    meta_train = np.concatenate([result_set.reshape(-1,1) for result_set in train_sets], axis=1)
    meta_test = np.concatenate([y_test_set.reshape(-1,1) for y_test_set in test_sets], axis=1)
    

    这时我们已经获取了第二层的训练集和测试集,接下来我们再用一个新的模型去进行训练和预测。

    from sklearn import svm
    from sklearn.model_selection import GridSearchCV
    from sklearn.metrics import f1_score
    #Find the svm(rbf) model with highest f1 score
    clfsecond = svm.SVC()
    grid_values = {'gamma': [0.001, 0.01, 0.05, 0.1, 1, 10],
                   'C':[0.01, 0.1, 1, 10, 100]}
    
    grid_clf = GridSearchCV(clfsecond, param_grid = grid_values,scoring = 'f1_macro')
    grid_clf.fit(meta_train, y_train)
    y_grid_pred = grid_clf.predict(meta_test)
    
    print('Test set F1: ', f1_score(y_test,y_grid_pred,average='macro'))
    print('Grid best parameter (max. f1): ', grid_clf.best_params_)
    print('Grid best score (accuracy): ', grid_clf.best_score_)
    

    最终合适的参数为{‘C’: 10, ‘gamma’: 0.01}。在这组参数下,我们获得的结果为85.83%的准确率和82.65%的macro f1,果然效果不是很好。当然,在这次实践中效果一般,不能否定其价值,也许是我在某些细节上还没有做到位,也欢迎大家给予更多意见和建议。

    4 Badcase分析

    为了更好地发现模型对于某些有共性案例的错误判断,我们往往会对预测错误的badcase进行分析。

    #badcase 预测标签和实际标签不一样的案例
    test = pd.read_csv('article_features_test.csv')
    test['predict'] = pd.Series(y_pred_ensemble.tolist())
    badcase = test[test.label != test.predict]
    truecase = test[test.label == test.predict]
    

    之前已经发现,模型对历史类别的分类表现较差,因此我们着重去观察历史类的错误分类文档,发现这些文章一部分是文物的出土,可能是因为这部分词的词频过低,因此在Word2Vec模型中就没有得到很好的训练,不巧这些词又在文章中扮演着重要作用,因此造成了判定错误的结论。当然,更多的历史文章都是讲述历史中的一个课题,比如过去某个时段的事件或名人,某种文化的发展进程等等,我们很难单独把历史这个类别割裂出来,这也造成了其准确率较差的表现。

    当然,以上仅是我对一些表现的原因分析,至于如何去完善或修正这些badcases,我在Word2Vec模型上的改进尝试没有取得理想的效果,或许添加一些预知的规则会有用,但是其实还是没有明确的思路。如果各位有什么经验或想法的话欢迎多多交流。

    5 小结

    通过模型融合,我们确实提升了模型的性能,尽管没有特别高的突破,但也是有所收获。至此,我们已经完整的完成了中文文本分类的全过程,包括文件提取,中文分词,词向量表达,模型构建和模型融合。当然,每一个部分都是以实践为主,而实践的方法肯定也会有不同之处。比如,将文本转化为向量会有其他方法,而模型的构建也是多种多样。只是我在学习过程中,发现每一个部分的知识都比较碎片,少有把整个过程整合起来的文章,所以既然自己也已经完成了一次中文文本分类的实践,就把自己所用到的方法略作总结,算是对知识的回顾也希望能为有需要的人提供帮助。如果有不足和错误也欢迎大家在评论区指出,很希望和大家交流心得!

    注:转载请注明出处!

    展开全文
  • 主要介绍了在keras下实现多个模型融合方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 迁移学习是深度学习中常用的一个手段,从头开始训练一个模型需要耗费大量的资源,在训练好的权重(预训练)的基础上训练自己的模型是迁移学习的重要思想。Keras 的应用模块(keras.applications)提供了带有预训练权...

    最近时间充裕在学习深度学习,用博客记录一下自己的理解,毕竟好记性不如烂笔头。如果有错误的地方,希望大家指正,一起进步。如果这篇博客对你有帮助,点赞支持一下,码字不易。。。。。
    迁移学习是深度学习中常用的一个手段,从头开始训练一个模型需要耗费大量的资源,在训练好的权重(预训练)的基础上训练自己的模型是迁移学习的重要思想。Keras 的应用模块(keras.applications)提供了带有预训练权值的深度学习模型,这些模型可以用来进行预测、特征提取和微调(fine-tuning)。关于keras.applications的详细应用可以参考博客,详细介绍了keras.applications的用法和一些具体的例子。

    1、迁移学习用于图像分类(基础版)

    迁移学习通俗来讲就是把预训练权重当作模型的初始化权重,使得模型站在巨人的肩膀上训练。
    我们通过一个例子来了解Keras中迁移学习用于图像分类的基础版实现,在预训练模型InceptionV3上微调训练出自己的模型。
    首先来介绍一下调用keras.applications中InceptionV3模型时各参数的意义:

    keras.applications.inception_v3.InceptionV3(include_top=False,
                                                weights='imagenet',
                                                input_tensor=None,
                                                input_shape=None,
                                                pooling=None,
                                                classes=1000)
    

    各参数的意义:
    include_top:是否保留顶层的全连接网络
    weights:None代表随机初始化,即不加载预训练权重。'imagenet’代表加载预训练权重
    input_tensor:可填入Keras tensor作为模型的图像输出tensor
    input_shape:可选,仅当include_top=False有效,应为长为3的tuple,指明输入图片的shape,图片的宽高必须大于197,如(200,200,3)
    pooling:当include_top=False时,该参数指定了池化方式。None代表不池化,最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化,‘max’代表全局最大值池化。
    classes:可选,图片分类的类别数,仅当include_top=True并且不加载预训练权重时可用。
    返回值:Keras 模型对象
    更多不同模型加载时的参数意义可参考Keras中文文档
    迁移学习实现代码如下,在代码中详细介绍了每一步的实现

    #首先导入相关的包,导入applications模块中的InceptionV3预训练模型
    from keras.applications.inception_v3 import InceptionV3
    from keras.preprocessing import image
    from keras.models import Model
    from keras.layers import Dense, GlobalAveragePooling2D
    from keras import backend as K
    #
    # 第二步:构建完整模型
    #include_top这个参数可以控制的是,到底要不要最后的这些全连接层。构建不带分类器的预训练模型
    base_model = InceptionV3(weights='imagenet', include_top=False) 
    
    x = base_model.output
    x = GlobalAveragePooling2D()(x)# 添加全局平均池化层
    x = Dense(1024, activation='relu')(x)# 添加一个全连接层
    predictions = Dense(200, activation='softmax')(x)# 自定义自己的分类器,这是一个200分类的分类器
    model = Model(inputs=base_model.input, outputs=predictions)# 构建我们需要训练的完整模型
    
    #第三步:在构建好的完整模型上用预训练权重开始训练,我们对模型进行两个训练
    
    # 第一次训练:我们只训练随机初始化的层
    # 锁住所有 InceptionV3 的卷积层
    for layer in base_model.layers:
        layer.trainable = False
    # 编译模型(一定要在锁层以后操作)
    model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
    # 在新的数据集上训练几代
    model.fit_generator(...)
    
    #第二次训练:开始微调Inception V3的卷积层,我们会锁住 Inception V3 中底下的几层,然后训练其余的顶层。
    
    # 让我们看看每一层的名字和层号,看看我们应该锁多少层呢:
    for i, layer in enumerate(base_model.layers):
       print(i, layer.name)
    
    # 我们选择训练最上面的两个 Inception block。也就是说锁住前面249层,然后放开之后的层。
    for layer in model.layers[:249]:
       layer.trainable = False
    for layer in model.layers[249:]:
       layer.trainable = True
    
    # 我们需要重新编译模型,才能使上面的修改生效
    # 让我们设置一个很低的学习率,使用 SGD 来微调
    from keras.optimizers import SGD
    model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')
    
    # 我们继续训练模型,这次我们训练最后两个 Inception block
    # 和两个全连接层
    model.fit_generator(...)
    

    至此,就可以实现在InceptionV3预训练权重上训练一个符合自己数据特征的200分类的分类模型。

    2、迁移学习高级实现(升级版)

    我们已经实现了迁移学习,将整个InceptionV3的网络用于特征提取网络,但有时根据任务的需要,我们不需要将整个网络用特征提取,只需要迁移部分模型。有的时候还需要进行不同模型的融合。

    2.1 迁移部分模型

    我们已经实现了迁移学习,将整个InceptionV3的网络用于特征提取网络,但有时根据任务的需要,我们不需要将整个网络用特征提取,从网络的任意中间层中抽取特征用于迁移学习;这时候就只需要迁移部分模型。
    首先,我们要先了解如何获得指定层的输出。有两种方法可以获得指定层的输出
    第一种:自定义用于输出中间层的model

    from keras.models import Model
    
    base_model = InceptionV3(weights='imagenet', include_top=False) 
    layer_name = 'my_layer' # 给定待输出的层的名字
    #自定义用于输出中间层的model
    model = Model(inputs=base_model.input, outputs=base_model.get_layer(layer_name).output)
    #获得指定层的输出
    layer_name_features = model.predict(input_data)
    

    第二中:通过定义Keras函数实现,用于输出指定层的输出

    from keras import backend as K
    # with a Sequential model
    get_3rd_layer_output = K.function([model.layers[0].input],
                                      [model.layers[3].output])
    layer_output = get_3rd_layer_output([x])[0]
    

    了解了如何获得指定层输出,下面看迁移部分模型用来训练的代码:与基础版相比只更改了第二步的代码。

    # 第二步:构建完整模型
    #include_top这个参数可以控制的是,到底要不要最后的这些全连接层。构建不带分类器的预训练模型
    Inp = Input((224,224,3)) #定义一个输入层,输入图片尺寸为224x224
    base_model = InceptionV3(weights='imagenet', include_top=False) 
    intermediate_layer_model = Model(inputs=base_model.input,outputs=base_model.get_layer('Layer_Name').output)
    
    x = intermediate_layer_model(Inp)
    x = GlobalAveragePooling2D()(x)# 添加全局平均池化层
    x = Dense(1024, activation='relu')(x)# 添加一个全连接层
    predictions = Dense(200, activation='softmax')(x)# 自定义自己的分类器,这是一个200分类的分类器
    model = Model(inputs=base_model.input, outputs=predictions)# 构建我们需要训练的完整模型
    

    Layer_Name可以根据自己的需要指定任意中间层,将代码与基础版的第二步换一下,就可以实现模型部分的迁移训练,灵活运用预训练模型。

    2.2 实现模型融合(多输入单输出,单输入单输出)

    不同的模型对同一张图片提取到的特征是不同的,在单独一个模型不能满足任务需求时,不妨试试模型融合,因为迁移训练不会增加太多的训练量,所以多个模型融合的训练量也在可以接受的范围内。
    这里一共介绍3中模型融合方式,如下图所示。

    Input1
    模型1特征提取器
    模型2特征提取器
    分类器

    第一种融合方式的实现和2.1迁移部分模型类似,将平均池化层和全连接层看作模型2特征提取器,最后的一层(Softmax层)看作分类器就可以实现了。

    Input
    模型1特征提取器
    模型2特征提取器
    x
    分类器

    第二种为单输入单输出的模型融合,我们依然使用Keras的applications模块来实现,这里我们将VGG16和Resnet50两个模型的特征提取网络融合。模型1为Resnet50并加载预训练权重。

    def model1():
        base_model1 = choice_model(weights='imagenet',
                                  include_top=False,
                                  input_shape=(norm_size, norm_size, 3))
        model = Model(inputs=base_model1.input, outputs=base_model1.get_layer('activation_43').output)
        return model
    

    模型2为VGG16并加载预训练权重。

    def model2():
        base_model2 = VGG16(weights='imagenet',
                                  include_top=False,
                                  input_shape=(norm_size, norm_size, 3))
        model = Model(inputs=base_model2.input, outputs=base_model2.get_layer('block5_pool').output)
        return model
    

    将模型1和模型2提取到的特征进行融合,输入为224x224大小的图片,得到的model即为融合后的模型。

    def merge_model( ):
        inp = Input((224,224,3))
    
        model_2 = model2()
        model_1 = model1()
    
        r1 = model_1(inp)
        r2 = model_2(inp)
    
        x = concatenate([r1,r2], axis=-1)
    
        model = Model(inputs=inp, outputs=x)
        return model
    

    融合后的特征提取网络结构如图:
    merge_model

    Input1
    模型1特征提取器
    x
    Input2
    模型2特征提取器
    分类器

    第三种为多输入单输出的模型融合,首先也是定义两个加载预训练权重的模型,不同的是在merge_model( )函数中定义了两个输入

    ##多输入单输出
    def merge_model_2( ):
        inp1 = Input((224,224,3))
        inp2 = Input((224, 224, 3))
    
        model_2 = model2()
        model_1 = model1()
    
        r1 = model_1(inp1)
        r2 = model_2(inp2)
    
        x = concatenate([r1,r2], axis=-1)
    
        model = Model(inputs=[inp1,inp2], outputs=x)
        return model
    

    融合后的特征提取网络结构如图:
    在这里插入图片描述

    3、总结

    (1)Keras内置的applications模块可以实现迁移学习,该模块的详细介绍见博客
    (2)Keras有两种方法可以输出指定层的特征图,
    第一种:自定义用于输出中间层的model
    第二种:通过定义Keras函数实现,用于输出指定层的输出(我没用过。。。)
    (3)Keras利用applications模块中自带的权重可以实现模型融合。

    如果这篇博客对你有帮助,点赞支持一下,码字不易。。。。。

    展开全文
  • python sklearn模型融合案例分享

    千次阅读 2019-04-16 13:37:32
    #创建RF模型和LR模型 model_rf = Regressor(dataset=dataset, estimator=RandomForestRegressor, parameters={'n_estimators': 50},name='rf') model_lr = Regressor(dataset=dataset, estimator=LinearRegression, ...

    heamy库的blending方法和mlxtend库的Stacking 方法

    # -*- coding: utf-8 -*-
    from heamy.dataset import Dataset
    from heamy.estimator import Regressor, Classifier
    from heamy.pipeline import ModelsPipeline
    from sklearn.model_selection import KFold
    from sklearn.model_selection import train_test_split
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.linear_model import LinearRegression
    from sklearn.metrics import mean_absolute_error
    from sklearn.model_selection import cross_val_score
    #加载数据集
    from sklearn.datasets import load_boston
    data = load_boston()
    X, y = data['data'], data['target']
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=111)
    #创建数据集
    dataset = Dataset(X_train,y_train,X_test)
    #创建RF模型和LR模型
    model_rf = Regressor(dataset=dataset, estimator=RandomForestRegressor, parameters={'n_estimators': 50},name='rf')
    model_lr = Regressor(dataset=dataset, estimator=LinearRegression, parameters={'normalize': True},name='lr')
    # Stack两个模型
    # Returns new dataset with out-of-fold predictions
    pipeline = ModelsPipeline(model_rf,model_lr)
    stack_ds = pipeline.stack(k=10,seed=111)
    #第二层使用lr模型stack
    stacker = Regressor(dataset=stack_ds, estimator=LinearRegression)
    results = stacker.predict()
    # 使用10折交叉验证结果
    results10 = stacker.validate(k=10,scorer=mean_absolute_error)
    
    from sklearn.metrics import explained_variance_score
    from mlxtend.regressor import StackingRegressor
    import numpy as np
    rf = RandomForestRegressor(n_estimators=100)
    lr =LinearRegression()
    
    sclf = StackingRegressor(regressors=[rf,lr],
                             meta_regressor=lr)
    n_folds = 10
    kf = KFold(n_folds, shuffle=True, random_state=42).get_n_splits(X)
    scores = cross_val_score(sclf,X_train,y_train,cv = kf,scoring='neg_mean_absolute_error')
    print("KF:,",np.mean(scores))
    
    scores2 = []
    for i in range(10):
        x_train,  x_test, Y_train,Y_test = train_test_split(X_train, y_train,test_size=0.1)
        sclf.fit(x_train, Y_train)
        prediction = sclf.predict(X_test)
        scores2.append(mean_absolute_error(y_test, prediction))
    print("for:",np.mean(scores2)) 
    展开全文
  • 模型融合方法总结

    千次阅读 2017-08-02 15:08:38
    模型融合主要通过几部分来实现:从提交结果文件中融合、stacking和blending。 从提交结果文件中融合 最简单便捷的方式就是从竞赛的提交结果文件中进行融合,因为这样做并不需要重新训练模型,只需
    模型融合是kaggle等比赛中经常使用到的一个利器,它通常可以在各种不同的机器学习任务中使结果获得提升。顾名思义,模型融合就是综合考虑不同模型的情况,并将它们的结果融合到一起。模型融合主要通过几部分来实现:从提交结果文件中融合、stacking和blending。

    从提交结果文件中融合
    最简单便捷的方式就是从竞赛的提交结果文件中进行融合,因为这样做并不需要重新训练模型,只需要把不同模型的测试结果弄出来,然后采取某种措施得出一个最终结果就ok。

    多数表决融合
    首先证明一下为什么 模型融合能提高准确率以及 对低相关的结果进行融合可以获得更好结果
    用一个概率的例子来说明。假如现在有10条记录,每条记录能被正确分类的概率为70%,或者某个模型对这10条记录进行分类能获得70%的准确率。现在拟合三个相当的模型,采用多数表决的情况下,对每条记录,三个模型都判断正确的概率为0.7*0.7*0.7~=0.34,两个模型判断正确的概率为0.7*0.7*0.3*3~=0.44,那么通过三个准确率0.7的模型来融合的话,理论上最终每条记录能被正确分类的概率提升到 0.78
    周志华教授在他的著作《机器学习》提到,结果的差异性越高,最终模型融合出来的结果也会越好。同样用一个简单的例子来证明:接着上面的话题,假设现在三个模型预测出来的结果是
    model1:1111111100 = 80% 准确率
    model2:1111111100 = 80% 准确率
    model3:1011111100 = 70% 准确率
    如果把这三个模型结果用多数表决组合起来,那么最终结果是:1111111100 = 80%,这个结果跟第一、二个模型是一致的,也就是,这样的模型融合对最终结果 没有任何的提升
    假如我们现在把三个模型结果改为:
    model1:1111111100 = 80% 准确率
    model2:0111011101 = 70% 准确率
    model3:1000101111 = 60% 准确率
    显然这三个模型之间的差异更大,而且表面来看性能也不如前面提到的三个模型,但它们融合出来的结果是:1111111101 = 90% 准确率

    加权表决融合
    多数表决的融合方式默认了所有模型的重要度是一样的,但通常情况下我们会更重视表现较好的模型而需要赋予更大的权值。在加权表决的情况下,表现较差的模型只能通过与其他模型获得一样的结果来增强自己的说服力。

    对结果取平均
    对结果取平均在很多机器学习问题上以及不同的评估准则上都获得很不错的结果。
    取均值的做法常常可以减少过拟合现象。在机器学习的应用上,过拟合现象是很普遍的,根本问题是训练数据量不足以支撑复杂的模型,导致模型学习到数据集上的噪音,这样产生的问题是模型很难泛化,因为模型“考虑”得过分片面。
    但如果对结果取平均,可以在一定程度上减轻过拟合现象。图中所示,单个模型因为过拟合产生了绿色的决策边界,但事实上黑色的决策边界因为有更好的泛化能力从而有更好的效果。如果通过拟合多个模型并对模型结果取平均,对这些噪音点的考虑就会因为结果拉平均的原因而减少,决策边界也会慢慢的往黑色线靠拢。
    记住,机器学习的目的并不是让模型记住训练数据,而是对未知数据有更好的推广。


    Stacking&Blending
    Stacking
    Stacking的基本思想是用一些基分类器进行分类,然后使用令一个分类器对结果进行整合。
    用2-fold stacking作为例子:
    1.将训练数据分成A和B两份
    2.使用第一阶段模型用A训练,然后对B生成预测值
    3.通过同样的模型用B训练,生成A的预测值
    4.然后使用整个训练集来拟合这个模型,并生成测试集的预测值
    5.像第(2)步一样训练第二阶段模型
    Stacking的模型可以在特征空间上获取更加多的信息,因为 第二阶段模型是以第一阶段模型的预测值会作为特征

    (注:此图是本人所画,如有不对请指正)

    Blending
    Blending与Stacking大致相同,只是 Blending的主要区别在于训练集不是通过K-Fold的CV策略来获得预测值从而生成第二阶段模型的特征,而是建立一个Holdout集,例如说10%的训练数据,第二阶段的stacker模型就基于第一阶段模型对这10%训练数据的预测值进行拟合。说白了,就是把Stacking流程中的K-Fold CV 改成 HoldOut CV。
    Blending的优点在于:
    1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)
    2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集
    3.在团队建模过程中,不需要给队友分享自己的随机种子
    而缺点在于:
    1.使用了很少的数据(第二阶段的blender只使用training set10%的量)
    2.blender可能会过拟合(其实大概率是第一点导致的)
    3.stacking使用多次的CV会比较稳健
    对于实践中的结果而言,stacking和blending的效果是差不多的,所以使用哪种方法都没什么所谓,完全取决于个人爱好。

    http://blog.csdn.net/sinat_29819401/article/details/71191219

    展开全文
  • 为了解决在复杂背景以及人流密集且互相遮挡的场景下, 对人流密度进行估计精度低的问题, 提出了基于YOLOv3增强模型融合的方法进行人流密度估计. 首先将数据集分别进行头部标注和身体标注, 生成头部集和身体集. 然后用...
  • 主要介绍了使用keras实现densenet和Xception的模型融合,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • Datawhale作者:田杨军,Datawhale优秀学习者摘要:对于数据挖掘项目,本文将学习如何进行模型融合?常见的模型融合的方法有哪些?针对不同的问题类型,应该选择哪种方法呢...
  • 初识模型融合方法(图解)

    千次阅读 2018-07-10 13:36:45
    因为在做比赛用到这方面的知识,应用是最大的动力,下面是自己的一点总结, 将从两方面展开:(1)最懒的融合---直接对几个模型的结果(即提交文件)进行融合。有下面几种方法可以尝试:· 投票法。例如得到了a、b、...
  • 模型融合:对调参完成的模型进行融合,一般在整个过程的后期进行,基于多个比较好的模型,融合后才有好的效果。 方法: 简单加权融合: 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合...
  • 【机器学习】模型融合方法概述

    万次阅读 2018-04-24 16:22:45
    转自:https://zhuanlan.zhihu.com/p/25836678我理解的Kaggle比赛中提高成绩主要有3个地方特征工程调参模型融合 之前每次打比赛都只做了前两部分,最后的模型融合就是简单的加权平均,对于进阶的Stacking方法一直没...
  • print('==============================随机森林模型==============================') rf_test_pred, rf_train_pred = stacking(model=rf, train_data=x_train, train_target=y_train, test_data=x_test, n_fold=...
  • 1 Ensemble Learning-模型融合 通过对多个单模型融合以提升整体性能。 1.1 Voting 投票制即为,投票多者为最终的结果。例如一个分类问题,多个模型投票(当然可以设置权重)。最终投票数最多的类为最终被预测的类...
  • 模型融合

    千次阅读 2019-05-31 17:35:09
    没有哪个机器学习模型可以常胜,...幸运的是,结合/融合/整合 (integration/ combination/ fusion)多个机器学习模型往往可以提高整体的预测能力。这是一种非常有效的提升手段,在多分类器系统(multi-classifier sy...
  • 向AI转型的程序员都关注了这个号????????????机器学习AI算法工程 公众号:datayx利用pytorch实现图像分类,其中包含的densenet,resnext,mobi...
  • 二、Python sklearn实现GBDT+LR融合模型 一、树模型与线性模型融合模型模型GBDT原理:https://blog.csdn.net/woniu201411/article/details/83114226 线性模型LR原理:...
  • 1.多模型融合中的问题: 首先,在使用融合神经网络模型的过程中遇到的第1个问题就是训练复杂神经网络非常耗时,因为优秀的模型一般都是深度神经网络模型,这些网络模型的特点是层次较深、参数较多,所以对融合了多个...
  • keras实现densenet和Xception的模型融合

    千次阅读 热门讨论 2018-04-05 20:54:08
    我正在参加天池上的一个竞赛,刚开始用的是DenseNet121但是效果没有达到预期,因此开始尝试使用模型融合,将Desenet和Xception融合起来共同提取特征。代码如下:def Multimodel(cnn_weights_path=None,all_weights_...
  • 这是一篇根据自己的理解,复写论文《Segmentation-Based ...首先,《基于分割的表面缺陷检测深度学习方法》这篇论文主要是利用分割模型和分类模型进行表面瑕疵的检测,主要优势为:只需要25-30个有缺陷的样本就可...
  • 模型集成 | 14款常规机器学习 + 加权平均模型融合

    千次阅读 多人点赞 2018-07-03 22:59:24
    模型融合的方法很多,Voting、Averaging、Bagging 、Boosting、 Stacking,那么一些kaggle比赛中选手会选用各种方法进行融合,其中岭回归就是一类轻巧且非常有效的方法,当然现在还有很多更有逼格的方法。...
  • Python 模型融合-投票法

    千次阅读 2020-12-07 09:26:01
    文章目录前言代码 前言   假设你已经训练了一些...软投票是基于分类标签概率投票,将所有模型预测样本为某一类别的概率的平均值作为标准,概率最高的对应的类型为最终的预测结果;   这种投票分类器往往比单个的
  • 该代码可以实现类似图片的效果,多个模型采用第一个输入。 图片来源:https://github.com/keras-team/keras/issues/4205   step 1:重新定义模型(这是我自己的模型,你们可以用你们自己的),与预训练不一样,...
  • 在keras下实现多个模型融合

    千次阅读 2019-09-30 10:41:54
    在网上搜过发现关于keras下的模型融合框架其实很简单,奈何网上说了一大堆,这个东西官方文档上就有,自己写了个demo: # Function:基于keras框架下实现,多个独立任务分类 # Writer: PQF # Time: 2019/9/29 ...
  • pytorch之多模型融合

    千次阅读 2020-02-24 10:36:07
    1.挑选结构较简单的网络层次上的神经网络参与到多模型融合 2. 多模型融合+迁移学习 辅助模型的融合 2.多模型融合的方法 1.结果多数表决 2.结果直接平均 3.结果加权平均 3.pytorch 之多模型融合实战(vgg16+resnet50...
  • 这是本人对模型融合的代码合集,环境是python3,只要复制过去就可以用了,非常方便。 目录 1.交叉验证 1.1 原理 1.2 GridSearchCV 2.绘制学习曲线 3.stacking 3.1 stacking原理 3.2 代码实现不同版本的...
  • Ensemble Learning-基于集成学习的模型融合-Python实现

    万次阅读 多人点赞 2017-07-16 19:08:36
    模型融合常用方法。 1 Voting 2 Averaging 3 Ranking 4 Binning 5 Bagging 6 Boosting 7 Stacking 8 Blending
  • 模型融合的blending方法

    千次阅读 2020-03-06 14:08:41
    模型融合有bagging, stacking, boosting,居然还有个blending!初学,初学^_^。 https://www.cnblogs.com/makefile/p/stacking.html这篇文章写的很清楚,以下是部分原文。 ------------------------------------ ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,195
精华内容 43,678
关键字:

模型融合实现