栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【1】【验证集制作】

第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【1】【验证集制作】

系列

【风况预测评分规则-python实现】第五届全国工业互联网数据创新应用大赛-机组数据驱动的风电场短期风况预测
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【1】【验证集制作】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【2】【验证集使用】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【3】【计算最终得分】

前言

上传答案返回成绩的机会每周只有3次,机会非常宝贵,为了能够随时验证自己的模型,于是这个博客应运而生。

验证集格式及数据来源(具体实现请看代码注释)
  1. 验证集和测试集的文件夹组织形式完全一致
  2. 文件名和测试集的文件名对应
    • 验证集_初赛 <- 测试集_初赛
    • 验证集_决赛 <- 测试集_决赛
  3. 验证数据完全遵从测试集说明
    • 验证样本区间:Y年M月D 日 的 00:00:30 -> Y年M月D日 的 01:00:00,共 120 行数据(30S分辨率,单位:秒)
    • 答案数据区间:Y年M月D 日 的 01:00:30 -> Y年M月D日 的 01:10:00,共 20 行数据(30S分辨率,单位:秒)
    • 气象数据区间:Y年M月D-1日 的 13:00:00 -> Y年M月D日 的 02:00:00,共 14 行数据(1H分辨率,单位:时)
    • 验证集的答案和答案样本说明一致
      • 若测试集含有部分时段缺失的情况,对于缺失值,一律用 0 填充

代码部分 1. 基本的准备
  • 部分变量名来源(采用谷歌翻译,省略“风”)
    • 风场: field
    • 风机: machine
    • 时段: period
    • 时刻: time
    • 风速: speed
    • 风向: direction
import glob
import os
import threading
from tqdm import tqdm
import warnings
warnings.filterwarnings('ignore')

import numpy as np
import pandas as pd
train_dir, test_dir, val_dir = 'train', '测试集_初赛', '验证集_初赛'

field_1, field_2 = '风场1', '风场2'

machine_1 = [f'x{i}' for i in list(range(26, 50+1))]
machine_2 = [f'x{i}' for i in list(range(25, 49+1))]

period = [f'{s}_{str(i).zfill(2)}' for s in ['春', '夏', '秋', '冬'] for i in range(1, 20+1)]


2. 气象数据相关准备 2.1. 准备容器存储验证集气象数据
field_1_weather_val = pd.Dataframe(
    data = {
        '时段': np.array(period * 14).reshape(14, 80).T.flatten(),
        '时刻': np.array(list(range(-11, 3)) * 80),
        '风速': None,
        '风向': None
    }
)

field_2_weather_val = pd.Dataframe(
    data = {
        '时段': np.array(period * 14).reshape(14, 80).T.flatten(),
        '时刻': np.array(list(range(-11, 3)) * 80),
        '风速': None,
        '风向': None
    }
)

2.2. 读取训练集气象数据
field_1_weather_train = pd.read_csv(os.path.join(train_dir, field_1, 'weather.csv'), encoding='utf-8')
field_2_weather_train = pd.read_csv(os.path.join(train_dir, field_2, 'weather.csv'), encoding='utf-8')

# 添加一个索引,方便后面制作验证集的气象数据
field_1_weather_train.insert(0, 'date', np.array([s.split(' ')[0].replace('/', '-') for s in field_1_weather_train['time'].values]))
field_2_weather_train.insert(0, 'date', np.array([s.split(' ')[0].replace('/', '-') for s in field_2_weather_train['time'].values]))

3. 答案相关准备 3.1. 准备容器存储答案数据
field_len = 2
machine_len = 25
period_len = 80

field = [field_1, field_2]
machine = [machine_1, machine_2]
time = [i * 30 for i in range(1, 20+1)]
time_len = len(time)

answer_val = pd.Dataframe(
    data={
        '风场': np.array(field * machine_len * period_len * time_len).reshape(-1, field_len).T.reshape(-1),
        '风机': np.array(machine * period_len * time_len).reshape(-1, field_len * machine_len).T.reshape(-1),
        '时段': np.array(np.array(period * time_len).reshape(-1, period_len).T.reshape(-1).tolist() * field_len * machine_len),
        '时刻': np.array(time * field_len * machine_len * period_len),
        '风速': None,
        '风向': None
    }
)

4. 验证数据相关准备 4.1. 生成与测试集对应的空文件夹

df.to_csv() 要求保存路径存在,不然会报错
FileNotFoundError: [Errno 2] No such file or directory

os.makedirs(val_dir, exist_ok=True)

os.makedirs(os.path.join(val_dir, field_1), exist_ok=True)
os.makedirs(os.path.join(val_dir, field_2), exist_ok=True)

[os.makedirs(os.path.join(val_dir, field_1, machine), exist_ok=True) for machine in machine_1];
[os.makedirs(os.path.join(val_dir, field_2, machine), exist_ok=True) for machine in machine_2];
4.2. 读取所有测试数据路径

path_list = glob.glob(os.path.join(test_dir, '*', 'x*', '*'))

5. 季节判定


  • 同一季节时间范围
    • 春 02-05 ~ 05-06
    • 夏 05-07 ~ 08-07
    • 秋 08-08 ~ 11-07
    • 冬 11-08 ~ 02-04
def check_file(train_file_path, target_season):
    
    """
    季节是否对应
    数据是否含缺失值
    """
    
    month, day = train_file_path.split(os.sep)[-1].split('.')[0].split('-')[1:]
    month, day = int(month), int(day)
    
    if (month == 2 and day >= 5) or month == 3 or month == 4 or (month == 5 and day <= 6):
        season = '春'
    if (month == 5 and day >= 7) or month == 6 or month == 7 or (month == 8 and day <= 7):
        season = '夏'
    if (month == 8 and day >= 8) or month == 9 or month == 10 or (month == 11 and day <= 7):
        season = '秋'
    if (month == 11 and day >= 8) or month == 12 or month == 1 or (month == 2 and day <= 4):
        season = '冬'
    
    if season == target_season:
        if len(pd.read_csv(train_file_path)[1:141].dropna()) == 140:
            return True
    
    return False
6. 开始制作验证集和验证集的答案
# path_list 存放了所有测试数据路径,根据这些路径一一制作与之对应的验证集

for test_file_path in tqdm(path_list):
    
    # 验证数据保存位置,与测试集相对应
    val_file_path = test_file_path.replace('测试', '验证')
    
    # 当前测试数据路径的信息(风场,风机,时段)
    _, field_test, machine_test, period_test = test_file_path.split(os.sep)
    
    # 验证数据从训练集中来(train),又要与测试集对应(风场对应,风机对应)
    machine_train = os.path.join(train_dir, field_test, machine_test)
    
    # 当前测试集对应的验证集制作成功就会保存到相应位置,未成功的话就一直循环到成功为止
    while not os.path.exists(val_file_path):
        
        # 从当前指定的训练集风机文件夹中抽取 1 个历史数据文件
        # 为防止BUG,采样时不包含现有历史数据的头一天,因为头一天没有前一天
        target_file_path = os.path.join(machine_train, np.random.choice(os.listdir(machine_train)[1:], 1)[0])
        
        # 检查文件是否符合标准,不符合标准就重新采样
        if check_file(target_file_path, period_test.split('_')[0]):    # period_test.split('_')[0] 将 '冬_01.csv' 变成 '冬'
            
            train_data = pd.read_csv(target_file_path)
            
            # -------------------- 制作时段数据 --------------------
            
            val_data = train_data[1:121]    # [1:121] 代表 00:00:30 -> 01:00:00
            val_data['time'] = np.arange(1, 121) * 30
            val_data.to_csv(val_file_path, float_format='%.7f', index=False, encoding='utf-8')
            
            # -------------------- 制作气象数据 --------------------
            
            date = target_file_path.split(os.sep)[-1].split('.')[0]    # 目标数据的日期。例如 2018-10-01
            date_list = eval(f'field_{field_test[-1]}_weather_train')['date']    # 前面添加的索引现在派上用场了
            
            # 目标气象数据在历史气象数据中的第一个数据的索引
            weather_data_index = np.where(date == date_list)[0][0]
            
            # 目标气象数据
            weather_data = eval(f'field_{field_test[-1]}_weather_train')[weather_data_index-11: weather_data_index+3][['wind_spd', 'wind_dir']].values
            eval(f'field_{field_test[-1]}_weather_val').loc[eval(f'field_{field_test[-1]}_weather_val')['时段'] == period_test.split('.')[0], ['风速', '风向']] = weather_data
            
            # -------------------- 制作答案数据 --------------------
            
            answer_data = train_data[121:141][['风速', '风向']].values    # [121:141] 代表 01:00:30 -> 01:10:00
            answer_val.loc[((answer_val['风场'] == field_test) * (answer_val['风机'] == machine_test) * (answer_val['时段'] == period_test.split('.')[0])), ['风速', '风向']] = answer_data
field_1_weather_val.to_csv(os.path.join(val_dir, field_1, 'weather.csv'), index=False, encoding='utf-8')
field_2_weather_val.to_csv(os.path.join(val_dir, field_2, 'weather.csv'), index=False, encoding='utf-8')

answer_val.fillna(0).to_csv('answer_val.csv', index=False, encoding='utf-8')
一些问题
  1. 验证集时间过于集中。我们需要的是能够预测任意时间的模型,不是只预测 01:00:30 -> 01:10:00 这一小段时间。
    • 这个问题过段时间就改进,难点还是在缺失值,毕竟是时序问题。
  2. 验证数据浮点精度问题。官方提供的测试集浮点精度在16位左右,而本代码所制作的验证集浮点精度只有7位。
    • 无法改进,因为验证集数据来源于训练集,训练集本来就是这样的,后面几位小数训练集不存在我也不能变出来对吧。
验证集咋用

你可以参考(【风况预测评分规则-python实现】第五届全国工业互联网数据创新应用大赛-机组数据驱动的风电场短期风况预测)
也可以等我的下一期博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/300872.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号