日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【算法竞赛学习】心跳信号分类预测-建模与调参

發布時間:2023/12/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法竞赛学习】心跳信号分类预测-建模与调参 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Task4 建模與調參

此部分為零基礎入門數據挖掘之心電圖分類的 Task4 建模調參部分,帶你來了解各種模型以及模型的評價和調參策略,歡迎大家后續多多交流。

賽題:零基礎入門數據挖掘 - 心電圖分類預測

項目地址:

比賽地址:

4.1 學習目標

  • 學習機器學習模型的建模過程與調參流程
  • 完成相應學習打卡任務

4.2 內容介紹

  • 邏輯回歸模型:

    • 理解邏輯回歸模型;
    • 邏輯回歸模型的應用;
    • 邏輯回歸的優缺點;
  • 樹模型:

    • 理解樹模型;
    • 樹模型的應用;
    • 樹模型的優缺點;
  • 集成模型

    • 基于bagging思想的集成模型
      • 隨機森林模型
    • 基于boosting思想的集成模型
      • XGBoost模型
      • LightGBM模型
      • CatBoost模型
  • 模型對比與性能評估:

    • 回歸模型/樹模型/集成模型;
    • 模型評估方法;
    • 模型評價結果;
  • 模型調參:

    • 貪心調參方法;

    • 網格調參方法;

    • 貝葉斯調參方法;

4.3 模型相關原理介紹

由于相關算法原理篇幅較長,本文推薦了一些博客與教材供初學者們進行學習。

4.3.1 邏輯回歸模型

https://blog.csdn.net/han_xiaoyang/article/details/49123419

4.3.2 決策樹模型

https://blog.csdn.net/c406495762/article/details/76262487

4.3.3 GBDT模型

https://zhuanlan.zhihu.com/p/45145899

4.3.4 XGBoost模型

https://blog.csdn.net/wuzhongqiang/article/details/104854890

4.3.5 LightGBM模型

https://blog.csdn.net/wuzhongqiang/article/details/105350579

4.3.6 Catboost模型

https://mp.weixin.qq.com/s/xloTLr5NJBgBspMQtxPoFA

4.3.7 時間序列模型(選學)

RNN:https://zhuanlan.zhihu.com/p/45289691

LSTM:https://zhuanlan.zhihu.com/p/83496936

4.3.8 推薦教材:

《機器學習》 https://book.douban.com/subject/26708119/

《統計學習方法》 https://book.douban.com/subject/10590856/

《面向機器學習的特征工程》 https://book.douban.com/subject/26826639/

《信用評分模型技術與應用》https://book.douban.com/subject/1488075/

《數據化風控》https://book.douban.com/subject/30282558/

4.4 模型對比與性能評估

4.4.1 邏輯回歸

  • 優點

    • 訓練速度較快,分類的時候,計算量僅僅只和特征的數目相關;
    • 簡單易理解,模型的可解釋性非常好,從特征的權重可以看到不同的特征對最后結果的影響;
    • 適合二分類問題,不需要縮放輸入特征;
    • 內存資源占用小,只需要存儲各個維度的特征值;
  • 缺點

    • 邏輯回歸需要預先處理缺失值和異常值【可參考task3特征工程】;

    • 不能用Logistic回歸去解決非線性問題,因為Logistic的決策面是線性的;

    • 對多重共線性數據較為敏感,且很難處理數據不平衡的問題;

    • 準確率并不是很高,因為形式非常簡單,很難去擬合數據的真實分布;

4.4.2 決策樹模型

  • 優點
    • 簡單直觀,生成的決策樹可以可視化展示
    • 數據不需要預處理,不需要歸一化,不需要處理缺失數據
    • 既可以處理離散值,也可以處理連續值
  • 缺點
    • 決策樹算法非常容易過擬合,導致泛化能力不強(可進行適當的剪枝)
    • 采用的是貪心算法,容易得到局部最優解

4.4.3 集成模型集成方法(ensemble method)

通過組合多個學習器來完成學習任務,通過集成方法,可以將多個弱學習器組合成一個強分類器,因此集成學習的泛化能力一般比單一分類器要好。

集成方法主要包括Bagging和Boosting,Bagging和Boosting都是將已有的分類或回歸算法通過一定方式組合起來,形成一個更加強大的分類。兩種方法都是把若干個分類器整合為一個分類器的方法,只是整合的方式不一樣,最終得到不一樣的效果。常見的基于Baggin思想的集成模型有:隨機森林、基于Boosting思想的集成模型有:Adaboost、GBDT、XgBoost、LightGBM等。

Baggin和Boosting的區別總結如下:

  • 樣本選擇上: Bagging方法的訓練集是從原始集中有放回的選取,所以從原始集中選出的各輪訓練集之間是獨立的;而Boosting方法需要每一輪的訓練集不變,只是訓練集中每個樣本在分類器中的權重發生變化。而權值是根據上一輪的分類結果進行調整
  • 樣例權重上: Bagging方法使用均勻取樣,所以每個樣本的權重相等;而Boosting方法根據錯誤率不斷調整樣本的權值,錯誤率越大則權重越大
  • 預測函數上: Bagging方法中所有預測函數的權重相等;而Boosting方法中每個弱分類器都有相應的權重,對于分類誤差小的分類器會有更大的權重
  • 并行計算上: Bagging方法中各個預測函數可以并行生成;而Boosting方法各個預測函數只能順序生成,因為后一個模型參數需要前一輪模型的結果。

4.4.4 模型評估方法

對于模型來說,其在訓練集上面的誤差我們稱之為訓練誤差或者經驗誤差,而在測試集上的誤差稱之為測試誤差

對于我們來說,我們更關心的是模型對于新樣本的學習能力,即我們希望通過對已有樣本的學習,盡可能的將所有潛在樣本的普遍規律學到手,而如果模型對訓練樣本學的太好,則有可能把訓練樣本自身所具有的一些特點當做所有潛在樣本的普遍特點,這時候我們就會出現過擬合的問題。

因此我們通常將已有的數據集劃分為訓練集和測試集兩部分,其中訓練集用來訓練模型,而測試集則是用來評估模型對于新樣本的判別能力。

對于數據集的劃分,我們通常要保證滿足以下兩個條件:

  • 訓練集和測試集的分布要與樣本真實分布一致,即訓練集和測試集都要保證是從樣本真實分布中獨立同分布采樣而得;
  • 訓練集和測試集要互斥

對于數據集的劃分有三種方法:留出法,交叉驗證法和自助法,下面挨個介紹:

  • ①留出法

    留出法是直接將數據集D劃分為兩個互斥的集合,其中一個集合作為訓練集S,另一個作為測試集T。需要注意的是在劃分的時候要盡可能保證數據分布的一致性,即避免因數據劃分過程引入額外的偏差而對最終結果產生影響。為了保證數據分布的一致性,通常我們采用分層采樣的方式來對數據進行采樣。

    Tips: 通常,會將數據集D中大約2/3~4/5的樣本作為訓練集,其余的作為測試集。

  • ②交叉驗證法

    k折交叉驗證通常將數據集D分為k份,其中k-1份作為訓練集,剩余的一份作為測試集,這樣就可以獲得k組訓練/測試集,可以進行k次訓練與測試,最終返回的是k個測試結果的均值。交叉驗證中數據集的劃分依然是依據分層采樣的方式來進行。

    對于交叉驗證法,其k值的選取往往決定了評估結果的穩定性和保真性,通常k值選取10。

    當k=1的時候,我們稱之為留一法

  • ③自助法

    我們每次從數據集D中取一個樣本作為訓練集中的元素,然后把該樣本放回,重復該行為m次,這樣我們就可以得到大小為m的訓練集,在這里面有的樣本重復出現,有的樣本則沒有出現過,我們把那些沒有出現過的樣本作為測試集。

    進行這樣采樣的原因是因為在D中約有36.8%的數據沒有在訓練集中出現過。留出法與交叉驗證法都是使用分層采樣的方式進行數據采樣與劃分,而自助法則是使用有放回重復采樣的方式進行數據采樣

數據集劃分總結

  • 對于數據量充足的時候,通常采用留出法或者k折交叉驗證法來進行訓練/測試集的劃分;
  • 對于數據集小且難以有效劃分訓練/測試集時使用自助法
  • 對于數據集小且可有效劃分的時候最好使用留一法來進行劃分,因為這種方法最為準確

4.4.5 模型評價標準

對于本次比賽,我們選用自定義的abs-sum作為模型評價標準。

4.5 代碼示例

4.5.1 導入相關關和相關設置

import pandas as pd import numpy as np from sklearn.metrics import f1_scoreimport os import seaborn as sns import matplotlib.pyplot as pltimport warnings warnings.filterwarnings("ignore")

4.5.2 讀取數據

reduce_mem_usage 函數通過調整數據類型,幫助我們減少數據在內存中占用的空間

def reduce_mem_usage(df):start_mem = df.memory_usage().sum() / 1024**2 print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))for col in df.columns:col_type = df[col].dtypeif col_type != object:c_min = df[col].min()c_max = df[col].max()if str(col_type)[:3] == 'int':if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:df[col] = df[col].astype(np.int8)elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:df[col] = df[col].astype(np.int16)elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:df[col] = df[col].astype(np.int32)elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:df[col] = df[col].astype(np.int64) else:if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:df[col] = df[col].astype(np.float16)elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:df[col] = df[col].astype(np.float32)else:df[col] = df[col].astype(np.float64)else:df[col] = df[col].astype('category')end_mem = df.memory_usage().sum() / 1024**2 print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))return df # 讀取數據 data = pd.read_csv('data/train.csv') # 簡單預處理 data_list = [] for items in data.values:data_list.append([items[0]] + [float(i) for i in items[1].split(',')] + [items[2]])data = pd.DataFrame(np.array(data_list)) data.columns = ['id'] + ['s_'+str(i) for i in range(len(data_list[0])-2)] + ['label']data = reduce_mem_usage(data) Memory usage of dataframe is 157.93 MB Memory usage after optimization is: 39.67 MB Decreased by 74.9%

4.5.3 簡單建模

基于樹模型的算法特性,異常值、缺失值處理可以跳過,但是對于業務較為了解的同學也可以自己對缺失異常值進行處理,效果可能會更優于模型處理的結果。

注:以下建模的據集并未構造任何特征,直接使用原特征。本次主要任務還是模建模調參。

建模之前的預操作

from sklearn.model_selection import KFold # 分離數據集,方便進行交叉驗證 X_train = data.drop(['id','label'], axis=1) y_train = data['label']# 5折交叉驗證 folds = 5 seed = 2021 kf = KFold(n_splits=folds, shuffle=True, random_state=seed)

因為樹模型中沒有f1-score評價指標,所以需要自定義評價指標,在模型迭代中返回驗證集f1-score變化情況。

def f1_score_vali(preds, data_vali):labels = data_vali.get_label()preds = np.argmax(preds.reshape(4, -1), axis=0)score_vali = f1_score(y_true=labels, y_pred=preds, average='macro')return 'f1_score', score_vali, True

使用Lightgbm進行建模

"""對訓練集數據進行劃分,分成訓練集和驗證集,并進行相應的操作""" from sklearn.model_selection import train_test_split import lightgbm as lgb # 數據集劃分 X_train_split, X_val, y_train_split, y_val = train_test_split(X_train, y_train, test_size=0.2) train_matrix = lgb.Dataset(X_train_split, label=y_train_split) valid_matrix = lgb.Dataset(X_val, label=y_val)params = {"learning_rate": 0.1,"boosting": 'gbdt', "lambda_l2": 0.1,"max_depth": -1,"num_leaves": 128,"bagging_fraction": 0.8,"feature_fraction": 0.8,"metric": None,"objective": "multiclass","num_class": 4,"nthread": 10,"verbose": -1, }"""使用訓練集數據進行模型訓練""" model = lgb.train(params, train_set=train_matrix, valid_sets=valid_matrix, num_boost_round=2000, verbose_eval=50, early_stopping_rounds=200,feval=f1_score_vali) Training until validation scores don't improve for 200 rounds [50] valid_0's multi_logloss: 0.0535465 valid_0's f1_score: 0.953675 [100] valid_0's multi_logloss: 0.0484882 valid_0's f1_score: 0.961373 [150] valid_0's multi_logloss: 0.0507799 valid_0's f1_score: 0.962653 [200] valid_0's multi_logloss: 0.0531035 valid_0's f1_score: 0.963224 [250] valid_0's multi_logloss: 0.0547945 valid_0's f1_score: 0.963721 Early stopping, best iteration is: [88] valid_0's multi_logloss: 0.0482441 valid_0's f1_score: 0.959676

對驗證集進行預測

val_pre_lgb = model.predict(X_val, num_iteration=model.best_iteration) preds = np.argmax(val_pre_lgb, axis=1) score = f1_score(y_true=y_val, y_pred=preds, average='macro') print('未調參前lightgbm單模型在驗證集上的f1:{}'.format(score)) 未調參前lightgbm單模型在驗證集上的f1:0.9596756568138634

更進一步的,使用5折交叉驗證進行模型性能評估

"""使用lightgbm 5折交叉驗證進行建模預測""" cv_scores = [] for i, (train_index, valid_index) in enumerate(kf.split(X_train, y_train)):print('************************************ {} ************************************'.format(str(i+1)))X_train_split, y_train_split, X_val, y_val = X_train.iloc[train_index], y_train[train_index], X_train.iloc[valid_index], y_train[valid_index]train_matrix = lgb.Dataset(X_train_split, label=y_train_split)valid_matrix = lgb.Dataset(X_val, label=y_val)params = {"learning_rate": 0.1,"boosting": 'gbdt', "lambda_l2": 0.1,"max_depth": -1,"num_leaves": 128,"bagging_fraction": 0.8,"feature_fraction": 0.8,"metric": None,"objective": "multiclass","num_class": 4,"nthread": 10,"verbose": -1,}model = lgb.train(params, train_set=train_matrix, valid_sets=valid_matrix, num_boost_round=2000, verbose_eval=100, early_stopping_rounds=200,feval=f1_score_vali)val_pred = model.predict(X_val, num_iteration=model.best_iteration)val_pred = np.argmax(val_pred, axis=1)cv_scores.append(f1_score(y_true=y_val, y_pred=val_pred, average='macro'))print(cv_scores)print("lgb_scotrainre_list:{}".format(cv_scores)) print("lgb_score_mean:{}".format(np.mean(cv_scores))) print("lgb_score_std:{}".format(np.std(cv_scores))) ... lgb_scotrainre_list:[0.9674515729721614, 0.9656700872844327, 0.9700043639844769, 0.9655663272378014, 0.9631137190307674] lgb_score_mean:0.9663612141019279 lgb_score_std:0.0022854824074775683

4.5.4 模型調參

  • 1. 貪心調參

    先使用當前對模型影響最大的參數進行調優,達到當前參數下的模型最優化,再使用對模型影響次之的參數進行調優,如此下去,直到所有的參數調整完畢。

    這個方法的缺點就是可能會調到局部最優而不是全局最優,但是只需要一步一步的進行參數最優化調試即可,容易理解。

    需要注意的是在樹模型中參數調整的順序,也就是各個參數對模型的影響程度,這里列舉一下日常調參過程中常用的參數和調參順序:

    • ①:max_depth、num_leaves
    • ②:min_data_in_leaf、min_child_weight
    • ③:bagging_fraction、 feature_fraction、bagging_freq
    • ④:reg_lambda、reg_alpha
    • ⑤:min_split_gain
    from sklearn.model_selection import cross_val_score # 調objective best_obj = dict() for obj in objective:model = LGBMRegressor(objective=obj)"""預測并計算roc的相關指標"""score = cross_val_score(model, X_train, y_train, cv=5, scoring='f1').mean()best_obj[obj] = score# num_leaves best_leaves = dict() for leaves in num_leaves:model = LGBMRegressor(objective=min(best_obj.items(), key=lambda x:x[1])[0], num_leaves=leaves)"""預測并計算roc的相關指標"""score = cross_val_score(model, X_train, y_train, cv=5, scoring='f1').mean()best_leaves[leaves] = score# max_depth best_depth = dict() for depth in max_depth:model = LGBMRegressor(objective=min(best_obj.items(), key=lambda x:x[1])[0],num_leaves=min(best_leaves.items(), key=lambda x:x[1])[0],max_depth=depth)"""預測并計算roc的相關指標"""score = cross_val_score(model, X_train, y_train, cv=5, scoring='f1').mean()best_depth[depth] = score""" 可依次將模型的參數通過上面的方式進行調整優化,并且通過可視化觀察在每一個最優參數下模型的得分情況 """

    可依次將模型的參數通過上面的方式進行調整優化,并且通過可視化觀察在每一個最優參數下模型的得分情況

  • 2. 網格搜索

    sklearn 提供GridSearchCV用于進行網格搜索,只需要把模型的參數輸進去,就能給出最優化的結果和參數。相比起貪心調參,網格搜索的結果會更優,但是網格搜索只適合于小數據集,一旦數據的量級上去了,很難得出結果。

    同樣以Lightgbm算法為例,進行網格搜索調參:

    """通過網格搜索確定最優參數""" from sklearn.model_selection import GridSearchCVdef get_best_cv_params(learning_rate=0.1, n_estimators=581, num_leaves=31, max_depth=-1, bagging_fraction=1.0, feature_fraction=1.0, bagging_freq=0, min_data_in_leaf=20, min_child_weight=0.001, min_split_gain=0, reg_lambda=0, reg_alpha=0, param_grid=None):# 設置5折交叉驗證cv_fold = KFold(n_splits=5, shuffle=True, random_state=2021)model_lgb = lgb.LGBMClassifier(learning_rate=learning_rate,n_estimators=n_estimators,num_leaves=num_leaves,max_depth=max_depth,bagging_fraction=bagging_fraction,feature_fraction=feature_fraction,bagging_freq=bagging_freq,min_data_in_leaf=min_data_in_leaf,min_child_weight=min_child_weight,min_split_gain=min_split_gain,reg_lambda=reg_lambda,reg_alpha=reg_alpha,n_jobs= 8)f1 = make_scorer(f1_score, average='micro')grid_search = GridSearchCV(estimator=model_lgb, cv=cv_fold,param_grid=param_grid,scoring=f1)grid_search.fit(X_train, y_train)print('模型當前最優參數為:{}'.format(grid_search.best_params_))print('模型當前最優得分為:{}'.format(grid_search.best_score_)) """以下代碼未運行,耗時較長,請謹慎運行,且每一步的最優參數需要在下一步進行手動更新,請注意"""""" 需要注意一下的是,除了獲取上面的獲取num_boost_round時候用的是原生的lightgbm(因為要用自帶的cv) 下面配合GridSearchCV時必須使用sklearn接口的lightgbm。 """ """設置n_estimators 為581,調整num_leaves和max_depth,這里選擇先粗調再細調""" lgb_params = {'num_leaves': range(10, 80, 5), 'max_depth': range(3,10,2)} get_best_cv_params(learning_rate=0.1, n_estimators=581, num_leaves=None, max_depth=None, min_data_in_leaf=20, min_child_weight=0.001,bagging_fraction=1.0, feature_fraction=1.0, bagging_freq=0, min_split_gain=0, reg_lambda=0, reg_alpha=0, param_grid=lgb_params)"""num_leaves為30,max_depth為7,進一步細調num_leaves和max_depth""" lgb_params = {'num_leaves': range(25, 35, 1), 'max_depth': range(5,9,1)} get_best_cv_params(learning_rate=0.1, n_estimators=85, num_leaves=None, max_depth=None, min_data_in_leaf=20, min_child_weight=0.001,bagging_fraction=1.0, feature_fraction=1.0, bagging_freq=0, min_split_gain=0, reg_lambda=0, reg_alpha=0, param_grid=lgb_params)""" 確定min_data_in_leaf為45,min_child_weight為0.001 ,下面進行bagging_fraction、feature_fraction和bagging_freq的調參 """ lgb_params = {'bagging_fraction': [i/10 for i in range(5,10,1)], 'feature_fraction': [i/10 for i in range(5,10,1)],'bagging_freq': range(0,81,10)} get_best_cv_params(learning_rate=0.1, n_estimators=85, num_leaves=29, max_depth=7, min_data_in_leaf=45, min_child_weight=0.001,bagging_fraction=None, feature_fraction=None, bagging_freq=None, min_split_gain=0, reg_lambda=0, reg_alpha=0, param_grid=lgb_params)""" 確定bagging_fraction為0.4、feature_fraction為0.6、bagging_freq為 ,下面進行reg_lambda、reg_alpha的調參 """ lgb_params = {'reg_lambda': [0,0.001,0.01,0.03,0.08,0.3,0.5], 'reg_alpha': [0,0.001,0.01,0.03,0.08,0.3,0.5]} get_best_cv_params(learning_rate=0.1, n_estimators=85, num_leaves=29, max_depth=7, min_data_in_leaf=45, min_child_weight=0.001,bagging_fraction=0.9, feature_fraction=0.9, bagging_freq=40, min_split_gain=0, reg_lambda=None, reg_alpha=None, param_grid=lgb_params)""" 確定reg_lambda、reg_alpha都為0,下面進行min_split_gain的調參 """ lgb_params = {'min_split_gain': [i/10 for i in range(0,11,1)]} get_best_cv_params(learning_rate=0.1, n_estimators=85, num_leaves=29, max_depth=7, min_data_in_leaf=45, min_child_weight=0.001,bagging_fraction=0.9, feature_fraction=0.9, bagging_freq=40, min_split_gain=None, reg_lambda=0, reg_alpha=0, param_grid=lgb_params) """ 參數確定好了以后,我們設置一個比較小的learning_rate 0.005,來確定最終的num_boost_round """ # 設置5折交叉驗證 # cv_fold = StratifiedKFold(n_splits=5, random_state=0, shuffle=True, ) final_params = {'boosting_type': 'gbdt','learning_rate': 0.01,'num_leaves': 29,'max_depth': 7,'objective': 'multiclass','num_class': 4,'min_data_in_leaf':45,'min_child_weight':0.001,'bagging_fraction': 0.9,'feature_fraction': 0.9,'bagging_freq': 40,'min_split_gain': 0,'reg_lambda':0,'reg_alpha':0,'nthread': 6}cv_result = lgb.cv(train_set=lgb_train,early_stopping_rounds=20,num_boost_round=5000,nfold=5,stratified=True,shuffle=True,params=final_params,feval=f1_score_vali,seed=0,)

    在實際調整過程中,可先設置一個較大的學習率(上面的例子中0.1),通過Lgb原生的cv函數進行樹個數的確定,之后再通過上面的實例代碼進行參數的調整優化。

    最后針對最優的參數設置一個較小的學習率(例如0.05),同樣通過cv函數確定樹的個數,確定最終的參數。

    需要注意的是,針對大數據集,上面每一層參數的調整都需要耗費較長時間,

  • 貝葉斯調參

    在使用之前需要先安裝包bayesian-optimization,運行如下命令即可:

    pip install bayesian-optimization

    貝葉斯調參的主要思想是:給定優化的目標函數(廣義的函數,只需指定輸入和輸出即可,無需知道內部結構以及數學性質),通過不斷地添加樣本點來更新目標函數的后驗分布(高斯過程,直到后驗分布基本貼合于真實分布)。簡單的說,就是考慮了上一次參數的信息,從而更好的調整當前的參數。

    貝葉斯調參的步驟如下:

    • 定義優化函數(rf_cv)
    • 建立模型
    • 定義待優化的參數
    • 得到優化結果,并返回要優化的分數指標
    from sklearn.model_selection import cross_val_score"""定義優化函數""" def rf_cv_lgb(num_leaves, max_depth, bagging_fraction, feature_fraction, bagging_freq, min_data_in_leaf, min_child_weight, min_split_gain, reg_lambda, reg_alpha):# 建立模型model_lgb = lgb.LGBMClassifier(boosting_type='gbdt', objective='multiclass', num_class=4,learning_rate=0.1, n_estimators=5000,num_leaves=int(num_leaves), max_depth=int(max_depth), bagging_fraction=round(bagging_fraction, 2), feature_fraction=round(feature_fraction, 2),bagging_freq=int(bagging_freq), min_data_in_leaf=int(min_data_in_leaf),min_child_weight=min_child_weight, min_split_gain=min_split_gain,reg_lambda=reg_lambda, reg_alpha=reg_alpha,n_jobs= 8)f1 = make_scorer(f1_score, average='micro')val = cross_val_score(model_lgb, X_train_split, y_train_split, cv=5, scoring=f1).mean()return val from bayes_opt import BayesianOptimization """定義優化參數""" bayes_lgb = BayesianOptimization(rf_cv_lgb, {'num_leaves':(10, 200),'max_depth':(3, 20),'bagging_fraction':(0.5, 1.0),'feature_fraction':(0.5, 1.0),'bagging_freq':(0, 100),'min_data_in_leaf':(10,100),'min_child_weight':(0, 10),'min_split_gain':(0.0, 1.0),'reg_alpha':(0.0, 10),'reg_lambda':(0.0, 10),} )"""開始優化""" bayes_lgb.maximize(n_iter=10) | iter | target | baggin... | baggin... | featur... | max_depth | min_ch... | min_da... | min_sp... | num_le... | reg_alpha | reg_la... | | 1 | 0.9785 | 0.5174 | 10.78 | 0.8746 | 10.15 | 4.288 | 48.97 | 0.2337 | 42.83 | 6.551 | 9.015 | | 2 | 0.9778 | 0.6777 | 41.77 | 0.5291 | 12.15 | 4.16 | 26.39 | 0.2461 | 55.78 | 6.528 | 0.6003 | | 3 | 0.9745 | 0.5825 | 68.77 | 0.5932 | 8.36 | 9.296 | 77.74 | 0.7946 | 79.12 | 3.045 | 5.593 | | 4 | 0.9802 | 0.9669 | 78.34 | 0.77 | 19.68 | 9.886 | 66.34 | 0.255 | 161.1 | 4.727 | 8.18 | | 5 | 0.9836 | 0.9897 | 51.9 | 0.9737 | 16.82 | 2.001 | 42.1 | 0.03563 | 134.2 | 3.437 | 1.368 | | 6 | 0.9749 | 0.5575 | 46.2 | 0.6518 | 15.9 | 7.817 | 34.12 | 0.341 | 153.2 | 7.144 | 7.899 | | 7 | 0.9793 | 0.9644 | 55.08 | 0.9795 | 18.5 | 2.085 | 41.22 | 0.7031 | 129.9 | 3.369 | 2.717 | | 8 | 0.9819 | 0.5926 | 58.23 | 0.6149 | 16.81 | 2.911 | 39.91 | 0.1699 | 137.3 | 2.685 | 2.891 | | 9 | 0.983 | 0.7796 | 50.38 | 0.7261 | 17.87 | 3.499 | 37.59 | 0.1404 | 136.1 | 2.442 | 6.621 | | 10 | 0.9843 | 0.638 | 49.32 | 0.9282 | 11.33 | 6.504 | 43.21 | 0.288 | 137.7 | 0.2083 | 6.966 | | 11 | 0.9798 | 0.8196 | 47.05 | 0.5845 | 9.075 | 2.965 | 46.16 | 0.3984 | 131.6 | 3.634 | 2.601 | | 12 | 0.9726 | 0.7688 | 37.57 | 0.9811 | 10.26 | 1.239 | 17.54 | 0.9651 | 46.5 | 8.834 | 6.276 | | 13 | 0.9836 | 0.5214 | 48.3 | 0.8203 | 19.13 | 3.129 | 35.47 | 0.08455 | 138.2 | 2.345 | 9.691 | | 14 | 0.9738 | 0.5617 | 45.75 | 0.8648 | 18.88 | 4.383 | 46.88 | 0.9315 | 141.8 | 4.968 | 5.563 | | 15 | 0.9807 | 0.8046 | 47.05 | 0.6449 | 12.38 | 0.3744 | 41.13 | 0.6808 | 138.7 | 0.8521 | 9.461 | ================================================================================================================================================= """顯示優化結果""" bayes_lgb.max {'target': 0.9842625,'params': {'bagging_fraction': 0.6379596054685973,'bagging_freq': 49.319589248277715,'feature_fraction': 0.9282486828608231,'max_depth': 11.32826513626976,'min_child_weight': 6.5044214037514845,'min_data_in_leaf': 43.211716584925405,'min_split_gain': 0.28802399981965143,'num_leaves': 137.7332804262704,'reg_alpha': 0.2082701560002398,'reg_lambda': 6.966270735649479}}

    參數優化完成后,我們可以根據優化后的參數建立新的模型,降低學習率并尋找最優模型迭代次數

    """調整一個較小的學習率,并通過cv函數確定當前最優的迭代次數""" base_params_lgb = {'boosting_type': 'gbdt','objective': 'multiclass','num_class': 4,'learning_rate': 0.01,'num_leaves': 138,'max_depth': 11,'min_data_in_leaf': 43,'min_child_weight':6.5,'bagging_fraction': 0.64,'feature_fraction': 0.93,'bagging_freq': 49,'reg_lambda': 7,'reg_alpha': 0.21,'min_split_gain': 0.288,'nthread': 10,'verbose': -1, }cv_result_lgb = lgb.cv(train_set=train_matrix,early_stopping_rounds=1000, num_boost_round=20000,nfold=5,stratified=True,shuffle=True,params=base_params_lgb,feval=f1_score_vali,seed=0 ) print('迭代次數{}'.format(len(cv_result_lgb['f1_score-mean']))) print('最終模型的f1為{}'.format(max(cv_result_lgb['f1_score-mean']))) 迭代次數4833 最終模型的f1為0.961641452120875

    模型參數已經確定,建立最終模型并對驗證集進行驗證

    import lightgbm as lgb """使用lightgbm 5折交叉驗證進行建模預測""" cv_scores = [] for i, (train_index, valid_index) in enumerate(kf.split(X_train, y_train)):print('************************************ {} ************************************'.format(str(i+1)))X_train_split, y_train_split, X_val, y_val = X_train.iloc[train_index], y_train[train_index], X_train.iloc[valid_index], y_train[valid_index]train_matrix = lgb.Dataset(X_train_split, label=y_train_split)valid_matrix = lgb.Dataset(X_val, label=y_val)params = {'boosting_type': 'gbdt','objective': 'multiclass','num_class': 4,'learning_rate': 0.01,'num_leaves': 138,'max_depth': 11,'min_data_in_leaf': 43,'min_child_weight':6.5,'bagging_fraction': 0.64,'feature_fraction': 0.93,'bagging_freq': 49,'reg_lambda': 7,'reg_alpha': 0.21,'min_split_gain': 0.288,'nthread': 10,'verbose': -1,}model = lgb.train(params, train_set=train_matrix, num_boost_round=4833, valid_sets=valid_matrix, verbose_eval=1000, early_stopping_rounds=200, feval=f1_score_vali)val_pred = model.predict(X_val, num_iteration=model.best_iteration)val_pred = np.argmax(val_pred, axis=1)cv_scores.append(f1_score(y_true=y_val, y_pred=val_pred, average='macro'))print(cv_scores)print("lgb_scotrainre_list:{}".format(cv_scores)) print("lgb_score_mean:{}".format(np.mean(cv_scores))) print("lgb_score_std:{}".format(np.std(cv_scores))) ... lgb_scotrainre_list:[0.9615056903324599, 0.9597829114711733, 0.9644760387635415, 0.9622009947666585, 0.9607941521618003] lgb_score_mean:0.9617519574991267 lgb_score_std:0.0015797109890455313
  • 模型調參小總結

    • 集成模型內置的cv函數可以較快的進行單一參數的調節,一般可以用來優先確定樹模型的迭代次數

    • 數據量較大的時候(例如本次項目的數據),網格搜索調參會特別特別慢,不建議嘗試

    • 集成模型中原生庫和sklearn下的庫部分參數不一致,需要注意,具體可以參考xgb和lgb的官方API

      xgb原生庫API,sklearn庫下xgbAPI

      lgb原生庫API, sklearn庫下lgbAPI

4.6 經驗總結

在本節中,我們主要完成了建模與調參的工作,首先在建模的過程中通過劃分數據集、交叉驗證等方式對模型的性能進行評估驗證

最后我們對模型進行調參,這部分介紹了貪心調參、網格搜索調參、貝葉斯調參共三種調參手段,重點使用貝葉斯調參對本次項目進行簡單優化,大家在實際操作的過程中可以參考調參思路進行優化,不必拘泥于以上教程所寫的具體實例。

總結

以上是生活随笔為你收集整理的【算法竞赛学习】心跳信号分类预测-建模与调参的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。