模型融合采用的的思想,即多个模型的组合可以改善整体的表现。集成模型是一种能在各种的机器学习任务上提高准确率的强有力技术。模型融合是kaggle竞赛后期一个重要的环节,大体来说有如下的类型方式:
1. 简单加权融合:
回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean)
分类:投票(Voting)
综合:排序融合(Rank averaging),log融合
2. stacking/blending:
构建多层模型,并利用预测结果再拟合预测
3. boosting/bagging:
多树的提升方法,在xgboost,Adaboost,GBDT等中已经用到
基本思想:对于回归问题,一个简单直接的思路是取平均。稍稍改进的方法是进行加权平均。权值可以用排序的方法确定,举个例子,比如A、B、C三种基本模型,模型效果进行排名,假设排名分别是1,2,3,那么给这三个模型赋予的权值分别是3/6、2/6、1/6。
平均法或加权平均法看似简单,其实后面的高级算法也可以说是基于此而产生的,Bagging或者Boosting都是一种把许多弱分类器这样融合成强分类器的思想。
基本思想:假设对于一个二分类问题,有3个基础模型,现在我们可以在这些基学习器的基础上得到一个投票的分类器,把票数最多的类作为我们要预测的类别。
投票法实现代码:`
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import VotingClassifier
model1 = LogisticRegression(random_state=2020)
model2 = DecisionTreeClassifier(random_state=2020)
model = VotingClassifier(estimators=[('lr', model1), ('dt', model2)], voting='hard')
model.fit(x_train, y_train)
model.score(x_test, y_test)
基本思想:stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。对不同模型预测的结果再进行建模。
在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器,次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。
Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法:
调用APi实现stacking:
from heamy.dataset import Dataset
from heamy.estimator import Regressor, Classifier
from heamy.pipeline import ModelsPipeline
from sklearn import cross_validation
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
#加载数据集
from sklearn.datasets import load_boston
data = load_boston()
X, y = data['data'], data['target']
X_train, X_test, y_train, y_test = cross_validation.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()
# 使用5折交叉验证结果
results10 = stacker.validate(k=5,scorer=mean_absolute_error)
手动实现:只创建一个基学习器为例:
from sklearn.model_selection import StratifiedKFold,KFold,RepeatedKFold
import xgboost.sklearn import XGBClassifier
import numpy as np
skf = StratifiedKFold(n_splits = 5, shuffle = True ,random_state=16)
oof_xgb = np.zeros(len(train)) #创建数组
pre_xgb = np.zeros(len(test))
for k,(train_in,test_in) in enumerate(skf.split(train,train_y)):
X_train,X_test,y_train,y_test = X[train_in],X[test_in],y[train_in],y[test_in]
params = {'learning_rate': 0.008,
'n_estimators': 1000
'max_depth': 5,
'subsample': 0.8,
'colsample_bytree': 0.8,
'objective':'binary:logistic',
'eval_metric':'auc',
'silent': True,
'nthread': 4,
}
# train
clf = XGBClassifier(params)
clf.fit(trn_x, trn_y,eval_set=[(val_x, val_y)],eval_metric='auc',early_stopping_rounds=100,verbose=100)
print('Start predicting...')
oof_xgb[test_in] = clf.predict(X_test)
pre_xgb += clf.predict(test) / skf.n_splits
print('XGB predict over')
基本思想:Blending采用了和stacking同样的方法,不过只从训练集中选择一个fold的结果,再和原始特征进行concat作为元学习器meta learner的特征,测试集上进行同样的操作。
把原始的训练集先分成两部分,比如70%的数据作为新的训练集,剩下30%的数据作为测试集。
Blending与 Stacking的对比:
优点:
缺点: