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

第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【3】【计算最终得分】

第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【3】【计算最终得分】

声明
  1. 系列博客不会出现任何真实数据
  2. 比赛期间将拒绝一切私信,有问题请发评论

系列文章目录

第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【0】【风况预测评分规则-最终得分R的计算】【已弃用】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【1】【验证集制作】【已弃用】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【2】【验证集使用】【已弃用】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【3】【计算最终得分】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【4】【数据管理】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【5】【数据可视化】【测试集_初赛】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【6】【数据可视化】【训练集】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【7】【数据管理】【验证集本地化】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【8】【数据可视化】【验证集】
第五届全国工业互联网数据创新应用大赛 机组数据驱动的风电场短期风况预测 【9】【数据可视化】【气象数据】


文章目录
  • 声明
  • 系列文章目录
  • 更新说明
  • 前言
  • 一、评分规则
  • 二、评分规则计算思路
  • 三、编程实现计算过程
    • 1. 模仿答案样本生成“预测值”和“真实值”
    • 2. 计算预测误差
      • 2.1 mj
      • 2.2 nj
    • 3 计算平均预测误差
    • 4. 计算最终得分R
  • 四、 封装


更新说明


前言

了解比赛的评分规则,可谓是比赛过程中非常重要的一环,从评分规则中可以得到很多信息,比如出题者在关注什么,损失函数的设计思路等。接下来就让我们来研究一下评分规则,然后把它代码化。


一、评分规则

评分规则的图片来源于大赛官网

二、评分规则计算思路

开始之前我觉得有必要先介绍一下数据集

  1. 一共有2个风场,每个风场25台风机
  2. 关于时段,每个时段的时间是1小时(3600秒),时间分辨率为30秒,也就是说一个时段有120行数据
    • 训练集每台风机一共两年(2 * 365 * 24 = 17520 个时段)
    • 测试集每台风机一共160个时段(初赛80段,春夏秋冬各20段,编号01~20;决赛80段,春夏秋冬各20段,编号21~40)
  3. 预测目标:某时段的未来10分钟,时间分辨率为30秒,也就是说需要预测20行数据

要求 R R R ,就要先求各个风场各个时段的平均预测误差

图1

要求 E ⋅ i E_{cdot i} E⋅i​,就要先求各个风机预测误差,然后求平均值

图2

要求 m j m_j mj​ 和 n j n_j nj​,就要先有风速和风向的预测值与真实值

图3

接着只需要一步一步计算回去就好了,但是怎样计算最高效呢?

观察一下答案样本,位置基本上都是特定的,比如第1 ~ 20行是风场1风机x26时段春_01的10分钟风速风向数据,第21 ~ 40行是风场1风机x26时段春_02的10分钟风速风向数据,最后20行是风场2风机x49时段冬_20的10分钟风速风向数据,然后风场、风机、时段、时刻的排列是有顺序的。位置固定,顺序已知,就是待会我们实现高效计算的基础。

图4
三、编程实现计算过程

由于现阶段还没有预测值,也没有真实值,所以拿随机数来代替一下先

先看一下答案样本

1. 模仿答案样本生成“预测值”和“真实值”
import itertools

import numpy as np
import pandas as pd
field = np.array([
    '风场1',
    '风场2'
])
field_len = field.shape[0]

machine = np.array([
    [f'x{i}' for i in range(26, 50+1)],
    [f'x{i}' for i in range(25, 49+1)]
])
machine_len = machine[0].shape[0]

season = np.array(['春', '夏', '秋', '冬'])
season_len = season.shape[0]

period = np.array([f'{s}_{str(i).zfill(2)}' for s in season for i in range(1, 20+1)])
period_len = period.shape[0]
df = pd.Dataframe(
    data = np.array([
        [*x0, x1, x2, x3, x4] for x0, x1, x2, x3, x4 in 
            itertools.product(
                np.vstack([list(itertools.product([field[f]], machine[f])) for f in range(field_len)]).tolist(),    # '风场', '风机'
                period,                     # '时段'
                np.arange(1, 20+1) * 30,    # '时刻'
                [None],                     # '风速'
                [None]                      # '风向'
            )
    ]),
    columns = ['风场', '风机', '时段', '时刻', '风速', '风向']
)
df

睁大你的眼睛看好了,这数据是np.random.random(size=(2 * 25 * 80 * 20, 2)),不是真实数据哈

val_true = df.copy()
val_true.loc[:, ['风速', '风向']] = np.random.random(size=(2 * 25 * 80 * 20, 2))
val_true

睁大你的眼睛看好了,这数据是np.random.random(size=(2 * 25 * 80 * 20, 2)),不是真实数据哈

val_pred = df.copy()
val_pred.loc[:, ['风速', '风向']] = np.random.random(size=(2 * 25 * 80 * 20, 2))
val_pred

2. 计算预测误差

图5
2.1 mj

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

预测值和真实值都有了,现在还差这个 w

w = np.arange(2 * 25 * 80 * 20, dtype=float) % 20
print(w[:20], w[20:40], w[40:60], sep='n')

w[w < 10] = 0.06
w[w >= 10] = 0.04

print(w[:20], w[20:40], w[40:60], sep='n')

这样,就为每个风场每个风机每个时段每个时刻都生成对应的 w 值了

接下来计算公式3

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

m = (w * np.abs(val_pred['风速'] - val_true['风速']).values).reshape(2 * 25 * 80, 20).sum(-1)
m.shape

公式中的求和体现在.reshape(2 * 25 * 80, 20).sum(-1)

2.2 nj

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

alpha 本质上就是部分权重为0的 w ,为什么变 0,是因为风速小所以风向不稳定。这个判断的阈值两个风场不一样。

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

前面一半是风场1,后面一半是风场2,直接根据这个生成阈值

threshold = np.repeat([0.15, 0.086], 25 * 80 * 20)
threshold

当风速小这个阈值时,w 置 0

a = w * (val_true['风速'].values > threshold)
a

注:符合条件为True,不符合条件为False,True 默认为 1, False 默认为 0。

直接按公式计算就可以了

e = np.minimum(np.mod((val_pred['风向'] - val_true['风向']).values, 1), np.mod((val_true['风向'] - val_pred['风向']).values, 1))

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

n = (a * e).reshape(2 * 25 * 80, 20).sum(-1)
n.shape

公式中的求和体现在.reshape(2 * 25 * 80, 20).sum(-1)

3 计算平均预测误差

图6

记住,位置固定,顺序已知。2个风场,每个风场25个风机,每个风机80个时段,每个时段20个时刻

E1, E2 = (0.7 * m + 0.3 * n).reshape(2, 25, 80).mean(1)
E1.shape, E2.shape

4. 计算最终得分R

图7
R = 100 / (1 + E1.sum() + E2.sum())
R

根据公式以及极限的知识可知,最高分无限接近于100分,最低分无限接近于0分。

随机数都能得2分,能得0分某种程度上也是挺厉害的。。

四、 封装

假设你存放真实数据的文件名为val_true.csv
假设你存放预测数据的文件名为val_pred.csv

问:这俩东西在哪搞?
答:【7】【数据管理】【验证集本地化】

import itertools

import numpy as np
import pandas as pd

field = np.array([
    '风场1',
    '风场2'
])
field_len = field.shape[0]

machine = np.array([
    [f'x{i}' for i in range(26, 50+1)],
    [f'x{i}' for i in range(25, 49+1)]
])
machine_len = machine[0].shape[0]

season = np.array(['春', '夏', '秋', '冬'])
season_len = season.shape[0]

period = np.array([f'{s}_{str(i).zfill(2)}' for s in season for i in range(1, 20+1)])
period_len = period.shape[0]
def standardize(val_df):
    
    """
    记住,位置固定,顺序已知。
    不管你是有缺失值还是顺序不对,这段代码都帮你解决。
    """
    
    df = pd.Dataframe(
        data = np.array([
            [*x0, x1, x2, x3, x4] for x0, x1, x2, x3, x4 in 
                itertools.product(
                    np.vstack([list(itertools.product([field[f]], machine[f])) for f in range(field_len)]).tolist(),    # '风场', '风机'
                    period,                     # '时段'
                    np.arange(1, 20+1) * 30,    # '时刻'
                    [None],                     # '风速'
                    [None]                      # '风向'
                )
        ]),
        columns = ['风场', '风机', '时段', '时刻', '风速', '风向']
    )

    return pd.merge(
        left = df[['风场', '风机', '时段', '时刻']].copy(),
        right = val_df,
        how = 'left',
        on = ['风场', '风机', '时段', '时刻']
    ).fillna(0)
def cal_R():
    
    val_true = standardize(pd.read_csv('val_true.csv', encoding='utf-8'))
    val_pred = standardize(pd.read_csv('val_pred.csv', encoding='utf-8'))

    # 公式 6
    w = np.arange(2 * 25 * 80 * 20, dtype=float) % 20
    w[w < 10] = 0.06
    w[w >= 10] = 0.04

    # 公式 3
    m = (w * np.abs(val_pred['风速'] - val_true['风速']).values).reshape(2 * 25 * 80, 20).sum(-1)

    # 公式 7
    threshold = np.repeat([0.15, 0.086], 25 * 80 * 20)
    a = w * (val_true['风速'].values > threshold)
    # 公式 5
    e = np.minimum(np.mod((val_pred['风向'] - val_true['风向']).values, 1), np.mod((val_true['风向'] - val_pred['风向']).values, 1))
    # 公式 4
    n = (a * e).reshape(2 * 25 * 80, 20).sum(-1)

    # 公式 2
    # 2个风场,每个风场25个风机,每个风机80个时段
    E1, E2 = (0.7 * m + 0.3 * n).reshape(2, 25, 80).mean(1)

    # 公式 1
    R = 100 / (1 + E1.sum() + E2.sum())
    print(f'R: {R:.3f}')
cal_R()


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

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

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