blending是和stack同性质的集成学习方法,都是通过组合多个弱学习器生成的输出作为最终学习器的输入而得到一个更好的结果,但是他们的数据划分方式有所区别,而且生成次级训练集的方法更简单了。其实也是很久之后我才想起来我写了stacking,所以不能漏掉blending。
我们将data划分为train和test两部分,其中train划分初级训练集和初级验证集(不像stacking那个妖艳贱货划分个数据还弯弯绕绕的)。
在生成模型之前,我们需要先生成两个数组,一个用来存放次级训练集dataset_train_val,一个用于存放次级测试集dataset_test。
dataset_train_val是一个模型作为一列,训练集train长度作为行数。
dataset_test也为一个模型作为一列,训练集test长度作为行数。
3、训练模型
训练之前根据自己的需求选择初级学习算法,和stacking一样,我使用了基于随机决策树的平均算法RandomForest算法和Extra-Trees算法(其中可分为gini,entropy),还有GBDT来作为初级学习算法。
以第一种初级学习算法为例,我先使用初级数据集进行训练,得到一个初级学习器,该初级学习器先对初级验证集进行预测,并输出其概率,将结果以列存入次级训练集。
接着再使用该初级学习器,对测试集test进行预测输出,同样结果以列保存至次级测试集。
因为我们只用了一种算法,接着循环其他四种并重复上述过程。这样我们就得到了五种初级学习器对初级验证集的输出的集合(次级训练集),还有对测试集的输出的集合(次级测试集)。
训练每种初级学习器后,可以检验其对测试集test的准确率
呃,暂时来看这效果就和随机猜测差不多,但是后面的结果会让人大吃一惊。
4、模型融合
我在这里依然选择了GBDT,因为stacking选了,后面也懒得改了。
在训练模型阶段,我们得到了次级训练集dataset_train_val和次级测试集dataset_test,如下图。
- dataset_train_val每一列对应每一个初级学习器对初级验证集的预测结果。
- 而dataset_test每一列则是初级学习器对测试集test的预测结果。
用次级训练集dataset_train_val作为输入和相应label进行拟合,生成次级学习器model。
然后将dataset_test喂给model,生成输出向量并用auc进行评估。
噔噔蹬蹬,这提升能力惊人,当然我这只是随便弄弄,数据都是自己造的,学会的可以自己玩。
代码
你若是看的懂stacking的思路,其实blending就是小孩子过家家
from sklearn import datasets
from sklearn.ensemble import RandomForestClassifier,ExtraTreesClassifier,GradientBoostingClassifier
from sklearn.model_selection import train_test_split,StratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
data,label = make_blobs(n_samples = 10000,centers = 2,random_state = 0,cluster_std = 0.60)
#划分训练集和测试
x_train,x_test,y_train,y_test = train_test_split(data,label,test_size = 0.33,random_state = 0)
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=5)
]
#训练集切分两部分,一部分作训练集,一部分作验证集
x_train_train,x_train_val,y_train_train,y_train_val = train_test_split(x_train,y_train,test_size=0.5,random_state = 0)
dataset_train_val = np.zeros((x_train_val.shape[0],len(clfs)))
dataset_test = np.zeros((x_test.shape[0],len(clfs)))
for j ,clf in enumerate(clfs):
#训练集生成模型
clf.fit(x_train_train,y_train_val)
#生成验证集结果
dataset_train_val[:,j] = clf.predict_proba(x_train_val)[:,1]
#生成测试集结果
dataset_test[:,j] = clf.predict_proba(x_test)[:,1]
#auc匹配测集生成结果
print("val auc Score: %f" % roc_auc_score(y_test, dataset_test[:,j]))
#模型融合
clf = GradientBoostingClassifier(learning_rate=0.02,subsample=0.5,max_depth=6,n_estimators=30)
#使用验证集生成的结果作为训练集再次训练
clf.fit(dataset_train_val,y_train_val)
#生成预测集结果
y_submission = clf.predict_proba(dataset_test)[:, 1]
# y_submission = (y_submission - y_submission.min()) / (y_submission.max() - y_submission.min())
print('模型融合后auc')
print("val auc Score: %f" % (roc_auc_score(y_test, y_submission)))