Datawhale第二期AI夏令营-机器学习-电力需求预测挑战赛尝试第三次-终于反击baseline

文摘   2024-07-17 09:58   湖北  
这次我们来梳理一下提分的代码。首先,我先把我在批改作业的时候写的不错的作业拿过来。给各位学习者看看:

https://d167yddq51j.feishu.cn/wiki/NYVQwUka7iledWkXdhUcKChDnmg

参考:@8群助教陈辅元

下面我们来梳理一下有关这个赛题的知识点吧。

先汇报一下最近的尝试情况,总结一下就是:

  1. 集成学习不一定比单个模型要强,这一点我们已经验证过了;

  2. 本次赛题单个boost模型不一定就比lgm好;

  3. 特征工程这次起到了非常大的作用;

  4. 数据探索性分析很重要。

结合陈助教的笔记,我猜测后续的提分思路是

1.时间序列模型+lgm提分;

2.继续做特征工程;

在本次学习中遇到困难的点:

1.lgm自动调参,有时本地跑很辛苦,跑很久出不了结果,这里的参数是参考了助教和别的学习者给的参数的。结果效果很好。

2.训练集和测试集的划分,这个地方很容易出错,我纯lgm得分是700多,但是加上特征工程就是230多了,真的效果很明显;

可以啦,我们上代码:

import pandas as pdimport lightgbm as lgbfrom sklearn.metrics import mean_squared_errorfrom sklearn.model_selection import train_test_split
# 1. 读取训练集和测试集train = pd.read_csv(r'train.csv')test = pd.read_csv(r'test.csv')

代码含义:读取数据。接下来的内容很重要:

# 合并训练数据和测试数据data = pd.concat([train, test], axis=0).reset_index(drop=True)data = data.sort_values(['id', 'dt'], ascending=False).reset_index(drop=True)

这段代码含义这样解释把,我们把训练集和测试集合并为一份数据进行处理。我们发现其实训练集和测试集给的特征不多,一般来说我们测试集要想根据训练集来进行学习,需要我们构造出一样的数据列,我才能预测啊。。。。

#这段代码放特征工程开始到结束的代码,我先讲解一下lgm的板块,特征工程最后讲。

我们讲lgm

# 进行数据切分train = data[data.target.notnull()].reset_index(drop=True)  # 筛选 'target' 列非空的行作为训练集test = data[data.target.isnull()].reset_index(drop=True)  # 筛选 'target' 列为空的行作为测试集
# 将id列作为索引train.set_index('id', inplace=True)test.set_index('id', inplace=True)
# 提取特征和目标变量X_train = train.drop(['target'], axis=1)y_train = train['target']X_test = test.drop(['target'], axis=1)
# 检查形状print(f"X_train shape: {X_train.shape}")print(f"y_train shape: {y_train.shape}")print(f"X_test shape: {X_test.shape}")

这段代码是为了防止代码报错,于是我们训练开始之前检查一下shape

# 创建LightGBM数据集lgb_train = lgb.Dataset(X_train, label=y_train)
# 定义参数params = { 'objective': 'regression', 'metric': 'mse', 'verbosity': -1, 'boosting_type': 'gbdt',}
# 训练模型num_round = 1000bst = lgb.train(params, lgb_train, num_round)
# 在预测之前检查形状if len(X_test.shape) == 1: X_test = X_test.values.reshape(1, -1) # 如果是一维的,重塑为二维数组
# 现在进行预测y_pred = bst.predict(X_test)
# 更新测试集的目标列test['target'] = y_pred
# 重新设置索引并保存结果文件到本地test.reset_index(inplace=True) # 重新设置索引,恢复 'id' 列test[['id', 'dt', 'target']].to_csv(r'submit_lgb2.csv', index=False)
# 打印完成提示print("预测结果已保存到 submit_lgb2.csv 文件中。")

这个地方可以调一下参数。

假如没有这个特征工程,那么我们的得分是700多

现在有了:

# 特征工程部分开始
# 历史平移for i in range(10, 36): data[f'target_shift{i}'] = data.groupby('id')['target'].shift(i)
# 历史平移 + 差分特征for i in range(1, 4): data[f'target_shift10_diff{i}'] = data.groupby('id')['target_shift10'].diff(i) # 窗口统计for win in [15, 30, 50, 70]: data[f'target_win{win}_mean'] = data.groupby('id')['target'].rolling(window=win, min_periods=3, closed='left').mean().values data[f'target_win{win}_max'] = data.groupby('id')['target'].rolling(window=win, min_periods=3, closed='left').max().values data[f'target_win{win}_min'] = data.groupby('id')['target'].rolling(window=win, min_periods=3, closed='left').min().values data[f'target_win{win}_std'] = data.groupby('id')['target'].rolling(window=win, min_periods=3, closed='left').std().values
# 历史平移 + 窗口统计for win in [7, 14, 28, 35, 50, 70]: data[f'target_shift10_win{win}_mean'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').mean().values data[f'target_shift10_win{win}_max'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').max().values data[f'target_shift10_win{win}_min'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').min().values data[f'target_shift10_win{win}_sum'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').sum().values data[f'target_shift10_win{win}_std'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').std().values
# 特征工程部分结束
为什么会出现这样的情况?
因为特征都是离散变量,很有可能做到顶尖的方案,也许是用了我们不熟悉的automl,这个玩意在有的AI比赛中真的用过,如果设备允许,要不要试试看我们这个特征可以带来的上限?
如下内容摘自Datawhale教程:

GBDT

GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。
GBDT不仅在工业界应用广泛,通常被用于多分类、点击率预测、搜索排序等任务;在各种数据挖掘竞赛中也是致命武器,据统计Kaggle上的比赛有一半以上的冠军方案都是基于GBDT

LightGBM

LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以快速处理海量数据等优点。
LightGBM 框架中还包括随机森林和逻辑回归等模型。通常应用于二分类、多分类和排序等场景。
例如:在个性化商品推荐场景中,通常需要做点击预估模型。使用用户过往的行为(点击、曝光未点击、购买等)作为训练数据,来预测用户点击或购买的概率。根据用户行为和用户属性提取一些特征,包括:
  • 类别特征(Categorical Feature):字符串类型,如性别(男/女)。
  • 物品类型:服饰、玩具和电子等。
  • 数值特征(Numrical Feature):整型或浮点型,如用户活跃度或商品价格等。
    Datawhale开源学习社区:




对于本次教程的改进建议:

从教学的角度来讲,教程思路是没问题的,事实证明lgm确实可以击败baseline。但是从本次赛题的情况来看,我们缺乏对特征工程的构造教学,很明显,这一次的比赛特征工程起了非常大的作用,把得分从700多打到了233多,这说明了许多的问题。
光看baseline,我们也发现了,平时的baseline是做了最起码一个机器学习模型或者就是lgm就可以做到让众多学习者头疼的“topline”了,在2023年的温度预测第一期学习里面我体会很深。最后没有打赢。
本次的数据多数是离散变量,然后具有时间序列性质,很明显带有周期性,这一点我在数据探索性分析中明确指出了。Datawhale第二期AI夏令营-机器学习-电力需求预测挑战赛尝试笔记第二次(小结最近的尝试)
最后附上我baseline的文章:Datawhale第二期AI夏令营-机器学习-电力需求预测挑战赛尝试笔记第一次(含baseline代码)
祝各位学习者努力找找特征工程,有啥好消息留言告诉我啊!!!

师苑数模
发布数模协会培训推文,讲解数模算法。赛题讲解及比赛通知。学校竞赛结果及学校竞赛成绩发布等文章。
 最新文章