13.3 予測をある範囲内に収める

予測が正値であって欲しい、あるいは、ある指定した範囲\([a,b]\)内でなければならない、というのはよくあることです。こうした状況はどちらも変換を使えば扱いは比較的容易です。

正値の予測

正値の制約を押し付けるには、対数尺度で行えば良いことです。例えば、図13.4の1ダースの卵の実質価格(1900-1993年、セント)を考えてみましょう。対数変換によって予測の分布は正値に留まるよう制約されるので、平均が減少するにつれ分布は次第に歪んできます。

egg_prices <- prices %>% filter(!is.na(eggs))
egg_prices %>%
  model(ETS(log(eggs) ~ trend("A"))) %>%
  forecast(h = 50) %>%
  autoplot(egg_prices) +
  labs(title = "年次卵価格", level = "区間予測",
       y = "米ドル (インフレ調整後セント) ")
Box-Cox変換で正値に制約された1ダース卵価格の予測

図 13.4: Box-Cox変換で正値に制約された1ダース卵価格の予測

ある範囲に制約された予測

ある範囲に制約されたデータの扱い方を見るため、卵価格が\(a=50\)\(b=400\)の間に制約されている、としましょう。すると、\((a,b)\)を全実数線に割り当てるスケール化ロジット変換を使ってデータを以下のように変換できます。 \[ y = \log\left(\frac{x-a}{b-x}\right) \] ただし、\(x\)は元の尺度で、\(y\)は変換後のデータです。逆変換するには、以下を使います。 \[ x = \frac{(b-a)e^y}{1+e^y} + a \] これは組み込み済みの変換にはないので、まず変換関数を作る必要があります。

scaled_logit <- function(x, lower = 0, upper = 1) {
  log((x - lower) / (upper - x))
}
inv_scaled_logit <- function(x, lower = 0, upper = 1) {
  (upper - lower) * exp(x) / (1 + exp(x)) + lower
}
my_scaled_logit <- new_transformation(
                    scaled_logit, inv_scaled_logit)
egg_prices %>%
  model(
    ETS(my_scaled_logit(eggs, lower = 50, upper = 400)
          ~ trend("A"))
  ) %>%
  forecast(h = 50) %>%
  autoplot(egg_prices) +
  labs(title = "年次卵価格", level = "区間予測",
       y = "米ドル (インフレ調整後セント) ")
50から400セントの間に制約された1ダース卵価格の予測

図 13.5: 50から400セントの間に制約された1ダース卵価格の予測

ここではバイアス調整は自動適用され、単調に増加する変換では分位数は維持されるので、これらの変換からの区間予測は、変換後尺度での場合と同じ被覆確率を持ちます。

変換により区間予測は50セント超にあります。この人工的な(そして非現実的な)制約の結果、予測の分布は極端に歪んだものになっています。