Modelo de Média Móvel para Previsão em Python

Recentemente, retomei os estudos de séries temporais. É um ponto fraco que eu tenho, nunca dei muita atenção porque não precisei em nenhuma das empresas pelas quais passei. Na última aula do curso online que eu peguei, do professor Fernando Amaral, acabei replicando o conteúdo e aplicando um modelinho bem simples na ação PETR4. O script é bastante intuitivo e autoexplicativo. Qualquer dúvida, não hesite em entrar em contato. Aqui, além de aprender a fazer um modelo preditivo com média móvel, tem lições legais de como importar um arquivo de séries temporais, tratar campo data, filtrar dataframe com base no índice, dentre outras coisas.

# carrega bibliotecas

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
%matplotlib inline
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 15, 6

# Funcao para trazer o campo data no formato adequado
dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m-%d')

# carrega arquivo, mas traz somente colunas date e close
data = pd.read_csv('PETR4.csv', parse_dates=['Date'], index_col='Date',date_parser=dateparse, usecols=['Date','Close'])

# Checa se o indice do df é o campo data
data.index

# verifica as primeiras linhas da tabela
data.head()

# filtra período que vamos trabalhar (2016-2019), mas nao perderemos o original
data_v2 = data.loc[(data.index > '2016-01-01 00:00:00') & (data.index < '2020-01-01 00:00:00')]

# plota cotacao de fechamento de PETR4
plt.figure(figsize=(10,6))
plt.plot(data_v2);
plt.title('Historico PETR4');
plt.ylabel('Cotacao Fechamento');

# Vamos excluir possiveis missing (outra opção rápida seria pegar a cotacao do dia anterior)
data_v2.dropna(inplace=True)

# Obtem melhor periodo para media movel com base na acuracia de cada periodo testado

optimal_n = None

best_mse = None

db = data_v2[['Close']].values.astype('float32')

mean_results_for_all_possible_n_values = np.zeros(int(len(db) / 2 - 2))

for n in range(3, int(len(db) / 2 + 1)):
mean_for_n = np.zeros(len(db) - n)
for i in range(0, len(db) - n):
mean_for_n[i] = np.power(np.mean(db[:, 0][i:i+n]) - db[i + n][0], 2)
mean_results_for_all_possible_n_values[n - 3] = np.mean(mean_for_n)

optimal_n = np.argmin(mean_results_for_all_possible_n_values) + 3
best_mse = np.min(mean_results_for_all_possible_n_values)

print("MSE = %s" % mean_results_for_all_possible_n_values)
print("Melhor MSE = %s" % best_mse)
print("Otimo n = %s" % optimal_n)

# Faz o forecast com o melhor periodo
forecast = np.zeros(len(db) + 1)
for i in range(0, optimal_n):
forecast[i] = db[i][0]
for i in range(0, len(db) - optimal_n + 1):
forecast[i+optimal_n] = np.mean(db[:, 0][i:i+optimal_n])

# plota forecast e actual
plt.figure(figsize=(10,6))
plt.plot(db[:, 0],label = 'Dados Originais')
plt.plot(forecast, label = 'Previsao')
plt.legend()

Se não tiver nada de errado, parece que temos um modelo simples bem preciso para previsão da cotação de fechamento da ação.

Gostou do conteúdo? Se inscreva para receber as novidades! Deixe seu e-mail em INSCREVA-SE na barra à direita, logo abaixo de pesquisar. E, por favor, não deixe de comentar, dar seu feedback e compartilhar com seus amigos. De verdade, isso faz toda a diferença. Você também pode acompanhar mais do meu trabalho seguindo a conta de Twitter @EstatSite ou por alguma das redes que você encontra em Sobre o Estatsite / Contato.

Bons estudos!

2 comentários em “Modelo de Média Móvel para Previsão em Python”

  1. Boa noite amigo, estou estudando este mesmo código do professor amaral, mas estou com dificuldades em entender exatamente o que o segundo for da formula executa.

    for i in range(0, len(db) – n):
    mean_for_n[i] = np.power(np.mean(db[:, 0][i:i+n]) – db[i + n][0], 2)

    poderia me explicar por favor.

    Obrigado

    1. Basicamente, se eu me lembro bem, ele está testando várias janelas para média móvel. É que essa identação está muito ruim, vou resgatar o notebook usado e corrigir depois. Então acho que ele tá tirando a diferença da predição para o realizado ao quadrado, pra depois pegar o RMSE.
      Basicamente, precisa entender esses conceitos, e as fórmulas do numpy:
      np.power (x1, x2): faz x1 elevado à x2
      np.mean(): média

      No fim de semana, eu ajusto o post e coloco alguns comentários para facilitar.

      Veja se você ficou mais fácil com essa resposta. Se não rolar, pode chamar lá na DM do Twitter que eu te ajudo.

      Abs!

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *