Sysmetic trading

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

quantoasis 2023. 1. 13. 13:03
반응형


아래는 모든 변수를 랜덤포레스트모델에 학습하여 나올 성능입니다. 이전 포스팅에서는 50%가 약간 넘는 수치가 나왔었는데, 다시 학습시키니 수치가 약간 달라졌네요. 학습데이터를 랜덤샘플링 했기 때문으로 보입니다.

 


feature importance가 높은 변수들만으로 다시 학습을 시켜보겠습니다. 아래 코드를 실행하면 top_feature변수에 상위 5개의 변수가 입력됩니다.

top_feature = []
num=0
for f in range(x_train.shape[1]):
    top_feature.append(stock_df.columns[indices][f])
    num = num+1
    if num>5:
        break
        
print(top_feature)

 

1250, 1530, 1100, 1520, 1430, 1200 순서로 변수가 채택되었네요. 10시 50분 ~ 11시 00분 수익률 빼고는 모두 오후장 10분 수익률이네요.

이제 채택된 변수로 다시 학습을 한 후 성능을 보겠습니다. 이전 포스팅에서 했던 작업의 반복이므로 한번에 코드로 작성했습니다.

 

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
from sklearn.metrics import f1_score, roc_auc_score


top_feature.append('gap')
top_stock_df=stock_df[top_feature]

x = top_stock_df.iloc[:, 0:-1].values
y = top_stock_df.iloc[:,-1].values


x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.26,  random_state=0,shuffle=True)


scale = MinMaxScaler()
x_train = scale.fit_transform(x_train)
x_test = scale.transform(x_test)


model = RandomForestClassifier(random_state=rs,n_estimators=es, min_samples_split=ss, min_samples_leaf=sl, max_depth=md, bootstrap=bs)

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


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))

 

성능이 많이 향상 된 것으로 보이네요. 표로 확인해 보면 아래와 같습니다.

 


feature selection 결과로 정확도 정밀도 재현율 모두 6% 정도의 향상이 있었습니다.

주가가 random walk이라고 가정하면 내일의 주가를 맞추는 것을 불가능합니다. 그런데 랜덤포레스트 모델을 이용한 주가예측의 결과는 55% 정도로 우수한 성능을 보였습니다. 물론 과최적화일 가능성도 매우 높습니다.

모델이 과최적화되지않았는지 확인하는 여러 방법론들도 존재하는데요, 이번엔 그중 하나인 k-fold cross validation을 적용해 보겠습니다.

k-fold cross validation은 학습용/평가용 데이터 세트를 k개로 분할한 뒤 k-1개를 학습용, 1개를 평가용 세트로 사용하여 성능을 얻어내는 방법입니다. 그럼 k번 검증이 가능한데요, k번 나온 성능을 평균을 내어 최종 성능으로 평가합니다.

자세한 설명은 아래 블로그 참고하시면 될 것 같습니다.

 

 

K-Fold Cross Validation(교차검증) 정의 및 설명

정의- K개의 fold를 만들어서 진행하는 교차검증 사용 이유- 총 데이터 갯수가 적은 데이터 셋에 대하여 정확도를 향상시킬수 있음- 이는 기존에 Training / Validation / Test 세 개의 집단으로 분류하는

nonmeyet.tistory.com

 

 

 

아래는 k-fold cross validation을 실행한 코드와 결과입니다.

 

from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import classification_report

scale = MinMaxScaler()
cv = StratifiedKFold(n_splits=5, random_state=123, shuffle=True)
    

x_data = top_stock_df.iloc[:, 0:-1]
y_data = top_stock_df.iloc[:,-1]

    
for (train, test), i in zip(cv.split(x_data, y_data), range(5)):
    x_data.iloc[train] = scale.fit_transform(x_data.iloc[train])
    x_data.iloc[test]=scale.transform(x_data.iloc[test])
    model.fit(x_data.iloc[train], y_data.iloc[train])
    predict = model.predict(x_data.iloc[test])
    confusion = confusion_matrix(y_data[test], predict)
    accuracy = accuracy_score(y_data[test], predict)
    precision = precision_score(y_data[test], predict,average='macro')
    recall = recall_score(y_data[test], predict,average='macro')
    f1 = f1_score(y_data[test], predict,average='macro')
    print(i,'정확도 {0:.4f}, 정밀도: {1:.4f}, 재현율: {2:.4f}'.format(accuracy,precision, recall))
    print(i,classification_report(y_data[test],predict))

 

 

총 5번의 검증을 수행했는데 평균 55% 정도의 성능이 나왔네요. 각 횟수마다의 성능차이가 커서 저라면 이 모델을 과최적화 된 모델이라고 판단할 것 같습니다.

raw data수가 적었기 때문에 더 장기간의 데이터로 한다면 결과가 어떻게 나올지 궁금하네요.


랜덤포레스트를 이용하여 주가예측을 실험해 보았으나, 한계점이 명확히 있습니다.

첫째, 통계분석 시에는 독립변수 간의 상관관계를 제한해야 합니다. 그러나 주가데이터에 있어 10분 전 수익률은 이번 10분 수익률에 영향을 미칩니다. 이러한 도메인지식들을 활용하여 로데이터 설계를 다시 할 필요가 있습니다.

둘째, 데이터 구성입니다. 이번 실험은 10분 수익률을 이용했지만 갭 수익률에 영향을 미치는 변수들은 이외에도 많이 있습니다. 특히 거래대금 같은 데이터는 단기수익률 예측에 key이므로 이를 고려해서 실험해 볼 필요가 있겠습니다.

셋째, 트레이딩에 적용하기 위해서는 아직 고려해주어야 할 것이 많습니다. 거래비용, 베팅사이즈 등입니다. 매번 마다 적용되는 거래비용은 가랑비에 옷 젖듯 자산을 깎아내려갑니다. 또한, 55%의 승률이라도 상승과 하락이 비대칭적이면 손실이 날 있습니다. 그러므로 확률에 따라 베팅 사이즈를 고려해 주는 것이 필요합니다.


랜덤포레스트를 이용한 주가예측 포스팅은 여기까지입니다.

읽어주셔서 감사합니다.

반응형