天池-贷款违约挑战赛(五)-模型融合

学习目标

天池-贷款违约挑战赛(四)-建模与调参中介绍的模型进行融合



学习内容

模型融合的方法
1、 平均(简单、加权)
2、 投票(简单、加权)
3、 综合(排序融合、log融合)
4、 stacking(构建多层模型,并利用预测结果再拟合预测)
5、 blending(选取部分数据预测训练得到预测结果作为新特征,带入剩下的数据中预测。blending只有一层,而stacking有多层)
6、 boosting/bagging(在天池-贷款违约挑战赛(四)-建模与调参介绍过)


stacking

将若干基学习器获得的预测结果,将预测结果作为新的训练集来训练一个学习器。如下图 假设有五个基学习器,将数据喂进五个基学习器中得到预测结果,将预测结果作为新的训练集喂进模型六中进行训练预测。但是由于将五个基学习器的结果直接喂进模型六中,容易导致过拟合。所以在使用五个基模型进行预测的时候,可以考虑使用K折验证,防止过拟合。


blending

与stacking不同,blending是将预测的值作为新的特征和原特征合并,构成新的特征值,用于预测。为了防止过拟合,将数据分为两部分d1、d2,使用d1的数据作为训练集,d2数据作为测试集。预测得到的数据作为新特征使用d2的数据作为训练集结合新特征,预测测试集结果

blending与stacking的不同
a. stacking

  • stacking中由于两层使用的数据不同,所以可以避免信息泄露的问题。在组队竞赛的过程中,不需要给队友分享自己的随机种子。

b. blending

  • blending比stacking简单,不需要构建多层模型。

  • 由于blending对将数据划分为两个部分,在最后预测时有部分数据信息将被忽略。同时在使用第二层数据时可能会因为第二层数据较少产生过拟合现象。

这里上一篇在datawhale一次组队学习中一位大佬的学习笔记,大佬也是从小白开始一步步学习整理,向大佬致敬!



代码示例

1、平均(简单、加权)

简单一点就是类似于求期望,n个模型的预测值相加并除以n

avg_simple= (pre1 + pre2 + pre3 +…+pren )/n

加权就是给不同的模型预测值加上权重,想凸显某个模型的重要性就把权值调大点

pre = 0.3pre1 + 0.3pre2 + 0.4pre3


2、投票(简单、加权)

# 简单投票
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],weights用于调节基模型的权重

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))

3、stacking

import warnings
warnings.filterwarnings('ignore')
import itertools
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from mlxtend.plotting import plot_learning_curves
from mlxtend.plotting import plot_decision_regions

# 以python自带的鸢尾花数据集为例
iris = datasets.load_iris()
X, y = iris.data[:, 1:3], iris.target

clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3], meta_classifier=lr)

label = ['KNN', 'Random Forest', 'Naive Bayes', 'Stacking Classifier']
clf_list = [clf1, clf2, clf3, sclf]

fig = plt.figure(figsize=(10,8))
gs = gridspec.GridSpec(2, 2)
grid = itertools.product([0,1],repeat=2)

clf_cv_mean = []
clf_cv_std = []
for clf, label, grd in zip(clf_list, label, grid):
	scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
	print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))
	clf_cv_mean.append(scores.mean())
	clf_cv_std.append(scores.std())
	
	clf.fit(X, y)
	ax = plt.subplot(gs[grd[0], grd[1]])
	fig = plot_decision_regions(X=X, y=y, clf=clf)
	plt.title(label)
plt.show()


# 以下是结果
Accuracy: 0.91 (+/- 0.07) [KNN]
Accuracy: 0.94 (+/- 0.04) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [Naive Bayes]
Accuracy: 0.94 (+/- 0.04) [Stacking Classifier]

在这里插入图片描述


4、blending

# 以python自带的鸢尾花数据集为例
data_0 = iris.data
data = data_0[:100,:]

target_0 = iris.target
target = target_0[:100]

# 模型融合中的基学习器
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)))



总结

平均是最常用的融合方式,最简单也最快。stacking的效果确实是好,但是速度太慢,层次加深十分吃时间和内存,会导致整个模型复杂度有一定提升,所以并不是模型融合得越多越好,有得必有失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值