数据挖掘|20200404零基础入门数据挖掘 - 二手车交易价格预测笔记(5)

五、模型融合 5.1 模型融合目标
对于多种调参完成的模型进行模型融合,因为多个模型组合在一起通常可以产生更强大的模型。
5.2 内容介绍
模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。
1. 简单加权融合:

  • 回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);
  • 分类:投票(Voting)
  • 综合:排序融合(Rank averaging),log融合
2. stacking/blending:
  • 构建多层模型,并利用预测结果再拟合预测。
3. boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):
  • 多树的提升方法
5.3 Stacking相关理论介绍
  1. 什么是 stacking
    将个体学习器结合在一起的时候使用的方法叫做结合策略。
    对于分类问题,我们可以使用投票法来选择输出最多的类。
    对于回归问题,我们可以将分类器输出的结果求平均值
    还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。
    在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。
  2. stacking原理
    stacking是一种分层模型集成框架;以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为训练集进行再训练,从而得到完整的stacking模型, stacking两层模型都使用了全部的训练数据。也就是在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。
  3. 会出现的问题
    对于训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法:
    - 次级模型尽量选择简单的线性模型
    - 利用K折交叉验证
5.4 分类模型融合
以下数据集都要进行导入:
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投票机制:
    分为软投票和硬投票两种,原理是少数服从多数。
    硬投票:对多个模型直接进行投票,不区分模型结果的相对重要度,最终投票数最多的类为最终被预测的类。
    软投票:和硬投票原理相同,但增加了设置权重的功能,可以为不同模型设置不同权重,进而区别模型不同的重要度。
  2. 分类的Stacking/Blending融合:
    此处需了解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使用多次的交叉验证会比较稳健
  3. 其它方法:将特征放进模型中预测,并将预测结果变换并作为新的特征加入原有特征中再经过模型预测结果 (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_

这一部分代码有用到StratifiedKFold,这主要是让抽样后的训练集和验证集的样本分类比例和原有的数据集尽量是一样的。
还有用到zeros的功能,用法如下。
用法:zeros(shape, dtype=float, order=‘C’)
返回:返回来一个给定形状和类型的用0填充的数组;
参数:shape:形状
dtype:数据类型,可选参数,默认numpy.float64
from sklearn.model_selection import cross_val_score, train_test_split from sklearn.linear_model import LogisticRegression clf = LogisticRegression()data_0 = iris.data data = https://www.it610.com/article/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)))

最后一次打卡了,还是想写写学习的感受,因为代码基础不够牢,这次很多模组都还不会用,故而对于代码的解读感觉还是很困难。 Datawhale团队提供的学习资料还是很详尽的,但因为自己本身的基础不够,第一次接触数据挖掘,所以很多名词还需要另外搜索进行了解,短短几天还没有学的特别的透彻,之后会再将代码翻来覆去看几次,了解每一个步骤的意图。这次大概算是先在脑海里建立起了一个建模的流程,之后要把细节都填充好。
【数据挖掘|20200404零基础入门数据挖掘 - 二手车交易价格预测笔记(5)】参考资料:
[1] https://blog.csdn.net/m0_37870649/article/details/104404963
[2] https://tianchi.aliyun.com/notebook-ai/detail?spm=5176.12281978.0.0.6802593ax7AOhM&postId=95535
[3]https://zhuanlan.zhihu.com/p/89898221

    推荐阅读