web-dev-qa-db-fra.com

Comment prédire les séries chronologiques dans Scikit-Learn?

Scikit-learn utilise une approche très pratique basée sur les méthodes fit et predict. J'ai des données chronologiques au format adapté à fit et predict.

Par exemple, j'ai le Xs suivant:

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

et le ys correspondant:

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

Ces données ont la signification suivante. Les valeurs stockées dans ys forment une série chronologique. Les valeurs dans Xs sont des "facteurs" correspondants dépendant du temps qui sont connus pour avoir une certaine influence sur les valeurs dans ys (par exemple: température, humidité et pression atmosphérique).

Maintenant, bien sûr, je peux utiliser fit(Xs,ys). Mais ensuite, j'obtiens un modèle dans lequel les valeurs futures de ys dépendent uniquement de facteurs et ne dépendent pas des valeurs de Y précédentes (au moins directement) et c'est une limitation du modèle. J'aimerais avoir un modèle dans lequel Y_n Dépend aussi de Y_{n-1} Et Y_{n-2} Et ainsi de suite. Par exemple, je pourrais vouloir utiliser une moyenne mobile exponentielle comme modèle. Quelle est la façon la plus élégante de le faire dans scikit-learn

AJOUTÉ

Comme cela a été mentionné dans les commentaires, je peux étendre Xs en ajoutant ys. Mais cette façon a certaines limites. Par exemple, si j'ajoute les 5 dernières valeurs de y en tant que 5 nouvelles colonnes à X, les informations sur l'ordre temporel de ys sont perdues. Par exemple, rien n'indique dans X que les valeurs de la 5e colonne suivent les valeurs de la 4e colonne et ainsi de suite. En tant que modèle, je pourrais vouloir avoir un ajustement linéaire des cinq derniers ys et utiliser la fonction linéaire trouvée pour faire une prédiction. Mais si j'ai 5 valeurs dans 5 colonnes, ce n'est pas si trivial.

AJOUTÉ 2

Pour rendre mon problème encore plus clair, je voudrais donner un exemple concret. J'aimerais avoir un modèle "linéaire" dans lequel y_n = c + k1*x1 + k2*x2 + k3*x3 + k4*EMOV_n, Où EMOV_n n'est qu'une moyenne mobile exponentielle. Comment puis-je implémenter ce modèle simple dans scikit-learn?

35
Roman

Cela pourrait être ce que vous recherchez, en ce qui concerne la moyenne mobile à pondération exponentielle:

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

Ici, com est un paramètre que vous pouvez lire sur ici . Ensuite, vous pouvez combiner EMOV_n à Xs, en utilisant quelque chose comme:

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

Et puis vous pouvez regarder différents modèles linéaires, ici , et faire quelque chose comme:

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

Bonne chance!

21
cjohnson318

Selon Wikipedia, l'EWMA fonctionne bien avec des données stationnaires, mais cela ne fonctionne pas comme prévu en présence de tendances ou de saisonnalité. Dans ces cas, vous devez utiliser une méthode EWMA de deuxième ou troisième ordre, respectivement. J'ai décidé de regarder la fonction pandas ewma pour voir comment elle gérait les tendances, et voici ce que j'ai trouvé:

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

Comme vous pouvez le voir, l'EWMA bat la tendance en montée et en descente. Nous pouvons corriger cela (sans avoir à implémenter un schéma de second ordre nous-mêmes) en prenant l'EWMA dans les deux directions, puis en faisant la moyenne. J'espère que vos données étaient stationnaires!

21
cjohnson318