模型融合的方法主要有:
- 平均:简单平均法和加权平均法
- 投票:简单投票法和加权投票法
- 综合:排序融合和log融合
- stacking
- blending
- boosting/bagging
stacking
stacking根据多个基学习器得到的预测结果作为新的训练集来训练一个学习器。如下图所示,假设共有5个基学习器,使用原始数据训练5个基学习器得到预测结果,然后将预测结果带入模型6进行训练,为了避免过拟合,可以使用K折交叉验证。
blending
blending将预测的值作为新的特征与原特征合并,构造新的特征值用于预测。为了防止过拟合,可以将数据分为d1和d2两部分,d1的数据为训练集,d2为测试集。如下图所示,模型的第一层中,将d1分为70%个30%的两部分,使用70%训练多个模型对30%进行预测。模型的第二层中,合并30%的预测结果作为新的训练集,d2的预测结果作为新的测试集,然后进行训练,
代码示例:
平均法:取基分类器的预测结果
#简单平均
pre = (pre1 + pre2 + pre3 +...+pren )/n
#加权平均
pre = 0.3pre1 + 0.3pre2 + 0.4pre3
投票法
#简单投票
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))
#加权投票,与简单投标相比,在VotingClassifier中加入参数 voting='soft', weights=[2, 1, 1]
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)], voting='soft', weights=[2, 1, 1])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))
stacking
from mlxtend.classifier import StackingClassifier
clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],
meta_classifier=lr)
blending
#模型融合中基学习器
clfs = [LogisticRegression(),
RandomForestClassifier(),
ExtraTreesClassifier(),
GradientBoostingClassifier()]
#切分一部分数据作为测试集
X, X_predict, y, y_predict = train_test_split(data, target, test_size=0.3, random_state=914)
#切分训练数据集为d1,d2两部分
X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=914)
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()
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)))
注:比赛中,简单平均和加权平均是常用的模型融合方式
参考文献:
[1] https://blog.csdn.net/wuzhongqiang/article/details/105012739