import numpy as np
def calculate_metrics(y_true, y_pred, alpha):
"""
计算区间预测的评价指标
参数:
y_true: 真实值,shape为(n_samples,)
y_pred: 区间预测值,shape为(n_samples, 2)
alpha: 置信水平,取值范围为(0, 1)
返回:
PICP: 区间预测置信度,float
PINAW: 区间预测置信区间宽度,float
SCORE: 区间预测得分,float
SKILL_SCORE: 区间预测技能得分,float
COVERAGE: 区间覆盖率,float
WIDTH: 区间宽度,float
"""
lower_bound = y_pred[:, 0]
upper_bound = y_pred[:, 1]
n_samples = len(y_true)
# 计算PICP
in_interval = np.logical_and(y_true >= lower_bound, y_true <= upper_bound)
PICP = np.sum(in_interval) / n_samples
# 计算PINAW
PINAW = np.mean(upper_bound - lower_bound)
# 计算SCORE
score = np.zeros(n_samples)
for i in range(n_samples):
if y_true[i] < lower_bound[i]:
score[i] = 2 * (lower_bound[i] - y_true[i]) / (upper_bound[i] - lower_bound[i])
elif y_true[i] > upper_bound[i]:
score[i] = 2 * (y_true[i] - upper_bound[i]) / (upper_bound[i] - lower_bound[i])
else:
score[i] = 0
SCORE = np.mean(score)
# 计算SKILL_SCORE
skill_score = np.zeros(n_samples)
for i in range(n_samples):
if y_true[i] < lower_bound[i] or y_true[i] > upper_bound[i]:
skill_score[i] = -1
else:
skill_score[i] = 2 * (upper_bound[i] - lower_bound[i]) / (upper_bound[i] - lower_bound[i] + (y_pred[i, 0] - y_true[i]) ** 2 + (y_true[i] - y_pred[i, 1]) ** 2)
SKILL_SCORE = np.mean(skill_score)
# 计算COVERAGE
COVERAGE = np.sum(upper_bound - lower_bound) / n_samples
# 计算WIDTH
WIDTH = np.mean(upper_bound - lower_bound)
return PICP, PINAW, SCORE, SKILL_SCORE, COVERAGE, WIDTH
以上代码来自“给我写一个采用PICP、PINAW、SCORE 、SKILL SCORE、区间覆盖率、区间宽度来评价区间预测的代码 - CSDN文库”
CWC作为区间预测的评价指标,论文IEEE Xplore Full-Text PDF:指出是不合适的。
时间序列预测之区间预测方法(PIs:MVE&Delta&Bayesian&Bootstrap&LUBE) | 码农家园 (codenong.com)
这个链接有每个公式的解释。
以下是我修改后的代码
''' SCORE:衡量真实值(y_true)与预测区间(由上限upper_bound和下限lower_bound定义)之间的偏差程度。'''
''' http://dx.doi.org/10.1016/j.energy.2014.06.104'''
# alpha = 0.01;0.05;0.1 置信水平(1-alpha)%,为99%,95%,90%
def calculate_S(alpha, Li, Ui, true):
m = len(true)
S = 0
for i in range(m):
di = Ui[i] - Li[i]
if true[i] < Li[i]:
Si = -2 * alpha * di - 4 * (Li[i] - true[i])
elif true[i] >= Li[i] and true[i] <= Ui[i]:
Si = -2 * alpha * di
else:
Si = -2 * alpha * di - 4 * (true[i] - Ui[i])
S += Si
S /= m
SCORE = np.abs(S) # 确保Socre的值是正数,值越小越好
return SCORE
alpha = 1- confidence
SCORE = calculate_S(alpha, Lower_sequence, Upper_sequence,true)
print()
print('SCORE', SCORE)
''' MPICD:'''
def calculate_MPICD(true, Li, Ui):
m = len(true)
MPICD = 0
for i in range(m):
pi = true[i]
avg = (Ui[i] + Li[i]) / 2
diff = abs(avg - pi)
MPICD += diff
MPICD /= m
return MPICD
MPICD = calculate_MPICD(true, Lower_sequence, Upper_sequence)
print("MPICD", MPICD)