時系列データに関する補間手法

時系列データに関する補間手法

私達の扱う多くの時系列データには欠損値が存在します。
その欠損値を扱うためにはいくつかの方法が存在し、例えば欠損値を含むレコードは全て削除してしまうという手法もあり得ます。しかし、削除をしてしまうことで時系列データに関しては特にデータの特徴がなくなってしまうことが考えられます。
そこで今回は時系列に対する欠損値の扱い方としてどのような補間手法がReNomに備わっているのかについて紹介していきたいと思います。

Required libraries

  • numpy 1.12.1
In [3]:
import numpy as np
from renom.utility import interpolate

補間するためのデータを準備

In [5]:
x = [[2.0, 3.0, 5.0], [3.0, np.nan, 8.0], [6.0, np.nan, 9.0],[7.0, 9.0, np.nan], [8.0, 10.0, 10.0], [10.0, 12.0, 14.0]]
x
Out[5]:
[[2.0, 3.0, 5.0],
 [3.0, nan, 8.0],
 [6.0, nan, 9.0],
 [7.0, 9.0, nan],
 [8.0, 10.0, 10.0],
 [10.0, 12.0, 14.0]]

補間手法について

時系列データに対する補間手法をいくつか用意しています。

  • 線形補間
  • スプライン補間
  • 固定値補間
  • 最近傍の値を使った補間
手法にはそれぞれ長所と短所があります。線形補間は簡単な手法ですが、強力な手法でもあります。基本的に大きな変化が起こるようなデータで無ければ線形補間で十分だと考えています。一方でスプライン補間はいくつかの条件を持って自然な補間を行います。
例えば1次微分や2次微分の値を用いて自然な補間を行うことができるため、大きな変化が起こるようなデータに対しては線形補間よりスプライン補間の方が適切な補間になることもあります。
固定値補間と最近傍の値を使った補間についてはある特定の値を代入したい時などに利用することが考えられます。
  • 線形補間

線形補間は簡単な補間手法であり、前の値を後ろの値を線形に補間する手法になります。

In [4]:
x_interp = interpolate(x, mode="linear")
x_interp
Out[4]:
array([[  2. ,   3. ,   5. ],
       [  3. ,   5. ,   8. ],
       [  6. ,   7. ,   9. ],
       [  7. ,   9. ,   9.5],
       [  8. ,  10. ,  10. ],
       [ 10. ,  12. ,  14. ]])
  • スプライン補間

スプライン補間は非線形モデルや欠損幅が大きいようなデータに対して有用な補間手法となっています。スプライン補間は補間多項式を構成する上において前の値や後ろの値の微分値を用いるために、なめらかな補間曲線を用いることが出来るために、自然な補間が可能な手法となっています。

In [8]:
x_interp = interpolate(x, mode="spline")
x_interp
Out[8]:
array([[  2.        ,   3.        ,   5.        ],
       [  3.        ,   6.4       ,   8.        ],
       [  6.        ,   8.1       ,   9.        ],
       [  7.        ,   9.        ,   9.03571429],
       [  8.        ,  10.        ,  10.        ],
       [ 10.        ,  12.        ,  14.        ]])
  • 固定値補間

固定値補間はある決まった値を全ての欠損値に代入します。例えばconstant=0として指定すると、全ての欠損値に0が代入されます。constantをmodeに指定する場合はconstantは必ず指定してください。

In [10]:
x_interp = interpolate(x, mode="constant", constant=0.0)
x_interp
Out[10]:
array([[  2.,   3.,   5.],
       [  3.,   0.,   8.],
       [  6.,   0.,   9.],
       [  7.,   9.,   0.],
       [  8.,  10.,  10.],
       [ 10.,  12.,  14.]])
  • 最近傍の値を使った補間

最近傍のインデックス、つまり最も近いインデックスの値をそのまま欠損値への代入値としてコピーします。

In [11]:
x_interp = interpolate(x, mode="nearest_index")
x_interp
Out[11]:
array([[  2.,   3.,   5.],
       [  3.,   3.,   8.],
       [  6.,   9.,   9.],
       [  7.,   9.,   9.],
       [  8.,  10.,  10.],
       [ 10.,  12.,  14.]])