一、学习知识点概要
文章目录
二、学习内容
模型融合的方式
- 平均:
- 简单平均法
- 加权平均法
- 投票:
- 简单投票法
- 加权投票法
- 综合:
- 排序融合
- log融合
- stacking:
- 构建多层模型,并利用预测结果再拟合预测。
- blending:
- 选取部分数据预测训练得到预测结果作为新特征,带入剩下的数据中预测。
- boosting/bagging(在Task4中已经提及,就不再赘述)
1. stacking \ blending 详解
1.1 stacking
主要思想是训练模型来学习使用底层学习器的预测结果。是将若干个基学习器获得的预测结果作为新的训练集来训练一个学习器 的一种有层次的融合模型。(以两层为例,第一层由多个基学习器组成,其输入为原始训练集,第二层的模型则是以第一层基学习器的输出作为特征加入训练集进行再训练,从而得到完整的stacking模型。(基学习器–次学习器))
但如果将前面的及学习期获得结果直接带入到一个新的模型中,容易导致过拟合。所以在使用前面的基模型进行预测的时候,可以考虑用K折验证,防止过拟合。
-
图解
stacking 网上有两种解释,一种是单个模型进行5次交叉验证得到一个结果,然后对每个模型都进行相同的操作,此时训练集的维度为(#样本数目 x #模型数目);另一种是每个模型对数据的每一折输出一个结果,然后把每一折的结果拼接起来,此时的训练集维度(#样本数目 x 1)。
-
流程
- 将数据划分为训练集和测试集(test_set),对训练集进行划分为K个大小相似的集合,取其中一份作为验证集val_set,其余的为训练集train_set;
- 创建第一层的多个模型,这些模型可以使同质的也可以是异质的;
- 对于每一个模型来说,train_set和val_set是不一样的,然后利用各自的train_set训练各自的模型,训练好的模型对各自的val_set和test_set进行预测,得到val_predict和test_predict; (各自训练各自的)
- 创建第二层的模型,将每个模型对应的val_predict拼接起来作为第二层的训练集,将所有模型的test_predict取平均值作为第二层的测试集;用训练好的第二层模型对第二层的测试集进行预测,得到的结果即为整个测试集的结果
1.2 blending
blending是将预测的值作为新的特征和原特征合并,构成新的特征值,用于预测。
为了防止过拟合,将数据分为两部分d1、d2,使用d1的数据作为训练集,d2数据作为测试集。预测得到的数据作为新特征使用d2的数据作为训练集结合新特征,预测测试集结果。
- 图解
- 流程
- 将数据划分为训练集和测试集(test_set),其中训练集需要再次划分为训练集(train_set)和验证集(val_set);
- 创建第一层的多个模型,这些模型可以使同质的也可以是异质的;
- 使用train_set训练步骤2中的多个模型,然后用训练好的模型预测val_set和test_set得到val_predict, test_predict1;
- 创建第二层的模型,使用val_predict作为训练集训练第二层的模型;
- 使用第二层训练好的模型对第二层测试集test_predict1进行预测,该结果为整个测试集的结果
1.3 stacking 和 blending 的区别
- stacking
- stacking中由于两层使用的数据不同,所以可以避免信息泄露的问题。
- 在组队竞赛的过程中,不需要给队友分享自己的随机种子。
- Blending
- 由于blending对将数据划分为两个部分,在最后预测时有部分数据信息将被忽略。
- 同时在使用第二层数据时可能会因为第二层数据较少产生过拟合现象。
2. 代码示例
2.1 平均
(1)简单加权平均
结果直接融合 求多个预测结果的平均值。pre1-pren分别是n组模型预测出来的结果,将其进行加权融
pre = (pre1 + pre2 + pre3 +...+pren )/n
(2)加权平均法
一般根据之前预测模型的准确率,进行加权融合,将准确性高的模型赋予更高的权重。
pre = 0.3pre1 + 0.3pre2 + 0.4pre3
2.2 投票
(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)])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))
(2)加权投票
加权投票法是一种计入 权重 的投票方法,其等同于加权平均法。每个弱学习器的分类票数乘以权重,并将各个类别的加权票数求和,最大值对应的类别即最终类别。
(在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))
2.3 Stacking
pip install mlxtend
[in] ↓ ↓ ↓
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()
[out] ↓ ↓ ↓
Accuracy: 0.91 (+/- 0.07) [KNN]
Accuracy: 0.93 (+/- 0.05) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [Naive Bayes]
Accuracy: 0.93 (+/- 0.04) [Stacking Classifier]
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]
2.4 blending
[in] ↓ ↓ ↓
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import roc_auc_score
# 以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)))
[out] ↓ ↓ ↓
val auc Score: 1.000000
val auc Score: 1.000000
val auc Score: 1.000000
val auc Score: 1.000000
Val auc Score of Blending: 1.000000
3. 总结
- 简单平均和加权平均是常用的两种比赛中模型融合的方式。其优点是快速、简单。
- stacking常被广泛应用,是一“大杀器”,但其速度较慢,同时stacking多层提升幅度并不能抵消其带来的时间和内存消耗,所以实际环境中应用还是有一定的难度
- 比赛中将加权平均、stacking、blending等混用也是一种策略
三、学习问题和解答
本章节中提及到的模型融合方式较多,特别是后面“综合”、“stacking”、“blending”、“ boosting/bagging”等要学习的知识点较多,没有摸清楚其原理、流程等之前容易有混淆和对实操用法的不解,后来不仅看了原笔记文件中提供的参考链接,还另外单个搜索各方式对应的详解,参考了别人的理解思路,在自己作归纳总结,并加以比较。
四、学习思考与总结
学习打卡已接近尾声,在进行本次学习任务的时候发现自己其实task4、5的掌握程度不足,task5有部分需要运用到task4中的学习笔记,记忆也不够深刻。反思下来,在模型和、调参的部分学习有大大的不足,应该要尽快回顾笔记并对知识库作进一步的补充。(参考了别人的笔记之后,有自己的理解很重要!!,如果怕自己忘性大,应该勤做记录,方便回顾思考过程)
PS:官方推荐笔记很nice!要回顾深究!!
[2]
https://blog.csdn.net/wstcjf/article/details/77989963
[3]
https://blog.csdn.net/maqunfi/article/details/82220115
[4]
https://blog.csdn.net/sinat_35821976/article/details/83622594
[5]
https://blog.csdn.net/wuzhongqiang/article/details/105012739