Post List

2019년 1월 25일 금요일

R을 이용한 데이터로 투자하기 - (3) 시각화 및 모델링하기



data science hadley에 대한 이미지 검색결과


첫번째 단계인 크롤링,
두번째 단계인 데이터 정리 및 변형 단계를 마쳤다면
마지막 단계인 시각화 및 모델링을 통해
원하는 종목을 뽑는 작업을 하도록 하겠습니다.

 시각화 역시 R의 기본함수인 plot()을 이용할 수 있지만
ggplot2 패키지를 이용할 경우
훨씬 아름답게 시각화를 할 수 있습니다.

이에 대한 간단한 설명은 지난 포스트에 있으며 (Link),
더욱 자세한 내용은
해들리 위컴의 'ggplot2 R로 분석한 데이터를 멋진 그래픽으로'
책을 참조하시면 좋습니다.





먼저 지난시간에 만들어놓은 data_market 데이터를 바탕으로
시각화를 통해 자료를 확인해보도록 하겠습니다.

library(ggplot2)
library(tidyr)

먼저 그래프 출력에 필요한 ggplot2 패키지와
데이터 변형에 필요한 tidyr 패키지를 불러옵니다.


ggplot(data_market, aes(x = ROE, y = PBR)) +
  geom_point()



먼저 가장 기본적으로 ROE와 PBR의 관계를 살펴봅니다.
x축에는 ROE, y축에는 PBR를 입력한 후
geom_point()를 통해 산점도로 살펴봅니다.

그러나 각 축에서 극단적으로 높은 값으로 인해,
값들이 알아보기 힘든 형태를 보입니다.

따라서 x축과 y축의 범위를 줄여보도록 하겠습니다.


ggplot(data_market, aes(x = ROE, y = PBR)) +
  geom_point() +
  coord_cartesian(xlim = c(0, 0.30), ylim = c(0, 3))


coord_cartesian() 함수를 통해
x축의 범위는 0부터 0.30까지,
y축의 범위는 0에서 3까지 데이터만 보여주도록 합니다.
극단치를 날려 데이터의 분포가 잘 보입니다.


ggplot(data_market, aes(x = ROE, y = PBR,
                        color = 시장구분, shape = 시장구분)) +
  geom_point() +
  coord_cartesian(xlim = c(0, 0.30), ylim = c(0, 3)) +
  geom_smooth()



이번에는 colorshape 변수 구분을 통해
시장구분 별 색과 모양이 다르게 표시하도록 합니다.
또한 geom_smooth() 함수를 통해 평활선도 추가해주도록 합니다.

그러나 위의 그림으로는 데이터로부터
직관적인 의미를 찾아내기는 아직 부족합니다.


ggplot(data_market, aes(x = PBR)) +
  geom_histogram(binwidth = 0.1) + 
  coord_cartesian(xlim = c(0, 10))


이번에는 PBR의 히스토그램을 나타내도록 합니다.
역시나 극단치 제거를 위해 x범위는 0에서 10으로 제한합니다.

국내 종목들의 대부분 PBR은 0과 2 사이 어딘가에 
위치하고 있음이 보입니다.



ggplot(data_market, aes(x = PBR)) +
  geom_histogram(binwidth = 0.1,
                 color = 'blue', fill = 'blue') + 
  coord_cartesian(xlim = c(0, 10)) +
  geom_vline(xintercept = market_PBR,
             color = 'red') +
  annotate(geom = 'text',
           x = market_PBR + 0.1,
           y = 20,
           label = 'Median PBR',
           angle = 90,
           vjust = 1,
           color = 'red')



이번에는 Median 값에 해당하는 부분에 붉은 석 밑
글자를 추가해주도록 합니다.

geom_vline() 함수를 통해 세로선을 그려주며,
annotate() 함수를 통해 각종 글자를 추가해줍니다.

각 입력값이 의미하는 바는
직관적으로도 이해하실 수 있을 겁니다.

우리는 이를 통해 PBR 분포가
굉장히 우측으로 꼬리가 길다는 사실을 알 수 있습니다.


ggplot(data_market, aes(x = ROE)) +
  geom_histogram(binwidth = 0.01) + 
  coord_cartesian(xlim = c(0, 1))


ROE 값도 간단하게 그려보면,
대부분 10% 언저리에 위치해 있으며,
우측으로 꼬리가 길다는 사실이 확인됩니다.


data_market %>%
  group_by(시장구분) %>%
  summarize(PBR = median(PBR, na.rm = TRUE),
            ROE = median(ROE, na.rm = TRUE)) %>%
  gather(index, value, -시장구분) %>%
  ggplot(aes(fill = 시장구분, x = index, y = value)) +
  geom_bar(position = "dodge", stat = "identity") +
  xlab('시장 별 지표') +
  ylab('데이터')


이번에는 시장 별 PBR과 ROE값을 비교해보도록 하겠습니다.
먼저 data_market 데이터에서
group_by() 함수를 통해 시장별 그룹을 나눈 후,
summarize() 함수를 통해 그루 별 PBR과 ROE의 median 값을 구합니다.
그 후 gather() 함수를 이용해 긴 열의 형태로 만들어 줍니다.

이처럼 그룹별 그래프를 나타낼 때는
gather() 함수를 이용하는 것이 좋습니다.

그 후, x축에는 PBR과 ROE에 해당하는 index,
y축에는 각 데이터를 나타내는 value를 지정하며,
fill에는 시장구분을 지정하여
그룹별로 데이터가 그려지도록 합니다.

그 후 geom_bar()함수에서
position은 dodge를 입력하여 데이터가 포개지지 않게 설정하며,
stat은 identity를 입력하여 고유값이 y축으로 오도록 합니다.


코스닥과 코스피 간 ROE는 거의 차이가 없지만,
코스닥의 PBR이 코스피의 PBR에 비해
현저히 높은 사실이 확인됩니다.


이번에는 가지고 있는 데이터를 바탕으로
마법공식을 활용해 종목을 선택하도록 하겠습니다.

퀄리티지표로는 ROE를,
밸류지표로는 PBR를 선택하도록 합니다.


data_market_magic = data_market %>%
  mutate(rank_PBR = rank(PBR),
         rank_ROE = rank(-ROE),
         rank = rank_PBR + rank_ROE,
         rank = rank(rank)) %>%
  arrange(rank) %>%
  slice(1:30) %>%
  select(종목명, 산업분류, PBR, ROE, rank)

data_market_magic %>% head()
        종목명 산업분류  PBR    ROE rank
1    STX중공업     기계 0.12 6.0000    1
2    APS홀딩스     금융 0.31 3.4444    2
3 SK디스커버리   금융업 0.29 0.3412    3
4          BGF   금융업 0.37 3.3636    4
5     대성산업   유통업 0.44 0.8980    5
6       쌍방울 섬유의복 0.43 0.4725    6


mutate() 함수를 통해
PBR의 랭킹을 구한 후 rank_PBR 열에,
ROE의 랭킹을 구한 후 rank_ROE 열에 저장하며,
ROE는 내림차순으로 순위를 매겨야 하므로
(-) 기호를 붙여주도록 합니다.

두 지표의 랭킹을 더하여 rank 열에 저장해준 후,
이를 다시 랭킹해주도록 합니다.

arrange() 함수를 통해 랭킹 별로 오름차순 정리를 한 후,
slice() 함수를 통해 1번부터 30번,
즉 1등부터 30번째 등수까지 종목을 선택합니다.

그 후 종목명, 산업분류, PBR, ROE, rank 열을 선택하여
data_market_magic 변수에 저장해줍니다.


data_market_magic %>%
  group_by(산업분류) %>%
  summarize(n())

# A tibble: 17 x 2
   산업분류      `n()`
   <chr>         <int>
 1 IT H/W            2
 2 건설              1
 3 건설업            2
 4 금속              1
 5 금융              2
 6 금융업           10
 7 기계              1
 8 기계·장비         1
 9 기타서비스        1
10 서비스업          1
11 섬유의복          1
12 운송장비·부품     2
13 운수장비          1
14 유통업            1
15 음식료·담배       1
16 전기전자          1
17 화학              1

이렇게 선택된 종목들 확인해보면
금융업 섹터의 비중이 압도적으로 많습니다.

data_market_magic %>%
  filter(산업분류 == '금융업')

             종목명 산업분류  PBR    ROE rank
1      SK디스커버리   금융업 0.29 0.3412  3.0
2               BGF   금융업 0.37 3.3636  4.0
3      경동인베스트   금융업 0.25 0.1397 12.0
4      오리온홀딩스   금융업 0.58 1.3182 13.0
5  크라운해태홀딩스   금융업 0.61 0.7821 15.0
6               HDC   금융업 0.44 0.1472 19.0
7        노루홀딩스   금융업 0.43 0.1443 20.0
8      미래에셋생명   금융업 0.37 0.1237 21.5
9         SJM홀딩스   금융업 0.35 0.1155 24.0
10       풍산홀딩스   금융업 0.43 0.1208 29.0

마법공식으로 선택된 종목에서 금융업에 해당하는 종목을 찾아보면
각종 지주회사가 많습니다.

이는 국내 거래소 기준 섹터가
지주회사를 금융업으로 정의하고 있으며,
지주회사가 극심하게 저평가 받는 상황때문에
해당 조건에 선택되는 영향이 있습니다.

data_market_magic %>%
  ggplot(aes(x = ROE, y = PBR)) +
  geom_point()


이번에는 ggplot()을 이용하여
마법공식 종목들의 ROE와 PBR를 확인해보도록 하겠습니다.

ROE가 2를 넘는 극단적인 종목들이 많으며,
이는 정상적인 종목이라 판단하기 어렵습니다.

따라서 이러한 극단치 데이터들을 제거한 후,
다시 마법공식으로 종목을 선택하도록 하겠습니다.


data_market_adjusted = 
  data_market %>%
  filter(ROE < 0.3 & PBR > 0.5)

data_market_adjusted_magic = 
  data_market_adjusted %>%
  mutate(rank_PBR = rank(PBR),
         rank_ROE = rank(-ROE),
         rank = rank_PBR + rank_ROE,
         rank = rank(rank)) %>%
  arrange(rank) %>%
  slice(1:30) %>%
  select(종목명, 산업분류, PBR, ROE)

먼저 filter() 함수를 통해
ROE는 30% 이하, PBR는 0.5 이상인 기업만을 선택하도록 합니다.

그 후 위와 동일한 과정을 거쳐 
ROE와 PBR 기준 마법공식 종목을 선정합니다.

data_market_adjusted_magic

           종목명     산업분류  PBR    ROE
1        한신공영       건설업 0.53 0.2163
2        영보화학         화학 0.53 0.2137
3             GST       IT H/W 0.56 0.2171
4        체리부로 음식료·담배 0.62 0.2288
5            서한         건설 0.66 0.2727
6    신원종합개발         건설 0.65 0.2181
7      신세계건설       건설업 0.60 0.1818
8    상신브레이크     운수장비 0.55 0.1549
9      현대중공업     운수장비 0.69 0.2300
10       계룡건설       건설업 0.57 0.1601
11       동원개발         건설 0.61 0.1690
12       화성산업       건설업 0.52 0.1323
13           삼호       건설업 0.68 0.2012
14     엠케이전자       IT H/W 0.61 0.1572
15       사조오양     음식료품 0.62 0.1623
16   아시아나항공   운수창고업 0.74 0.2196
17     한화케미칼         화학 0.56 0.1393
18   한화손해보험       금융업 0.58 0.1491
19         코오롱       금융업 0.53 0.1268
20     세보엠이씨         건설 0.70 0.1795
21   한국특수형강     철강금속 0.73 0.1877
22   푸른저축은행         금융 0.51 0.1123
23       동신건설         건설 0.56 0.1239
24 우진아이엔에스       건설업 0.80 0.2222
25 우리손에프앤지 음식료·담배 0.68 0.1650
26       덕우전자 일반전기전자 0.77 0.1949
27       동원산업         어업 0.75 0.1834
28       티에스이       IT H/W 0.54 0.1139
29     엘오티베큠       IT H/W 0.84 0.2320
30       하림지주         금융 0.60 0.1319


얼핏 보기에도 지주사의 비중이 확연히 줄어든 것이 보입니다.


ggplot(data_market_adjusted_magic, aes(x = ROE, y = PBR)) +
  geom_point()



ROE와 PBR 그래프를 확인해보아도,
기존에 비해 훨씬 안정적인 모습이 보입니다.


ggplot(data_market_adjusted_magic, aes(x = 산업분류)) +
  geom_bar(stat = 'count') +
  theme(axis.text.x = element_text(angle = 40, hjust = 1))


선택된 종목의 산업분류를 막대그래프로 나타내보면,
비교적 여러 섹터에 종목이 포진되어 있음이 확인됩니다.


data_market_adjusted_magic %>%
  select(종목명, PBR, ROE) %>%
  gather(지표, data, -종목명) %>%
  ggplot(aes(x = data)) +
  geom_histogram() +
  facet_wrap( ~ 지표, ncol = 1, scales="free")


마지막으로 facet_wrap() 함수를 이용하여
종목들의 ROE와 PBR 별 히스토그램을 나타내보도록 합니다.



데이터로 투자하기 마지막 단계로써

시각화를 통해 데이터를 이해해보고,
ROE와 PBR를 이용해 마법공식을 이용한
퀀트 종목을 선택해보았습니다.


데이터과학 접근의 금융 투자 이해에 도움이 되셨길 기원합니다.

댓글 없음:

댓글 쓰기