데이터 기반 기상 예측
먼저 읽을 장 27.1 기상·기후 데이터의 기초18.7 시계열 딥러닝
수치 예보는 대기의 운동 방정식을 슈퍼컴퓨터로 적분해 미래를 계산한다. 데이터 기반 예보는 같은 일을 다르게 한다. 수십 년의 재분석 자료에서 "지금 대기 상태가 이렇다면 6시간 뒤에는 이렇다"는 사상을 학습하고, 그 사상을 반복해 며칠 뒤까지 굴린다. 이 접근은 최근 몇 년 사이 중기 예보(며칠에서 2주)에서 수치 예보와 견줄 만한 점수를 보고하며 빠르게 자리 잡았다.
이 장은 특정 모델을 재현하지 않는다. 그 대신 어떤 데이터 기반 예보 논문을 읽거나 직접 모델을 만들 때 필요한 판단을 다룬다. 문제를 어떻게 정의하는가, 구면 위의 상태를 어떤 구조로 다루는가, 자기 출력을 다시 입력으로 넣을 때 무엇이 깨지는가, 결정론적 예보와 확률적 예보는 무엇이 다른가, 그리고 이 모든 것을 어떤 baseline에 대해 보고해야 하는가. 시계열 예측의 일반론(18.7장)과 데이터 분할(15.4장)은 이미 보았으므로, 여기서는 대기라는 대상에 맞춰 무엇이 달라지는지에 집중한다.
학습 목표
- 데이터 기반 예보 모델의 구조를 이해한다
- 결정론적 예보와 확률적 예보를 구분한다
- 리드 타임별 성능을 지속성·기후값 baseline과 시간 누수 없는 분할로 평가한다
문제 정의
왜 필요한가. "기상 예보 모델이 RMSE 1.6을 얻었다"는 문장은 정보가 없다. 무엇을, 몇 시간 뒤까지, 어떤 정답에 대해, 무엇과 비교해 얻은 1.6인지가 빠졌다. 문제 정의는 이 네 가지를 정하는 일이다.
정의. 대기 상태 는 격자 위의 여러 변수(기압면별 기온·바람·습도·지위고도, 지표 변수)를 모은 큰 벡터다. 데이터 기반 예보 모델은 한 step (흔히 6시간) 뒤의 상태를 예측하는 사상
를 학습한다. 는 시각·태양 복사·지형·해륙 분포 같은 외부 정보다. 예보 시작 시각부터 예측 시각까지의 시간을 리드 타임(lead time)이라 한다. 며칠 뒤의 예보는 를 자기 출력에 반복 적용해 얻는다.
이 반복을 autoregressive rollout이라 한다. 19.2장의 자기회귀 모델, 18.7장의 recursive 다중 horizon 예측과 같은 구조다.
baseline. 기상 예보에는 오래 쓰여 온 두 baseline이 있다.
- 지속성(persistence): 지금 상태가 그대로 유지된다고 예측한다. . 짧은 리드에서 이기기 어렵다.
- 기후값(climatology): 그 시기의 평년값을 예측한다(27.1장). 긴 리드에서 이기기 어렵다.
두 baseline의 성질을 장난감 대기로 확인한다. Lorenz-96 모형(Lorenz, 1996)은 위도권 한 바퀴를 따라 놓인 개의 격자점이
를 따르는 계다. 2차 항은 상태를 이웃으로 옮기는 이류(advection), 는 감쇠, 는 외부 강제력을 흉내 낸다. 이면 혼돈적이고, 시간 0.05가 대기의 약 6시간에 해당하도록 척도를 잡는 것이 관례다. 크기가 작아 브라우저에서 돌지만 오차가 자라는 방식은 실제 대기와 닮았다.
import numpy as np
K, F, DT = 40, 8.0, 0.05 # 격자점 수, 강제력, 한 step(약 6시간에 해당)
def tend(x): # x: (..., K) 위도권 한 바퀴의 격자점
return (np.roll(x, -1, -1) - np.roll(x, 2, -1)) * np.roll(x, 1, -1) - x + F
def step(x): # 4차 Runge–Kutta 한 step
k1 = tend(x); k2 = tend(x + DT / 2 * k1); k3 = tend(x + DT / 2 * k2); k4 = tend(x + DT * k3)
return x + DT / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
rng = np.random.default_rng(0)
x = F + rng.normal(0, 1, K)
for _ in range(1000): # spin-up: 초기값의 흔적을 지운다
x = step(x)
traj = np.empty((12000, K)) # (T, K) 약 8년치 6시간 간격 자료
for t in range(len(traj)):
traj[t] = x = step(x)
train, test = traj[:8000], traj[8400:] # 시간 순서 분할, 사이 400 step은 버린다(gap)
clim = train.mean() # 학습 기간의 기후값(격자점 모두 같은 통계)
starts = np.arange(0, len(test) - 41, 10) # (N,) 시험 기간의 예보 시작 시점
truth = np.stack([test[starts + h] for h in range(41)], 1) # (N, 41, K) 리드 0–40 step
rmse = lambda f: np.sqrt(((f - truth) ** 2).mean(axis=(0, 2))) # 리드별 RMSE (41,)
r_pers, r_clim = rmse(truth[:, :1]), rmse(np.full_like(truth, clim))
for h in [1, 4, 8, 20, 40]:
print(f"리드 {h:2d} step 지속성 {r_pers[h]:.2f} 기후값 {r_clim[h]:.2f}")리드 1 step 지속성 0.93 기후값 3.66 리드 4 step 지속성 3.31 기후값 3.66 리드 8 step 지속성 4.94 기후값 3.66 리드 20 step 지속성 5.48 기후값 3.66 리드 40 step 지속성 5.22 기후값 3.66
지속성은 6시간 뒤(리드 1)에 기후값의 4분의 1 오차로 압도적이지만 하루(리드 4)면 거의 따라잡히고, 이틀(리드 8)부터는 기후값보다 나쁘다. 긴 리드에서 지속성의 RMSE는 기후값의 약 배로 간다. 현재와 미래가 무상관이 되면 지속성 오차 의 분산은 두 분산의 합 이기 때문이다. 기후값 RMSE는 리드와 무관하게 일정하다. 두 baseline 중 더 나은 쪽이 리드마다 다르므로, 모델은 모든 리드에서 둘 다와 비교한다.
스킬 점수. baseline 대비 개선은 스킬 점수(skill score)로 요약한다.
1이면 완벽, 0이면 baseline과 같음, 음수면 baseline보다 나쁨이다. 같은 이름으로 RMSE의 비를 쓰는 문헌도 있으므로 정의를 함께 적는다.
시간 누수 없는 분할. 대기 상태는 며칠 동안 강하게 자기상관되어 있다. 위 결과에서 6시간 뒤 상태가 지금 상태와 얼마나 비슷한지(지속성 RMSE 0.93 대 기후값 3.66)가 그 크기를 보여 준다. 시각을 무작위로 나누면 시험 시각의 앞뒤 6시간이 학습에 들어가 모델은 예측이 아니라 보간을 배운다(15.4장). 위 코드는 앞 8000 step으로 학습하고, 400 step의 간격을 둔 뒤 나머지로 시험했다. 실제 연구에서는 연도 단위로 나누고, 시험 기간에 최소 1년을 넣어 모든 계절을 포함한다. 기후값과 입력 정규화 통계도 학습 기간에서만 계산한다.
모델 구조
왜 필요한가. 대기 상태는 구면 위의 수십 채널 격자다. 0.25° 격자 한 장만 해도 약 100만 칸이다. 칸마다 독립된 파라미터를 두는 모델은 학습할 수 없고, 구면의 기하를 무시한 모델은 극과 날짜변경선에서 깨진다. 구조는 무엇을 공유하고 무엇을 구분할지에 대한 선택이다.
국소성과 공유. 짧은 시간 동안의 변화는 주로 가까운 곳의 상태가 정한다. 바람이 공기를 옮기는 거리는 6시간에 수백 km 정도다. 그래서 대부분의 구조는 국소 연산을 위치마다 공유한다. 18.2장의 CNN이 평면에서 하는 일이다. 구면에서는 세 계열이 주로 쓰인다.
- 그래프 신경망(18.6장): 구면 위에 점을 고르게 깐 메시를 그래프로 보고 이웃끼리 메시지를 주고받는다. 위경도 격자의 극 근처 밀집을 피할 수 있고, 촘촘한 메시와 성긴 메시를 함께 써서 먼 거리의 정보를 빠르게 전달한다.
- Transformer(18.4장): 격자를 패치로 잘라 토큰으로 만들고 attention으로 섞는다. 전 지구 attention은 비싸므로 창(window) 안에서만 attention하는 변형이 흔하다.
- Neural operator(24.4장): 함수 공간 사이의 사상을 배우는 구조다. Fourier 공간에서 섞는 계열은 주기 경계를, 구면 조화 함수(spherical harmonics) 공간에서 섞는 계열은 구면을 자연스럽게 다룬다.
학습 손실. 손실은 대개 채널별로 표준화한 위도 가중 MSE다(27.1장). 위도 가중이 없으면 면적이 작은 극지방에 용량을 낭비한다. 채널 사이의 가중치(지표 변수와 상층 변수 중 무엇을 더 중시할지)는 설계 선택이고, 평가표의 순위를 바꿀 수 있으므로 논문에 적는다.
rollout의 안정성. 한 step 오차를 줄이는 것과 rollout을 안정적으로 굴리는 것은 다른 문제다. 학습은 언제나 실제 상태를 입력으로 받는다. rollout에서는 모델 자신의 출력, 즉 오차가 섞인 상태가 입력이 된다. 오차가 상태를 학습 분포 밖으로 밀면 모델은 본 적 없는 입력을 받는다(21.4장의 분포 이동이 모델 내부에서 생긴다). Lorenz-96 자료로 직접 확인한다. 각 격자점의 이웃 4개 의 1·2차 항 15개를 특징으로 다음 상태를 최소제곱으로 맞히고, 모든 격자점이 계수를 공유한다. 입력에 잡음을 섞어 학습하는 변형도 함께 본다.
def feats(x): # x: (..., K) → (..., K, 15) 국소 stencil의 1·2차 항
s = np.stack([np.roll(x, k, -1) for k in (2, 1, 0, -1)], -1) # (..., K, 4) x_{i-2..i+1}
quad = [s[..., a] * s[..., b] for a in range(4) for b in range(a, 4)]
return np.concatenate([np.ones(s.shape[:-1] + (1,)), s, np.stack(quad, -1)], -1)
def fit(noise_sd): # 입력에 잡음을 넣고 다음 상태를 맞히도록 학습
x_in = train[:-1] + np.random.default_rng(1).normal(0, noise_sd, train[:-1].shape)
coef = np.linalg.lstsq(feats(x_in).reshape(-1, 15), (train[1:] - x_in).ravel(), rcond=None)[0]
return lambda x: x + feats(x) @ coef # 모든 격자점이 계수 15개를 공유한다
def rollout(model, x0, n=40): # 자기 출력을 다음 입력으로 넣는다
out = [x0]
with np.errstate(all="ignore"):
for _ in range(n):
out.append(model(out[-1]))
return np.stack(out, 1) # (N, n+1, K)
for sd in [0.0, 0.7, 1.5]:
fc = rollout(fit(sd), truth[:, 0])
with np.errstate(all="ignore"):
r = rmse(fc)
bad = (~np.isfinite(fc[:, -1]).all(-1)).sum()
print(f"입력 잡음 {sd}: RMSE 리드1 {r[1]:.2f} 리드8 {r[8]:.2f} 리드20 {r[20]:.2f} 발산 {bad}/{len(fc)}")입력 잡음 0.0: RMSE 리드1 0.15 리드8 1.26 리드20 inf 발산 99/356 입력 잡음 0.7: RMSE 리드1 0.21 리드8 1.64 리드20 3.15 발산 0/356 입력 잡음 1.5: RMSE 리드1 0.58 리드8 2.92 리드20 3.57 발산 0/356
결과는 세 가지를 말한다.
- 1-step 오차가 가장 작은 모델이 가장 먼저 무너진다. 잡음 없이 학습한 모델은 6시간 오차 0.15로 가장 정확하지만, 356개 예보 중 99개가 10일(리드 40) 안에 발산한다. 2차 다항식은 학습 분포 밖에서 제곱으로 커지고, 그 출력이 다음 입력이 되기 때문이다.
- 입력 잡음은 안정성을 산다. 잡음 0.7로 학습한 모델은 1-step 오차가 조금 커졌지만 하나도 발산하지 않는다. 학습 분포 바깥의 상태에서도 "실제 상태 쪽으로 돌아가라"를 배운 셈이다.
- 잡음이 지나치면 예보가 흐려진다. 잡음 1.5에서는 모델이 입력을 덜 믿고 평균 쪽으로 당기므로 모든 리드에서 오차가 커진다.
실제 모델에서도 같은 긴장이 있다. 자주 쓰는 처방은 여러 step을 굴린 뒤의 오차로 미세조정하는 다중 step 학습(rollout fine-tuning), 입력 잡음, 그리고 물리적 제약이다. 다중 step 학습은 rollout 안정성을 높이지만, 평균 오차를 줄이는 방향으로 학습되므로 긴 리드에서 예보를 매끄럽게 만드는 경향이 있다. 이 흐릿함이 왜 RMSE로는 보이지 않는지는 27.4장에서 다룬다.
리드 타임별 평가. 안정적인 모델(잡음 0.7)을 두 baseline과 비교한다. 결정론적 예보의 두 표준 지표는 RMSE와 anomaly correlation coefficient(ACC)다. ACC는 예보와 정답의 기후값 편차 사이의 공간 상관이다.
는 예보, 는 정답, 는 학습 기간의 기후값, 는 위도 가중치다(Lorenz-96에서는 모두 1). RMSE가 오차의 크기를 재는 반면 ACC는 편차의 패턴이 맞는지를 잰다. 편차의 크기를 절반으로 줄인 예보도 ACC는 1일 수 있다.
fc = rollout(fit(0.7), truth[:, 0]) # (N, 41, K) 안정적으로 굴러간 모델
r_model = rmse(fc)
an_f, an_o = fc - clim, truth - clim # 학습 기간 기후값에 대한 편차
acc = ((an_f * an_o).sum(-1) / np.sqrt((an_f**2).sum(-1) * (an_o**2).sum(-1))).mean(0) # (41,)
print("리드 모델RMSE ACC 스킬(지속성) 스킬(기후값)")
for h in [1, 4, 8, 12, 20, 40]:
ss_p = 1 - r_model[h]**2 / r_pers[h]**2 # MSE 기반 스킬 점수
ss_c = 1 - r_model[h]**2 / r_clim[h]**2
print(f"{h:3d} {r_model[h]:6.2f} {acc[h]:5.2f} {ss_p:+8.2f} {ss_c:+8.2f}")리드 모델RMSE ACC 스킬(지속성) 스킬(기후값) 1 0.21 1.00 +0.95 +1.00 4 0.83 0.98 +0.94 +0.95 8 1.64 0.90 +0.89 +0.80 12 2.30 0.78 +0.82 +0.60 20 3.15 0.54 +0.67 +0.26 40 4.10 0.22 +0.38 -0.25
이틀(리드 8)까지는 두 baseline을 크게 앞선다. 리드가 길어지면 기후값 대비 스킬이 빠르게 줄고, 10일(리드 40)에는 기후값보다 나쁘다(-0.25). 지속성 대비 스킬은 여전히 양수(+0.38)인데, 긴 리드의 지속성이 원래 기후값보다 나쁜 baseline이기 때문이다. 지속성만 baseline으로 보고하면 이 모델은 10일까지 쓸 만해 보인다. 기상 분야에서 ACC 0.6은 쓸모 있는 예보의 경험적 기준으로 자주 인용되는데, 이 모델은 리드 12와 20 사이에서 그 아래로 내려간다.
연구에서의 의미. 데이터 기반 예보 논문을 읽을 때는 다음을 확인한다. 리드 타임별 곡선인가 한 리드의 숫자인가, 정답은 어느 분석장인가, 기후값은 어느 기간으로 계산했는가, 시험 기간은 학습 이후의 연속된 1년 이상인가, 지표는 위도 가중인가.
확률적 예보
왜 필요한가. 대기는 혼돈계다. 초기 상태의 작은 오차가 며칠 사이에 기후값 수준으로 자란다. 모델이 완벽해도 초기 상태를 완벽하게 알 수 없으므로, 리드가 길어질수록 "내일 서울에 비가 온다"가 아니라 "비가 올 확률이 30%다"가 정직한 예보가 된다.
앙상블. 수치 예보 기관은 분석 오차 크기의 섭동을 초기 상태에 더한 수십 개의 예보(멤버)를 함께 굴려 예측분포를 표본으로 낸다. 멤버의 평균은 결정론적 예보로, 멤버의 퍼짐(spread)은 불확실성의 추정으로 쓴다. 모델 오차를 반영하기 위해 모델 내부에 확률적 섭동을 넣기도 한다.
생성모델 기반 예보. 데이터 기반 모델에서 앙상블을 만드는 방법은 두 가지다. 결정론적 모델에 초기 상태 섭동을 넣어 여러 번 굴리거나, 처음부터 다음 상태의 조건부 분포 를 학습해 표본을 뽑는다(19장의 생성모델, 특히 19.5장의 diffusion). 후자는 MSE로 학습한 모델의 흐릿함을 피하고 멤버마다 날카로운 장을 낸다. 대신 표본을 여러 개 뽑아야 하므로 계산이 더 들고, 평가도 분포 수준에서 해야 한다.
완벽한 모델(참 Lorenz-96 동역학)에 분석 오차 0.5를 넣고 20개 멤버를 굴려, 초기조건만으로 생기는 불확실성을 본다. 단일 예보(control)도 같은 분석장에서 출발한다. 확률적 예보의 지표로는 CRPS(21.2장)를 쓴다. 표본 CRPS는 이고, 멤버를 정렬하면 둘째 항을 멤버 수에 비례하는 계산으로 구할 수 있다.
def roll_true(x0, n=40): # 참 동역학으로 굴린다(모델 오차 없음)
out = [x0]
for _ in range(n):
out.append(step(out[-1]))
return np.stack(out, -2) # (..., n+1, K)
g = np.random.default_rng(2)
analysis = truth[:, 0] + g.normal(0, 0.5, truth[:, 0].shape) # (N, K) 분석 오차 0.5
members = roll_true(analysis[None] + g.normal(0, 0.5, (20,) + analysis.shape)) # (20, N, 41, K)
control = roll_true(analysis) # (N, 41, K)
mean = members.mean(0)
spread = np.sqrt(members.var(0, ddof=1).mean(axis=(0, 2))) # (41,)
M, xs = len(members), np.sort(members, 0) # 정렬하면 E|X-X'|를 O(M)으로 계산
pair = 2 * ((2 * np.arange(1, M + 1) - M - 1)[:, None, None, None] * xs).sum(0) / M**2
crps = (np.abs(members - truth).mean(0) - pair / 2).mean(axis=(0, 2)) # (41,) 표본 CRPS
mae_c = np.abs(control - truth).mean(axis=(0, 2))
print("리드 단일RMSE 평균RMSE spread CRPS 단일MAE")
for h in [1, 8, 20, 40]:
print(f"{h:3d} {rmse(control)[h]:6.2f} {rmse(mean)[h]:6.2f} {spread[h]:6.2f} {crps[h]:5.2f} {mae_c[h]:5.2f}")리드 단일RMSE 평균RMSE spread CRPS 단일MAE 1 0.50 0.51 0.50 0.30 0.40 8 1.10 1.10 1.11 0.57 0.78 20 2.72 2.35 2.30 1.22 1.87 40 4.33 3.28 3.19 1.84 3.31
읽을 것은 네 가지다.
- 모델이 완벽해도 오차는 자란다. 0.5였던 분석 오차가 10일 뒤 4.33이 된다. 이것은 모델의 결함이 아니라 예측 가능성의 한계다. 리드 40의 단일 예보는 기후값(3.66)보다 나쁘다.
- 앙상블 평균은 긴 리드에서 단일 예보보다 RMSE가 작다(3.28 대 4.33). 멤버들이 갈라지는 예측 불가능한 부분을 평균이 지워 기후값 쪽으로 다가가기 때문이다. 그 대가로 평균장은 어떤 멤버보다 매끄럽고, 실현 가능한 대기 상태가 아니다.
- spread가 평균의 RMSE와 거의 같다(3.19 대 3.28). 초기 섭동이 실제 분석 오차와 같은 크기여서 앙상블이 잘 보정된 경우다. 이 관계(spread–skill)와 멤버 수에 따른 보정은 27.4장에서 다룬다.
- CRPS는 같은 리드의 단일 예보 MAE보다 훨씬 작다(1.84 대 3.31). 점 예보의 CRPS는 절댓값 오차와 같으므로 두 값은 같은 척도에서 비교된다. 불확실성을 정직하게 낸 예보가 보상받는다.
연구에서의 의미. 결정론적 데이터 기반 모델과 수치 예보의 앙상블 평균을 RMSE로 비교하는 것은 공정하지만, 결정론적 모델과 앙상블의 단일 멤버를 비교하면 긴 리드에서 결정론적 모델이 유리해 보인다. 반대로 확률 예보를 RMSE로만 평가하면 앙상블 평균의 매끄러움이 상을 받는다. 확률 예보는 CRPS와 보정 진단(rank histogram, spread–skill)으로 평가한다(27.4장).
수치 예보와의 관계
왜 필요한가. 데이터 기반 예보를 수치 예보의 "대체"로만 보면 둘의 의존 관계를 놓친다. 데이터 기반 모델의 학습 자료와 예보 시작 상태는 대부분 수치 모델과 자료동화가 만든다.
초기조건과 자료동화. 예보를 시작하려면 현재 대기 상태가 필요하다. 관측은 불규칙하고 불완전하므로, 수치 예보 체계는 짧은 예보(배경장)와 새 관측을 각자의 오차 공분산에 따라 결합해 분석장을 만든다. 이 과정이 자료동화다. 칼만 필터(16.7장의 상태공간 모델)가 그 가장 단순한 형태이고, 실제 체계는 변분법(4D-Var)이나 앙상블 칼만 필터 같은 대규모 변형을 쓴다(24.6장). 데이터 기반 모델은 대개 이 분석장에서 출발한다. 그래서 운영 중인 데이터 기반 예보는 지금도 수치 예보 체계의 자료동화에 기대고, 관측에서 직접 분석장을 만드는 것은 별도의 연구 주제다.
정답 자료의 출처. 재분석으로 학습한 모델을 운영 분석장에서 출발시키면 입력 분포가 미묘하게 달라진다. 두 분석장은 서로 다른 모델 버전과 관측 처리로 만들어졌기 때문이다. 평가에서도 같은 문제가 있다. 수치 예보는 자기 체계의 분석장에 대해 평가하면 짧은 리드에서 유리하고, 재분석으로 학습한 모델은 재분석에 대해 평가하면 유리하다. 두 정답에 대해 모두 보고하거나, 관측소 자료로 따로 검증한다.
하이브리드 접근. 둘을 섞는 방법도 여러 가지다(24.5장).
- 수치 모델의 역학 코어(dynamical core)는 그대로 두고, 구름·대류처럼 격자보다 작은 과정의 모수화(parameterization)만 학습한 모델로 바꾼다.
- 수치 모델의 예보를 입력으로 받아 체계적 오차를 보정하는 후처리 모델을 학습한다. 가장 오래되고 널리 쓰이는 형태다.
- 학습한 모델이 tendency(시간 미분)를 내고 수치 적분기가 그것을 적분한다. 물리 법칙의 구조(보존, 적분기의 안정성)를 일부 물려받는다.
어떤 접근이든 판단 기준은 같다. 같은 시험 기간, 같은 정답, 같은 지표에서 순수 수치 예보와 순수 데이터 기반 모델을 함께 baseline으로 놓는다.
실습
저해상도 재분석 자료로 작은 autoregressive 예보 모델을 학습하고, 리드 타임별 오차를 지속성·기후값 baseline과 비교한다.
- 자료. 재분석에서 한두 변수(예: 500 hPa 지위고도, 850 hPa 기온)를 5.625° 같은 저해상도로 다시 격자화한 자료를 준비한다. 공개 벤치마크가 제공하는 저해상도 판을 쓰면 편하다. 27.1장의 데이터 카드를 먼저 쓴다.
- 분할. 연도 단위로 학습·검증·시험을 나누고, 경계에 며칠의 간격을 둔다. 시험 기간은 최소 1년이다. 기후값과 정규화 통계는 학습 기간에서만 계산한다.
- baseline. 지속성과 기후값의 리드별 위도 가중 RMSE·ACC를 먼저 계산한다. 이 표가 없으면 모델 결과를 해석할 수 없다.
- 모델. 선형 회귀(편차에 대한 한 step 사상)를 먼저 학습하고, 이어서 작은 CNN이나 그래프 모델(18.2장, 18.6장)을 학습한다. 손실은 위도 가중 MSE로 한다. PyTorch가 필요하므로 로컬 실습 환경에서 실행한다.
- rollout과 평가. 6시간에서 5일 리드의 RMSE·ACC·스킬 점수 표를 만들고, 발산한 예보가 있으면 그 수를 함께 적는다.
먼저 아래 연습문제로 평가 함수를 구현한다. 4–5단계에서 그대로 쓴다.
실패 사례
- 지속성·기후값 baseline 없이 예보 성능을 보고하는 것. 짧은 리드에서는 지속성이, 긴 리드에서는 기후값이 생각보다 강하다. 한 baseline만 고르면 다른 쪽 리드에서 모델이 쓸모없다는 사실이 가려진다. 본문의 모델은 지속성 대비로는 10일까지 양의 스킬이었지만 기후값보다 나빴다.
- 시각을 무작위로 섞어 분할하는 것. 6시간 이웃 상태가 학습에 들어가 시험 점수가 부풀려진다.
- 1-step 오차만 보고 모델을 고르는 것. 1-step이 가장 정확한 모델이 rollout에서 가장 먼저 발산할 수 있다. 리드별 곡선과 발산 수를 함께 본다.
- 결정론적 모델을 앙상블의 단일 멤버와 비교하거나, 확률 예보를 RMSE로만 평가하는 것. 비교 대상과 지표가 예보의 종류와 맞지 않으면 순위가 뒤집힌다.
- 위도 가중 없는 지표. 극지방이 과대 대표되어 다른 논문의 숫자와 비교할 수 없다.
통과 기준
- 리드 타임별 위도 가중 RMSE와 ACC를 지속성·기후값 baseline과 함께 표로 보고하고, 각 리드에서 더 나은 baseline 대비 스킬 점수를 적는다.
- 학습·시험 분할이 시간 순서이고 간격을 두었으며, 기후값이 학습 기간에서만 계산되었음을 코드로 보인다.
- 연습문제
lead-time-scores의 테스트를 통과한다.
참고 문헌
- Lorenz (1996). Predictability – a problem partly solved. Proceedings of the Seminar on Predictability, Vol. 1, ECMWF. — Lorenz-96 모형과 오차 성장으로 본 예측 가능성
- Rasp 외 (2020). WeatherBench: A benchmark data set for data-driven weather forecasting. Journal of Advances in Modeling Earth Systems, 12, e2020MS002203. — 데이터 기반 중기 예보의 공통 자료·지표·baseline
- Lam 외 (2023). Learning skillful medium-range global weather forecasting. Science, 382(6677), 1416–1421. — 그래프 신경망 기반 전 지구 중기 예보(GraphCast)