A essência da aprendizagem de máquina:
- existe um padrão
- não conseguimos descobrí-lo matematicamente (formalmente)
- mas nós temos dados!!
library(tidyverse)
library(rvest)
library(GetDFPData2)
library(yfR)
df.info <- get_info_companies()
O sítio da Fundamentus disponibiliza informações financeiras e fundamentalistas das empresas com ações listadas na Bovespa.
# Função para limpar os dados do site da Fundamentus -----
limpa_dados <- function(x) {
# Limpeza dos dados da Fundamentus (http://www.fundamentus.com.br)
# Primeiro elimina todos os caracteres não-dígitos e qualquer outro após estes
# Depois elimina os pontos
# Finalmente, converte vírgulas em pontos
# Se é um valor representado com "%", divide por 100
z <- trimws(x)
n_digitos <- nchar(z)
ultimo <- substr(z, n_digitos, n_digitos)
z <- gsub("[^0-9,.]", "", z)
z <- gsub("\\.", "", z)
z <- as.numeric(gsub(",", ".", z))
if(ultimo[1] == "%") {
z <- z/100
}
return(z)
}
# Nomes das empresas
url.detalhes <- "http://www.fundamentus.com.br/detalhes.php?papel="
empresas.b3 <- url.detalhes %>%
read_html() %>%
rvest::html_table(header = TRUE) %>%
map_df(bind_cols) %>% # tranforma a lista em um dataframe
as_tibble() # converte para um 'tibble'
# Dados fundamentalistas
url.dados <- "http://www.fundamentus.com.br/resultado.php"
dados.Fund <- url.dados %>%
read_html() %>%
rvest::html_table(header = TRUE) %>%
map_df(bind_cols) %>% # tranforma a lista em um dataframe
as_tibble() %>% # transforma para um tibble
mutate_at(colnames(.)[-1], limpa_dados) %>% # converte ao formato adequado utilizando a função limpa_dados()
mutate(Nome = empresas.b3$`Nome Comercial`[match(.$Papel, empresas.b3$Papel)]) %>%
select(Papel, Nome, everything())
dados.Fund
Se desejar criar uma planilha Excel.
## Com o pacote 'openxlsx' - não depende do Java -------
library(openxlsx)
# Cria um arquivo vazio
arq <- createWorkbook()
# Adiciona planilhas ao arquivo
addWorksheet(arq, "Empresas")
addWorksheet(arq, "Dados fundamentalistas")
# Escreve os dados nas planilhas
writeData(arq,
sheet = "Empresas",
x = empresas.b3)
writeData(arq,
sheet = "Dados fundamentalistas",
x = dados.Fund)
# Exporta o arquivo completo
saveWorkbook(arq, "Dados/Fundamentus2.xlsx", overwrite = TRUE)
Quantos NA´s?
sum(colSums(is.na(dados.Fund[])))
## [1] 0
# Nenhum!
glimpse(dados.Fund)
## Rows: 986
## Columns: 22
## $ Papel <chr> "PMET3", "MNSA4", "CSTB4", "CFLU4", "PORP4", "CLAN…
## $ Nome <chr> "PRO METALURG", "MANASA", "COMPANHIA SIDERÚRGICA D…
## $ Cotação <dbl> 0.00, 0.47, 147.69, 1000.00, 2.40, 0.00, 0.42, 150…
## $ `P/L` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `P/VP` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ PSR <dbl> 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0…
## $ Div.Yield <dbl> 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.…
## $ `P/Ativo` <dbl> 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0…
## $ `P/Cap.Giro` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `P/EBIT` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `P/Ativ Circ.Liq` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `EV/EBIT` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `EV/EBITDA` <dbl> 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.…
## $ `Mrg Ebit` <dbl> 0.0000, 2.0815, 0.4085, 0.0888, 0.0000, 0.0000, 2.…
## $ `Mrg. Líq.` <dbl> 0.0000, 3.6266, 0.2898, 0.1072, 0.0000, 0.0000, 3.…
## $ `Liq. Corr.` <dbl> 0.00, 3.63, 2.60, 1.10, 0.00, 0.00, 3.63, 2.60, 0.…
## $ ROIC <dbl> 0.0000, 0.1350, 0.2240, 0.1768, 0.0000, 0.0000, 0.…
## $ ROE <dbl> 0.0410, 1.4570, 0.2011, 0.3215, 0.0208, 0.0105, 1.…
## $ Liq.2meses <dbl> 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00…
## $ `Patrim. Líq` <dbl> 290863000, 9105000, 8420670000, 60351000, 22399000…
## $ `Dív.Brut/ Patrim.` <dbl> 0.00, 6.52, 0.14, 0.06, 0.00, 0.00, 6.52, 0.14, 0.…
## $ `Cresc. Rec.5a` <dbl> 0.3774, 0.4111, 0.3191, 0.0814, 0.1366, 0.6396, 0.…
summary(dados.Fund)
## Papel Nome Cotação P/L
## Length:986 Length:986 Min. : 0.000 Min. : 0.00
## Class :character Class :character 1st Qu.: 4.352 1st Qu.: 1.86
## Mode :character Mode :character Median : 12.000 Median : 7.77
## Mean : 59.599 Mean : 102.01
## 3rd Qu.: 28.285 3rd Qu.: 17.64
## Max. :10081.900 Max. :35858.80
## P/VP PSR Div.Yield P/Ativo
## Min. : 0.0 Min. : 0.00 Min. :0.00000 Min. : 0.0000
## 1st Qu.: 0.5 1st Qu.: 0.09 1st Qu.:0.00000 1st Qu.: 0.0880
## Median : 1.2 Median : 0.68 Median :0.00000 Median : 0.3975
## Mean : 1464.1 Mean : 140.95 Mean :0.03865 Mean : 1.9460
## 3rd Qu.: 2.2 3rd Qu.: 1.75 3rd Qu.:0.02438 3rd Qu.: 0.8728
## Max. :723708.0 Max. :125972.00 Max. :3.85080 Max. :721.2280
## P/Cap.Giro P/EBIT P/Ativ Circ.Liq EV/EBIT
## Min. : 0.000 Min. : 0.0 Min. : 0.000 Min. : 0.0
## 1st Qu.: 0.140 1st Qu.: 0.8 1st Qu.: 0.050 1st Qu.: 2.9
## Median : 2.200 Median : 4.9 Median : 1.210 Median : 7.8
## Mean : 39.145 Mean : 363.4 Mean : 13.621 Mean : 451.4
## 3rd Qu.: 7.327 3rd Qu.: 12.3 3rd Qu.: 4.405 3rd Qu.: 17.0
## Max. :15159.500 Max. :324900.0 Max. :6206.380 Max. :368611.0
## EV/EBITDA Mrg Ebit Mrg. Líq. Liq. Corr.
## Min. : 0.000 Min. : 0.0000 Min. : 0.0000 Min. : 0.000
## 1st Qu.: 2.663 1st Qu.: 0.0422 1st Qu.: 0.0222 1st Qu.: 0.520
## Median : 6.270 Median : 0.1315 Median : 0.0988 Median : 1.295
## Mean : 44.412 Mean : 4.1470 Mean : 6.6552 Mean : 1.875
## 3rd Qu.: 14.075 3rd Qu.: 0.2731 3rd Qu.: 0.2125 3rd Qu.: 2.047
## Max. :7466.350 Max. :787.0000 Max. :1567.2900 Max. :66.470
## ROIC ROE Liq.2meses Patrim. Líq
## Min. :0.0000 Min. : 0.000 Min. :0.000e+00 Min. :0.000e+00
## 1st Qu.:0.0279 1st Qu.: 0.067 1st Qu.:0.000e+00 1st Qu.:2.894e+08
## Median :0.0908 Median : 0.152 Median :0.000e+00 Median :1.152e+09
## Mean :0.1567 Mean : 28.145 Mean :2.194e+07 Mean :6.387e+09
## 3rd Qu.:0.1751 3rd Qu.: 0.299 3rd Qu.:9.308e+05 3rd Qu.:4.004e+09
## Max. :6.2387 Max. :13632.000 Max. :2.672e+09 Max. :4.105e+11
## Dív.Brut/ Patrim. Cresc. Rec.5a
## Min. : 0.000 Min. : 0.0000
## 1st Qu.: 0.040 1st Qu.: 0.0642
## Median : 0.475 Median : 0.1352
## Mean : 44.264 Mean : 0.3575
## 3rd Qu.: 1.218 3rd Qu.: 0.2891
## Max. :21227.000 Max. :63.5407
sumario.fund <- psych::describe(dados.Fund[, -c(1, 2)])
sumario.fund
Quantas empresas pagaram dividendos maiores do que R$0,02 por ação?
Quantas possuem PL maior do que R$ 5 Bilhões?
Quais empresas apresentam um ROE maior do que 40%?
sum(dados.Fund$Div.Yield > 0.02)
## [1] 269
sum(dados.Fund$`Patrim. Líq` > 5.5e9) # 5e9 = 5.500.000.000
## [1] 207
grande.ROE <- dados.Fund %>%
filter(ROE > 0.40) %>%
select(Papel, Nome, ROE)
grande.ROE
O sítio da Status Invest possui muitas informações importantes sobre as ações listadas na BOVESPA. Por exemplo, aqui podemos selecionar as empresas do setor Consumo Cíclico, Tecido, Vestuário e Calçados e baixar um arquivo com os dados.
A função read_csv2() lê os dados no formato que
gostamos: separador ‘;’ e vírgulas para os decimais.
empresas <- read_csv2('Dados/statusinvest-busca-avancada.csv')
Inclui ‘Patrimônio Líquido’ e ‘Dív.Brut/ Patrim.’ nos dados da StatusInvest, buscando na Fundamentus.
empresas$PatLiq <- dados.Fund$`Patrim. Líq`[match(empresas$TICKER, dados.Fund$Papel)]
empresas$DivBruta <- dados.Fund$'Dív.Brut/ Patrim.'[match(empresas$TICKER, dados.Fund$Papel)]
summary(empresas)
## TICKER PRECO DY P/L
## Length:32 Min. : 0.000 Min. : 1.29 Min. : -9.9200
## Class :character 1st Qu.: 4.325 1st Qu.: 1.73 1st Qu.: -0.8575
## Mode :character Median : 9.400 Median : 2.33 Median : 2.7050
## Mean : 19.257 Mean : 3.87 Mean : 6.7706
## 3rd Qu.: 23.145 3rd Qu.: 4.15 3rd Qu.: 7.5350
## Max. :103.610 Max. :15.54 Max. :101.9900
## NA's :19
## P/VP P/ATIVOS MARGEM BRUTA MARGEM EBIT
## Min. :-1.1300 Min. :0.0000 Min. :14.56 Min. :-0.59
## 1st Qu.: 0.0000 1st Qu.:0.0500 1st Qu.:19.35 1st Qu.: 7.34
## Median : 0.5550 Median :0.2800 Median :32.23 Median :10.40
## Mean : 0.8459 Mean :0.5516 Mean :31.98 Mean :10.94
## 3rd Qu.: 1.6375 3rd Qu.:0.7650 3rd Qu.:40.38 3rd Qu.:14.21
## Max. : 3.7600 Max. :2.4800 Max. :67.90 Max. :20.81
## NA's :2 NA's :2
## MARG. LIQUIDA P/EBIT EV/EBIT
## Min. :-83.8700 Min. :-707.6500 Min. :-713.650
## 1st Qu.: -3.0750 1st Qu.: 0.6125 1st Qu.: 4.830
## Median : 5.3100 Median : 1.9350 Median : 8.535
## Mean : 0.2687 Mean : -18.1450 Mean : -13.728
## 3rd Qu.: 10.0300 3rd Qu.: 5.5250 3rd Qu.: 13.572
## Max. : 25.5600 Max. : 25.3100 Max. : 22.370
## NA's :2
## DIVIDA LIQUIDA / EBIT DIV. LIQ. / PATRI. PSR P/CAP. GIRO
## Min. :-5.990 Min. :-0.3000 Min. :0.0000 Min. : -2.2300
## 1st Qu.: 0.230 1st Qu.: 0.0200 1st Qu.:0.0750 1st Qu.: -0.0025
## Median : 2.500 Median : 0.3300 Median :0.2850 Median : 0.9850
## Mean : 4.119 Mean : 0.4012 Mean :0.8637 Mean : 13.1116
## 3rd Qu.: 7.480 3rd Qu.: 0.7100 3rd Qu.:0.8800 3rd Qu.: 5.5350
## Max. :22.040 Max. : 1.7800 Max. :4.1800 Max. :175.5700
## NA's :7 NA's :2
## P. AT CIR. LIQ. LIQ. CORRENTE ROE ROA
## Min. :-5.590 Min. :0.040 Min. :-80.560 Min. :-47.520
## 1st Qu.:-1.442 1st Qu.:0.940 1st Qu.: -7.433 1st Qu.: -3.020
## Median :-0.625 Median :1.470 Median : 6.930 Median : 3.775
## Mean :-1.216 Mean :1.911 Mean : 1.276 Mean : 1.359
## 3rd Qu.:-0.110 3rd Qu.:2.380 3rd Qu.: 12.260 3rd Qu.: 7.080
## Max. : 0.000 Max. :7.000 Max. : 26.290 Max. : 17.130
##
## ROIC PATRIMONIO / ATIVOS PASSIVOS / ATIVOS GIRO ATIVOS
## Min. :-68.120 Min. :-1.6700 Min. :0.1000 Min. :0.0000
## 1st Qu.: 3.330 1st Qu.: 0.1400 1st Qu.:0.4675 1st Qu.:0.5200
## Median : 8.060 Median : 0.4550 Median :0.5300 Median :0.7300
## Mean : 2.075 Mean : 0.1584 Mean :0.8347 Mean :0.6959
## 3rd Qu.: 11.158 3rd Qu.: 0.5325 3rd Qu.:0.8500 3rd Qu.:0.9300
## Max. : 19.540 Max. : 0.9000 Max. :2.6700 Max. :1.2000
##
## CAGR RECEITAS 5 ANOS CAGR LUCROS 5 ANOS LIQUIDEZ MEDIA DIARIA
## Min. :-7.540 Min. :-26.63 Min. : 1900
## 1st Qu.:-0.530 1st Qu.: 10.32 1st Qu.: 8960
## Median : 8.130 Median : 34.56 Median : 43022
## Mean : 5.352 Mean : 30.89 Mean : 9400429
## 3rd Qu.:10.410 3rd Qu.: 54.47 3rd Qu.: 204408
## Max. :13.540 Max. : 59.07 Max. :109503606
## NA's :3 NA's :21 NA's :4
## VPA LPA PEG Ratio VALOR DE MERCADO
## Min. :-3571.28 Min. :-240.610 Min. :-1.23000 Min. :8.804e+06
## 1st Qu.: 2.71 1st Qu.: -2.955 1st Qu.:-0.02000 1st Qu.:6.294e+07
## Median : 6.35 Median : 0.360 Median : 0.00500 Median :1.739e+08
## Mean : -161.74 Mean : -10.537 Mean :-0.02031 Mean :1.594e+09
## 3rd Qu.: 12.13 3rd Qu.: 1.035 3rd Qu.: 0.06000 3rd Qu.:5.437e+08
## Max. : 1048.02 Max. : 128.530 Max. : 0.60000 Max. :1.250e+10
##
## PatLiq DivBruta
## Min. :1.028e+08 Min. :0.000
## 1st Qu.:1.939e+08 1st Qu.:0.135
## Median :3.386e+08 Median :0.560
## Mean :1.066e+09 Mean :0.853
## 3rd Qu.:1.326e+09 3rd Qu.:0.900
## Max. :5.733e+09 Max. :3.510
## NA's :2 NA's :2
colSums(is.na(empresas))
## TICKER PRECO DY
## 0 0 19
## P/L P/VP P/ATIVOS
## 0 0 0
## MARGEM BRUTA MARGEM EBIT MARG. LIQUIDA
## 2 2 2
## P/EBIT EV/EBIT DIVIDA LIQUIDA / EBIT
## 0 0 0
## DIV. LIQ. / PATRI. PSR P/CAP. GIRO
## 7 2 0
## P. AT CIR. LIQ. LIQ. CORRENTE ROE
## 0 0 0
## ROA ROIC PATRIMONIO / ATIVOS
## 0 0 0
## PASSIVOS / ATIVOS GIRO ATIVOS CAGR RECEITAS 5 ANOS
## 0 0 3
## CAGR LUCROS 5 ANOS LIQUIDEZ MEDIA DIARIA VPA
## 21 4 0
## LPA PEG Ratio VALOR DE MERCADO
## 0 0 0
## PatLiq DivBruta
## 2 2
sum(colSums(is.na(empresas)))
## [1] 66
sumario.StatInv <- psych::describe(empresas[, -1])
empresas <- empresas %>%
mutate_all(~replace(., is.na(.), 0))
# poderia ter substituído pelo valor médio, ou por uma regressão
moda <- function(v) {
# cálculo da moda de um conjunto de dados (não existe no R)
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
grafico <- function(df, .var, binwidth = 10, mostra = TRUE) {
nome_var <- deparse(substitute(.var))
nome_df <- deparse(substitute(df))
nome <- substr(nome_var, nchar(nome_df)+1, nchar(nome_var))
x <- seq(min(.var), max(.var), length.out = 100)
normal <- data.frame(x = x, y = dnorm(x, mean(.var), sd(.var)))
g <- ggplot(df, aes(x = .var, y = ..density..)) +
geom_histogram(binwidth = binwidth, color = "black", fill = "lightblue") +
xlab(nome) +
geom_vline(xintercept = mean(.var), color = "darkgreen",
linetype = "dashed", lwd = 1) +
geom_vline(xintercept = median(.var), color = "darkred",
linetype = "dashed", lwd = 1) +
geom_vline(xintercept = moda(.var), color = "black",
linetype = "dashed", lwd = 1) +
geom_rug(aes(x = .var, y = 0), color = 'darkred', position = position_jitter(height = 0)) +
geom_density(color = "darkblue", lwd = 1) +
geom_line(data = normal, aes(x = x, y = y), color = "darkred") # uma curva Normal
if(mostra) print(g)
return(invisible(g))
}
library(gridExtra)
g1 <- grafico(empresas, empresas$`P/L`, binwidth = 2, mostra = TRUE)
g2 <- grafico(empresas, empresas$`EV/EBIT`, binwidth = 2, mostra = FALSE)
g3 <- grafico(empresas, empresas$ROA, binwidth = 2, mostra = FALSE)
g4 <- grafico(empresas, empresas$`P/EBIT`, binwidth = 2, mostra = FALSE)
g5 <- grafico(empresas, empresas$ROIC, binwidth = 2, mostra = FALSE)
g6 <- grafico(empresas, empresas$ROE, binwidth = 2, FALSE)
grid.arrange(g1, g2, g3, g4, g5, g6, nrow = 2)
Não parece que algumas aproximações pela distribuição Normal sejam válidas aqui.
outliers <- boxplot(empresas$'P/L', main = 'Boxplot de P/L')$out
(emp.out <- empresas$TICKER[empresas$'P/L' %in% outliers])
## [1] "ALPA4" "DOHL3" "HGTX3"
Benjamin Graham é um dos maiores investidores de todos os tempos e, muito provavelmente, um dos personagens mais influentes da área.
O preço justo de uma ação é uma das premissas da análise
fundamentalista, que consiste em avaliar as perspectivas de uma
determinada companhia, ou seja, analisar a situação financeira dela e
até onde ela pode chegar no longo prazo. Graham estabeleceu alguns
modelos, entre eles a seleção de ações de acordo com o valor de alguns
indicadores. A seguinte função retorna TRUE se a empresa
atinge os valores mínimos passados em seus parâmetros.
is.graham <- function(df,
pl = 9, # Patrimônio líquido
pvp = 1.2, # Preço / valor patrimonial
l.corr = 1.5, # Índice de liquidez corrente (at. Circ. / Passivo Circ.)
roe = 0, # Retorno sobre o patrimônilo líquido
roic = 0, # Retorno sobre o capital investido (inclui dívidas) -> EBIT - (Ativos-Fornecedores-Caixa)
mrg.liq = 0, # Lucro líquido / receita líquida
marg.ebit = 0, # EBIT (lucro operacional) / receita líquida
div.brut = 1.1, # Dívida bruta / PL
pat.liq = 0, # Patrimõnio Líquido
cresc.rec.5a = 0) { # Crescimento da receita líquida (5 anos)
selecao <- df$'P/L' < pl &
df$'P/VP' < pvp &
df$'LIQ. CORRENTE' > l.corr &
df$ROE > roe &
df$ROIC > roic &
df$'MARG. LIQUIDA' > mrg.liq &
df$'MARGEM EBIT' > marg.ebit &
df$DivBruta < div.brut &
df$PatLiq > pat.liq &
df$'CAGR RECEITAS 5 ANOS' > cresc.rec.5a
return(selecao)
}
Selecionemos as empresas listadas de acordo com o padrão de Graham.
empresas.graham <- empresas %>%
filter(is.graham(., pl = 12, l.corr = 1.0))
# ou, em R básico
#empresas.graham <- empresas[is.graham(empresas, pl = 12, l.corr = 1.0), ]
empresas.graham
Ações que fazem parte do índice IBOVESPA (atuais).
### Ações que fazem parte do índice IBOVESPA (atuais)
ibovespa <- yf_index_composition('IBOV')
# Ações listadas na Fundamentus que estão no Ibovespa
dados.Fund.ibov <- dados.Fund %>%
filter(Papel %in% ibovespa$ticker)
Calcula o dividendo mediano (metade das empresas pagam este valor ou mais dividendos por ação). Cria-se uma coluna com o valor “1” neste caso.
med.dividendo.ibov <- median(dados.Fund.ibov$Div.Yield)
dados.Fund.ibov$dividendo <- ifelse(dados.Fund.ibov$Div.Yield > med.dividendo.ibov, 1, 0)
Podemos fazer o mesmo para todas as empresas listadas na B3.
med.dividendo <- median(dados.Fund$Div.Yield)
dados.Fund$dividendo <- ifelse(dados.Fund$Div.Yield > med.dividendo, 1, 0)
# Normalização dos dados
# 1. todos com média zero e desvio-padrão um
#dados.scaled <- as.data.frame(scale(dados.Fund[, -c(1, 2, 3, 7)], scale = TRUE))
dados.scaled <- as.data.frame(scale(dados.Fund[, -c(1, 2, 3, 7)], scale = TRUE))
# 2. normalização Max-Min - todos entre zero e um (vamos utilizar este modelo aqui)
normaliza <- function(x) {
return((x - min(x)) / (max(x) - min(x)))
}
# Retirando algumas variáveis ("Papel", "Nome", "Cotação" e "Div.Yield" )
maxmindf <- as.data.frame(lapply(dados.Fund[, -c(1, 2, 3, 7)], normaliza))
# Segregando dados para o modelo (trainset) 80% e para testar o modelo (testset)
# Utilizando o pacote caret para manter o equilibrio entre 0 e 1´s
library(caret)
set.seed(1234)
indices <- createDataPartition(maxmindf$dividendo,
p = 0.8,
list = FALSE,
times = 1)
treinamento <- maxmindf[indices, ]
teste <- maxmindf[-indices, ]
prop.table(table(treinamento$dividendo))
##
## 0 1
## 0.6413181 0.3586819
prop.table(table(teste$dividendo))
##
## 0 1
## 0.6548223 0.3451777
# Uma Rede Neural Simples
library(neuralnet)
# Selecionando dividendo como variável dependente
formula <- dividendo ~ . # todas as variáveis ?
nn <- neuralnet(formula = formula,
data = treinamento,
hidden = c(10,4),
linear.output = FALSE,
threshold = 0.05)
# Testando os resultados
nn.resultados <- compute(nn, teste)
#Acurária da rede neural
resultados <- data.frame(actual = teste$dividend, prediction = nn.resultados$net.result)
library(gmodels)
CrossTable(round(resultados$actual, digits = 0),
round(resultados$prediction, digits = 0))
##
##
## Cell Contents
## |-------------------------|
## | N |
## | Chi-square contribution |
## | N / Row Total |
## | N / Col Total |
## | N / Table Total |
## |-------------------------|
##
##
## Total Observations in Table: 197
##
##
## | round(resultados$prediction, digits = 0)
## round(resultados$actual, digits = 0) | 0 | 1 | Row Total |
## -------------------------------------|-----------|-----------|-----------|
## 0 | 110 | 19 | 129 |
## | 9.679 | 16.804 | |
## | 0.853 | 0.147 | 0.655 |
## | 0.880 | 0.264 | |
## | 0.558 | 0.096 | |
## -------------------------------------|-----------|-----------|-----------|
## 1 | 15 | 53 | 68 |
## | 18.362 | 31.878 | |
## | 0.221 | 0.779 | 0.345 |
## | 0.120 | 0.736 | |
## | 0.076 | 0.269 | |
## -------------------------------------|-----------|-----------|-----------|
## Column Total | 125 | 72 | 197 |
## | 0.635 | 0.365 | |
## -------------------------------------|-----------|-----------|-----------|
##
##
# matriz de confusão
result.round <- sapply(resultados, round, digits = 0)
result.round.df <- data.frame(result.round)
(tabela <- table(result.round.df$actual, result.round.df$prediction))
##
## 0 1
## 0 110 19
## 1 15 53
source(paste0(dirname(getwd()),'/Matriz de Confusao.R'))
mc <- confusionMatrix(tabela, positive = '1')
plot_matconf(mc)
Rede Neural - Dividendos?
library(rattle)
library(rpart.plot)
library(RColorBrewer)
fit_dividendos_tree <- rpart(dividendo ~ P.L + PSR + P.Cap.Giro + ROE + Mrg..Líq.,
data = treinamento,
method = "class")
fit_dividendos_tree
## n= 789
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 789 283 0 (0.64131812 0.35868188)
## 2) P.L< 5.410109e-05 200 11 0 (0.94500000 0.05500000) *
## 3) P.L>=5.410109e-05 589 272 0 (0.53820034 0.46179966)
## 6) P.L>=0.0002760829 339 123 0 (0.63716814 0.36283186)
## 12) Mrg..Líq.< 6.358109e-05 231 72 0 (0.68831169 0.31168831)
## 24) PSR>=4.163624e-06 148 39 0 (0.73648649 0.26351351) *
## 25) PSR< 4.163624e-06 83 33 0 (0.60240964 0.39759036)
## 50) P.L>=0.0004510748 52 14 0 (0.73076923 0.26923077) *
## 51) P.L< 0.0004510748 31 12 1 (0.38709677 0.61290323)
## 102) P.L< 0.0003074559 7 1 0 (0.85714286 0.14285714) *
## 103) P.L>=0.0003074559 24 6 1 (0.25000000 0.75000000) *
## 13) Mrg..Líq.>=6.358109e-05 108 51 0 (0.52777778 0.47222222)
## 26) ROE>=2.816168e-05 12 0 0 (1.00000000 0.00000000) *
## 27) ROE< 2.816168e-05 96 45 1 (0.46875000 0.53125000)
## 54) P.Cap.Giro>=0.0006464593 40 16 0 (0.60000000 0.40000000)
## 108) ROE< 6.451731e-06 11 1 0 (0.90909091 0.09090909) *
## 109) ROE>=6.451731e-06 29 14 1 (0.48275862 0.51724138)
## 218) Mrg..Líq.>=0.000120367 9 2 0 (0.77777778 0.22222222) *
## 219) Mrg..Líq.< 0.000120367 20 7 1 (0.35000000 0.65000000) *
## 55) P.Cap.Giro< 0.0006464593 56 21 1 (0.37500000 0.62500000) *
## 7) P.L< 0.0002760829 250 101 1 (0.40400000 0.59600000)
## 14) ROE>=5.731001e-05 15 2 0 (0.86666667 0.13333333) *
## 15) ROE< 5.731001e-05 235 88 1 (0.37446809 0.62553191)
## 30) PSR>=1.43008e-05 41 14 0 (0.65853659 0.34146341)
## 60) P.Cap.Giro< 0.0001550183 19 3 0 (0.84210526 0.15789474) *
## 61) P.Cap.Giro>=0.0001550183 22 11 0 (0.50000000 0.50000000)
## 122) ROE>=2.274061e-05 8 1 0 (0.87500000 0.12500000) *
## 123) ROE< 2.274061e-05 14 4 1 (0.28571429 0.71428571) *
## 31) PSR< 1.43008e-05 194 61 1 (0.31443299 0.68556701)
## 62) ROE< 9.991197e-06 43 19 0 (0.55813953 0.44186047)
## 124) P.Cap.Giro>=0.0001246743 14 0 0 (1.00000000 0.00000000) *
## 125) P.Cap.Giro< 0.0001246743 29 10 1 (0.34482759 0.65517241)
## 250) P.L< 0.0001415273 7 1 0 (0.85714286 0.14285714) *
## 251) P.L>=0.0001415273 22 4 1 (0.18181818 0.81818182) *
## 63) ROE>=9.991197e-06 151 37 1 (0.24503311 0.75496689) *
fit_prune <- prune(fit_dividendos_tree, cp = 0.03)
fit_prune
## n= 789
##
## node), split, n, loss, yval, (yprob)
## * denotes terminal node
##
## 1) root 789 283 0 (0.6413181 0.3586819)
## 2) P.L< 5.410109e-05 200 11 0 (0.9450000 0.0550000) *
## 3) P.L>=5.410109e-05 589 272 0 (0.5382003 0.4617997)
## 6) P.L>=0.0002760829 339 123 0 (0.6371681 0.3628319) *
## 7) P.L< 0.0002760829 250 101 1 (0.4040000 0.5960000)
## 14) ROE>=5.731001e-05 15 2 0 (0.8666667 0.1333333) *
## 15) ROE< 5.731001e-05 235 88 1 (0.3744681 0.6255319)
## 30) PSR>=1.43008e-05 41 14 0 (0.6585366 0.3414634) *
## 31) PSR< 1.43008e-05 194 61 1 (0.3144330 0.6855670) *
fancyRpartPlot(fit_dividendos_tree)
fancyRpartPlot(fit_prune)
previsao.dividendos <- predict(fit_dividendos_tree)
norm <- scale(dados.Fund.ibov[, -c(1:2)], center = TRUE) # normaliza os dados antes de calcular as distâncias
rownames(norm) <- dados.Fund.ibov$Papel
library(cluster)
clusters <- hclust(dist(norm), method = 'complete')
clusters2 <- hclust(dist(norm, method = 'euclidean'), method = "ward.D2")
plot(x = clusters2,
labels = dados.Fund.ibov$Papel,
main = 'Clusters',
ylab = 'Altura',
col = 'darkblue')
wss <- nrow(norm) * sum(apply(norm, 2, var))
num.clusters.max <- 25
for (i in 2:num.clusters.max) {
wss[i] <- sum(kmeans(norm, centers = i)$withinss)
}
plot(1:num.clusters.max,
wss,
col = 'darkred',
main = 'Curva do cotovelo (elbow curve)',
type = "b",
xlab = "Número de Clusters",
ylab = "Soma dos Quadrados - Within")
library(factoextra)
library(dendextend)
library(igraph)
dist <- dist(norm , method = "euclidean")
hc <- hclust(d = dist,
method = "ward.D2")
num.clusters <- 10
fviz_dend(hc,
k = num.clusters,
cex = 0.8,
title = paste0('Dendograma com ', num.clusters, ' clusters'),
k_colors = 'startrek',
type = 'phylogenic',
repel = TRUE)
fviz_dend(hc, k = num.clusters,
cex = 0.8,
title = paste0('Dendograma com ', num.clusters, ' clusters'),
k_colors = 'startrek',
type = 'rectangle',
repel = TRUE)
fviz_dend(clusters2,
k = num.clusters,
cex = 0.5,
k_colors = 'uchicago',
color_labels_by_k = TRUE,
ggtheme = theme_gray())
fviz_nbclust(norm,
FUNcluster = kmeans,
method = "wss",
k.max = 10) +
geom_vline(xintercept = 10, linetype = 2)
km.res <- kmeans(norm,
centers = 10,
nstart = 25)
print(km.res)
## K-means clustering with 10 clusters of sizes 11, 25, 1, 25, 1, 1, 3, 1, 12, 8
##
## Cluster means:
## Cotação P/L P/VP PSR Div.Yield P/Ativo
## 1 0.6848670 -0.1186502 1.5931849 0.5966564 -0.40285300 1.85346120
## 2 -0.5946481 0.5845733 -0.3925551 -0.1577991 -0.55791070 -0.25271139
## 3 -0.5146810 -0.2731574 4.9340310 -0.7376414 0.02799878 -0.33824568
## 4 -0.1113657 -0.3080757 -0.1556809 -0.4232167 0.34876030 -0.34224455
## 5 -0.9741427 1.5099635 -0.5005506 0.7900540 -0.61489080 0.09409975
## 6 0.1544381 -0.3555786 -0.4806619 -0.8716070 2.82420611 0.60174859
## 7 1.7759366 -0.3440666 -0.4193385 -0.4130386 3.71935135 -0.20668110
## 8 -1.1488571 -0.2652340 -0.3762464 0.2098610 -0.19561499 -0.71606105
## 9 0.7037352 -0.2540450 -0.4222389 -0.5072205 -0.18862706 -0.63664625
## 10 -0.1465726 -0.2678177 -0.1338531 1.9871588 -0.15951068 0.38801025
## P/Cap.Giro P/EBIT P/Ativ Circ.Liq EV/EBIT EV/EBITDA Mrg Ebit
## 1 0.26914985 -0.10662517 -0.09904890 -0.1066553 -0.01572028 -0.07282534
## 2 -0.27925038 -0.10639240 -0.10272952 -0.1064178 -0.08877634 -0.35611641
## 3 -0.38287960 -0.10699087 -0.11674707 -0.1069086 -0.20897418 -0.68956331
## 4 -0.15699921 -0.10696834 -0.11592027 -0.1068977 -0.13658145 0.16855355
## 5 5.20066595 9.27422189 -0.11366243 9.2742253 0.86295010 -1.12359822
## 6 1.05680143 -0.09680078 -0.06618324 -0.0983115 8.78435632 -1.12359822
## 7 0.01051151 -0.10703794 -0.11671683 -0.1070077 -0.30031477 1.57124631
## 8 -0.40417923 -0.10679366 9.26562600 -0.1067514 -0.13914112 0.07830131
## 9 -0.27047697 -0.10690040 -0.11796555 -0.1068562 -0.23090212 -0.84822155
## 10 0.71117149 -0.10660284 -0.08093921 -0.1066076 0.02243082 1.72669104
## Mrg. Líq. Liq. Corr. ROIC ROE Liq.2meses Patrim. Líq
## 1 -0.2215008 -0.08530456 0.2498402 0.02642156 -0.05858178 -0.2793928
## 2 -0.3389845 -0.14124432 -0.4321343 -0.60040339 -0.24006810 -0.3505912
## 3 -0.6175891 0.03344225 1.4015254 3.97741669 -0.32905363 -0.4883153
## 4 -0.0257196 0.05893705 0.5440410 0.53453966 -0.29453943 -0.2865995
## 5 -0.6621605 -0.45442115 -1.1776534 -0.97510022 0.43758171 0.2043757
## 6 -0.7369254 3.44061730 -1.1416992 2.56749290 -0.40597314 -0.3871171
## 7 0.8495919 -0.25507912 2.1001631 1.04509136 4.31901080 4.3250606
## 8 0.1521058 -0.36786474 -0.6404566 -0.47624620 -0.22097384 -0.3464419
## 9 -0.5196998 -0.84392500 -0.9884537 -0.45834856 0.23327312 0.7635098
## 10 2.1382877 1.40457447 0.1966661 -0.17158729 -0.15353791 -0.2645889
## Dív.Brut/ Patrim. Cresc. Rec.5a dividendo
## 1 -0.1685880 -0.11441606 -0.6327376
## 2 -0.1341853 0.10409040 -0.9943019
## 3 7.5885806 -0.04666141 0.9943019
## 4 0.3248024 -0.06197669 0.8352136
## 5 -0.4583754 1.15791618 -0.9943019
## 6 -0.5650754 -0.93747588 0.9943019
## 7 -0.3101810 -0.16504258 0.9943019
## 8 -0.2716504 -0.20490717 0.9943019
## 9 -0.4680080 -0.12692111 0.1657170
## 10 -0.3322249 0.28188042 0.4971510
##
## Clustering vector:
## MGLU3 EMBR3 HAPV3 RAIL3 NTCO3 IGTI11 CASH3 COGN3 BRFS3 VIIA3 CVCB3
## 2 2 5 2 2 2 2 2 2 2 4
## IRBR3 AZUL4 GOLL4 MRFG3 BRAP4 USIM5 GOAU4 GGBR4 PETR4 JBSS3 PETR3
## 2 2 2 4 6 4 4 4 7 4 7
## PCAR3 VALE3 BRKM5 BBAS3 CSNA3 SUZB3 KLBN11 CPLE6 ENBR3 JHSF3 DXCO3
## 2 7 4 9 4 4 4 4 4 10 4
## ITSA4 ENGI11 TAEE11 CSAN3 BBDC3 SANB11 CCRO3 CPFE3 VBBR3 CYRE3 QUAL3
## 10 4 10 4 9 9 4 4 2 4 4
## EQTL3 BBDC4 UGPA3 CMIG4 PRIO3 ITUB4 MRVE3 EZTC3 BEEF3 TIMS3 BBSE3
## 2 9 4 4 10 9 2 10 3 4 1
## CIEL3 VIVT3 BPAN4 SBSP3 FLRY3 ASAI3 BRML3 BPAC11 CRFB3 B3SA3 LCAM3
## 8 9 9 9 4 1 10 9 2 10 4
## ABEV3 ELET3 EGIE3 ELET6 HYPE3 ENEV3 MULT3 ECOR3 LREN3 SULA11 SOMA3
## 1 9 4 9 1 2 10 2 1 2 2
## ALPA4 RENT3 AMER3 WEGE3 TOTS3 RADL3 RDOR3 PETZ3 BIDI11 YDUQ3 LWSA3
## 1 1 9 1 1 1 1 2 2 2 2
##
## Within cluster sum of squares by cluster:
## [1] 101.74543 209.66266 0.00000 151.15266 0.00000 0.00000 33.11929
## [8] 0.00000 56.47886 155.01812
## (between_SS / total_SS = 61.3 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
clusplot(norm,
km.res$cluster,
main = 'Representação 2D dos clusters',
color = TRUE,
shade = TRUE,
labels = 2,
lines = 0)
options(ggrepel.max.overlaps = 30)
fviz_cluster(km.res, data = norm,
pallete = 'rickandmorty',
ellipse.type = "euclid", # elipse de concentração
star.plot = TRUE,# adiciona segmentos dos centróides
repel = TRUE, # evita sobreposição de rótulos
ggtheme = theme_minimal()
)