【数据竞赛】“达观杯”文本智能处理挑战赛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