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!
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
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!