0%

FSS_FractionScoreSkill

思想

问题

http://shuwenlovestudy.top/FSS_FractionScoreSkill%20/%E5%BC%95%E5%85%A5%E9%97%AE%E9%A2%98.png

对于如上预测场和观测场,虽然降水都分布在7个降水格点上,但位置均未能一一对应,所以其TS评分等评分为0(没有降水预报技巧),但从概率角度看,观测与预报的降水发生概率是一样的,7/49,具有相同的降水预报面积

FSS

作者:Robert、Lean(2008)

作用:考察不同尺度内降水发生概率

具体公式

按步骤

  1. Brier评分的变形:比较预报与观测的降水频率 FBS (Fraction Brier Score)

    公式:$FBS = \frac{1}{N} \displaystyle \sum_{N}(P_{fcst} - P_{obs})^2$

    $P_{fcst}$、$P_{obs}$:每个领域尺度内 预报与预测降水发生概率(0 - 1)

    N:网格数量

  2. 方差技巧评分:获取正定的(特征值均为正)评分

    公式:$FSS = 1 - \frac{FBS} {\frac{1}{N}(\displaystyle \sum_N P_{fcst}^2 + \displaystyle \sum_N P_{obs}^2)}$

    FSS

    1. 范围(0 - 1)

      0 :完全不匹配

      1:完美匹配

    2. 特点:
      领域尺度增加 -> FSS评分增大

      当$P_{fcst} = bP_{obs}$,FSS评分向 $2b/(b^2+1)$ 渐近

简写

$FSS = 1 - \frac{\frac{1}{N} \displaystyle \sum_{N}(P_{fcst} - P_{obs})^2} {\frac{1}{N}(\displaystyle \sum_N P_{fcst}^2 + \displaystyle \sum_N P_{obs}^2)}$

代码

R语言

代码

链接:https://rdrr.io/cran/verification/src/R/fss.R#heading-0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
fss <- function(obs, pred, w = 0, FUN = mean, ...){
### compare matrixes of forecast of observed values and forecast.
### values can be calcuated using different windows.

### with a window size of 0, obs is returned.
obs.matrix <- matrix.func(DAT = obs, w = w, FUN = FUN)

### with a window size of 0, obs is returned.
frcs.matrix <- matrix.func(DAT = pred, w = w, FUN = FUN)

if(nrow(obs)!= nrow(pred) & ncol(obs)!= nrow(obs) ) stop("Observation matrix and forecast matrix different sizes")

n <- prod(dim(obs.matrix)) ### number of gridpoints

N <- sum((obs.matrix-frcs.matrix)^2, na.rm = TRUE)/n ### numerator
D <- (sum(obs.matrix^2, na.rm = TRUE) +sum(frcs.matrix^2, na.rm = TRUE))/n ### denominator

FSS <- 1 - N/D
return(FSS)
}

matrix.func <- function(DAT, w = 0, FUN = mean, ...){

### w is the '' radius'' of window. eg. w = 2, defines a 5 by 5 square

### define function
FUN <- match.fun(FUN)

### define output dimension
II <- nrow(DAT) - 2*w ## output row dimension
JJ <- ncol(DAT) - 2*w

if(JJ<=0|II <= 0) {stop("The window exceeds the size of the observation" ) }
OUT <- matrix(NA, nrow= II, ncol = JJ)

for(i in 1:II){
for(j in 1:JJ){
sub <- DAT[ i :(i + 2*w ),
j :(j + 2*w ) ] # subset data

OUT[i,j] <- FUN(sub,...)
} ## close J
} ## close I

return(OUT)
} ## close functionr

测试

链接:https://rdrr.io/cran/verification/man/fss.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
library(verification)

grid<- list( x= seq( 0,5,,100), y= seq(0,5,,100))
obj<-Exp.image.cov( grid=grid, theta=.5, setup=TRUE)
look<- sim.rf( obj)
look[look < 0] <- 0

look2 <- sim.rf( obj)
look2[look2<0] <- 0

fss(look, look2, w=5)


## Not run:
# The following example replicates Figure 4 in Roberts and Lean (2008).
#### examples

LAG <- c(1,3,11,21)
box.radius <- seq(0,24,2)

OUT <- matrix(NA, nrow = length(box.radius), ncol = length(LAG) )

for(w in 1:4){

FRCS <- OBS <- matrix(0, nrow = 100, ncol = 100)

obs.id <- 50
OBS[,obs.id] <- 1

FRCS[, obs.id + LAG[w]] <- 1

for(i in 1:length(box.radius)){

OUT[i, w] <- fss(obs = OBS, pred = FRCS, w = box.radius[i] )

} ### close i
} ### close w

b <- mean(OBS) ## base rate

fss.uniform <- 0.5 + b/2
fss.random <- b

matplot(OUT, ylim = c(0,1), ylab = "FSS", xlab = "grid squares",
type = "b", lty = 1, axes = FALSE , lwd = 2)

abline(h = c(fss.uniform, fss.random), lty = 2)
axis(2)
box()
axis(1, at = 1:length(box.radius), lab = 2*box.radius + 1)
grid()

legend("bottomright", legend = LAG, col = 1:4, pch = as.character(1:4),
title = "Spatial Lag", inset = 0.02, lwd = 2 )

## End(Not run)

结果截图

http://shuwenlovestudy.top/FSS_FractionScoreSkill%20/r%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%9C%E5%9B%BE.png

Python

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import numpy as np 

def func(data, w = 0):
row = data.shape[0]
col = data.shape[1]

ii = row - 2 * w
jj = col - 2 * w

if(ii <= 0 or jj <=0):
print("error!")

out = np.zeros((ii, jj))

for i in range(1, ii):
for j in range(1, jj):

sub = data[i : (i + 2 * w + 1), j : (j + 2 * w + 1)]

out[i, j] = np.mean(sub)
return out

def fss(obs, fc, w = 0):
obs_m = func(obs, w)
# print(obs_m[0][16])
# print(obs_m[0][17])
# print(obs_m[0][18])
fc_m = func(fc, w)
# print(obs_m)
# print(fc_m)
n = obs_m.shape[0] * obs_m.shape[1]
N = ((obs_m - fc_m) ** 2).sum() / n
# print(N.shape)
D = ((obs_m ** 2).sum() + (fc_m ** 2).sum()) / n
# print(n)
# print(N)
# print(D)
return 1 - N / D

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import matplotlib.pyplot as plt

lag = [1, 3, 11, 21]
radius = np.arange(0, 24 + 2, 2)

out = np.zeros((len(radius), len(lag)))

frcs = np.zeros((100, 100))
obs = np.zeros((100, 100))

id = 50 - 1
obs[ : , id] = 1

for l in range(0, len(lag)):
for r in range(0, len(radius)):
frcs[ : , id + lag[l - 1]] = 0
frcs[ : , id + lag[l]] = 1
out[r][l] = fss(obs, frcs, radius[r])
b = np.mean(obs)
uniform = 0.5 + b / 2
random = b

plt.plot(out)
plt.ylabel("FSS")
plt.xlabel("grid squares")

结果截图

http://shuwenlovestudy.top/FSS_FractionScoreSkill%20/python%E7%BB%93%E6%9E%9C%E5%9B%BE.png

坐标可以自定义修改,值是一样的

http://shuwenlovestudy.top/FSS_FractionScoreSkill%20/%E7%BB%93%E6%9E%9C%E7%9F%A9%E9%98%B5.png

下载

Roberts2008原文

Q:如果阅读本文需要付费,你是否愿意为此支付1元?