이번 주에는 6주차에 진행했던 python을 활용한 모델 제작을 KNIME으로 동일하게 진행해보았다. 전체 workflow는 아래와 같다.

간단하게 workflow에 대해 서술해보고, node 별로 하나씩 알아보자.
- python source : data를 python code로 가져와서 table(dataframe) 형태로 저장
- string manipulation : string 형태의 date column을 yyyy-mm-dd 형태로 변환
- string to date&time : string을 date&time type으로 변환
- partitioning : 전체 데이터를 train / test로 분할
- train, test : metanode(메타노드)로, 내부에서 모델링을 위해 필요한 전처리 수행
- rf, svm, xgboost, catboost, lgbm : ML 모형 사용, 결과 확인
python source


python source node는 local python 환경에서 script를 실행시킬 수 있다. python 2 및 3을 지원하며, knime_jupyter module을 통해 jupyter notebook을 python으로 가져올 수도 있다. 단, 출력 형식은 dataframe만 가능하다. KNIME에서 python을 사용하기 위해서는 설정이 필요한데, 아래의 포스팅에 기록해두었다.
[KNIME] python 설정
KNIME에서 python을 사용할 수 있지만, 사용에 앞서 몇 가지 설정해야할 사항들이 있다. 순서대로 알아보도록 하자. Anaconda 설치 Anaconda는 데이터 분석 및 ML에 사용되는 workflow로, KNIME에서 python 가상
hr1588.tistory.com
6주차의 python code를 활용해서 2012년부터 2023년 8월까지의 data를 load 시켰다. raw data는 python과 동일하게 기간, 변동률, log화된 변동률 3개의 column을 준비했고, 결과가 이상없이 출력됨을 확인할 수 있다.
String Manipulation

String Manipulation node는 다양한 함수를 활용해서 문자열을 가공할 수 있다. 위의 예시는 substr(column, start point, length) 함수를 사용해서 Date column에서 정해진 길이만큼을 추출하여 일 단위보다 아래의 시간을 제거하고있다. 만약 원하는 함수가 없다면, regex(정규표현식)을 활용해 문자를 처리할 수도 있다.
String to date&time

String to Date&Time node는 문자를 Datetime 형식으로 바꿔주는 column이다. 원하는 column을 include에 넣고, Replace를 체크하면 기존 column이 datetime format으로 변경된다. 또한 아래의 Type and Formate Selection에서 문자열과 일치하는 형태의 format으로 변경하는 기능(Guess data type and format)도 존재한다. 제일 처음 데이터를 가져왔을때는 datetime이 맞지만, string manipulation을 거치면서 type이 string으로 변환되었기 때문에 다시 datetime format으로 변환해야 한다.
Partitioning

Partitioning은 scikit-learn의 train_test_split과 동일한 역할을 수행한다. 각각의 옵션에 대해 간단하게 알아보자.
- Absolute : 첫 번째 분할의 개수를 숫자로 지정
- Relative : 첫 번째 분할의 개수를 %로 지정
- Take from top : 데이터셋의 처음부터 순차적으로 데이터를 선택해서 분할
- Linear Sampling : 데이터셋에서 일정한 간격으로 행을 선택 ex) 1,4,7,,, 마지막 행
- Draw randomly : 전체 데이터셋에서 무작위로 샘플을 추출해서 분할
- Stratified sampling : 선택한 column의 분포를 유지하면서 분할
- random seed : 시드를 고정해서 재실행 시 동일한 결과를 출력
위의 예시에서는 Relative로 8:2의 비율을 사용하였고, 데이터가 시간의 순서대로 흐르기 때문에 Take from top을 사용해 순차적으로 train과 test data를 분할하였다.
Train, Test

Train, Test는 metanode를 사용해서 전체적인 workflow에서는 과정을 간소하게 표현하였다. metanode를 사용하면 다수의 node를 하나의 node로 묶어서, 보다 직관적으로 전체 pipeline을 구성할 수 있다. 내부가 복잡해 보이지만, 사실 모두 동일한 원리로 구성되어 있다. python script 부터 확인해보자.


python script를 활용해 7일간의 log 변동률 및 그 다음날의 실제 변동률을 상승/하락에 맞춰 3개의 table로 분리하였다. knio는 KNIME에서 table 형식의 dataframe을 만들기 위해 사용되는 package이다. 위의 예시는 첫 번째 table의 결과로, 7일간의 log화된 변동률을 보여주고 있다. 마찬가지로 2번째 테이블은 0.7보다 상승하면 1, 그렇지 않으면 0을 나타내고, 3번째 테이블은 -0.7보다 하락하면 1, 그렇지 않으면 0을 나타내고 있다.

partitioning을 통해 feature, up, down data 별로 validation data를 분리한다. 옵션은 test를 분리할 때와 동일하게 사용한다. python에서는 ML 모델을 사용할 때 별도로 분리해서 값을 넣어도 되지만, KNIME에서는 target value가 포함된 하나의 table을 input으로 넣어서 학습을 진행하기 때문에 feature value를 기준으로 left join을 진행해서 up(상승), down(하락) data 별로 각각 2개의 train/val data를 제작한다. 차후 성능 지표 비교를 위해 target value의 type을 모델의 예측 결과의 type과 동일하게 하기 위해 number to string을 사용해 target을 문자열로 바꿔준다. 최종 상승 예측 모델의 훈련 데이터는 다음과 같다. 7개의 double feature와 하나의 string target value를 확인할 수 있다.



데이터는 잘 만들어졌지만, 여기서 하나의 문제를 식별할 수 있다. 상승 모델과 하락 모델의 train data가 모두 unbalanced data로, 상승과 하락이라고 규정한 날보다 그렇지 않은날이 훨씬 많아 데이터의 분포가 맞지 않는다는 점이다. 일단 진행을 해보고, 결과를 확인한 후 alpha 값인 0.7을 조정해서 성능을 비교해보자. Test 역시 validation으로 분할하는 과정을 제외하고는 Train metanode와 동일한 방법으로 진행했다.
rf, svm, xgboost, catboost, lgbm

상승, 하락 예측을 위해 train, val, test data 준비가 끝났으니, 모델을 사용해서 예측을 진행해보자. 우선 위에서 도출한 unbalanced 문제를 확인해보기 위해 random forest 모델을 기준으로 alpha 값을 변형해보고, 결과를 비교하는 방식으로 진행하였다.


역시 예상한 대로, 상승과 하락에 해당하는 value 1의 개수가 부족해서 의미없는 결과가 출력됨을 확인할 수 있다. 그렇다면, 현재 alpha 값인 0.7을 0.5, 0.3으로 떨어트려서 각각 결과를 비교해보자.


alpha를 0.3으로 바꿔서 상승과 하락에 해당하는 데이터의 양을 늘렸다. 수치를 더 감소시키면 데이터는 증가하겠지만, 분석 자체의 의미가 사라질 수 있다는 생각이 들어서 이대로 진행해보고, 결과를 비교해보았다. 0.5는 데이터의 개수가 조금 부족해보여서 배제하였다.


alpha를 0.3으로 변경해서 데이터의 수를 늘린 결과, 상승 예측 모델의 precision은 약 10%, 하락 예측 모델의 precision은 약 12% 향상된 결과를 확인할 수 있었다. 이제 모델들의 Test 결과도 확인해보고, 최종적으로 bagging 및 stacking에 활용할 모델을 정해보자. 정밀도는 예측하고싶은 Target value 1을 기준으로 작성하였다,
<상승 예측 모델 Test 결과>
| Model | Accuracy | Precision |
| Random Forest | 56.11 | 35.48 |
| SVM | 60.88 | 0 |
| Xgboost | 53.1 | 35.14 |
| Catboost | 58.23 | 41.38 |
| LightGBM | 54.34 | 37.91 |
<하락 예측 모델 Test 결과>
| Model | Accuracy | Precision |
| Random Forest | 60 | 38.6 |
| SVM | 62.3 | 0 |
| Xgboost | 61.06 | 45.68 |
| Catboost | 62.3 | 50 |
| LightGBM | 60.88 | 44.74 |
최종 Test 결과, 상승 예측에서는 정밀도를 기준으로 Catboost, LightGBM, Random Forest가 우세를 보이고, 하락 예측에서는 LightGBM, Catboost, Xgboost가 우세를 보이고 있다.
원래 이번주에 KNIME을 활용한 코스피 방향 예측을 끝내려고 했으나, 내용이 너무 길어져서 다음 주 포스팅에 hybrid model을 활용한 결과를 확인하면서 프로젝트를 마무리하도록 하자.
'데이터 분석 > 주식 선행연구 분석' 카테고리의 다른 글
| [주식] 기계학습을 활용한 주식 데이터 분석 - 9주차 (0) | 2023.09.05 |
|---|---|
| [주식] 기계학습을 활용한 주식 데이터 분석 - 7주차 (0) | 2023.08.19 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 6주차 (0) | 2023.08.14 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 5주차 (0) | 2023.08.08 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 4주차 (0) | 2023.08.06 |