본문 바로가기
Project/Predict Stock price Project

4. 주식 데이터 분석 - 전처리, EDA (주가 예측 프로젝트)

by inhovation97 2022. 3. 12.

학부 연구생으로서 진행한 주가 예측 프로그램의 일련의 과정을 차례로 포스팅합니다. 

위 그림처럼 어떤 종목이든 10일간의 데이터로

다음날 종가 상승 여부를 예측하는 머신러닝 프로젝트입니다.

 

주식 데이터는 여기저기 예제들도 굉장히 많이 있고,

비교적 얻기 쉬운 빅데이터이기 때문에 여러가지 프로젝트를 하시는 분들은 굉장히 많을 거라고 생각합니다. 

 

하지만 어려운 도메인인만큼 유의미한 모델링을 한 사례는 굉장히 적습니다. 

특히 주식을 잘 모르시는 분들에게는 정말 어려운 데이터죠...

제가 얻은 인사이트를 기록합니다.

데이터 수집 - EDA - 전처리 - 모델링 - 성능 개선

저번 포스팅은 데이터 정보가 너무 적은 단점을 커버하기 위해 수십개의 보조 지표를 추가하는 방법을 다뤘습니다.

이번 포스팅은 EDA를 통해 주식 데이터의 특성을 살펴보고, 데이터의 질을 높이는 전처리 과정에 대해서 다룹니다. 

 

1. 모델 선정 & 데이터 정의
2. 주식 종목 선정 & 전처리

 

1. 모델 선정 & 데이터 정의

 

보조 지표를 추가한 데이터 shape

저는 이미 모델링을 한 번 실패했습니다. 

그냥 전부 1,890개 회사의 데이터를 stack하여 모델에게 맡겨버리니 데이터가 난잡하여 모델이 잘 학습을 못한다고 생각했습니다. 

교수님께서도 사람이 맞추기 힘든 문제는 모델도 맞추기 어렵다고 하셨습니다. 따라서 위 사진처럼 보조 지표를 추가하고, EDA를 다시 하여 모델이 보다 패턴을 쉽게 인식할 수 있도록 데이터의 어떤 바운더리를 잡아주기로 결정했습니다. 

 

 

선정 모델 - 그래디언트 부스팅 트리 모델류 ( XGBoost & LGBM )

n개의 컬럼을 가진 10일치의 데이터를 1행으로 만들어 n*10컬럼을 가진 데이터로 shape을 변형하여 트리모델을 이용하였습니다.

약간 양방향 시계열 모델?로 의도할 수 있을 것 같아 괜찮다고 생각했습니다.

 

데이터 정의

주식 데이터에는 소음이 너무 많기에 조건을 걸어 바운더리를 어느 정도 잡아주기로 결정했습니다.

거래량 * 종가 = 해당 영업일의 거래 대금 으로 어림잡아 계산

이 거래 대금이 10억 이상인 날을 D-day로 잡았습니다. 

거래량으로 데이터의 범위를 줄여주어 학습할 패턴을 조금은 잡아주게 됩니다. 

(위 조건으로도 모델이 패턴을 잘 잡지 못하여 나중에는 추가 조건을 더 걸어주었습니다.)

이렇게 거래량이 터진 날을 기점으로 10일 간의 데이터를 학습에 이용합니다. 라벨 y는 D+1 시점의 주가 상승 여부가 되는 것이죠.

D+1 시점의 데이터는 절대 학습에 이용되지 않으며 오직 라벨로만 쓰게됩니다. 

라벨 y는 D+1 시점의 종가가 D-day에 비해 5% 이상 상승했으면, 1 아니면 0으로 두어 이진 분류를 의도했습니다.

 

최종 데이터 shape

0번째 컬럼은 거래 대금이 10억 이상인 날 D-day로 샘플링된 날을 의미하며, 그날을 기점으로 10일치의 데이터를 전부 1행으로 만든 것입니다. ( 1일치 데이터는 55개의 컬럼으로 결국 1행은 55*10의 컬럼을 갖게 됨.)

 

앞으로 프로젝트에서 쓰게될 최종 데이터의 shape입니다.

 

 

 

 

 

2. 주식 종목 선정 & 전처리

 

주식 데이터는 배경지식이 없으면, EDA 해석도 너무 힘들더라구요. 

EDA를 통해 얻은 인사이트로 전처리한 방식을 설명합니다.

 

우선 저는 크롤링을 통해 1,890개의 종목 코드를 얻었습니다.

예측해야 하는 데이터 y에 대한 분포를 확인해 봅시다. 거래 대금이 10억 이상 터진 다음날( D+1 )의 주가 상승률 분포를 확인해보는 것이죠. 

 

<거래량이 10억 이상인 날의 주가 변화량 분포>

 

D-day의 주가 상승률 분포 & 1600% 상승한 데이터 인덱싱

 

데이터 분포를 살펴보니 스케일이 커서 보기 힘듭니다.

하지만 주식을 하시는 분이라면 분명 이상한 것을 아실 겁니다.

우리나라 주식시장은 상한가 하한가가 최대 30%입니다. 따라서 주가 상승률 분포의 스케일은 -0.3 ~ 0.3 이어야 합니다.

뭔가 잘못된 부분이 있습니다. 하루만에 1600%가 오를 수가 없습니다.

인덱싱하여 해당 종목 2020-11-05에 무슨 일이 있었는지 검색해봅시다.

 

 

정말로 1605%가 올랐네요.

감자라는 말이 적혀있는 것을 보니 유통 주식의 개수를 줄여 액면가의 변화가 생겼나봅니다. 

주식의 액면가는 발행 주식의 개수에 따라 액면가가 결정되기 때문에 그것이 이유였나봅니다.

이렇게 액면가가 변하는 이슈로 인해 생기는 주가 변화는 모델 학습에 좋지 않을 겁니다. 

상한가 하한가가 30%를 초과하는 날짜들은 제거해줘야합니다.

 

상한가와 하한가가 초과하는 날들은 모두 제거해준 뒤에 주가 상승률 분포도를 다시 plot해봤습니다.

주가 변화량의 분포가 정규 분포에 가깝습니다.

다행히도 예측하려는 데이터가 그렇게 쓰레기는 아니라는 것을 알 수 있습니다. 

5% 상승을 기준으로 라벨링 했는데, 그냥 제 맘대로 정한겁니다.

이것도 하이퍼 파라미터가 되겠네요.

 

위처럼 라벨링하면 데이터 불균형이라는 문제가 생기는데, 그걸 해결하는게 이번 프로젝트 핵심일 것 같습니다.

93 : 7

라벨 1은 약 7%에 불과합니다.

데이터 불균형에 대해서는 마지막 포스팅에서 다룹니다.

 

 

 

<거래량의 편차가 큰 기업들과 작은 기업들의 주가 상승률 분포 비교>

 

거래량의 편차 하위 & 상위 100개 기업의 종가 변화량 y 분포

 

주식을 하다보면, 잡주라는 말을 들을 수 있습니다. 저는 잡주의 기준을 거래량의 편차가 큰 기업으로 생각하여 편차가 큰 기업 100개 작은 기업 100개로 데이터를 슬라이싱하여 종가 상승률의 분포를 다시 확인했습니다. 

 

거래량의 편차가 작은 상위 100개 기업의 분포 (왼쪽)와 편차가 큰 상위 100개의 기업의 분포가 조금 다른 양상을 보입니다. 

왜 이럴까요? 거래량의 편차가 큰 기업 몇 개를 서칭해보면...

코넥스 기업

들어본 적 없는 기업인데 코넥스 상장사입니다. 

코넥스는 정말 생소할 수 있는데, 우리나라 주식시장에서는 코스피 & 코스닥 외에 코넥스라고 코스닥에 들어가기 전에 거치는 아주 작은 기업들이 상장돼있는 시장입니다.

코넥스 시장은 상한가와 하한가도 15%로 시장의 성격이 다릅니다. 그래서 위 분포에서 +- 0.15 부근에서 종 모양으로 분포가 형성된 것이죠.

또한 수요도 굉장히 적어서 오른쪽 이미지에 거래량의 편차가 매우 크고 거래 정지일도 굉장히 많습니다.

왼쪽의 직선같은 것은 몇 달이 넘도록 계속 거래 정지 상태였던 것이죠.

거래정지일 또한 많으면 모델이 학습하는 데에 문제가 될 수 있습니다. 

당연히 제거해야겠죠...? 거래 정지일은 Volume이 0인 날을 drop해주면 됩니다.

 

하지만 거래 정지라는 것이 나쁜 이벤트만은 아니라서 무작정 거래 정지있는 기업을 drop할 순 없습니다.

삼성 전자나 카카오 같은 대형주들도 근 몇 년 내에 액면 분할 같은 액면가 변화 이슈로 했었습니다. 

( 어려운 주식 데이터... )

 

따라서 저는 최종적으로

 

1. 예측해야 할 데이터를 거래량이 10억 이상인 날로 범위를 좁혀주었습니다.

2. 액면가가 바뀌어 상한가 하한가를 초과하는 이상치는 drop해주었습니다.  

3. 특정 기준일로부터 코스피 & 코스닥에 상장했던 기업들만 다룹니다. 

4. 거래일이 20거래일(약 한달)이상 정지된 기업은 제외합니다. 

 

코넥스 기업을 거르는 방식은 제 첫번째 포스팅과 마찬가지로 KRX에서 코넥스 기업 리스트만 크롤링하여 1,890개 중 포함된 기업들을 제거해주는 방식으로 필터링하였습니다.

사실 코넥스 상장사들만 걸러주니 2와 4에 해당하는 기업들은 많이 없었던 것 같습니다. 

 

위 규칙으로 필터링하여 최종 1,561개의 기업들로 종목을 정하였습니다. 

따로 데이터 베이스를 서버 PC에 올려서 프로젝트를 진행중이라 코드는 공유하기가 애매하네요...

댓글