Как прогнозировать временные ряды в 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
. Но этот способ имеет некоторые ограничения. Например, если я добавлю последние 5 значений Y
в качестве 5 новых столбцов на X
, информация о временном упорядочении ys
будет потеряна. Например, в X
нет указаний на то, что значения в пятом столбце соответствуют значению в 4-м столбце и так далее. В качестве модели я мог бы иметь линейную подгонку последних пяти ys
и использовать найденную линейную функцию для предсказания. Но если у меня 5 значений в 5 столбцах, это не так тривиально.
ADDED 2
Чтобы сделать мою проблему еще более ясной, я хотел бы привести один конкретный пример. Я хотел бы иметь "линейную" модель, в которой y_n = c + k1*x1 + k2*x2 + k3*x3 + k4*EMOV_n
, где EMOV_n - только экспоненциальная скользящая средняя. Как я могу реализовать эту простую модель в scikit-learn?
Ответы
Ответ 1
Это может быть то, что вы ищете, в отношении экспоненциально взвешенной скользящей средней:
import pandas, numpy
ewma = pandas.stats.moments.ewma
EMOV_n = ewma( ys, com=2 )
Здесь com
- это параметр, который вы можете прочитать здесь здесь. Затем вы можете объединить EMOV_n
в Xs
, используя что-то вроде:
Xs = numpy.vstack((Xs,EMOV_n))
И тогда вы можете посмотреть на различные линейные модели, здесь и сделать что-то вроде:
from sklearn import linear_model
clf = linear_model.LinearRegression()
clf.fit ( Xs, ys )
print clf.coef_
Удачи!
Ответ 2
Согласно Википедии, EWMA хорошо работает со стационарными данными, но она не работает должным образом при наличии тенденций или сезонности. В этих случаях вы должны использовать метод 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 в обоих направлениях, а затем усреднив. Надеюсь, ваши данные будут неподвижными!