Sysmetic trading

[Randomforest] 10분 수익률을 이용한 주가 예측-2

quantoasis 2023. 1. 11. 23:11
반응형

 

 

 

 

 

이전 포스팅에서는 독립변수인 x와 종속변수인 y로 데이터를 전처리 과정을 보였습니다.

 

이후 진행 과정은 학습데이터와 테스트데이터를 나누어 모델을 생성 및 검증하는 것입니다.

 

train_test_split함수를 통해 학습, 검증용 데이터를 나눌 수 있습니다. 여기서 shuffle을 통해 데이터를 섞을지 말지를 결정할 수 있습니다. 이번 실험은 시계열예측이 아니라 횡단면 예측이므로 데이터를 섞어도 무방하니 셔플을 해줍시다.

 

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.26,  random_state=0, shuffle=True)

 

이번엔 데이터의 표준화를 진행하겠습니다. 표준화는 여러 방법이 있는데, 여기서는 MinMaxScaler를 이용할 것입니다.

 

주가수익률은 -30%부터 30%까지 최고 최저점이 있는 값이기 때문입니다. 만약 주가데이터 였으면 절대적인 고가가 없기 때문에 StandardScaler를 써서 평균은 0 분산은 1로 맞추는 정규화를 했을 것 같습니다.

 

여기서 주의할 점은 학습용 데이터에는 fit_transform을써야하고 검증용 데이터에는 transform을 써야 한다는 점입니다.

 

from sklearn.preprocessing import StandardScaler
scale = StandardScaler()
x_train = scale.fit_transform(x_train)
x_test = scale.transform(x_test)

 

아래는 RandomForest의 하이퍼파라미터들을 최적화하는 코드입니다. RandomizedSearchCV를 통해 가장 성능이 좋은 하이퍼파라미터들을 찾아줍니다. 사람이 하는 노가다를 편하게 해주는 것이죠 ㅎㅎ 

 

import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import RandomizedSearchCV
model = RandomForestClassifier()



grid_rf = {
'n_estimators': [20, 50, 100, 500, 1000],  
'max_depth': np.arange(1, 15, 1),  
'min_samples_split': [2, 10, 9], 
'min_samples_leaf': np.arange(1, 15, 2, dtype=int),  
'bootstrap': [True, False], 
'random_state': [1, 2, 30, 42]
}
rscv = RandomizedSearchCV(estimator=model, param_distributions=grid_rf, cv=3, n_jobs=-1, verbose=2, n_iter=200)
rscv_fit = rscv.fit(x_train, y_train)
best_parameters = rscv_fit.best_params_
print(best_parameters)

 

여러 변수를 조합해서 최적 파라미터들을 찾았습니다. 결과는 아래와 같습니다.

 

 

이 변수들을 적용하여 모델을 생성 후, x_test를 넣어 y값을 예측해보겠습니다. 아래 1,0,0,0,0으로 예측한 결과가 모델이 x변수에 대해 예측한 갭상승과 갭하락 결과입니다.

 

model = RandomForestClassifier(random_state=42,n_estimators=20, min_samples_split=2, min_samples_leaf=3, max_depth=6, bootstrap=True)

model.fit(x_train, y_train)
predict = model.predict(x_test)
print(predict)

 

이 모델의 성능평가를 해야하는데요, 이때 정확도(acurracy), 정밀도(precision), 재현율(recall), f1점수(f1-score)가 쓰입니다. 이 데이터들은 confusion_matrix를 통해 계산할 수 있어요.

 

정확도, 정밀도, 재현율의 의미는 아래와 같습니다.

 

정확도 :  전체 데이터중에서 상승과 하락을 맞춘 확률

정밀도 : 상승을 예측한(하락을 예측한) 결과가 실제 상승(하락) 일 확률,

재현율 :  전체 상승(하락)데이터 중 상승(하락)을 맞춘 확률

f1점수 : 정밀도와 재현율으 기하평균

 

아래 코드를 돌리면 성능지표의 결괏값이 나옵니다.

 

from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
from sklearn.metrics import f1_score, roc_auc_score


confusion = confusion_matrix(y_test, predict)
accuracy = accuracy_score(y_test, predict)
precision = precision_score(y_test, predict,average='macro')
recall = recall_score(y_test, predict,average='macro')
f1 = f1_score(y_test, predict,average='macro')
print(confusion)
print('정확도 {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}'.format(accuracy,precision, recall))

정확도는 51.55, 정밀도는 51.64, 재현율도 51.64가 나왔습니다. 뭔가 기대보다 찝찝한 수치긴 하지만 반타작보다는 잘했다는 것에서 의미를 부여해 봅니다.

 

 

graphviz를 이용하면 랜덤포레스트 모델이 어떤 방식으로 값을 예측했는지 도식화도 할 수 있습니다.

 

from sklearn.tree import export_graphviz
import graphviz


estimator = model.estimators_[0]

export_graphviz(estimator, out_file='tree.dot', 
                feature_names = stock_df.columns[:-1],
                class_names = ['0','1'],
                max_depth = 2, 
                precision = 3,
                filled = True,
                rounded=True, 
               )

with open("tree.dot") as f:
    dot_graph = f.read()
    
graphviz.Source(dot_graph)

 

설명가능한(explainable) AI라고 XAI가 유행인데 이런 도식화된 자료들이 있으면 해석하기도 용이하겠죠? 

 

 

다음 포스팅에서는 feature importance, PermutationImportance 등으로 y값에 영향을 많이 미치는 변수들을 중심으로 모델을 재학습시켜 성능을 개선시켜 볼 예정입니다.

 

감사합니다.

 

반응형