AI夏令营-初赛PartIII

我按照手册后面的优化建议,对代码进行了修改:

import pandas as pd
import lightgbm as lgb
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import KFold
from tqdm import tqdm

# 数据准备
train_dataset = pd.read_csv("./data/train.csv") # 原始训练数据。
test_dataset = pd.read_csv("./data/test.csv") # 原始测试数据(用于提交)。

submit = pd.DataFrame() # 定义提交的最终数据。
submit["序号"] = test_dataset["序号"] # 对齐测试数据的序号。

MAE_scores = dict() # 定义评分项。

# 模型训练与预测
pred_labels = list(train_dataset.columns[-34:]) # 需要预测的标签。

# 设定 LightGBM 训练参,查阅参数意义:https://lightgbm.readthedocs.io/en/latest/Parameters.html
lgb_params = {
    'boosting_type': 'gbdt',
    'objective': 'regression',
    'metric': 'mae',
    'min_child_weight': 5,
    'num_leaves': 2 ** 5,
    'lambda_l2': 30,
    'feature_fraction': 0.8,
    'bagging_fraction': 0.8,
    'bagging_freq': 4,
    'learning_rate': 0.03,
    'seed': 2023,
    'nthread': 16,
    'verbose': -1,
}

def data_feature(data: pd.DataFrame, pred_labels: list=None) -> pd.DataFrame:
    # ... (之前的 data_feature 函数定义,此处省略) ...
    return data # 返回最后处理的数据。

# 处理测试集的时间特征,无需 pred_labels。
test_features = data_feature(test_dataset) 

# 采用5折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=42)

for pred_label in tqdm(pred_labels):
    MAE_scores[pred_label] = []
    
    for train_index, valid_index in kf.split(train_dataset):
        train_set, valid_set = train_dataset.iloc[train_index], train_dataset.iloc[valid_index]

        train_features = data_feature(train_set, pred_labels=pred_labels)
        train_labels = train_set[pred_label]
        train_data = lgb.Dataset(train_features, label=train_labels)

        valid_features = data_feature(valid_set, pred_labels=pred_labels)
        valid_labels = valid_set[pred_label]
        valid_data = lgb.Dataset(valid_features, label=valid_labels)

        model = lgb.train(lgb_params,
                          train_data,
                          valid_sets=[train_data, valid_data],
                          num_boost_round=1000,
                          early_stopping_rounds=50,
                          verbose_eval=50)

        valid_pred = model.predict(valid_features, num_iteration=model.best_iteration)
        MAE_score = mean_absolute_error(valid_pred, valid_labels)
        MAE_scores[pred_label].append(MAE_score)

        test_pred = model.predict(test_features, num_iteration=model.best_iteration)
        submit[pred_label] += test_pred / kf.n_splits

    # 打印每个标签的MAE得分
    print(f"MAE scores for {pred_label}: {MAE_scores[pred_label]}")
    print(f"Mean MAE score for {pred_label}: {sum(MAE_scores[pred_label]) / len(MAE_scores[pred_label])}")

submit.to_csv('submit_result_new.csv', index=False)
print(MAE_scores)

因为曾经在比分中,出现了10分以及17分的分数,因此我猜测是否出现了过拟合的现象,因此改进了自己的代码,希望能够将过拟合的现象消除。但是,经过修改之后,代码出现需要修改的现象,因此暂时为了能够提高分数,依然选择修改参数。同时,也进一步优化自己的代码。

# 设定 LightGBM 训练参,查阅参数意义:https://lightgbm.readthedocs.io/en/latest/Parameters.html
lgb_params = {
        'boosting_type': 'gbdt',
        'objective': 'regression',
        'metric': 'mae',
        'min_child_weight': 5,
        'num_leaves': 2 ** 5,
        'lambda_l2': 30,
        'feature_fraction': 0.8,
        'bagging_fraction': 0.8,
        'bagging_freq': 4,
        'learning_rate': 0.03,
        'seed': 2023,
        'nthread' : 16,
        'verbose' : -1,
    }

no_info = lgb.callback.log_evaluation(period=-1) # 禁用训练日志输出。

其他的,尝试过使用XGBoost模型:

# 导入所需的库
import pandas as pd # 用于处理数据的工具
import xgboost as xgb # 机器学习模型 XGBoost
from sklearn.metrics import mean_absolute_error # 评分 MAE 的计算函数
from sklearn.model_selection import train_test_split # 拆分训练集与验证集工具
from tqdm import tqdm # 显示循环的进度条工具

# 数据准备
train_dataset = pd.read_csv("./data/train.csv") # 原始训练数据。
test_dataset = pd.read_csv("./data/test.csv") # 原始测试数据(用于提交)。

submit = pd.DataFrame() # 定义提交的最终数据。
submit["序号"] = test_dataset["序号"] # 对齐测试数据的序号。

MAE_scores = dict() # 定义评分项。

# 模型训练
pred_labels = list(train_dataset.columns[-34:]) # 需要预测的标签。
train_set, valid_set = train_test_split(train_dataset, test_size=0.2) # 拆分数据集。

# 设定 XGBoost 训练参
xgb_params = {
    'objective': 'reg:squarederror',
    'eval_metric': 'mae',
    'min_child_weight': 5,
    'max_depth': 5,
    'subsample': 0.8,
    'colsample_bytree': 0.8,
    'learning_rate': 0.03,
    'seed': 2023,
    'nthread': 16,
    'verbosity': 0,
}

# 数据处理函数
def data_feature(data: pd.DataFrame, pred_labels: list=None) -> pd.DataFrame:
    # 省略数据处理的代码,保持不变
    pass

test_features = data_feature(test_dataset) # 处理测试集的时间特征,无需 pred_labels。

# 从所有待预测特征中依次取出标签进行训练与预测。
for pred_label in tqdm(pred_labels):
    train_features = data_feature(train_set, pred_labels=pred_labels) # 处理训练集的时间特征。
    train_labels = train_set[pred_label] # 训练集的标签数据。
    dtrain = xgb.DMatrix(train_features, label=train_labels) # 将训练集转换为 XGBoost 可处理的类型。

    valid_features = data_feature(valid_set, pred_labels=pred_labels) # 处理验证集的时间特征。
    valid_labels = valid_set[pred_label] # 验证集的标签数据。
    dvalid = xgb.DMatrix(valid_features, label=valid_labels) # 将验证集转换为 XGBoost 可处理的类型。

    # 训练模型
    model = xgb.train(xgb_params,
                      dtrain,
                      num_boost_round=1000,
                      early_stopping_rounds=50,
                      evals=[(dtrain, 'train'), (dvalid, 'eval')],
                      verbose_eval=50)

    valid_pred = model.predict(dvalid) # 选择效果最好的模型进行验证集预测。
    test_pred = model.predict(xgb.DMatrix(test_features)) # 选择效果最好的模型进行测试集预测。
    MAE_score = mean_absolute_error(valid_pred, valid_labels) # 计算验证集预测数据与真实数据的 MAE。
    MAE_scores[pred_label] = MAE_score # 将对应标签的 MAE 值 存入评分项中。

    submit[pred_label] = test_pred # 将测试集预测数据存入最终提交数据中。
     
submit.to_csv('submit_result_new.csv', index=False) # 保存最后的预测结果到 submit_result_new.csv。
print(MAE_scores) # 查看各项的 MAE 值

结果并不算非常好,而且还经常需要重新启动程序,因为初赛提交到ddl了,但是接下来也会继续优化这个代码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值