Aprendizagem supervisionada é um dos tipos mais comuns de aprendizado de máquina, em que o modelo aprende com um conjunto de dados de treinamento que contém rótulos para cada exemplo, sendo então usado para prever os rótulos para novos exemplos.
É um dos principais paradigmas do Aprendizado de Máquina , sendo usado para resolver uma ampla variedade de problemas, como classificação, regressão e agrupamento, mapeando as entradas para as saídas corretas.
A aprendizagem supervisionada é um processo de quatro etapas:
É um tipo de aprendizagem de máquina em que o modelo é treinado em um conjunto de dados que contém exemplos de entrada e saída.
O modelo aprende a associar as entradas às saídas e, em seguida, pode ser usado para fazer previsões para novos dados de entrada.
Nessa abordagem, o algoritmo é treinado em um conjunto de dados rotulados, ou seja, um conjunto de exemplos em que as saídas desejadas (rótulos) são fornecidas junto com as entradas.
Aqui estão alguns tipos comuns usados com a aprendizagem supervisionada:
Apresentaremos os principais modelos de algoritmos usados na aprendizagem supervisionada, incluindo:
Estes são apenas alguns dos muitos tipos de aprendizagem supervisionada, campo ativo de pesquisa e pesquisadores constantemente desenvolvendo novos métodos de aprendizagem supervisionada.
A aprendizagem supervisionada é uma ferramenta poderosa que pode ser usada para resolver uma ampla variedade de problemas.
É um campo ativo de pesquisa e os pesquisadores estão constantemente desenvolvendo novos métodos de aprendizagem supervisionada.
O desempenho do modelo é avaliado comparando os rótulos previstos com os rótulos reais.
A aprendizagem supervisionada é uma ferramenta poderosa que pode ser usada para resolver uma ampla variedade de problemas.
No entanto, é importante observar que a aprendizagem supervisionada requer um conjunto de dados de treinamento que contenha rótulos para cada exemplo.
Se não houver rótulos disponíveis, a aprendizagem não supervisionada ou a aprendizagem por reforço podem ser usadas.
Discutiremos várias métricas de avaliação utilizadas para medir o desempenho de modelos de Aprendizagem Supervisionada, como precisão, recall, F1-score, matriz de confusão e curva ROC.
As etapas para aplicar a aprendizagem supervisionada para o aprendizado de máquina:
A aprendizagem supervisionada é uma ferramenta poderosa que pode ser usada para resolver uma ampla variedade de problemas.
O Projeto Dados da Bovespa consiste de um conjunto de instruções Python utilizando dados da Bovespa (Bolsa de Valores de São Paulo), obtidos a partir do site da companhia B3, visando explicar o funcionamento da regressão logística na previsão de classes.
O objetivo não é o de prever valores de cotações futuras, visando saber se o papel irá valorizar ou não no pregão seguinte ao do dia atual, mas explicar como que, utilizando-se indicadores corretos para a regressão logística, o modelo consegue prever com grande acurâcia a classe relacionada com o pregão de cada data.
Esperamos que você, ao final do projeto, possa compreender como as colunas indicadoras das linhas nos conjuntos de dados levam, através de treinamento vinculando estes indicadores a determinadas classes, à previsão correta das classes dos dados.
Utilizaremos um objeto DataFrame do Pandas carregado com os dados provenientes de um arquivo csv, contendo a tabela de linhas representando os pregões em diferentes datadas e as colunas com os valores do pregão da linha, formando o conjunto de dados da bovespa para o treinamento.
O arquivo csv contém as linhas de cotações dos pregões com os seguintes campos, que serão as colunas no dataframe:
Este arquivo está disponível em "" e deve ser carregado com um objeto DataFrame do Pandas.
As colunas das linhas de dados dos pregões, no arquivo csv, são as seguintes:
O arquivo foi preparado com o programa MB - Multicieda Bovespa, da CIEDA, específico para extrair, processar e analisar os dados da Bovespa usando como base o Multicieda.
Assim, foi preparado arquivo csv "bv.csv", que você pode baixar aqui, com os valores de cotação dos pregões das empresas Vale (VALE3), Petrobrás (PETR4)e Bradesco (BBDC4), três das principais empresas do Brasil e presentes na Bovespa, do período de 04-01-2010 até 30-06-2023.
Importe as bibliotecas Python que serão utilizadas:
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
Carregue o dataframe do arquivo csv "bv.csv" (baixar).
dfbv = pd.read_csv("bv.csv")
Defina um máximo de 10 linhas do dataframe para que a impressão de dataframes apresenta apenas as cinco primeiras e as cinco últimas.
pd.set_option('display.max_rows', 10)
Imprima o dataframe dfbv para checar se o conjunto de dados foi carregado.
print(dfbv)
Imprima as informações do conjunto de dados.
print(dfbv.info())
Verifique se há algum valor ausente no conjunto de dados.
print(dfbv.isnull().sum())
Agora, podemos obter os campos preant e preseg com os preços anterior e seguinte ao de fechamento, em cada data de pregão.
Mantenha o dataframe dfbv com os dados originais oriundos do arquivo csv.
Portanto, crie um novo dataframe chamado v3, apenas com as cotações da empresa VALE, da área de mineração, localizando as linhas de cotações com o código de negociação "VALE3" na coluna codneg, e contendo apenas os campos numéricos preabe, premed, premax, premin e preult.
#v3 = dfbv[dfbv['codneg']=='VALE3'].copy()
v3 = dfbv.loc[dfbv['codneg']=='VALE3'].copy()
v3 = v3[['preabe','premed','premax','premin','preult']]
Imprima o número de linhas e colunas do novo conjunto de dados:
print("Linhas e colunas do conjunto de dados: ", v3.shape)
Agora realizaremos uma transformação nas linhas dos pregões incluindo dois novos campos, preant e preseg, respectivamente contendo os preços anterior e seguinte.
A coluna preant conterá os valores das classes em que os preços subiram, comparando-se o preço de fechamento do pregão da linha com o imediatamente anterior.
A coluna preseg conterá os valores das classes em que os preços subirão, comparando-se o preço de fechamento do pregão da linha com o imediatamente seguinte.
Observe que a capacidade de determinar-se se o preço subirá, no pregão seguinte ao da linha de pregão atual, só é possível pelo fato dos pregões seguintes a cada pregão já terem acontecido, num período passado em relação ao último dos pregões no conjunto de dados.
Os preços seguintes serão utilizados visando ao propósito de explicação das previsões de regressão em relação ao conjunto de dados, e não visando a prever dados de eventos futuros que ainda acontecerão, pois na Bovespa, tirando fins de semana e feriados, todo dia tem pregão.
Utilize a função do Pandas shift() para obter os preços seguinte e anterior.
# Inclui as colunas preant e preseg no conjunto de dados v3 contendo
# os valores anteriores e seguintes a uma cotação.
# Empurra os preços de fechamento do passado para agora
v3['preant'] = v3['preult'].shift()
# Puxa os preços de fechamento do futuro para agora
v3['preseg'] = v3['preult'].shift(-1)
Imprima o conjunto de dados v3:
print(v3)
Retire a primeira e última linha do conjunto de dados, contendo valores nulos em preant e preseg, respectivamente.
# Retire a primeira e última linha do conjunto de dados, pois estão contendo valores nulos.
v3 = v3.dropna()
# Correspondente a:
# v3 = v3.drop(v3.index[0])
# v3 = v3.drop(v3.index[-1])
Imprima o número de linhas do novo conjunto de dados:
print("Novo número de linhas: ", v3.shape[0])
As classes são valores inteiros que representam determinados estados representativos das colunas nas linhas de dados, e utilizaremos basicamente duas classes, 0 e 1, representando os estados de verdadeiro ou falso para as colunas de classes do dataframe, nomeadas "subiu" e "subira", respectivamente.
Utilizaremos as colunas preult, preant e preseg para obter e atribuir, nas variáveis ultant e segult, as diferenças entre os preços de fechamento e o preço anterior, e entre o preço seguinte e o preço de fechamento.
# Inclui as colunas ultant e segult no conjunto de dados v3 contendo, respectivamente,
# as diferenças entre os preços de fechamento e o preço anterior, e do preço seguinte e o preço de fechamento.
v3["ultant"] = v3['preult'] - v3['preant']
v3["segult"] = v3['preseg'] - v3['preult']
Se o preço de fechamento for maior que o preço anterior, a classe da coluna "subiu" será representada pelo valor 1, caso contrário, a classe será representada pelo valor 0.
Se o preço seguinte for maior que o preço de fechamento, a classe da coluna "subira" será representada pelo valor 1, caso contrário, a classe será representada pelo valor 0.
Criamos as colunas de classes.
v3['subiu'] = np.where(v3['preult'] > v3['preant'], 1, 0)
v3['subira'] = np.where(v3['preseg'] > v3['preult'], 1, 0)
Preserve em v3_inicial o conjunto de dados v3, visando a operações futuras:
v3_inicial = v3.copy()
O projeto será desenvolvido e explicado com 10 partes:
Separe os dados que subiram no pregão dos dados que não subiram.
v3_subiu = v3[v3['subiu'] == 1]
v3_naosubiu = v3[v3['subiu'] == 0]
Imprima as quantidades de linhas que subiram e as quantidades de linhas que não subiram.
print("Linhas que subiram: ", v3_subiu.shape[0])
print("Linhas que não subiram: ", v3_naosubiu.shape[0])
Preparamos os dados balanceados para o treinamento do modelo, com o mesmo número de amostras de cada classe 0 e 1 da coluna "subiu".
# Definimos o número de amostras balanceadas
total_amostras_balanceadas = 60
# Calculamos a metade para cada classe
metade_amostras_balanceadas = total_amostras_balanceadas // 2
# Separamos a amostra da classe 1, relativas ao estado 'subiu'
amostra_subiu = v3_subiu.sample(metade_amostras_balanceadas,axis=0)
# Separamos a amostra da classe 0, relativas ao estado 'não subiu'
amostra_naosubiu = v3_naosubiu.sample(metade_amostras_balanceadas,axis=0)
# Concatenamos as amostras em um conjunto de dados balanceado
balanceado = pd.concat([amostra_subiu,amostra_naosubiu],axis=0)
# Separamos as amostras restantes que não estão presentes na amostra balanceada
restante = v3.drop(balanceado.index,axis=0)
Imprimimos as dimensões dos dataframes formados.
print("Amostras que subiram:", v3_subiu.shape[0])
print("Amostras que não subiram:", v3_naosubiu.shape[0])
print("Amostras balanceadas:", balanceado.shape[0])
print("Amostras restantes:", restante.shape[0])
Separamos os dados indicadores (data) dos dados alvos (targets) usando os valores de classe da coluna "subiu", respectivamente em dados_subiu e alvos_subiu.
Os dados indicadores são os valores das colunas excluindo-se as colunas "subiu" e "subira", e os dados alvos são os valores das colunas "subiu" e "subira", utilizadas separadamente (com as classes 0 e 1 em cada uma das colunas) ou em conjunto (com a combinação das colunas formando as classes 0, 1, 2 e 3).
O dataframe dados_subiu contém os dados indicadores e o dataframe alvos_subiu contém os dados alvos, da coluna de classes "subiu".
dados_subiu = balanceado.drop(['subiu','subira'],axis=1)
alvos_subiu = balanceado['subiu']
Imprima os dados.
print(dados_subiu)
Imprima os alvos.
print(alvos_subiu)
Prepare dois conjuntos separados de dados para o treinamento e teste do modelo, na proporção de 4 linhas de treinamento para 1 de teste (test_size = 0.2).
A função train_test_split() do sklearn permite separar os dados em treinamento e teste, usando as variáveis:
dados_subiu_treino, dados_subiu_teste, alvos_subiu_treino, alvos_subiu_teste = train_test_split(
dados_subiu, alvos_subiu, test_size=0.2, stratify=alvos_subiu, random_state=2)
Observe o número somado de linhas dos conjuntos de dados de treino e teste é igual ao número de linhas do conjunto de dados, e o mesmo para os alvos.
print("Linhas dos conjuntos de dados e alvos balanceados: ", dados_subiu.shape[0],alvos_subiu.shape[0])
print("Linhas dos conjuntos de dados e alvos de treino: ", dados_subiu_treino.shape[0], alvos_subiu_treino.shape[0])
print("Linhas do conjunto de dados e alvos de teste: ", dados_subiu_teste.shape[0], alvos_subiu_teste.shape[0])
Imprima os dados de dados_subiu_treino do conjunto de dados de treino.
print(dados_subiu_treino)
Imprima os dados de alvos_subiu_treino do conjunto de alvos de treino.
print(alvos_subiu_treino)
Imprima os dados de dados_subiu_teste do conjunto de dados de teste.
print(dados_subiu_teste)
Imprima os dados de alvos_subiu_teste do conjunto de alvos de teste.
print(alvos_subiu_teste)
Crie o objeto com o algoritmo do modelo de regressão logística.
modlog = LogisticRegression()
Treine o modelo usando o método fit(), que em inglês significa ajustar.
modlog.fit(dados_subiu_treino,alvos_subiu_treino)
alvos_subiu_previstos = modlog.predict(dados_subiu_teste)
Avalie e imprima o desempenho do modelo.
acuracia = accuracy_score(alvos_subiu_teste,alvos_subiu_previstos)
print(f'Acurácia: {acuracia:.4f}')
Avalie o desempenho do modelo com os dados e alvos restantes.
dados_restantes = restante.drop(["subiu","subira"],axis=1)
alvos_restantes = restante["subiu"]
alvos_subiu_previstos = modlog.predict(dados_restantes)
acuracia = accuracy_score(alvos_restantes,alvos_subiu_previstos)
print(f'Acurácia: {acuracia:.4f}')
As colunas utilizadas foram as seguintes:
print(dados_restantes.columns)
Analisando as colunas utilizadas, observamos a presença das colunas preant e preult.
É a diferença entre as colunas preant e preult que determina as classes 0 e 1 à coluna subiu.
Portanto a presença dessas colunas nos permite identificar as classes 0 e 1 da coluna subiu, e por isso a alta acurâcia do modelo.
Separe os dados que subirão no pregão seguinte dos dados que não subirão.
v3_subira = v3[v3['subira'] == 1]
v3_naosubira = v3[v3['subira'] == 0]
Imprima as quantidades de linhas que subirão e as quantidades de linhas que não subirão.
print("Linhas que subirão no pregão seguinte: ", v3_subira.shape[0])
print("Linhas que não subirão no pregão seguinte: ", v3_naosubira.shape[0])
Prepare uma amostra balanceada de 60 amostras, com o mesmo número de amostras de cada classe 0 (não subirão) e 1 (subirão).
metade_amostras_balanceadas = 30
amostra_subira = v3_subira.sample(metade_amostras_balanceadas,axis=0)
amostra_naosubira = v3_naosubira.sample(metade_amostras_balanceadas,axis=0)
balanceado = pd.concat([amostra_subira,amostra_naosubira],axis=0)
restante = v3.drop(balanceado.index,axis=0)
Imprimimos os dados.
print("Amostras que subirão:", amostra_subira.shape[0])
print("Amostras que não subirão:", amostra_naosubira.shape[0])
print("Amostras balanceadas:", balanceado.shape[0])
print("Amostras restantes:", restante.shape[0])
Separamos os dados (data) dos alvos (target). Os dados são todas as colunas menos as "subiu" e "subira", e o alvo inicialmente será a coluna "subiu" e depois a coluna "subira".
dados_subira = balanceado.drop(['subiu','subira'],axis=1)
alvos_subira = balanceado['subira']
Imprima os dados indicadores.
print(dados_subira)
Imprima os dados alvos, contendo o mesmo número de linhas que os dados indicadores.
print(alvos_subira)
Prepare dois conjuntos separados de dados para o treinamento e teste do modelo, na proporção 4:1 (test_size=0.2).
dados_subira_treino, dados_subira_teste, alvos_subira_treino, alvos_subira_teste = train_test_split(
dados_subira, alvos_subira, test_size=0.2, stratify=alvos_subira, random_state=2)
Observe o número somado de linhas dos conjuntos de dados de treino e teste é igual ao número de linhas do conjunto de dados, e o mesmo para os alvos.
print("Linhas do conjunto de dados: ", dados_subira.shape[0])
print("Linhas do conjunto de alvos: ", alvos_subira.shape[0])
print("Linhas do conjunto de dados de treino: ", dados_subira_treino.shape[0])
print("Linhas do conjunto de alvos de treino: ", alvos_subira_treino.shape[0])
print("Linhas do conjunto de dados de teste: ", dados_subira_teste.shape[0])
print("Linhas do conjunto de alvos de teste: ", alvos_subira_teste.shape[0])
Imprima os dados indicadores do conjunto de treino:
print(dados_subira_treino)
Imprima os dados alvos do conjunto de treino:
print(alvos_subira_treino)
Imprima os dados indicadores do conjunto de teste:
print(dados_subira_teste)
Imprima os dados alvos do conjunto de teste:
print(alvos_subira_teste)
Crie o objeto com o algoritmo do modelo de regressão logística.
modlog = LogisticRegression()
Treine o modelo usando o método fit(), que em inglês significa ajustar.
modlog.fit(dados_subira_treino,alvos_subira_treino)
Realize as previsões usando os próprios dados de treino.
alvos_previstos = modlog.predict(dados_subira_treino)
Avalie o desempenho do modelo usando os dados de treino.
acuracia = accuracy_score(alvos_subira_treino,alvos_previstos)
print(f'Acurácia: {acuracia:.4f}')
Realize as previsões para os dados de teste.
alvos_previstos = modlog.predict(dados_subira_teste)
Avalie o desempenho do modelo usando os dados de teste.
acuracia = accuracy_score(alvos_subira_teste,alvos_previstos)
print(f'Acurácia: {acuracia:.4f}')
A amostra restante não inclui os dados balanceados usados no treinamento e teste.
Avalie o desempenho do modelo usando os dados da amostra restante.
X_restante = restante.drop(["subiu","subira"],axis=1)
Y_restante = restante["subira"]
Y_previsao = modlog.predict(X_restante)
acuracia = accuracy_score(Y_restante,Y_previsao)
print(f'Acurácia: {acuracia:.4f}')
Importe a biblioteca tabulate para montar a tabela bem-formatada de previsões
from tabulate import tabulate
Crie a função previsao_ultima para prever a tendência da última entrada do conjunto de dados.
def previsao_ultima(df, nome_classe, tam_amostra_balanceada=60, test_size=0.2, random_state=2, modlog=modlog):
# Separar os dados das classes de valor 1 e 0.
classe_1 = df[df[nome_classe]==1]
classe_0 = df[df[nome_classe]==0]
# Preparar dados balanceados para o treinamento do modelo, com o mesmo número de amostras de cada classe 0 e 1 da coluna "subiu".
metade_amostras_balanceadas = tam_amostra_balanceada // 2
amostra_classe_1 = classe_1.sample(metade_amostras_balanceadas,axis=0)
amostra_classe_0 = classe_0.sample(metade_amostras_balanceadas,axis=0)
amostra_balanceada = pd.concat([amostra_classe_1,amostra_classe_0],axis=0)
amostra_restante = df.drop(amostra_balanceada.index,axis=0)
# Separamos os dados (data) dos alvos (target). Os dados são todas as colunas menos as "subiu" e "subira", e o alvo inicialmente será a coluna "subiu" e depois a coluna "subira".
dados_amostra_balanceada = amostra_balanceada.drop([nome_classe],axis=1)
alvos_amostra_balanceada = amostra_balanceada[nome_classe]
# Preparar dois conjuntos separados de dados para o treinamento e teste do modelo, na proporção 4:1 (test_size=0.2).
dados_treino, dados_teste, alvos_treino, alvos_teste=train_test_split(
dados_amostra_balanceada,
alvos_amostra_balanceada,
test_size=test_size,
stratify=alvos_amostra_balanceada,
random_state=random_state)
# Treine o modelo usando o método <i>fit()</i>, que em inglês é "ajustar".
modlog.fit(dados_treino,alvos_treino)
def previsao_acuracia(dados,alvos,modlog=modlog):
alvos_previstos = modlog.predict(dados)
acuracia = accuracy_score(alvos,alvos_previstos)
return acuracia
dados_amostra_restante = amostra_restante.drop([nome_classe],axis=1)
alvos_amostra_restante = amostra_restante[nome_classe]
# Prever alvos e a acurâcia das previsões usando dados de treino, teste e restantes
acuracia_treino = previsao_acuracia(dados_treino,alvos_treino)
acuracia_teste = previsao_acuracia(dados_teste,alvos_teste)
acuracia_restantes = previsao_acuracia(dados_amostra_restante,alvos_amostra_restante)
linha = [
df.shape[0],
amostra_balanceada.shape[0],
amostra_restante.shape[0],
dados_treino.shape[0],
dados_teste.shape[0],
acuracia_treino,
acuracia_teste,
acuracia_restantes
]
return linha
Crie uma função para calcular as acurâcias de teste, treino e restantes
def montar_tabela_previsoes(df, nome_classe, nomes_campos, tamanhos_amostra_balanceada=[60,600,1200,1800,2400,3000], est_size=0.2, modlog=modlog):
if type(nome_classe) == list:
nomes_campos.extend(nome_classe)
else:
nomes_campos.append(nome_classe)
dfaux = df[nomes_campos]
previsoes = [['POP','BAL','RES','TRE','TES','AC TRE','AC TES','AC RES']]
for tamanho_amostra_balanceada in tamanhos_amostra_balanceada:
previsoes.append(previsao_ultima(dfaux, nome_classe, tam_amostra_balanceada=tamanho_amostra_balanceada, modlog=modlog))
print(tabulate(previsoes, headers='firstrow', tablefmt='fancy_grid', floatfmt=".4f"))
return previsoes
Crie o objeto do algoritmo do modelo de regressão logística.
modlog = LogisticRegression()
A coluna preant apenas não é suficiente para criar uma correlação direta com a classe "subiu", que está correlacionada com a diferença entre o preço de fechamento e o preço anterior, o que explica a baixa acurâcia das previsões com relação ao conjunto de treino, e taxa de uma acerto em dois.
previsoes = montar_tabela_previsoes(v3,'subiu',['preant'])
O mesmo explica a baixa acurâcia da coluna premed, com um acerto de um em dois.
previsoes = montar_tabela_previsoes(v3,'subiu',['premed'])
Novamente o mesmo explica a baixa acurâcia da coluna preabe, com um acerto de um em dois.
previsoes = montar_tabela_previsoes(v3,'subiu',['preabe'])
A baixa acurâcia dos indicadores premax e premin é explicada pelo fato de que os valores de preço máximo estarem sempre acima do preço de fechamento, e os valores de preço mínimo estarem sempre abaixo, não sendo bons critérios para determinar se o preço de fechamento subiu em relação ao preço anterior.
previsoes = montar_tabela_previsoes(v3,'subiu',['premax','premin'])
Utilizando as colunas preabe, premed, preant, premax e premin, conseguimos uma melhoria na acurâcia de previsões, com diversos indicadores que mantêm determinada correlação que permite uma melhor avaliação de classe.
previsoes = montar_tabela_previsoes(v3,'subiu',['preabe','premed','preant','premax','premin'])
A coluna preult do preço de fechamento apenas não é suficiente para criar uma correlação direta com a classe "subiu", que está correlacionada com a diferença entre o preço de fechamento e o preço anterior, o que explica a baixa acurâcia das previsões com relação ao conjunto de treino, e taxa de aproximadamente, um acerto em dois.
previsoes = montar_tabela_previsoes(v3,'subiu',['preult'])
Então enfim quando utilizamos as colunas preult e preant, conseguimos uma alta acurâcia de previsões, afinal são as duas colunas que determinam a diferença que determina se o preço de fechamento subiu ou não.
previsoes = montar_tabela_previsoes(v3,'subiu',['preult','preant'])
Monte a tabela de previsões.
Quando utilizamos a coluna única ultant, conseguimos uma acurâcia ainda melhor de previsões, afinal é uma coluna com valores diretamente ligado às classes, com valores positivos indicando que o preço de fechamento subiu (1) e negativos indicando que o preço de fechamento não subiu (0).
previsoes = montar_tabela_previsoes(v3,'subiu',['ultant'])
Ao usarmos diversos indicadores incluindo preul e preant, conseguimos uma alta acurâcia de previsões, entretanto menor do que apenas com estas duas colunas, pela interferência na regressão das demais colunas.
previsoes = montar_tabela_previsoes(v3,'subiu',['preabe','premed','preant','premax','premin','preant','preult'])
Como com as classes da coluna subiu, a coluna preant apenas não é suficiente para criar uma correlação direta com as classes da coluna subira, que está correlacionada com a diferença entre o preço seguinte e o preço de fechamento, o que explica a baixa acurâcia das previsões com relação ao conjunto de treino, e taxa de um acerto em dois.
previsoes = montar_tabela_previsoes(v3,'subira',['preant'])
O mesmo explica a baixa acurâcia da coluna preabe, com um acerto de um em dois. O preço de abertura de um pregão não tem como explicar o preço de fechamento no dia seguinte.
previsoes = montar_tabela_previsoes(v3,'subira',['preabe'])
Os indicadores premax e premin de um pregão não têm como explicar o preço de fechamento no dia seguinte, com baixa acurâcia e um acerto de um em dois.
previsoes = montar_tabela_previsoes(v3,'subira',['premin','premax'])
A coluna preult apenas não é suficiente para criar uma correlação direta com as classes da coluna subira, que está correlacionada com a diferença entre o preço seguinte e o preço de fechamento, o que explica a baixa acurâcia das previsões com relação ao conjunto de treino, e taxa de um acerto em dois.
previsoes = montar_tabela_previsoes(v3,'subira',['preult'])
As colunas preult e preant não estabelecem uma correlação direta com as classes da coluna subira que permita prever o preço de fechamento no dia seguinte subirá ou não.
previsoes = montar_tabela_previsoes(v3,'subira',['preant','preult'])
Mesmo utilizando diversas colunas de dados indicadores não obtemos através de regressão uma acurâcia válida nas previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['preabe','premed','premax','premin','preult','preant','ultant'])
Agora, como as coluna preult e preant, a coluna preseg apenas não é suficiente para criar uma correlação direta com as classes da coluna subira, que está correlacionada com a diferença entre o preço seguinte e o preço de fechamento, explicando a baixa acurâcia das previsões com relação ao conjunto de treino, e taxa de um acerto em dois.
previsoes = montar_tabela_previsoes(v3,'subira',['preseg'])
Monte a tabela de previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['preult','preseg'])
Monte a tabela de previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['preant','preult','preseg'])
Monte a tabela de previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['segult'])
Monte a tabela de previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['preseg','premax','premin','preult','preant','segult','ultant'])
Monte a tabela de previsões.
previsoes = montar_tabela_previsoes(v3,'subira',['premax','premin','preult','preant'])
def calcular_mms(df):
df['mms1'] = df['preult'].rolling(window=1).mean()
df['mms2'] = df['preult'].rolling(window=2).mean()
df['mms3'] = df['preult'].rolling(window=3).mean()
df['mms4'] = df['preult'].rolling(window=4).mean()
df['mms5'] = df['preult'].rolling(window=5).mean()
df['mms6'] = df['preult'].rolling(window=6).mean()
df['mms7'] = df['preult'].rolling(window=7).mean()
df['mms8'] = df['preult'].rolling(window=8).mean()
df['mms9'] = df['preult'].rolling(window=9).mean()
df['mms10'] = df['preult'].rolling(window=10).mean()
df['mms11'] = df['preult'].rolling(window=11).mean()
df['mms12'] = df['preult'].rolling(window=12).mean()
df['mms13'] = df['preult'].rolling(window=13).mean()
df['mms14'] = df['preult'].rolling(window=14).mean()
df['mms15'] = df['preult'].rolling(window=15).mean()
df['mms16'] = df['preult'].rolling(window=16).mean()
df['mms17'] = df['preult'].rolling(window=17).mean()
df['mms18'] = df['preult'].rolling(window=18).mean()
df['mms19'] = df['preult'].rolling(window=19).mean()
df['mms20'] = df['preult'].rolling(window=20).mean()
df['mms21'] = df['preult'].rolling(window=21).mean()
x
v3ext = v3.copy()
calcular_mms(v3ext)
v3ext = v3ext.dropna()
x
previsoes = montar_tabela_previsoes(v3ext,'subira',['preant','preult','mms1','mms2','mms3','mms4','mms5','mms6','mms7','mms8','mms9','mms10','mms11','mms12','mms13','mms14','mms15','mms16','mms17','mms18','mms19','mms20','mms21'])
Até agora utilizamos basicamente os campos provenientes do conjunto de dados (premax, premin, preult, preant, segult, ultant, subira).
v3 = v3.assign(
maxmin = v3['premax'] - v3['premin'],
maxult = v3['premax'] - v3['preult'],
maxant = v3['premax'] - v3['preant'],
minult = v3['premin'] - v3['preult'],
minant = v3['premin'] - v3['preant'])
print('*** num linhas x colunas')
print(v3.shape)
print()
print('*** tabela')
print(v3)
x
previsoes = montar_tabela_previsoes(v3,'subiu',['maxmin','maxult','maxant','minult','minant','ultant'])
x
previsoes = montar_tabela_previsoes(v3,'subira',['maxmin','maxult','maxant','minult','minant','ultant'])
x
v3 = v3.assign(
pmaxult = v3['maxult'] / v3['maxmin'],
pmaxant = v3['maxant'] / v3['maxmin'],
pminult = v3['minult'] / v3['maxmin'],
pminant = v3['minant'] / v3['maxmin'],
pultant = v3['ultant'] / v3['maxmin'],
psegult = v3['segult'] / v3['maxmin'])
print(v3.shape)
x
previsoes = montar_tabela_previsoes(v3,'subiu',['pmaxult','pmaxant','pminult','pminant','pultant'])
x
previsoes = montar_tabela_previsoes(v3,'subira',['pmaxult','pmaxant','pminult','pminant','pultant'])
x
previsoes = montar_tabela_previsoes(v3,'subira',['pmaxult','pmaxant','pminult','pminant','pultant','psegult'])
Utilizados nos exemplos anteriores os valores reais (e em reais), das cotações de um pregão: máximo, mínimo, médio, de abertura e último.
Normalizamos os dados:
Até agora utilizamos basicamente os campos provenientes do conjunto de dados (premax, premin, preult, preant, segult, ultant, subira).
v3aux = v3[['preabe','premax','premin','preult','subiu','subira']].copy()
v3aux = v3aux.assign(
mmspreabe = v3aux['preabe'].rolling(window=21).mean(),
mmspremax = v3aux['premax'].rolling(window=21).mean(),
mmspremin = v3aux['premin'].rolling(window=21).mean(),
mmspreult = v3aux['preult'].rolling(window=21).mean())
v3aux = v3aux.assign(
preseg = v3aux['preult'].shift(-1),
preant = v3aux['preult'].shift(),
mmspreseg = v3aux['mmspreult'].shift(-1),
mmspreant = v3aux['mmspreult'].shift())
v3aux = v3aux.dropna()
v3aux = v3aux.assign(
ultant = v3aux['preult'] - v3aux['preant'],
segult = v3aux['preseg'] - v3aux['preult'],
mmsultant = v3aux['mmspreult'] - v3aux['mmspreant'],
mmssegult = v3aux['mmspreseg'] - v3aux['mmspreult'])
v3aux = v3aux.assign(
subiu = v3aux['ultant'].apply(lambda x: 1 if x > 0 else 0),
subira = v3aux['segult'].apply(lambda x: 1 if x > 0 else 0))
v3aux = v3aux.drop(v3aux.index[0])
v3aux = v3aux.drop(v3aux.index[-1])
print('*** Lin x Col:', v3aux.shape)
print()
print('*** tabela')
print(v3aux)
x
previsoes = montar_tabela_previsoes(v3aux,'subiu',['mmspreabe','mmspremax','mmspremin','mmspreult','mmspreant','mmspreseg'])
x
previsoes = montar_tabela_previsoes(v3aux,'subira',['mmspreabe','mmspremax','mmspremin','mmspreult','mmspreant','mmspreseg'])
x
v3 = v3.assign(
pmaxult = v3['maxult'] / v3['maxmin'],
pmaxant = v3['maxant'] / v3['maxmin'],
pminult = v3['minult'] / v3['maxmin'],
pminant = v3['minant'] / v3['maxmin'],
pultant = v3['ultant'] / v3['maxmin'],
psegult = v3['segult'] / v3['maxmin'])
print(v3.shape)
x
previsoes = montar_tabela_previsoes(v3,'subiu',['pmaxult','pmaxant','pminult','pminant','pultant'])
x
previsoes = montar_tabela_previsoes(v3,'subira',['pmaxult','pmaxant','pminult','pminant','pultant'])
x
previsoes = montar_tabela_previsoes(v3,'subira',['pmaxult','pmaxant','pminult','pminant','pultant','psegult'])
Crie a função previsao_ultima para prever a tendência da última entrada do conjunto de dados.
def previsao_ultima_2(df, tam_amostra_balanceada=120, test_size=0.2, random_state=2, modlog=modlog):
# Separar os dados das classes de valor 0, 1, 2 e 3.
classe_0 = df[df['subiu_subira']==0]
classe_1 = df[df['subiu_subira']==1]
classe_2 = df[df['subiu_subira']==2]
classe_3 = df[df['subiu_subira']==3]
# Preparar dados balanceados para o treinamento do modelo, com o mesmo número de amostras de cada classe 0 e 1 da coluna "subiu".
quarto_amostras_balanceadas = tam_amostra_balanceada // 4
amostra_classe_0 = classe_0.sample(quarto_amostras_balanceadas,axis=0)
amostra_classe_1 = classe_1.sample(quarto_amostras_balanceadas,axis=0)
amostra_classe_2 = classe_2.sample(quarto_amostras_balanceadas,axis=0)
amostra_classe_3 = classe_3.sample(quarto_amostras_balanceadas,axis=0)
amostra_balanceada = pd.concat([amostra_classe_0,amostra_classe_1,amostra_classe_2,amostra_classe_3],axis=0)
amostra_restante = df.drop(amostra_balanceada.index,axis=0)
# Separamos os dados (data) dos alvos (target). Os dados são todas as colunas menos as "subiu" e "subira", e o alvo inicialmente será a coluna "subiu" e depois a coluna "subira".
dados_amostra_balanceada = amostra_balanceada.drop(['subiu_subira'],axis=1)
alvos_amostra_balanceada = amostra_balanceada['subiu_subira']
# Preparar dois conjuntos separados de dados para o treinamento e teste do modelo, na proporção 4:1 (test_size=0.2).
dados_treino, dados_teste, alvos_treino, alvos_teste=train_test_split(
dados_amostra_balanceada,
alvos_amostra_balanceada,
test_size=test_size,
stratify=alvos_amostra_balanceada,
random_state=random_state)
# Treine o modelo usando o método <i>fit()</i>, que em inglês é "ajustar".
modlog.fit(dados_treino,alvos_treino)
def previsao_acuracia(dados,alvos,modlog=modlog):
alvos_previstos = modlog.predict(dados)
acuracia = accuracy_score(alvos,alvos_previstos)
return acuracia
dados_amostra_restante = amostra_restante.drop(['subiu_subira'],axis=1)
alvos_amostra_restante = amostra_restante['subiu_subira']
# Prever alvos e a acurâcia das previsões usando dados de treino, teste e restantes
acuracia_treino = previsao_acuracia(dados_treino,alvos_treino)
acuracia_teste = previsao_acuracia(dados_teste,alvos_teste)
acuracia_restantes = previsao_acuracia(dados_amostra_restante,alvos_amostra_restante)
linha = [
df.shape[0],
amostra_balanceada.shape[0],
amostra_restante.shape[0],
dados_treino.shape[0],
dados_teste.shape[0],
acuracia_treino,
acuracia_teste,
acuracia_restantes
]
return linha
Crie uma função para calcular as acurâcias de teste, treino e restantes
def montar_tabela_previsoes_2(df, nomes_campos, tamanhos_amostra_balanceada=[120,300,600,1200,1800], est_size=0.2, modlog=modlog):
nomes_campos.append('subiu_subira')
dfaux = df[nomes_campos]
previsoes = [['POP','BAL','RES','TRE','TES','AC TRE','AC TES','AC RES']]
for tamanho_amostra_balanceada in tamanhos_amostra_balanceada:
previsoes.append(previsao_ultima_2(dfaux, tam_amostra_balanceada=tamanho_amostra_balanceada, modlog=modlog))
print(tabulate(previsoes, headers='firstrow', tablefmt='fancy_grid', floatfmt=".4f"))
return previsoes
v3ext = v3.copy()
v3ext['subiu_subira'] = 2 * v3ext['subiu'] + v3ext['subira']
print(v3ext['subiu_subira'])
montar_tabela_previsoes_2(v3ext,['preant','preult'],tamanhos_amostra_balanceada=[80,300,600,1200,1800])