Capturing seasonal component using Fourier Decomposition
Dummy Data¶
Using the definition of a fourier series, $$ \begin{aligned} S_i(t) &= \sum_{n=1}^N\left(a_n \cos\left(\frac{2\pi nt}{P_i}\right) + b_n \sin\left(\frac{2\pi nt}{P_i}\right)\right) \\ \end{aligned} $$ we create two series ($i\in\{1,2\}$) where $P_1 = 365$ and $P_2 = 30.5$ representing yearly and monthly seasonalities respectively for $N=3$.
P = 365
P2 = 30.5
N = 365
t = np.arange(N)
# Coefficients
an = [1, 0.5, -1.5]
bn = [1, -0.5, 1.5]
an2 = [-1, 0.5, -1.5]
bn2 = [1, -0.5, 2]
s = [a*np.cos(2*np.pi*(n+1)*t/P) + b*np.sin(2*np.pi*(n+1)*t/P)
for n,(a,b) in enumerate(zip(an, bn))]
s2 = [a*np.cos(2*np.pi*(n+1)*t/P2) + b*np.sin(2*np.pi*(n+1)*t/P2)
for n,(a,b) in enumerate(zip(an2, bn2))]
y = sum(s) + sum(s2)
plt.subplot(2,1,1)
plt.plot(t, sum(s), label='Yearly')
plt.plot(t, sum(s2), label='Monthly')
plt.legend()
plt.subplot(2,1,2)
plt.plot(t, y, label='Time Series')
plt.legend()
plt.show()
Testing¶
model = FourierModel()
learner = Learner(db, model, loss_func=F.l1_loss)
wd = 0
learner.lr_find(wd=wd)
learner.recorder.plot(skip_end=0)
epochs = 5
learner.fit_one_cycle(epochs, 2e-1, wd=wd)
y2 = learner.model(torch.Tensor(t)[:,None])
plt.plot(t, y, label='actual')
plt.plot(t, y2, label='prediction')
plt.show()
learner.model.plot()
model = Seasonal(w_n=0)
learner = Learner(db, model, loss_func=F.l1_loss)
wd = 0
learner.lr_find(wd=wd)
learner.recorder.plot(skip_end=0)
epochs = 5
learner.fit_one_cycle(epochs, 2e-1, wd=wd)
y2 = learner.model(torch.Tensor(t)[:,None])
plt.plot(t, y, label='actual')
plt.plot(t, y2, label='prediction')
plt.show()
learner.model.plot_components()