terça-feira, 16 de dezembro de 2014

A Análise de Componentes Principais (PCA em inglês) é um método matemático para análise multivariada. Ela consiste em um modo de identificar a relação entre atributos/características presentes nos dados, convertendo um conjunto de observações de variáveis que possam estar correlacionadas em um conjunto de valores linearmente não correlacionado, que são as componentes principais.

No mercado financeiro, a análise de componentes principais é útil para entender o comportamento do retorno de um ativo em relação a outro ativo. Pode não fazer sentido do ponto de vista econômico, mas é totalmente relevante do ponto de vista matemático. Por exemplo, vamos ver a correlação entre os retornos diários de alguns papéis da bolsa brasileira.

library("quantmod") 
library(moments)  # para o cálculo da assimetria e curtose

#Seleção do período de análise
startDate = as.Date("2014-01-01") 
endDate = as.Date("2014-12-15")

#Seleção das ações
tickers = c('^BVSP','GGBR4.SA','USIM5.SA','VALE5.SA','PETR4.SA','BBDC4.SA','ITUB4.SA')
tickers_setor = c('Mercado','Siderugira','Siderurgia','Mineracao','Petroleo','Banco','Banco')

getSymbols(tickers, src = "yahoo", from = startDate, to = endDate)

Com os dados capturados, vamos calcular os retornos diários de cada um deles com a função dailyReturn()  e plotar como exemplo os retornos do índice Bovespa.

BVSP_RET <- dailyReturn(BVSP)
GGBR4_RET <- dailyReturn(GGBR4.SA)
USIM5_RET <- dailyReturn(USIM5.SA)
VALE5_RET <- dailyReturn(VALE5.SA)
PETR4_RET <- dailyReturn(PETR4.SA)
BBDC4_RET <- dailyReturn(BBDC4.SA)
ITUB4_RET <- dailyReturn(ITUB4.SA)

plot(BVSP_RET)


Apenas por curiosidade, repare no aumento da volatilidade a partir do mês de setembro, quando iniciou a forte queda do petróleo, eleições no Brasil e operação a Lava a Jato.

Com a função cor(), calculamos a correlação entre os retornos da Gerdau (GGBR4) e Usiminas(USIM5). Note que a correlação é alta, de 0,63.

> cor(GGBR4_RET,USIM5_RET)
              daily.returns
daily.returns     0.6289431

Além disso, poderíamos dizer que os retornos praticamente obedecem uma distribuição normal?

hist(GGBR4_RET)

Para verificar se a distribuição é próxima a uma normal, podemos rodar um teste de normalidade. Vamos utilizar o teste de Shapiro.


shapiro.test(as.numeric(GGBR4_RET))

Shapiro-Wilk normality test data: as.numeric(GGBR4_RET) W = 0.9856, p-value = 0.01611

H0: A amostra provém de uma distribuição Normal
H1: A amostra não provém de uma distribuição Normal

Como resultado, temos um p-valor menor que 0,05. Ou seja, rejeitamos H0 ao nível de significância de 95%. Graficamente, podemos criar um gráfico do tipo Norm Q-Q Plot. Quanto mais linear for a figura, mais próximo a distribuição do conjunto de dados é de uma distribuição normal. Naturalmente, distribuições de retornos não são normais, o que foi comprovado pelo teste e pode ser observado no gráfico abaixo.

qqnorm(GGBR4_RET)
qqline(GGBR4_RET, col = 2)


Agora vamos calcular algumas estatísticas básicas dos retornos.

statNames <- c("Media", "Desvio", "Assimetria", "Curtose")
GGBR4_STATS <- c(mean(GGBR4_RET), sd(GGBR4_RET), skewness(GGBR4_RET), kurtosis(GGBR4_RET))
names(GGBR4_STATS) <- statNames
GGBR4_STATS

       Media       Desvio             Assimetria       Curtose 
-0.002790937  0.019011483 -0.070110480  3.474567187 

Passados todos estes primeiros testes, vamos ao cálculo das componentes principais. Começamos agrupando todos os retornos na variável grupo_ret e utilizamos a função prcomp() para o cáculo das componentes.

grupo_ret <- cbind(BVSP_RET,GGBR4_RET,USIM5_RET,VALE5_RET,PETR4_RET,BBDC4_RET,ITUB4_RET)
PCA <- prcomp(grupo_ret,center = TRUE, scale. = TRUE)
plot(PCA)
summary(PCA)

Importance of components:
                                         PC1    PC2      PC3       PC4     PC5       PC6     PC7
Standard deviation         2.0828 1.1831 0.6879 0.60938 0.50816 0.3230 0.23508
Proportion of Variance  0.6197 0.1999 0.0676 0.05305 0.03689 0.0149 0.00789
Cumulative Proportion  0.6197 0.8197 0.8873 0.94032 0.97721 0.9921 1.00000

No gráfico acima, cada barra é uma componente principal (PC) e o eixo y representa as variâncias. Podemos exibir este gráfico de um modo mais explicativo, em função do percentual da variância que é explicada por cada uma das componentes. Para isto, temos:

PCA_VAR_EXPLAINED = PCA$sdev^2 / sum(PCA$sdev^2)
barplot(100*PCA_VAR_EXPLAINED, las=2, xlab='', ylab='% Variância Explicada', main = "Variância por PC")
Ou seja, a primeira componente explica um pouco mais de 60% da variância do mercado (ou todo o conjunto de dados analisado).

Agora, vamos plotar PC1 em função de PC2 para entender a relação dos retornos diários dos papéis. Esta é a análise final das componentes principais. Não poderíamos entender esta relação apenas utilizando os retornos diários de cada ativo, pois eles possuem correlação alta entre si. Aqui, eliminamos este efeito e podemos entender como os retornos estão relacionados.


p = princomp(na.omit(grupo_ret))
loadings = p$loadings[]
PC1 = loadings[,1]
PC2 = loadings[,2]

plot(PC1, PC2, type='p', pch=20, 
     xlab='Componente 1', 
     ylab='Componente 2', 
     ylim = c(-0.75,0.45), 
     xlim = c(-0.7,-0.1),
     main = 'PCA para o IBovespa')
text(PC1, PC2, tickers, cex=.7, pos=4)


Note que papéis de mesmo setores ficam agrupados entre si. Além disso, os bancos estão bem mais próximos do Índice Bovespa (BVSP) do que a Petrobrás, por exemplo.

O código completo está disponível no GitHub do Arte dos Dados.

Um abraço e até o próximo post!


0 comentários:

Postar um comentário