【数据竞赛】“达观杯”文本智能处理挑战赛6——模型优化
文章目录
- 一、超参数
- 1、网格搜索
- 2、随机搜索
- 3、贝叶斯优化
- 二、Stacking
- 1、核心图解
- (1)构建新的训练集
- (2)构建新的测试集
- (3)最终的训练与预测
- 2、示例
- (1)构建新的训练集
- (2)构建新的测试集
- (3)多模型的处理
- (4)最终的训练与预测
- 三、实现
- 1、超参数调参
- 2、模型融合
一、超参数
优化可以分为参数优化和超参数优化。其中,可学习的参数通过优化算法可以进行优化;还有一类参数是用来定义模型结构或优化策略的,这类参数称为超参数(hyper-parameter)
超参数优化(Hyperparameter Optimization)主要存在两方面的困难。
- 超参数优化是一个组合优化问题,无法像一般参数那样通过梯度下降方法来优化,也没有一种通用有效的优化方法。
- 评估一组超参数配置(Configuration)的时间代价非常高,从而导致一些优化方法(比如演化算法(Evolution Algorithm))在超参数优化中难以应用。
对于超参数的设置,比较简单的方法有人工搜索、 网格搜索和随机搜索。
1、网格搜索
网格搜索(grid search) 是一种通过尝试所有超参数的组合来寻址合适一组超参数配置的方法。
假设总共有 KKK 个超参数,第 kkk 个超参数的可以取 mkm_kmk 个值。那么总共的配置组合数量为 m1×m2×...×mKm_1 ×m_2 ×...× m_Km1×m2×...×mK。如果超参数是连续的,需要根据超参数自身的特点进行离散化。
实现:sklearn.model_selection.GridSearchCV 官网文档链接
class sklearn.model_selection.GridSearchCV(estimator, param_grid, scoring=None, fit_params=None, n_jobs=None, iid=’warn’, refit=True, cv=’warn’, verbose=0, pre_dispatch=‘2*n_jobs’, error_score=’raise-deprecating’, return_train_score=’warn’)实际当中有用的参数,以clf表示我们的GridSearchCV对象
- clf.best_params_ 返回最好的参数
- clf.best_score_ 返回最好的测试分数,它的值和 clf.cv_results_['mean_test_score'][dt_grid.best_index_] 是相同的。
- clf.best_index_ 返回列表中分数最好的下表
- clf.best_estimator_ 返回最好的模型
- clf.cv_results_ 返回使用交叉验证进行搜索的结果,它本身又是一个字典,里面又有很多内容。
2、随机搜索
对超参数进行随机组合,然后选取一个性能最好的配置,这就是随机搜索(Random Search)。随机搜索在实践中更容易实现,一般会比网格搜索更加有效。
3、贝叶斯优化
贝叶斯优化(Bayesian optimization)是一种自适应的超参数搜索方法,根据当前已经试验的超参数组合,来预测下一个可能带来最大收益的组合。
常用的贝叶斯优化方法:时序模型优化(Sequential Model-Based Optimization,SMBO)
二、Stacking
概述:将个体机器学习器的结果结合在一起,即对学习器的结果再加上一层学习器。将训练集学习器的学习结果作为输入,将训练集的输出作为输出,重新训练一个学习器来得到最终结果。(也就是常说的两层)
术语:
- 弱学习器称为初级学习器,将用于结合的学习器称为次级学习器;
- 对于测试集,我们首先用初级学习器预测一次,得到次级学习器的输入样本,再用次级学习器预测一次,得到最终的预测结果。
1、核心图解
对于每一轮的 5-fold,Model 1都要做满5次的训练和预测。
(1)构建新的训练集
(2)构建新的测试集
(3)最终的训练与预测
2、示例
(1)构建新的训练集
Train Data有890行。(请对应图中的上层部分)
每1次的fold,都会生成 713行 小train, 178行 小test。我们用Model 1来训练 713行的小train,然后预测 178行 小test。预测的结果是长度为 178 的预测值。
这样的动作走5次! 长度为178 的预测值 X 5 = 890 预测值,刚好和Train data长度吻合。这个890预测值是Model 1产生的,我们先存着,因为,一会让它将是第二层模型的训练来源。
重点:这一步产生的预测值我们可以转成 890 X 1 (890 行,1列),记作 P1 (大写P)
(2)构建新的测试集
Test Data 有 418 行。(请对应图中的下层部分,对对对,绿绿的那些框框)
每1次的fold,713行 小train训练出来的Model 1要去预测我们全部的Test Data(全部!因为Test Data没有加入5-fold,所以每次都是全部!)。此时,Model 1的预测结果是长度为418的预测值。
这样的动作走5次!我们可以得到一个 5 X 418 的预测值矩阵。然后我们根据行来就平均值,最后得到一个 1 X 418 的平均预测值。
重点:这一步产生的预测值我们可以转成 418 X 1 (418行,1列),记作 p1 (小写p)
(3)多模型的处理
走到这里,你的第一层的Model 1完成了它的使命。
第一层还会有其他Model的,比如Model 2,同样的走一遍, 我们有可以得到 890 X 1 (P2) 和 418 X 1 (p2) 列预测值。
这样吧,假设你第一层有3个模型,这样你就会得到:
来自5-fold的预测值矩阵 890 X 3,(P1,P2, P3) 和 来自Test Data预测值矩阵 418 X 3, (p1, p2, p3)。
(4)最终的训练与预测
来自5-fold的预测值矩阵 890 X 3 作为你的Train Data,训练第二层的模型
来自Test Data预测值矩阵 418 X 3 就是你的Test Data,用训练好的模型来预测他们吧。
三、实现
1、超参数调参
# -*- coding: utf-8 -*- import pandas as pd import pickle import lightgbm as lgb from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model.logistic import LogisticRegression from sklearn.svm import LinearSVC from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_scorefp = open('./features/data_tfidf_train.pkl', 'rb') x_train,y_train = pickle.load(fp) x_train, x_test, y_train, y_test = train_test_split(x_train[:5000], y_train[:5000], test_size=0.3, random_state=2019)print('Start Training:Logistic Regression...') lr_grid={'C':list((100,120,140))} lr = GridSearchCV(LogisticRegression(),param_grid = lr_grid, cv = 5) lr.fit(x_train, y_train) print('Best param is ', lr.best_params_) print('The best score is ', lr.best_score_)print('Start Training:SVM...') svm_grid={'C':list((1, 5, 10))} svm = GridSearchCV(LinearSVC(),param_grid = svm_grid, cv = 5) svm.fit(x_train, y_train) print('Best param is ', svm.best_params_) print('The best score is ', svm.best_score_)print('Start Training:LightGBM...') lgbm_grid={'num_leaves':list((25, 30, 35)), 'learning_rate':list((0.2, 0.1, 0.005)), 'n_estimators':list((10, 20, 50))} lgbm = GridSearchCV(lgb.sklearn.LGBMClassifier(),param_grid = lgbm_grid, cv = 5) lgbm.fit(x_train, y_train) print('Best param is ', lgbm.best_params_) print('The best score is ', lgbm.best_score_)输出结果
结果后续补上,运行时间太长。。。。
2、模型融合
## 使用多模型实现 from mlxtend.classifier import StackingClassifierlr_model = LogisticRegression() svm_model = LinearSVC() lgbm_model = lgb.sklearn.LGBMClassifier() dt_model = DecisionTreeClassifier()sclf = StackingClassifier(classifiers=[lr_model,svm_model,lgbm_model],meta_classifier=dt_model) sclf.fit(x_train,y_train)for clf,label in zip([lr_model,svm_model,lgbm_model,sclf],['逻辑回归','SVM','LightGBM','StackingClassifier']):scores = cross_val_score(clf,x_train,y_train,cv = 5,scoring='accuracy')print("Accuracy: %0.2f (+/- %0.2f) [%s]"% (scores.mean(), scores.std(), label))结果输出
Accuracy: 0.77 (+/- 0.01) [逻辑回归] Accuracy: 0.80 (+/- 0.00) [SVM] Accuracy: 0.79 (+/- 0.01) [LightGBM] Accuracy: 0.78 (+/- 0.01) [StackingClassifier]总结
以上是生活随笔为你收集整理的【数据竞赛】“达观杯”文本智能处理挑战赛6——模型优化的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 集成学习(ensemble learni
- 下一篇: 集成学习(ensemble learni