例えば 1 秒ごとに計測された以下のような時系列データがあったとする。
t-24 | t-23 | t-22 | t-21 | t-20 | t-19 | t-18 | t-17 | t-16 | t-15 | t-14 | t-13 | t-12 | t-11 | t-10 | t-9 | t-8 | t-7 | t-6 | t-5 | t-4 | t-3 | t-2 | t-1 | t0 | t1 |
v-24 | v-23 | v-22 | v-21 | v-20 | v-19 | v-18 | v-17 | v-16 | v-15 | v-14 | v-13 | v-12 | v-11 | v-10 | v-9 | v-8 | v-7 | v-6 | v-5 | v-4 | v-3 | v-2 | v-1 | v0 | v1 |
rrdtool では PREDICT という関数が用意されており、これは過去の時系列データ (vi<0) から近い将来の時系列データ (vi=>0) の挙動を予想 (sliding window average) する。PREDICT を以下のように利用する場合を考える。
CDEF:predict=6,-3,5,v,PREDICT
このとき v0 の計算に使われるデータは以下の 3 * 5 = 15 個のデータの平均値。
t-24 | t-23 | t-22 | t-21 | t-20 | t-19 | t-18 | t-17 | t-16 | t-15 | t-14 | t-13 | t-12 | t-11 | t-10 | t-9 | t-8 | t-7 | t-6 | t-5 | t-4 | t-3 | t-2 | t-1 | t0 | t1 |
v-10 | v-9 | v-8 | v-7 | v-6 | |||||||||||||||||||||
v-16 | v-15 | v-14 | v-13 | v-12 | |||||||||||||||||||||
v-22 | v-21 | v-20 | v-19 | v-18 |
v1 の計算に使われるデータは以下の 3 * 5 = 15 個のデータの平均値。
t-24 | t-23 | t-22 | t-21 | t-20 | t-19 | t-18 | t-17 | t-16 | t-15 | t-14 | t-13 | t-12 | t-11 | t-10 | t-9 | t-8 | t-7 | t-6 | t-5 | t-4 | t-3 | t-2 | t-1 | t0 | t1 |
v-9 | v-8 | v-7 | v-6 | v-5 | |||||||||||||||||||||
v-15 | v-14 | v-13 | v-12 | v-11 | |||||||||||||||||||||
v-21 | v-20 | v-19 | v-18 | v-17 |
PREDICT 関数の構文は一般に以下のようにかける。時系列データについて、周期は shift 秒、ある時間 t における値 v は window 秒前までの傾向を反映、していると考えられる場合予想はよくあうはずである。将来予測の確からしさを上げるには周期 (shift) をうまく設定することが最重要である。室温のデータなら 24 時間周期、サーバへの訪問者数なら 1 週間周期などの valid と考えられる周期を設定しなければいけない。
CDEF:predict=shift,-n,window,v,PREDICT
周期の次に重要なのは窓 (window) である。上の例で v-10>v-9>v-8>v-7>v-6 のような場合を考えると、周期が 6 秒の場合に最も真の値に近いと考えられる v-6 を低く評価している。このため得られる v0 は v-6 よりも必ず大きくなる。window サイズが十分に狭ければ window 内での挙動は一般に以下の 4 つのケースに分類される。どの場合でも、すべてのデータを等しく評価していることが原因で v-6 に対する評価が相対的に低くなっていることがわかる。残念ながら、平均化するデータに重み付けすることはできないため、これを防ぐには window サイズを周期よりも十分に狭くする方法しかない。
単調減少 | v-10>v-9>v-8>v-7>v-6 | v0~v-8 |
上に凸 | v-10<v-9<v-8>v-7>v-6 | v0~v-9,-7 |
単調増加 | v-10<v-9<v-8<v-7<v-6 | v0~v8 |
下に凸 | v-10>v-9>v-8<v-7<v-6 | v0~v-9,-7 |
しかし、そもそも predict 関数は時系列データが周期を持つことを前提にしているわけで、周期 6 秒なら 6, 12, 18, ... 秒前を中心にある時間幅で値を平均するほうが任意のデータについてよい結果が得られるはずだと考えるかもしれない。つまり v0 を求めるために以下のデータの平均値を取るということである。(これは前に説明した方法の window / 2 時間シフトと考えられる。window 幅を広げる場合に予測曲線が未来側にシフトすることを抑制するためには効果がある。しかし、予測曲線の値が合わなくなるという点については効果が薄い。これが値に関しても有効なのは |dv/dt| が任意の時間で変わらない場合のみである。)
t-24 | t-23 | t-22 | t-21 | t-20 | t-19 | t-18 | t-17 | t-16 | t-15 | t-14 | t-13 | t-12 | t-11 | t-10 | t-9 | t-8 | t-7 | t-6 | t-5 | t-4 | t-3 | t-2 | t-1 | t0 | t1 |
v-8 | v-7 | v-6 | v-5 | v-4 | |||||||||||||||||||||
v-14 | v-13 | v-12 | v-11 | v-10 | |||||||||||||||||||||
v-20 | v-19 | v-18 | v-17 | v-16 |
これを行うには、前に説明した構文を使うことはできない。以下のような構文を使う。
CDEF:predict=16,10,4,3,5,v,PREDICT
一般に以下のようにかける。平均化する時間範囲 n で周期が変化する場合にはこちらを使うほうがよい場合がある。
CDEF:predict=shift_n,...,shift_1,n,window,v,PREDICT