数据竞赛中提高成绩主要有3个地方
特征工程
调参
模型融合
本节介绍用网格搜索来调参,它主要是指尝试我们关心的参数的所有可能组合。
交叉验证是在特定数据集上对给定算法进行评估的一种方法,是一种评估泛化性能的统计学方法,它比单次划分训练集和测试集的方法更加稳定、全面。在交叉验证中,数据被多次划分,并且需要训练多个模型。最常用的是k折交叉验证(k-fold cross-validation)。
但它通常与网格搜索等参数搜索的方法结合使用。因此,许多人用交叉验证(cross-validation)这一术语来通俗地指代带交叉验证的网格搜索。
最后介绍模型融合。
1. 网格搜索
GridSearchCV
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html
KFold
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html
网格搜索算法是一种通过遍历给定的参数组合来优化模型表现的方法。
以决策树为例,当我们确定了要使用决策树算法的时候,为了能够更好地拟合和预测,我们需要调整它的参数。在决策树算法中,我们通常选择的参数是决策树的最大深度。
于是我们会给出一系列的最大深度的值,比如 {'max_depth': [1,2,3,4,5]},我们会尽可能包含最优最大深度。
不过,我们如何知道哪一个最大深度的模型是最好的呢?我们需要一种可靠的评分方法,对每个最大深度的决策树模型都进行评分,这其中非常经典的一种方法就是交叉验证,下面我们就以K折交叉验证为例,详细介绍它的算法过程。
2. 交叉验证
首先我们先看一下数据集是如何分割的。我们拿到的原始数据集首先会按照一定的比例划分成训练集和测试集。比如下图,以8:2分割的数据集:
训练集用来训练我们的模型,它的作用就像我们平时做的练习题;测试集用来评估我们训练好的模型表现如何,它的作用像我们做的高考题,这是要绝对保密不能提前被模型看到的。
因此,在K折交叉验证中,我们用到的数据是训练集中的所有数据。我们将训练集的所有数据平均划分成K份(通常选择K=10),取第K份作为验证集,它的作用就像我们用来估计高考分数的模拟题,余下的K-1份作为交叉验证的训练集。
对于我们最开始选择的决策树的5个最大深度 ,以 max_depth=1 为例,我们先用第2-10份数据作为训练集训练模型,用第1份数据作为验证集对这次训练的模型进行评分,得到第一个分数;然后重新构建一个 max_depth=1 的决策树,用第1和3-10份数据作为训练集训练模型,用第2份数据作为验证集对这次训练的模型进行评分,得到第二个分数……以此类推,最后构建一个 max_depth=1 的决策树用第1-9份数据作为训练集训练模型,用第10份数据作为验证集对这次训练的模型进行评分,得到第十个分数。于是对于 max_depth=1 的决策树模型,我们训练了10次,验证了10次,得到了10个验证分数,然后计算这10个验证分数的平均分数,就是 max_depth=1 的决策树模型的最终验证分数。
对于 max_depth = 2,3,4,5 时,分别进行和 max_depth=1 相同的交叉验证过程,得到它们的最终验证分数。然后我们就可以对这5个最大深度的决策树的最终验证分数进行比较,分数最高的那一个就是最优最大深度,我们利用最优参数在全部训练集上训练一个新的模型,整个模型就是最优模型。
3. 模型融合
一、Voting
模型融合其实也没有想象的那么高大上,从最简单的Voting说起,这也可以说是一种模型融合。假设对于一个二分类问题,有3个基础模型,那么就采取投票制的方法,投票多者确定为最终的分类。
二、Averaging
对于回归问题,一个简单直接的思路是取平均。稍稍改进的方法是进行加权平均。权值可以用排序的方法确定,举个例子,比如A、B、C三种基本模型,模型效果进行排名,假设排名分别是1,2,3,那么给这三个模型赋予的权值分别是3/6、2/6、1/6
这两种方法看似简单,其实后面的高级算法也可以说是基于此而产生的,Bagging或者Boosting都是一种把许多弱分类器这样融合成强分类器的思想。
三、Bagging
Bagging就是采用有放回的方式进行抽样,用抽样的样本建立子模型,对子模型进行训练,这个过程重复多次,最后进行融合。大概分为这样两步:
重复K次
有放回地重复抽样建模
训练子模型
2.模型融合
分类问题:voting
回归问题:average
Bagging算法不用我们自己实现,随机森林就是基于Bagging算法的一个典型例子,采用的基分类器是决策树。R和python都集成好了,直接调用。
四、Boosting
Bagging算法可以并行处理,而Boosting的思想是一种迭代的方法,每一次训练的时候都更加关心分类错误的样例,给这些分类错误的样例增加更大的权重,下一次迭代的目标就是能够更容易辨别出上一轮分类错误的样例。最终将这些弱分类器进行加权相加。
五、Stacking
4. 代码实战
from sklearn.model_selection import GridSearchCV
params = {'penalty':['l2','l1'],'C':[2.0,3.0,5.0]}
svc = LinearSVC(dual=False)
clf = GridSearchCV(estimator=svc, param_grid=params, scoring = 'f1_macro', n_jobs=1, cv=3, verbose=3)
clf.fit(x_train,y_train)
print('最优参数:{}'.format(clf.best_params_))
from sklearn.svm import LinearSVC
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import f1_score
"""
进行K次训练;用K个模型分别对测试集进行预测,并得到K个结果,再进行结果的融合
"""
preds = []
i = 0
skf = StratifiedKFold(n_splits=10, random_state=1)
score_sum = 0
for train_idx, vali_idx in skf.split(x_train, y_train):
i += 1
"""获取训练集和验证集"""
f_train_x = x_train[train_idx]
f_train_y = y_train[train_idx]
f_vali_x = x_train[vali_idx]
f_vali_y = y_train[vali_idx]
"""训练分类器"""
classifier = LinearSVC()
classifier.fit(f_train_x, f_train_y)
"""对测试集进行预测"""
y_test = classifier.predict(x_test)
preds.append(y_test)
"""对验证集进行预测,并计算f1分数"""
pre_vali = classifier.predict(f_vali_x)
score_vali = f1_score(y_true=f_vali_y, y_pred=pre_vali, average='macro')
print("第{}折, 验证集分数:{}".format(i, score_vali))
score_sum += score_vali
score_mean = score_sum / i
print("第{}折后, 验证集分平均分数:{}".format(i, score_mean))
"""对K个模型的结果进行融合,融合策略:投票机制"""
print("开始对K个模型的结果进行融合")
preds_arr = np.array(preds).T
y_test = []
for pred in preds_arr:
result_vote = np.argmax(np.bincount(pred))
y_test.append(result_vote)
K个模型融合分数:0.7770647623109819
---------------------
作者:NLP_victor
来源:CSDN
原文:https://blog.csdn.net/IOT_victor/article/details/89319974
版权声明:本文为博主原创文章,转载请附上博文链接!