2024datawhale电力需求预测挑战赛

news2024/11/15 4:49:19

电力需求预测挑战赛

比赛链接:https://challenge.xfyun.cn/topic/info?type=electricity-demand&option=ssgy&ch=dw24_uGS8Gs

学习链接:https://datawhaler.feishu.cn/wiki/CuhBw9vBaiG1nJklIPkcRhqVnmk

一句话介绍赛题任务可以这样理解赛题:

【训练时序预测模型助力电力需求预测】

电力需求的准确预测对于电网的稳定运行、能源的有效管理以及可再生能源的整合至关重要。

赛题任务

给定多个房屋对应电力消耗历史N天的相关序列数据等信息,预测房屋对应电力的消耗。

赛题数据简介

赛题数据由训练集和测试集组成,为了保证比赛的公平性,将每日日期进行脱敏,用1-N进行标识。

即1为数据集最近一天,其中1-10为测试集数据。

数据集由字段id(房屋id)、 dt(日标识)、type(房屋类型)、target(实际电力消耗)组成。

下面进入baseline代码

以下代码均在kaggle平台运行,不用配置环境和可以使用GPU,较为方便。

Task1

使用移动平均预测,评分373左右,不太行,建议从Task2开始。

import pandas as pd
import numpy as np

train = pd.read_csv('/kaggle/input/2024abcd/train.csv')
test = pd.read_csv('/kaggle/input/2024abcd/test.csv')

# 计算训练数据最近11-20单位时间内对应id的目标均值
target_mean = train[train['dt']<=20].groupby(['id'])['target'].mean().reset_index()

# 将target_mean作为测试集结果进行合并
test = test.merge(target_mean, on=['id'], how='left')

# 保存结果文件到本地
test[['id','dt','target']].to_csv('submit1.csv', index=None)

Task2 入门lightgbm,开始特征工程

import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error
import tqdm # 用于显示循环进度条的库
import sys
import os
import gc # 提供了与垃圾回收机制相关的接口,可以手动执行垃圾回收、调整垃圾回收器的参数等,主要用于内存管理和优化。
import argparse # 用于命令行参数解析的库,可以方便地编写用户友好的命令行接口。可以定义程序所需的参数和选项,并自动生成帮助和使用信息。
import warnings
warnings.filterwarnings('ignore')
train = pd.read_csv('/kaggle/input/2024abcd/train.csv')
test = pd.read_csv('/kaggle/input/2024abcd/test.csv')
train.head(),train.shape,test.head(),test.shape
(           id  dt  type  target
 0  00037f39cf  11     2  44.050
 1  00037f39cf  12     2  50.672
 2  00037f39cf  13     2  39.042
 3  00037f39cf  14     2  35.900
 4  00037f39cf  15     2  53.888,
 (2877305, 4),
            id  dt  type
 0  00037f39cf   1     2
 1  00037f39cf   2     2
 2  00037f39cf   3     2
 3  00037f39cf   4     2
 4  00037f39cf   5     2,
 (58320, 3))

可视化观察

# 不同type类型对应target的柱状图
import matplotlib.pyplot as plt
# 不同type类型对应target
type_target_df = train.groupby('type')['target'].mean().reset_index()
plt.figure(figsize=(8, 4))
plt.bar(type_target_df['type'], type_target_df['target'], color=['blue', 'green'])
plt.xlabel('Type')
plt.xticks([i for i in range(0,19)])
plt.ylabel('Average Target Value')
plt.title('Bar Chart of Target by Type')
plt.show()

在这里插入图片描述

# id为00037f39cf的按dt为序列关于target的折线图
specific_id_df = train[train['id'] == '00037f39cf']
plt.figure(figsize=(10, 5))
plt.plot(specific_id_df['dt'], specific_id_df['target'], marker='o', linestyle='-')
plt.xlabel('DateTime')
plt.ylabel('Target Value')
plt.title("Line Chart of Target for ID '00037f39cf'")
plt.show()

在这里插入图片描述

特征工程

这里主要构建了历史平移特征和窗口统计特征。

  • 历史平移特征:是一种特征工程技术,通过将之前时间点的数据转移到当前时间点,从而为当前时间点提供额外的信息。
  • 窗口统计特征:窗口统计可以构建不同的窗口大小,然后基于窗口范围进统计均值、最大值、最小值、中位数、方差的信息,可以反映最近阶段数据的变化情况。下列代码可以将d时刻之前的三个时间单位的信息进行统计构建特征给作为d时刻的特征。
# 合并训练数据和测试数据,并进行排序
data = pd.concat([test, train], axis=0, ignore_index=True)
data = data.sort_values(['id','dt'], ascending=False).reset_index(drop=True)

# 历史平移
for i in range(10,30):
    data[f'last{i}_target'] = data.groupby(['id'])['target'].shift(i)
    
# 窗口统计
data[f'win3_mean_target'] = (data['last10_target'] + data['last11_target'] + data['last12_target']) / 3

# 进行数据切分
train = data[data.target.notnull()].reset_index(drop=True)
test = data[data.target.isnull()].reset_index(drop=True)

# 确定输入特征
train_cols = [f for f in data.columns if f not in ['id','target']]
test.head()
iddttypetargetlast10_targetlast11_targetlast12_targetlast13_targetlast14_targetlast15_target...last21_targetlast22_targetlast23_targetlast24_targetlast25_targetlast26_targetlast27_targetlast28_targetlast29_targetwin3_mean_target
0fff81139a7105NaN29.57133.69127.03433.06330.10936.227...32.51332.98431.41334.68523.51829.39231.08129.18530.63130.098667
1fff81139a795NaN28.67729.57133.69127.03433.06330.109...28.66432.51332.98431.41334.68523.51829.39231.08129.18530.646333
2fff81139a785NaN21.92528.67729.57133.69127.03433.063...26.58828.66432.51332.98431.41334.68523.51829.39231.08126.724333
3fff81139a775NaN29.60321.92528.67729.57133.69127.034...33.81626.58828.66432.51332.98431.41334.68523.51829.39226.735000
4fff81139a765NaN30.27929.60321.92528.67729.57133.691...37.08033.81626.58828.66432.51332.98431.41334.68523.51827.269000

5 rows × 25 columns

模型训练与测试集预测

需要注意的训练集和验证集的构建:因为数据存在时序关系,所以需要严格按照时序进行切分,

  • 这里选择原始给出训练数据集中dt为30之后的数据作为训练数据,之前的数据作为验证数据,
  • 这样保证了数据不存在穿越问题(不使用未来数据预测历史数据)
def time_model(lgb, train_df, test_df, cols):
    # 训练集和验证集切分
    trn_x, trn_y = train_df[train_df.dt>=31][cols], train_df[train_df.dt>=31]['target']
    val_x, val_y = train_df[train_df.dt<=30][cols], train_df[train_df.dt<=30]['target']
    # 构建模型输入数据
    train_matrix = lgb.Dataset(trn_x, label=trn_y)
    valid_matrix = lgb.Dataset(val_x, label=val_y)
    # lightgbm参数
    lgb_params = {
        'boosting_type': 'gbdt',
        'objective': 'regression',
        'metric': 'mse',
        'min_child_weight': 5,
        'num_leaves': 2 ** 5,
        'lambda_l2': 10,
        'feature_fraction': 0.8,
        'bagging_fraction': 0.8,
        'bagging_freq': 4,
        'learning_rate': 0.05,
        'seed': 2024,
        'nthread' : 16,
        'verbose' : -1,
        'device': 'gpu',
        'gpu_platform_id': 0,
        'gpu_device_id': 0
    }
    # 训练模型
    model = lgb.train(lgb_params, train_matrix, 50000, valid_sets=[train_matrix, valid_matrix], 
                      categorical_feature=[], callbacks=[lgb.early_stopping(500), lgb.log_evaluation(500)])
    # 验证集和测试集结果预测
    val_pred = model.predict(val_x, num_iteration=model.best_iteration)
    test_pred = model.predict(test_df[cols], num_iteration=model.best_iteration)
    # 离线分数评估
    score = mean_squared_error(val_pred, val_y)
    print(score)
       
    return val_pred, test_pred
    
lgb_oof, lgb_test = time_model(lgb, train, test, train_cols)

# 保存结果文件到本地
test['target'] = lgb_test
test[['id','dt','target']].to_csv('submit2.csv', index=None)

Task3:尝试使用深度学习方案

特征优化

这里主要构建了历史平移特征、差分特征、和窗口统计特征;每种特征都是有理可据的,具体说明如下:

(1)历史平移特征:通过历史平移获取上个阶段的信息;

(2)差分特征:可以帮助获取相邻阶段的增长差异,描述数据的涨减变化情况。在此基础上还可以构建相邻数据比值变化、二阶差分等;

(3)窗口统计特征:窗口统计可以构建不同的窗口大小,然后基于窗口范围进统计均值、最大值、最小值、中位数、方差的信息,可以反映最近阶段数据的变化情况。

import numpy as np
import pandas as pd
import lightgbm as lgb
from sklearn.metrics import mean_squared_log_error, mean_absolute_error, mean_squared_error
import tqdm # 用于显示循环进度条的库
import sys
import os
import gc # 提供了与垃圾回收机制相关的接口,可以手动执行垃圾回收、调整垃圾回收器的参数等,主要用于内存管理和优化。
import argparse # 用于命令行参数解析的库,可以方便地编写用户友好的命令行接口。可以定义程序所需的参数和选项,并自动生成帮助和使用信息。
import warnings
warnings.filterwarnings('ignore')

train = pd.read_csv('/kaggle/input/2024abcd/train.csv')
test = pd.read_csv('/kaggle/input/2024abcd/test.csv')
train.head()
iddttypetarget
000037f39cf11244.050
100037f39cf12250.672
200037f39cf13239.042
300037f39cf14235.900
400037f39cf15253.888
# 合并训练数据和测试数据
data = pd.concat([train, test], axis=0).reset_index(drop=True) # 在重置索引时删除旧索引,避免将旧索引添加为新的一列
data = data.sort_values(['id','dt'], ascending=False).reset_index(drop=True)

# 历史平移
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_shift710win{win}_std'] = data.groupby('id')['target_shift10'].rolling(window=win, min_periods=3, closed='left').std().values
# 进行数据切分
train = data[data.target.notnull()].reset_index(drop=True)
test = data[data.target.isnull()].reset_index(drop=True)

# 确定输入特征
train_cols = [f for f in data.columns if f not in ['id','target']]

test.head()
iddttypetargettarget_shift10target_shift11target_shift12target_shift13target_shift14target_shift15...target_shift10_win50_meantarget_shift10_win50_maxtarget_shift10_win50_mintarget_shift10_win50_sumtarget_shift710win50_stdtarget_shift10_win70_meantarget_shift10_win70_maxtarget_shift10_win70_mintarget_shift10_win70_sumtarget_shift710win70_std
0fff81139a7105NaN29.57133.69127.03433.06330.10936.227...36.1514657.52722.6311807.5736.71672235.67862957.52710.7792497.5047.157341
1fff81139a795NaN28.67729.57133.69127.03433.06330.109...36.3539057.52722.6311817.6956.81252636.15965757.52722.6312531.1766.566787
2fff81139a785NaN21.92528.67729.57133.69127.03433.063...36.0273057.52722.6311801.3656.92959236.06824357.52722.6312524.7776.669118
3fff81139a775NaN29.60321.92528.67729.57133.69127.034...35.8751057.52722.6311793.7557.06349235.95405757.52722.6312516.7846.770835
4fff81139a765NaN30.27929.60321.92528.67729.57133.691...36.0508057.52722.6311802.5407.08692035.97740057.52722.6312518.4186.786546

5 rows × 79 columns

模型融合

进行模型融合的前提是有多个模型的输出结果,比如使用catboost、xgboost和lightgbm三个模型分别输出三个结果,这时就可以将三个结果进行融合,最常见的是将结果直接进行加权平均融合。
下面我们构建了cv_model函数,内部可以选择使用lightgbm、xgboost和catboost模型,可以依次跑完这三个模型,然后将三个模型的结果进行取平均进行融合。
对于每个模型均选择经典的K折交叉验证方法进行离线评估,大体流程如下:

  1. K折交叉验证会把样本数据随机的分成K份;

  2. 每次随机的选择K-1份作为训练集,剩下的1份做验证集;

  3. 当这一轮完成后,重新随机选择K-1份来训练数据;

  4. 最后将K折预测结果取平均作为最终提交结果。

# 这段代码运行特别久,几乎半个小时!
from sklearn.model_selection import StratifiedKFold, KFold, GroupKFold
import lightgbm as lgb
import xgboost as xgb
from catboost import CatBoostRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error

def cv_model(clf, train_x, train_y, test_x, clf_name, seed=2024):
    '''
    clf: 调用的模型(LightGBM、XGBoost 或 CatBoost)
    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 = train_x.iloc[train_index], train_y[train_index]
        val_x, val_y = train_x.iloc[valid_index], train_y[valid_index]

        if clf_name == "lgb":
            train_matrix = lgb.Dataset(trn_x, label=trn_y)
            valid_matrix = lgb.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': 2024,
                'nthread': 16,
                'verbose': -1,
                'device': 'gpu'
            }
            model = lgb.train(params, train_matrix, 1000, valid_sets=[train_matrix, valid_matrix],
                              categorical_feature=[], callbacks=[lgb.early_stopping(100), lgb.log_evaluation(200)])
            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': 'gpu_hist',
                'seed': 520,
                'nthread': 16
            }
            train_matrix = xgb.DMatrix(trn_x, label=trn_y)
            valid_matrix = xgb.DMatrix(val_x, label=val_y)
            test_matrix = xgb.DMatrix(test_x)

            watchlist = [(train_matrix, 'train'), (valid_matrix, 'eval')]

            model = xgb.train(xgb_params, train_matrix, num_boost_round=1000, 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, 'task_type': 'GPU'}

            model = CatBoostRegressor(iterations=1000, **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[train_cols], train['target'], test[train_cols], 'lgb')
# 选择xgboost模型
xgb_oof, xgb_test = cv_model(xgb, train[train_cols], train['target'], test[train_cols], 'xgb')
# 选择catboost模型
cat_oof, cat_test = cv_model(CatBoostRegressor, train[train_cols], train['target'], test[train_cols], 'cat')

# 进行取平均融合
final_test = (lgb_test + xgb_test + cat_test) / 3
# 保存结果文件到本地
test['target'] = final_test
test[['id','dt','target']].to_csv('submit3.1.csv', index=None)

# 如果前面模型没有变动,则保存目前的结果以便日后直接读取即可,就不用再重复运行前面的程序了
import numpy as np
import pandas as pd

# 将 numpy.ndarray 转换为 pandas.DataFrame
lgb_oof_df = pd.DataFrame(lgb_oof, columns=['oof'])
lgb_test_df = pd.DataFrame(lgb_test, columns=['test'])

xgb_oof_df = pd.DataFrame(xgb_oof, columns=['oof'])
xgb_test_df = pd.DataFrame(xgb_test, columns=['test'])

cat_oof_df = pd.DataFrame(cat_oof, columns=['oof'])
cat_test_df = pd.DataFrame(cat_test, columns=['test'])

# 保存 DataFrame 到 CSV 文件
lgb_oof_df.to_csv('lgb_oof.csv', index=False)
lgb_test_df.to_csv('lgb_test.csv', index=False)

xgb_oof_df.to_csv('xgb_oof.csv', index=False)
xgb_test_df.to_csv('xgb_test.csv', index=False)

cat_oof_df.to_csv('cat_oof.csv', index=False)
cat_test_df.to_csv('cat_test.csv', index=False)
import pandas as pd

# 读取 CSV 文件并转换为 numpy.ndarray
lgb_oof = pd.read_csv('lgb_oof.csv').values
lgb_test = pd.read_csv('lgb_test.csv').values

xgb_oof = pd.read_csv('xgb_oof.csv').values
xgb_test = pd.read_csv('xgb_test.csv').values

cat_oof = pd.read_csv('cat_oof.csv').values
cat_test = pd.read_csv('cat_test.csv').values

另外一种就是stacking融合。Stacking融合(Stacking Ensemble)是一种集成学习的方法,它结合了多个不同的机器学习模型,以提高整体预测性能。通过将多个基础模型的预测结果作为输入,再训练一个新的模型(称为元模型或次级模型),可以利用基础模型的多样性和不同的学习能力来提升最终的预测效果。

主要步骤:

  1. 训练基础模型(Level-0 models):
  • 将训练数据分成 K 个折(folds)。
  • 对每一折的数据,使用其他 K-1 折的数据训练基础模型,并在当前折上进行预测。
  • 对每一个基础模型,保存每一折的预测结果(称为 out-of-fold predictions),以及在测试集上的预测结果。
  1. 构建新的训练集:
  • 将所有基础模型的 out-of-fold predictions 作为特征,构建新的训练集。
  • 新的训练集的标签仍然是原始训练集的标签。
  1. 训练元模型(Level-1 model):
  • 使用新的训练集训练一个新的模型,称为元模型或次级模型。
  • 元模型可以是任何机器学习模型,通常选择简单且鲁棒的模型,如线性回归、决策树等。
  1. 最终预测:
  • 使用基础模型对测试集进行预测,将所有基础模型的预测结果作为特征,构建新的测试集。
  • 使用训练好的元模型对新的测试集进行预测,得到最终的预测结果。

Stacking参考代码:

from sklearn.model_selection import RepeatedKFold
from sklearn.linear_model import Ridge, LinearRegression
from sklearn.metrics import mean_absolute_error
import numpy as np
import pandas as pd

def stack_model(oof_1, oof_2, oof_3, predictions_1, predictions_2, predictions_3, y):
    train_stack = pd.concat([oof_1, oof_2, oof_3], axis=1) # (len(train), 3)
    test_stack = pd.concat([predictions_1, predictions_2, predictions_3], axis=1) # (len(test), 3)
    
    # 元模型
    models = {
        'Ridge': Ridge(random_state=42),
        'LinearRegression': LinearRegression(),
    }
    
    scores = {}
    oof_dict = {}
    predictions_dict = {}
    
    folds = RepeatedKFold(n_splits=5, n_repeats=2, random_state=42)
    
    for model_name, model in models.items():
        oof = np.zeros((train_stack.shape[0],))
        predictions = np.zeros((test_stack.shape[0],))
        fold_scores = []
        
        for fold_, (trn_idx, val_idx) in enumerate(folds.split(train_stack, y)): 
            print(f"Model: {model_name}, Fold {fold_+1}")
            trn_data, trn_y = train_stack.iloc[trn_idx], y.iloc[trn_idx]
            val_data, val_y = train_stack.iloc[val_idx], y.iloc[val_idx]
            
            model.fit(trn_data, trn_y)

            oof[val_idx] = model.predict(val_data)
            predictions += model.predict(test_stack) / (5 * 2)
            
            score_single = mean_absolute_error(val_y, oof[val_idx])
            fold_scores.append(score_single)
            print(f'Fold {fold_+1}/{5*2}', score_single)
        
        mean_score = np.mean(fold_scores)
        scores[model_name] = mean_score
        oof_dict[model_name] = oof
        predictions_dict[model_name] = predictions
        print(f'{model_name} Mean Score:', mean_score)
    
    # 选择得分最小的模型
    best_model_name = min(scores, key=scores.get)
    print(f'Best model: {best_model_name}')
    
    return oof_dict[best_model_name], predictions_dict[best_model_name]

# 假设 lgb_oof, xgb_oof, cat_oof, lgb_test, xgb_test, cat_test 已经定义,并且 train['target'] 是目标变量
stack_oof, stack_pred = stack_model(pd.DataFrame(lgb_oof), pd.DataFrame(xgb_oof), pd.DataFrame(cat_oof), 
                                    pd.DataFrame(lgb_test), pd.DataFrame(xgb_test), pd.DataFrame(cat_test), train['target'])

# 保存结果文件到本地
test['target'] = stack_pred
test[['id','dt','target']].to_csv('submit3.2.csv', index=None)

在官网提交多次,以上一些结果的得分大致如下,作参考。
在这里插入图片描述

深度学习方案尝试

没学过LSTM,运行太久了没跑出来。不管了,以后学了再修改。

import tensorflow as tf

# 检查可用的 GPU 设备
gpus = tf.config.list_physical_devices('GPU')
if gpus:
    print(f"GPUs detected: {gpus}")
else:
    print("No GPU detected.")
    

# 检查 TensorFlow 是否使用 GPU
print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
GPUs detected: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]
Num GPUs Available:  2
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping

print("开始读取数据...")
# 读取数据
train_data = pd.read_csv('/kaggle/input/2024abcd/train.csv')
test_data = pd.read_csv('/kaggle/input/2024abcd/test.csv')
print("数据读取完成。")

print("准备训练数据...")
# 准备训练数据,去掉非数值列
X_train = train_data.drop(columns=['target', 'id'])
y_train = train_data['target'].values

# 准备测试数据,去掉非数值列
X_test = test_data.drop(columns=['target', 'id'], errors='ignore')
test_dt = test_data['dt'].values  # 保存测试数据的 dt 列
print("训练数据准备完成。")

print("重新组织数据以适应LSTM输入...")
# 重新组织数据以适应LSTM输入
def create_sequences(X, y, seq_length):
    sequences = []
    targets = []
    
    for i in range(len(X) - seq_length):
        seq = X.iloc[i:i+seq_length].values
        target = y[i+seq_length]
        sequences.append(seq)
        targets.append(target)
        
    return np.array(sequences), np.array(targets)

SEQ_LENGTH = 10
X_train_seq, y_train_seq = create_sequences(X_train, y_train, SEQ_LENGTH)

# 将数据类型转换为 float32
X_train_seq = X_train_seq.astype(np.float32)
y_train_seq = y_train_seq.astype(np.float32)

# 注意测试数据没有目标值,因此不进行序列化处理
X_test_seq = np.array([X_test.iloc[i:i+SEQ_LENGTH].values for i in range(len(X_test) - SEQ_LENGTH)])
X_test_seq = X_test_seq.astype(np.float32)  # 转换为 float32 类型
print("数据组织完成。")

# 检查数据维度
print(f'X_train_seq 形状: {X_train_seq.shape}')
print(f'y_train_seq 形状: {y_train_seq.shape}')

print("开始构建LSTM模型...")
# 构建LSTM模型
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(SEQ_LENGTH, X_train_seq.shape[2]), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(50, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1))

model.compile(optimizer='adam', loss='mean_squared_error')
print("LSTM模型构建完成。")

# 早停回调
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)

print("开始训练模型...")
# 训练模型
history = model.fit(X_train_seq, y_train_seq, epochs=10, batch_size=128, validation_split=0.2, 
                    callbacks=[early_stopping], verbose=1)
print("模型训练完成。")

print("开始评估模型...")
# 评估模型
mse = model.evaluate(X_train_seq, y_train_seq)
print(f'Train MSE: {mse}')

print("开始对测试集进行预测...")
# 对测试集进行预测
predictions = model.predict(X_test_seq)
print("预测完成。")

print("开始保存预测结果...")
# 保存预测结果
submission = pd.DataFrame({
    'id': test_data['id'].values[SEQ_LENGTH:], 
    'dt': test_dt[SEQ_LENGTH:], 
    'target': predictions.flatten()
})
submission.to_csv('/kaggle/working/submission.csv', index=False)
print("预测结果保存完成。")

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

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

相关文章

【Vue实战教程】之Vuex状态管理详解

Vuex状态管理 1 Vuex简介 1.1 什么是Vuex Vuex是一个专为Vue.js应用程序开发的状态管理工具。它采用了集中式存储管理应用的所有的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 简单来说&#xff0c;Vuex是一个适用于在Vue项目开发时使用的状态管理…

Nginx反向代理概述

正向代理与反向代理概述 正向代理&#xff1a; 定义&#xff1a;正向代理位于客户端和目标服务器之间&#xff0c;客户端的请求首先发送到代理服务器&#xff0c;然后由代理服务器转发到目标服务器&#xff0c;最后将目标服务器的响应返回给客户端。 作用&#xff1a;正向代理…

逻辑回归推导

逻辑回归既可以看作是回归算法&#xff0c;也可以看做是分类算法。通常作为分类算法使用&#xff0c;只可以解决二分类问题。 在上述平面中&#xff0c;每个颜色代表一个类别&#xff0c;即有4个类别 将红色的做为一个类别&#xff0c;其他三个类别都统称为其他类别&#xff0…

javascript 的上下文与作用域

目录 1. 初步了解 上下文&#xff08;context&#xff09;2. 全局上下文(global context)3. 上下文栈 (context stack)4. 作用域链( scope chain)5. 作用域(scope)6. 作用域链增强7. 变量声明7.1 var 声明变量7.2 let 声明变量7.3 const 常量声明 8. 标识符查找总结 带着疑问去…

D3.高精度

1.分类情况 AB、A-B、A*a、A/b A和B指的是超大超长整数&#xff0c;长度<1e6; a的值<10000&#xff1b; 2.大整数的存储 int 变量肯定是存不了这么大的数的&#xff0c;做法是将大整数先存到string字符串&#xff0c;再使用字符串的访问方式&#xff0c;将每一位数存到…

C++树形结构(3 树的中心、重心)

目录 一.树的中心&#xff1a; 1.树的概念&#xff1a; 2.树的性质&#xff1a; 性质1&#xff1a; 性质2&#xff1a; 3.树的中心求解&#xff1a; 4.例题&#xff1a; 二.树的重心&#xff1a; 1.基础概念&#xff1a; 2.求解方法&#xff1a; 3.例题&#xff1a;…

运筹学笔记

计算的时间问题&#xff01;计算机解决了计算量的问题&#xff01; 计算机的发展对运筹学研究起到了极大的促进作用。 运筹学的一个特征之一是它常常会考虑寻求问题模型的最佳解决方案&#xff08;称为最优解&#xff09;。 没有人能成为运筹学所有方面的专家。 分析学越来越流…

反弹shell的方式——之NC反弹shell

反弹shell是指在攻击机监听某个端口&#xff0c;然后通过目标连接攻击机监听的端口&#xff0c;在攻击机反弹得到目标机的shell。通常在目标网络有防火墙或者其他因素限制&#xff0c;导致无法持续控制目标&#xff0c;或者执行命令受阻等情况时需要进行反弹shell 常见的反弹s…

Null和 Undefined 两者区别?

1、 Undefined 和 null 的 区 别 首 先 Undefined 和 Null 都 是 基 本 数 据 类 型 &#xff0c; 这 两 个 基 本 数 据 类 型 分 别 都 只 有 一 个 值 &#xff0c; 就 是 undefined 和 null。 2、undefined 代 表 的 含 义 是 未 定 义 &#xff0c; null 代 表 的 含 义 …

Python Flask入门到精通:详细教程和实战案例

前言 Flask是一个轻量级的Web框架&#xff0c;用于快速开发Web应用程序。它的设计理念是简洁、灵活和易于扩展&#xff0c;非常适合于从简单的单页应用到复杂的大型项目。通过Flask&#xff0c;可以创建各种Web应用程序&#xff0c;比如博客、电子商务网站、RESTful API等。 …

META 备受期待的 Llama 3 405B 即将发布

本心、输入输出、结果 文章目录 META 备受期待的 Llama 3 405B 即将发布前言Llama 3 405B或许会彻底改变专用模型的数据质量Llama 3 405B将形成新的模型生态系统:从基础模型到专家组合Llama 3 405B有最高效 API 的竞争Llama 3 405B 基准测试META 备受期待的 Llama 3 405B 即将…

韦东山嵌入式linux系列-具体单板的按键驱动程序(查询方式)

1 GPIO 操作回顾 &#xff08;1&#xff09;使能模块&#xff1b; &#xff08;2&#xff09;设置引脚的模式&#xff08;工作于GPIO模式&#xff09;&#xff1b; &#xff08;3&#xff09;设置GPIO本身&#xff08;输入/输出&#xff09;&#xff1b; &#xff08;4&…

Linux_make/Makefile的理解

1.make是一个命令&#xff0c;makefile是一个文件, 依赖关系和依赖方法. a.快速使用一下 i.创建一个Makefile文件(首字母也可以小写) b.依赖关系和依赖方法 i.依赖关系: 我为什么要帮你? mybin:mytest.c ii.依赖方法: 怎么帮? gcc -o mybin mytest.c make之前要注意先创建…

UE4-构建光照后导入的静态网格体变黑

当我们将我们的静态网格体导入到项目当中的时候&#xff0c;此时我们进行重新构建光照&#xff0c;我们在从新构建完光照后&#xff0c;会发现我们的静态网格体全部变黑了&#xff0c;此时是因为没有设置光照贴图分辨率和坐标索引引起的。 将General Settings中的L…

Unite 上海 强势回归

​​​ 他回归了 Unite 大会是一年一度的 Unity 全球开发者盛会。今年&#xff0c;Unite 将于 7 月盛夏点亮上海外滩。此次盛会&#xff0c;我们将以“团结”为核心&#xff0c;凝聚全球 3000 多位 Unity 社区精英的力量&#xff0c;共同开启 Unity 技术的新纪元。 在这里&am…

【C++】透析类和对象(上)

有不懂的&#xff0c;可翻阅我之前文章哦&#xff01; 个人主页&#xff1a;CSDN_小八哥向前冲 所属专栏&#xff1a;C入门 目录 类的定义 访问限定符 类域 类的实例化 实例化概念 对象大小 this指针 类的默认成员函数 构造函数 析构函数 模拟栈&#xff08;初学者&…

(最最最全)远程服务器连接新手教程-服务器基本指令、连接服务器、安装Anaconda、配置Conda、配置环境、bashrc环境变量修改(为空怎么办)

一、服务器基本指令 ls - 列出当前目录的文件和子目录cd - 改变当前目录pwd - 显示当前目录的路径df - 查看当前内存mkdir - 创建新目录rm - 删除文件cp - 复制文件mv - 移动或重命名文件 https://blog.csdn.net/weixin_43693391/article/details/133984143?ops_request_mis…

Ubuntu20.04版本升级openssh9.8p1方法

一、问题描述&#xff1a; 8.5p1 和 9.7p1 之间的openssh版本漏洞可能会导致linux系统以root身份进行RCE&#xff0c;所以需安装最新版本 二、解决方法&#xff1a; 将当前openssh版本升级到最新的版本即openssh-9.8p1版本&#xff0c;OpenSSL大版本升级且OpenSSH有新稳定版本…

今天我们聊聊C#的并发和并行

并发和并行是现代编程中的两个重要概念&#xff0c;它们可以帮助开发人员创建高效、响应迅速、高性能的应用程序。在C#中&#xff0c;这些概念尤为重要&#xff0c;因为该语言提供了对多线程和异步编程的强大支持。本文将介绍C#中并发和并行编程的关键概念、优点&#xff0c;并…

CSS(二)——CSS 背景

CSS 背景 CSS 背景属性用于定义HTML元素的背景。 CSS 背景属性 Property描述background简写属性&#xff0c;作用是将背景属性设置在一个声明中。background-attachment背景图像是否固定或者随着页面的其余部分滚动。background-color设置元素的背景颜色。background-image把…