Datawhale AI夏令营学习(机器学习)

73 阅读4分钟
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error
def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 2024):
    '''
    clf:调用模型
    train_x:训练数据
    train_y:训练数据对应标签
    test_x:测试数据
    clf_name:选择使用模型名
    seed:随机种子
    '''
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)
    oof = np.zeros(train_x.shape[0])
    test_predict = np.zeros(test_x.shape[0])
    cv_scores = []
    
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]
        
        if clf_name == "lgb":
            train_matrix = clf.Dataset(trn_x, label=trn_y)
            valid_matrix = clf.Dataset(val_x, label=val_y)
            params = {
                'boosting_type': 'gbdt',
                'objective': 'regression',
                'metric': 'mae',
                'min_child_weight': 6,
                'num_leaves': 2 ** 6,
                'lambda_l2': 10,
                'feature_fraction': 0.8,
                'bagging_fraction': 0.8,
                'bagging_freq': 4,
                'learning_rate': 0.1,
                'seed': 2023,
                'nthread' : 16,
                'verbose' : -1,
            }
            model = clf.train(params, train_matrix, 1000, valid_sets=[train_matrix, valid_matrix],
                              categorical_feature=[], verbose_eval=200, early_stopping_rounds=100)
            val_pred = model.predict(val_x, num_iteration=model.best_iteration)
            test_pred = model.predict(test_x, num_iteration=model.best_iteration)
        
        if clf_name == "xgb":
            xgb_params = {
              'booster': 'gbtree', 
              'objective': 'reg:squarederror',
              'eval_metric': 'mae',
              'max_depth': 5,
              'lambda': 10,
              'subsample': 0.7,
              'colsample_bytree': 0.7,
              'colsample_bylevel': 0.7,
              'eta': 0.1,
              'tree_method': 'hist',
              'seed': 520,
              'nthread': 16
              }
            train_matrix = clf.DMatrix(trn_x , label=trn_y)
            valid_matrix = clf.DMatrix(val_x , label=val_y)
            test_matrix = clf.DMatrix(test_x)
            
            watchlist = [(train_matrix, 'train'),(valid_matrix, 'eval')]
            
            model = clf.train(xgb_params, train_matrix, num_boost_round=1000, evals=watchlist, verbose_eval=200, early_stopping_rounds=100)
            val_pred  = model.predict(valid_matrix)
            test_pred = model.predict(test_matrix)
            
        if clf_name == "cat":
            params = {'learning_rate': 0.1, 'depth': 5, 'bootstrap_type':'Bernoulli','random_seed':2023,
                      'od_type': 'Iter', 'od_wait': 100, 'random_seed': 11, 'allow_writing_files': False}
            
            model = clf(iterations=1000, **params)
            model.fit(trn_x, trn_y, eval_set=(val_x, val_y),
                      metric_period=200,
                      use_best_model=True, 
                      cat_features=[],
                      verbose=1)
            
            val_pred  = model.predict(val_x)
            test_pred = model.predict(test_x)
        
        oof[valid_index] = val_pred
        test_predict += test_pred / kf.n_splits
        
        score = mean_absolute_error(val_y, val_pred)
        cv_scores.append(score)
        print(cv_scores)
        
    return oof, test_predict

# 选择lightgbm模型
lgb_oof, lgb_test = cv_model(lgb, train[train_cols], train['target'], test[train_cols], 'lgb')
# 选择xgboost模型
xgb_oof, xgb_test = cv_model(xgb, train[train_cols], train['target'], test[train_cols], 'xgb')
# 选择catboost模型
cat_oof, cat_test = cv_model(CatBoostRegressor, train[train_cols], train['target'], test[train_cols], 'cat')

# 进行取平均融合
final_test = (lgb_test + xgb_test + cat_test) / 3

代码解读

该函数用于进行交叉验证(CV)并评估或预测使用不同机器学习模型(如 LightGBM, XGBoost, CatBoost)的性能。不过,你的代码中只有 LightGBM 的实现部分,并且关于学习率调度器(LR Scheduler)的警告并没有直接体现在你给出的代码片段中,因为这个警告通常与 PyTorch 的优化器和调度器相关。

首先,关于 LightGBM 部分,这里并没有直接使用 PyTorch 的优化器和学习率调度器,因此你不会遇到这个特定的警告。但是,如果你的目标是优化 LightGBM 的学习率(虽然 LightGBM 通常通过 learning_rate 参数直接设置),应该注意在训练过程中不要误用类似 PyTorch 中的学习率调度逻辑。

然而,如果你的代码或其他部分的代码确实使用了 PyTorch,并且你遇到了这个警告,你应该按照警告的建议调整代码顺序:

  1. 在调用 optimizer.step() 后调用 lr_scheduler.step() :这是 PyTorch 1.1.0 及以后版本的要求。确保在每个 epoch 或每个 batch 更新模型参数(通过 optimizer.step())之后,再更新学习率(通过 lr_scheduler.step())。
  2. 检查学习率调度器的更新逻辑:确保你没有在不应该更新学习率的时候调用了 lr_scheduler.step()。例如,在训练循环外部或在每个 batch 而不是每个 epoch 结束时调用它。

代码修改

  1. 在调用 optimizer.step() 后调用 lr_scheduler.step() :这是 PyTorch 1.1.0 及以后版本的要求。确保在每个 epoch 或每个 batch 更新模型参数(通过 optimizer.step())之后,再更新学习率(通过 lr_scheduler.step())。
  2. 检查学习率调度器的更新逻辑:确保你没有在不应该更新学习率的时候调用了 lr_scheduler.step()。例如,在训练循环外部或在每个 batch 而不是每个 epoch 结束时调用它。

由于代码片段是关于 LightGBM 的,并且没有直接涉及 PyTorch,这里是一个简化的 PyTorch 示例,展示如何正确设置和使用学习率调度器:

解释
	import torch  

	from torch import optim  

	from torch.optim.lr_scheduler import StepLR  

	  
  

	model = ...  

	optimizer = optim.Adam(model.parameters(), lr=0.01)  

	scheduler = StepLR(optimizer, step_size=30, gamma=0.1)  # 每30个epoch学习率乘以0.1  

	  

	for epoch in range(100):  

	    # 训练模型...  

	    # 假设你有一个训练函数 train_model(model, optimizer, ...)  

	    train_model(model, optimizer, ...)  

	      

	    # 更新学习率  

	    optimizer.step()  # 这通常在你的训练函数内部调用  

	    scheduler.step()  # 确保在 optimizer.step() 之后调用