web-dev-qa-db-ja.com

scikit-learnで時系列を予測する方法は?

Scikit-learnは、fitおよびpredictメソッドに基づく非常に便利なアプローチを利用します。 fitおよびpredictに適した形式の時系列データがあります。

たとえば、次のXsがあります。

_[[1.0, 2.3, 4.5], [6.7, 2.7, 1.2], ..., [3.2, 4.7, 1.1]]
_

および対応するys

_[[1.0], [2.3], ..., [7.7]]
_

これらのデータには次の意味があります。 ysに格納された値は時系列を形成します。 Xsの値は、ysの値に何らかの影響を与えることが知られている対応する時間依存の「要因」です(例:温度、湿度、気圧)。

今、もちろん、fit(Xs,ys)を使用できます。しかし、その後、ysの将来の値が要因のみに依存し、以前のY値に依存しない(少なくとも直接)モデルを取得します。これはモデルの制限です。 _Y_n_が_Y_{n-1}_および_Y_{n-2}_などにも依存するモデルが必要です。たとえば、指数移動平均をモデルとして使用したい場合があります。 scikit-learnでそれを行う最もエレガントな方法は何ですか

[〜#〜] added [〜#〜]

コメントで述べたように、Xsを追加することでysを拡張できます。しかし、この方法にはいくつかの制限があります。たとえば、yの最後の5つの値を5つの新しい列としてXに追加すると、ysの時間順序に関する情報が失われます。たとえば、Xには、5番目の列の値が4番目の列の値に続くという指示はありません。モデルとして、最後の5つのysの線形近似を取得し、見つかった線形関数を使用して予測を行いたい場合があります。しかし、5つの列に5つの値がある場合、それほど簡単ではありません。

追加2

私の問題をさらに明確にするために、具体的な例を挙げたいと思います。 _y_n = c + k1*x1 + k2*x2 + k3*x3 + k4*EMOV_n_(EMOV_nは単なる指数移動平均)の「線形」モデルが欲しいです。この単純なモデルをscikit-learnで実装するにはどうすればよいですか?

35
Roman

このmightは、指数加重移動平均に関して、探しているものです。

import pandas, numpy
ewma = pandas.stats.moments.ewma
EMOV_n = ewma( ys, com=2 )

ここで、comhere について読むことができるパラメーターです。その後、EMOV_nからXsに、次のようなものを使用します。

Xs = numpy.vstack((Xs,EMOV_n))

そして、さまざまな線形モデル here を見て、次のようなことを行うことができます。

from sklearn import linear_model
clf = linear_model.LinearRegression()
clf.fit ( Xs, ys )
print clf.coef_

幸運を祈ります!

21
cjohnson318

ウィキペディアによると、EWMAは定常データではうまく機能しますが、トレンドや季節性がある場合は期待どおりに機能しません。これらの場合、それぞれ2次または3次のEWMAメソッドを使用する必要があります。 pandas ewma関数を見て、どのようにトレンドを処理したかを確認することにしました。これが私が思いついたものです。

import pandas, numpy as np
ewma = pandas.stats.moments.ewma

# make a hat function, and add noise
x = np.linspace(0,1,100)
x = np.hstack((x,x[::-1]))
x += np.random.normal( loc=0, scale=0.1, size=200 )
plot( x, alpha=0.4, label='Raw' )

# take EWMA in both directions with a smaller span term
fwd = ewma( x, span=15 )          # take EWMA in fwd direction
bwd = ewma( x[::-1], span=15 )    # take EWMA in bwd direction
c = np.vstack(( fwd, bwd[::-1] )) # lump fwd and bwd together
c = np.mean( c, axis=0 )          # average  

# regular EWMA, with bias against trend
plot( ewma( x, span=20 ), 'b', label='EWMA, span=20' )

# "corrected" (?) EWMA
plot( c, 'r', label='Reversed-Recombined' )

legend(loc=8)
savefig( 'ewma_correction.png', fmt='png', dpi=100 )

enter image description here

ご覧のように、EWMAはトレンドの上り坂と下り坂に逆らっています。 EWMAを両方向に取得し、平均化することで、これを(自分で2次スキームを実装することなく)修正できます。データが静止していたことを願っています!

21
cjohnson318