Datawhale-新能源时间序列赛事学习笔记(1)

news2024/11/18 13:58:51

1.赛题描述

        在电动汽车充电站运营管理中,准确预测充电站的电量需求对于提高充电站运营服务水平和优化区域电网供给能力非常关键。本次赛题旨在建立站点充电量预测模型,根据充电站的相关信息和历史电量数据,准确预测未来某段时间内充电站的充电量需求。赛题数据中提供了电动汽车充电站的场站编号、位置信息、历史电量等基本信息。参赛者需要基于这些数据,利用人工智能相关技术,建立预测模型来预测未来一段时间内的需求电量,帮助管理者提高充电站的运营效益和服务水平,促进电动汽车行业的整体发展。

2.赛题任务

        根据赛题提供的电动汽车充电站多维度脱敏数据,构造合理特征及算法模型,预估站点未来一周每日的充电量。(以天为单位)

3.赛题数据集

        本赛题提供的数据集包含三张数据表。其中,power_forecast_history.csv 为站点运营数据,power.csv为站点充电量数据,stub_info.csv为站点静态数据,训练集为历史一年的数据,测试集为未来一周的数据。

数据集清单与格式说明:

注:

(1)h3编码是一种用于分层地理编码的系统,可以将地球划分为不同的六边形网格。选手可以尝试使用 h3 编码来构造与地理位置相关的额外特征。

(2)脱敏字段,不提供字段业务描述,供选手自由探索。

4.评估指标-RMSE

y_{i}为第个数据的真实值,y^{*}_{i}为第个数据的预测值,n为样本总数。

5.Baseline

5.1 导入库

import numpy as np
import pandas as pd
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
from sklearn.metrics import mean_squared_error, mean_absolute_error
import matplotlib.pyplot as plt
import tqdm
import sys
import os
import gc
import argparse
import warnings
warnings.filterwarnings('ignore')

5.2 数据准备与探索

# 读取数据
train_power_forecast_history = pd.read_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\训练集\power_forecast_history.csv')
train_power = pd.read_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\训练集\power.csv')
train_stub_info = pd.read_csv('F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\训练集\stub_info.csv')

test_power_forecast_history = pd.read_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\测试集\power_forecast_history.csv')
test_stub_info = pd.read_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\测试集\stub_info.csv')

# 聚合数据(按日期+场站编码分组后取每一组第一条数据)
train_df = train_power_forecast_history.groupby(['id_encode','ds']).head(1)
del train_df['hour']
test_df = test_power_forecast_history.groupby(['id_encode','ds']).head(1)
del test_df['hour']

tmp_df = train_power.groupby(['id_encode','ds'])['power'].sum()
tmp_df.columns = ['id_encode','ds','power']

# 合并充电量数据
train_df = train_df.merge(tmp_df, on=['id_encode','ds'], how='left')

### 合并数据
train_df = train_df.merge(train_stub_info, on='id_encode', how='left')
test_df = test_df.merge(test_stub_info, on='id_encode', how='left')
# 定义要绘制的列
cols = ['power']

# 遍历id_encode的五个值
for ie in [0,1,2,3,4]:

    # 获取train_df中id_encode为当前值ie的所有行,并重置索引
    tmp_df = train_df[train_df['id_encode']==ie].reset_index(drop=True)

    # 再次重置索引,并为新索引添加一个名为'index'的列
    tmp_df = tmp_df.reset_index(drop=True).reset_index()

    # 遍历要绘制的列
    for num, col in enumerate(cols):

        # 设置图的大小
        plt.figure(figsize=(20,10))

        # 创建子图,总共有4行1列,当前为第num+1个子图
        plt.subplot(4,1,num+1)

        # 绘制图形:x轴为'index',y轴为当前列的值
        plt.plot(tmp_df['index'],tmp_df[col])

        # 为当前子图设置标题,标题为当前列的名称
        plt.title(col)

# 显示图形
plt.show()

# 创建一个新的图,大小为20x5
plt.figure(figsize=(20,5))

5.3 特征工程

train_df['flag'] = train_df['flag'].map({'A':0,'B':1})
test_df['flag'] = test_df['flag'].map({'A':0,'B':1})

def get_time_feature(df, col):
    
    df_copy = df.copy()
    prefix = col + "_"
    df_copy['new_'+col] = df_copy[col].astype(str)
    
    col = 'new_'+col
    df_copy[col] = pd.to_datetime(df_copy[col], format='%Y%m%d')
    df_copy[prefix + 'year'] = df_copy[col].dt.year
    df_copy[prefix + 'month'] = df_copy[col].dt.month
    df_copy[prefix + 'day'] = df_copy[col].dt.day
    # df_copy[prefix + 'weekofyear'] = df_copy[col].dt.weekofyear
    df_copy[prefix + 'dayofweek'] = df_copy[col].dt.dayofweek
    df_copy[prefix + 'is_wknd'] = df_copy[col].dt.dayofweek // 6
    df_copy[prefix + 'quarter'] = df_copy[col].dt.quarter
    df_copy[prefix + 'is_month_start'] = df_copy[col].dt.is_month_start.astype(int)
    df_copy[prefix + 'is_month_end'] = df_copy[col].dt.is_month_end.astype(int)
    del df_copy[col]
    
    return df_copy   
    
train_df = get_time_feature(train_df, 'ds')
test_df = get_time_feature(test_df, 'ds')

cols = [f for f in test_df.columns if f not in ['ds','power','h3']]

5.4 模型训练与验证

def cv_model(clf, train_x, train_y, test_x, clf_name, seed = 2023):
    '''
    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, 2000, 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=2000, 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=2000, **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_df[cols], train_df['power'], test_df[cols])

----------------------------------------------------------------------------------
#交叉验证分数
[266.7260370569527, 269.9232639345857, 265.154677843001, 265.21192193943574, 266.49163591068003]
test_df['power'] = lgb_test
test_df['power'] = test_df['power'].apply(lambda x: 0 if x<0 else x)
test_df[['id_encode','ds','power']].to_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\result.csv', index=False)

线上分数:240.51261765759443

◒XGBoost

xgb_oof, xgb_test = cv_model(xgb, train_df[cols], train_df['power'], test_df[cols], 'xgb')

------------------------------------------------------------------------------------
#交叉验证分数
[188.14222230685203, 189.79883333942658, 189.98780480651146, 188.90711501159402, 189.63885769696023]
test_df['power'] = xgb_test
test_df['power'] = test_df['power'].apply(lambda x: 0 if x<0 else x)
test_df[['id_encode','ds','power']].to_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\xgb_result.csv', index=False)

线上分数:269.1201702406025

◒CatBoost

cat_oof, cat_test = cv_model(CatBoostRegressor, train_df[cols], train_df['power'], test_df[cols], 'cat')
---------------------------------------------------------------------------------
#交叉验证分数
[217.60469992799398, 221.48162281844884, 221.30109254841568, 220.89774625184162, 219.70713010328046]
test_df['power'] = cat_test
test_df['power'] = test_df['power'].apply(lambda x: 0 if x<0 else x)
test_df[['id_encode','ds','power']].to_csv(r'F:\Jupyter Files\比赛\新能源赛道初赛数据集\初赛1008\cat_result.csv', index=False)

线上分数:302.69904271933

6.总结

从线下结果来看,XGBoost>CatBoost>LightGBM,即XGBoost的效果最优;而从线上结果来看,LightGBM>XGBoost>CatBoost,即LightGBM的效果最优。因为不同模型结果相差较大,所以没有考虑对这三模型进行融合。接下来会更侧重对LightGBM和XGBoost进行调参,并做特征工程,争取有更好的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1109923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

COCO数据集解析

介绍 官网&#xff1a;https://cocodataset.org/ 下载地址&#xff1a;https://cocodataset.org/#download COCO的全称是Common Objects in COntext&#xff0c;起源于微软于2014年出资标注党的Microsoft COCO数据&#xff0c;与ImageNet竞赛一样&#xff0c;是计算机视觉领域…

通讯协议学习之路:RS422协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 一、…

京东店铺公司名爬虫

内容仅供学习参考&#xff0c;如有侵权联系删除 先通过京东非自营的店铺名拿到的公司名&#xff0c;再通过公司名称去其他平台拿到联系方式&#xff08;代码省略&#xff09; from aioscrapy.spiders import Spider from aioscrapy.http import Request, FormRequest import dd…

【LeetCode75】第七十四题 每日温度

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个数组&#xff0c;表示每天的温度&#xff0c;要我们返回一个同样长度的数组&#xff0c;答案里装着当前气温的下一个更高气…

Linux用户管理与远程管理

一、用户管理 1、回顾用户组管理 groupadd &#xff1a;组添加 groupmod&#xff1a;组修改 groupdel&#xff1a;组删除 与用户组相关的文件/etc/group&#xff0c;一共拥有4列 itheima:x:1000: 1-组名称 2-组密码 3-组编号 4-组内用户信息&#xff08;这个组必须是这个…

阿里云优惠口令(2023更新)

2023年阿里云域名优惠口令&#xff0c;com域名续费优惠口令“com批量注册更享优惠”&#xff0c;cn域名续费优惠口令“cn注册多个价格更优”&#xff0c;cn域名注册优惠口令“互联网上的中国标识”&#xff0c;阿里云优惠口令是域名专属的优惠码&#xff0c;可用于域名注册、续…

微信公众号粉丝迁移步骤?

公众号迁移有什么作用&#xff1f;只能变更主体吗&#xff1f;公众号迁移是将原公众号的粉丝、违规记录、文章和素材库&#xff08;可选&#xff09;迁移至一个新的公众号。整体流程较为复杂&#xff0c;需花费7-10天。通过公众号迁移功能可以将A账号的粉丝、文章素材&#xff…

ROS工具RViz可视化3D空间的一些错误的解决方案

1、引言 RViz是ROS的一个可视化3D空间的工具&#xff0c;它用于帮助用户在ROS系统中导航、查看和交互。RViz可以显示来自各种ROS节点的信息&#xff0c;例如传感器数据、机器人的状态和路径等。通过RViz&#xff0c;用户可以以图形方式查看和交互各种ROS数据&#xff0c;非常直…

连锁药店的自有品牌之争:老百姓大药房能否突围?

文丨新熔财经 作者丨楷楷 近年来&#xff0c;随着医保谈判药品的“双通道”&#xff08;即消费者可在有资质的药店买到新进医保的创新药&#xff09;&#xff0c;以及“门诊统筹”将药店纳入医保报销等医改政策出台&#xff0c;药企开始重新重视起零售药店渠道&#xff0c;很…

C++对象模型(18)-- 函数语义学:函数调用过程

1、栈帧结构 函数执行是通过系统栈来实现的&#xff0c;系统栈分为若干个栈帧。 栈帧就是函数运行的环境&#xff0c;每个函数在被调用时都会在系统栈区形成一个叫栈帧的结构。一次函数调用相关的数据保存在栈帧中&#xff0c;比如函数参数、函数的局部变量、函数执行完后的返…

Leetcode 21 合并两个有序链表 (链表)

Leetcode 21 合并两个有序链表 &#xff08;链表&#xff09; 解法1 复杂的第一版本&#xff08;优化大于和等于合并见方法二&#xff09;解法2 注意注意&#xff1a;先添加元素toadd.next list1&#xff0c;添加之后才可以移动指针toadd toadd.next 解法1 复杂的第一版本&a…

数字电路常用芯片合集

前言 本文归纳了本科数字电路中常见的芯片型号及其功能&#xff0c;分为以下几类&#xff1a; 组合逻辑电路芯片 时序逻辑电路芯片 D/A A/D相关芯片 组合逻辑电路芯片 优先编码器74HC148 功能&#xff1a;多→1&#xff0c;选通 逻辑框图 功能表 补充&#xff1a;可以…

react native 使用夜神模拟器开发调试 windows+android

执行adb devices, 提示List of devices attached 打开本地sdk目录中的platform-tools文件夹&#xff0c;复制下面3个文件 打开夜神模拟器安装目录中的bin目录&#xff0c;把复制出来的文件复制替换到bin目录中 在复制一份platform-tools目录中的adb.exe&#xff0c;重命名为…

java最新Springboot3+微服务实战12306高性能售票系统全套开发课程

java最新Springboot3微服务实战12306高性能售票系统全套开发课程 视频课程在文末获取 第1章 课程介绍与学习指南。 1-1 课前必读&#xff08;不读错过一个亿&#xff09; 1-2 课程导学 1-3 为什么要选择最新版本SpringBoot3和JDK17&#xff1f; 1-4 在线demo网站演示 第2…

现货黄金的走势怎么看

成功的现货黄金交易者&#xff0c;都有自己一套的看行情的方法&#xff0c;以及自己最熟悉的交易获利机会&#xff0c;这使他们获利的胜率能够保持在一定的水平之上&#xff0c;长远来说&#xff0c;这也使他们成为市场上的赢家。 现货黄金的价格走势总在不断的变化之中&#x…

GEE:绘制土地利用类型面积分布柱状图

作者:CSDN @ _养乐多_ 本文记录了,在 Google Earth Engine (GEE)中进行随机森林分类后绘制不同类型面积分布柱状图的代码片段。 完整代码请看博客《GEE:随机森林分类教程(样本制作、特征添加、训练、精度、参数优化、贡献度、统计面积)》 柱状图效果如下所示, 文章目…

Pulsar-Pulsar 之 Functions

Pulsar 之 Functions Pulsar FunctionsPulsar Functions是什么&#xff1f;为什么使用Pulsar Functions&#xff1f;实例 完全限定函数名函数实例函数workerFunctions 运行时处理保证和订阅类型上下文函数消息类型Window functionwindow的类型快速开始启用有状态的函数使用Puls…

通讯协议学习之路:RS485协议理论

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 序&…

接口测试vs功能测试

接口测试和功能测试的区别&#xff1a; 本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什…

“一键替换视频封面,高效批量剪辑从未如此简单

在一个充满竞争和创意的世界&#xff0c;吸引人的视频封面往往能够决定内容的成败。今天&#xff0c;我将向大家介绍一种可以轻松替换视频封面图片的实用技巧&#xff0c;让你在创作中更胜一筹&#xff01; 首先&#xff0c;我们要进入媒体梦工厂主页面&#xff0c;并点击“视…