Kaggle Solo第一!


简介

第一名方案主要由4个XGBoost模型(2个不同的标签)以及2个GRU模型(2个不同模型)组成。

验证策略

使用前500天数据进行训练并且将剩余的时间用做验证。

特征

  • county+datetime+data_block_id的组合特征。
  • fw_new_feature可以提升大致 0.1~0.2
# client_df
client_df = client_df.drop(["date"]).sort(["data_block_id"], descending=False)
df = df.join(client_df.select(["county""is_business""product_type""data_block_id","eic_count","installed_capacity"]), how="left", on=["county""is_business""product_type""data_block_id"])
# electricity
electricity_df = electricity_df.drop(["origin_date"]).rename({"forecast_date":"datetime"}).with_columns([(pl.col("datetime").str.to_datetime()+pl.duration(days=1)).alias("datetime"), (pl.col("euros_per_mwh").abs()+0.1).alias("euros_per_mwh"),])
df = df.join(electricity_df[["data_block_id","datetime","euros_per_mwh"]], how="left", on=["data_block_id","datetime"])

# fw_df 
fw_df = fw_df.with_columns(
                (pl.col("origin_datetime").str.to_datetime()+pl.duration(hours="hours_ahead")).alias("datetime"),
                pl.col("latitude").cast(pl.datatypes.Float32).round(1),
                pl.col("longitude").cast(pl.datatypes.Float32).round(1),
                pl.col("data_block_id").cast(pl.datatypes.Int64),
            ).join(weather_station_to_county_mapping.drop(["county_name"]).with_columns(
                pl.col("latitude").cast(pl.datatypes.Float32).round(1),
                pl.col("longitude").cast(pl.datatypes.Float32).round(1),
            ), how="left",on=["longitude","latitude"]).drop(["longitude","latitude","origin_datetime"])
fw_df = fw_df.group_by(["county","datetime","data_block_id"]).agg([pl.mean(col).alias("fw_{}".format(col)) for col in forecast_weather_cols]).with_columns([pl.col("county").cast(pl.datatypes.Int64),    
                                                                    pl.col("data_block_id").cast(pl.datatypes.Int64),])
df = df.join(fw_df, how="left", on=["county","datetime","data_block_id"]).with_columns([(pl.col("installed_capacity")*pl.col("fw_surface_solar_radiation_downwards") / (pl.col("fw_temperature") + 273.15)).alias("fw_new_feature"),])

# hw_df 
hw_df = hw_df.with_columns(
            (pl.col("datetime").str.to_datetime()+pl.duration(days=1)).alias("datetime"),
                pl.col("latitude").cast(pl.datatypes.Float32).round(1),
                pl.col("longitude").cast(pl.datatypes.Float32).round(1),
                pl.col("data_block_id").cast(pl.datatypes.Int64),
            ).join(weather_station_to_county_mapping.drop(["county_name"]).with_columns(
                pl.col("latitude").cast(pl.datatypes.Float32).round(1),
                pl.col("longitude").cast(pl.datatypes.Float32).round(1),
            ), how="left",on=["longitude","latitude"]).drop(["longitude","latitude"])
hw_df = hw_df.group_by(["county","datetime","data_block_id"]).agg([pl.mean(col).alias("hw_{}".format(col)) for col in historical_weather_cols]).with_columns([                                                            pl.when(pl.col("datetime").dt.hour()>10).then(pl.col("datetime")+pl.duration(days=1)).otherwise(pl.col("datetime")).alias("datetime"),
                                                                pl.col("county").cast(pl.datatypes.Int64),    
                                                                pl.col("data_block_id").cast(pl.datatypes.Int64),])
df = df.join(hw_df, how="left", on=["county","datetime","data_block_id"])

Target

  • (target-target_shift2)/installed_capacity.
  • target/installed_capacity.
df = df.with_columns([
pl.when(pl.col('target').shift(2).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('target').shift(2).over(['prediction_unit_id','hour'])).when(pl.col('target').shift(3).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('target').shift(3).over(['prediction_unit_id','hour'])).when(pl.col('target').shift(4).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('target').shift(4).over(['prediction_unit_id','hour'])).when(pl.col('target').shift(2).mean().over(['datetime']).is_null()).then(pl.col('target').mean()).otherwise(pl.col('target').shift(2).mean().over(['datetime'])).fill_null(0.0).cast(pl.Float32).alias('target_shift_tmp'),

        pl.when(pl.col('data_block_id')<=1).then(pl.col('installed_capacity').shift(-2).over(['prediction_unit_id','hour'])).when(pl.col('installed_capacity').shift(1).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('installed_capacity').shift(1).over(['prediction_unit_id','hour'])).when(pl.col('installed_capacity').shift(2).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('installed_capacity').shift(2).over(['prediction_unit_id','hour'])).when(pl.col('installed_capacity').shift(3).over(['prediction_unit_id','hour']).is_not_null()).then(pl.col('installed_capacity').shift(3).over(['prediction_unit_id','hour'])).when(pl.col('installed_capacity').mean().over(['datetime']).is_null()).then(pl.col('installed_capacity').mean()).otherwise(pl.col('installed_capacity').mean().over(['datetime'])).cast(pl.Float32).alias('installed_capacity_tmp'),
        ])
df = df.with_columns([   pl.when(pl.col('installed_capacity').is_null()).then(pl.col('installed_capacity_tmp')).otherwise(pl.col('installed_capacity')).clip(10,None).cast(pl.Float32).alias('installed_capacity_tmp'),   #clip(10,None) 
        ]).with_columns([
        pl.when(pl.col('installed_capacity_tmp')<2*pl.col('target_shift_tmp').abs()).then(2*pl.col('target_shift_tmp').abs()).otherwise(pl.col('installed_capacity_tmp')).cast(pl.Float32).alias('installed_capacity_tmp'),
        ])
df = df.with_columns([
        ((pl.col('target')-pl.col('target_shift_tmp')) / pl.col('installed_capacity_tmp')).alias('target2'),
        (pl.col('target') / pl.col('installed_capacity_tmp')).alias('target3'),
        ])

模型

  • XGBoost
  • GRU模型,输入的tensor大小为:(batch_size, 24 hours, 600 dense_feature_dim + 6*16 cat_feature_dim),输出的tensor的shape为(batch_size, 24 hours),此处类别特征为:['county', 'product_type', 'hour', 'month', 'weekday', 'day'],NN模型可以将最终分数提升0.9。

在线学习策略

在线学习策略可以使用更多数据,这对public learderboard帮助较小,但private leaderboard可能会带来更多的帮助。

参考文献

  1. https://www.kaggle.com/competitions/predict-energy-behavior-of-prosumers/discussion/472793
  2. https://www.kaggle.com/competitions/predict-energy-behavior-of-prosumers/overview

作者:hyd


🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉 PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫 等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

相关推荐

  • 用于时间序列概率预测的蒙特卡罗模拟
  • DPO作者新作|From r to Q*
  • 如何优雅的实现在线人数统计功能?
  • 8 个关于 Promise 高级用途的技巧
  • ICLR2024杰出论文——Never Train from Scratch!
  • 60*16K,大厂高端岗位卷爆了!
  • 手把手教大家实现OAuth2第三方登录
  • Node 之父新作:一个全新的 NPM 下载源工具!!!
  • 摸鱼网站精选分享第一番
  • 三个实用开源项目工具:无代码编辑器
  • 万丈高楼平地起,一切从 PyObject 开始
  • 一不小心成了知名开源项目的贡献者?!
  • 30%参数达到92%的表现,大模型稀疏化方法显神通
  • 从零开始手搓GPU,照着英伟达CUDA来,只用两个星期
  • Sam Altman 5月最新2万字谈AI未来:GPT-5与OpenAI的使命 (附全文+视频)
  • [开源]综合性在线网校平台,内容分享、付费、营销一站式解决方案
  • 偷偷爆料下银行信息科技岗(含各大银行薪资)
  • 与AI角色共筑虚拟人生是啥体验?
  • 进程之间的通信方式有哪些?我被问倒了。。
  • 被 Bug 折磨疯后,我写了本 Bug 修复手册。