Seed-New Energy

一、数据预处理

1.1  聚合数据

train_df = train_power_forecast_history.groupby(['id_encode','ds']).head(1)
# .groupby(['id_encode','ds'])将数据框按照'id_encode'和'ds'列的唯一组合进行分组,并选择每个组中的第一个行作为结果
# 唯一组合指,对于'id_encode'列和'ds'列的每个唯一值的组合,都会形成一个独立的组。例如,如果'id_encode'列有3个唯一值(1、2、3),'ds'列有4个唯一值(2023-01-01、2023-01-02、2023-01-03、2023-01-04),那么根据这两列的唯一组合,将会形成12个不同的组
# 最后得到每个站点每日的相关信息
del train_df['hour']
# 删除了train_df数据框中的'hour'列

tmp_df = train_power.groupby(['id_encode','ds'])['power'].sum()
#.groupby(['id_encode','ds'])将数据框按照'id_encode'和'ds'列的唯一组合进行分组。然后,['power'].sum()将对每个组中的'power'列进行求和操作。
# 此步是为了提取每个站点每日的总充电量

1.2 合并充电量数据

train_df = train_df.merge(tmp_df, on=['id_encode','ds'], how='left')
# merge()函数将根据指定的列(在这里是'id_encode'和'ds')将两个数据框进行合并。左连接意味着结果数据框将包含左侧数据框(train_df)中的所有行,并将右侧数据框(tmp_df)中与左侧数据框匹配的行合并在一起
# on=['id_encode','ds'],根据'id_encode'和'ds'列的匹配关系进行对应。如果在tmp_df中找不到与train_df中的'id_encode'和'ds'列匹配的行,对应的列将会填充为缺失值(NaN)

1.3 合并数据

train_df = train_df.merge(train_stub_info, on='id_encode', how='left')
# 同2. train_stub_info不包含ds 所以不需要匹配“ds”列
tmp_df
id_encode  ds
0          20220415    2288.2240
           20220416    2398.5730
           20220417    2313.0330
           20220418    2095.3259
           20220419    1834.3590
                         ...    
499        20230410     653.9099
           20230411     663.0800
           20230412     678.3201
           20230413     704.5300
           20230414     658.4100

合并后,得到每个站点每日的总充电量和其他信息 train_df
id_encode  ele_price  ser_price  after_ser_price  total_price   f1  \
0               0       0.64       0.95             0.31         1.59  0.0   
1               0       0.64       0.95             0.31         1.59  0.0   
2               0       0.64       0.95             0.31         1.59  0.0   
3               0       0.64       0.95             0.31         1.59  0.0   
4               0       0.64       0.95             0.31         1.59  0.0   
...           ...        ...        ...              ...          ...  ...   
149039        499       0.00       0.51             0.51         0.51  3.0   

            f2   f3        ds      power  
0          0.0  1.0  20220415  2288.2240  
1          0.0  1.0  20220416  2398.5730  
2          0.0  1.0  20220417  2313.0330  
3          0.0  1.0  20220418  2095.3259  
4          0.0  1.0  20220419  1834.3590  
...        ...  ...       ...        ...  
149039  1240.0  NaN  20230410   653.9099 

思考:train_df = train_power_forecast_history.groupby(['id_encode','ds']).head(1) baseline中为什么要取head(1) ?

可能是前面每个站点一天中ele_price等信息基本相同?所以忽略了每时的变化可以进行数据处理,如均值,归一化等,而不是采用第一个小时的信息作为参考标准


数据预处理 将数据中的字符映射成数字,便于模型回归计算

#数据预处理
train_df['flag'] = train_df['flag'].map({'A':0,'B':1})
test_df['flag'] = test_df['flag'].map({'A':0,'B':1})
# 映射操作 train_df['flag']表示选择train_df数据框中的'flag'列。.map({'A':0,'B':1})表示将'flag'列中的'A'替换为0,将'B'替换为1

二、获取时间特征

def get_time_feature(df, col):
# 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') 
    # 使用pd.to_datetime()函数将new_col列中的字符串日期时间转换为datetime类型。这里使用了format='%Y%m%d'参数来指定日期时间的格式
    # format='%Y%m%d'中%Y表示四位数的年份,%m表示两位数的月份,%d表示两位数的日期

    # 根据ds信息添加时间特征列,即年份、月份、星期几、月初、月末等
    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')

三、模型训练

3.1 K折交叉验证

K折交叉验证 sklearn.model_selection.KFold
KFold(n_splits=几折 , random_state=随机种子  , shuffle=是否打乱 )

eg:
KFold(n_splits=2, random_state=None, shuffle=False)
>>> for i, (train_index, test_index) in enumerate(kf.split(X)):
...     print(f"Fold {i}:")
...     print(f"  Train: index={train_index}")
...     print(f"  Test:  index={test_index}")
Fold 0:
  Train: index=[2 3]
  Test:  index=[0 1]
Fold 1:
  Train: index=[0 1]
  Test:  index=[2 3]


实战:
    folds = 5
    kf = KFold(n_splits=folds, shuffle=True, random_state=seed)

    # 初始化oof预测和测试集预测
    oof = np.zeros(train_x.shape[0])
    test_predict = np.zeros(test_x.shape[0])
    cv_scores = []

    # KFold交叉验证
    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):
        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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值