이번주에는 '코스피 방향 예측을 위한 하이브리드 머신러닝 모델' 논문을 자세히 읽어보고, 사용한 데이터 및 방법론에 대해 정리해보았다. 논문에서는 국내 kospi data를 활용해 ETF 예측 분석을 진행하였으며, 5가지 머신러닝 알고리즘 모델을 사용해서 결과를 산출하였다. 기계학습 알고리즘을 찾아보기 전에 주식 데이터에 대한 분석이 왜 필요하고, kospi와 ETF가 무엇인지부터 알아보자.
1. 주식에 대한 관심도 증가

사진은 2021년의 기사로, 10명 중 4명은 코로나19 확산 이후 주식 직접투자를 시작했다고 서술하였다. 오른쪽의 3년간 코스피 추이를 봐도 2020년 초반 이후 꾸준히 상승세를 보임을 확인할 수 있다. 하지만, 주식 투자로 인해 모든 사람이 이득을 취할 수는 없다. 그래프를 보면 알 수 있듯이, Kospi 지수는 등락을 반복한다. 지수의 추세는 국제 정세에 따른 경제 상황에 따라 달라지는데, 개미 투자자들은 경제 용어를 잘 모르고, 대출을 받아 투자를 진행하는 경우도 존재한다. 이러한 경우 투자를 해서 손해를 보는 불쾌한 경험을 겪게된다.

구글 트렌드는 해당 기간에서 구글에 특정 검색어를 얼마나 검색했는지를 그래프로 확인해볼 수 있는 지표이다. 2020년 초반 이후 많은 사람들이 주식을 구글에 검색하고, 관련된 정보를 탐색했음을 확인할 수 있다. 하지만, 실제 경제 뉴스를 확인해보면 알 수 없는 용어로 인해 필요한 정보를 식별하는 데는 많은 어려움이 존재한다. 이러한 어려움을 조금이나마 해소시킬 수 있는 방법이 분산 투자이다. 분산 투자란, 하나의 종목에 투자하는 것이 아니라 본인이 원하는 종목을 몇 가지 선정해서 투자하는 방식이다. 대표적인 예시로, ETF가 있다.
2. KOSPI와 ETF란?
KOSPI(Korea Composite Stock Price Index)는 한국 증권 거래소에 상장된 주식을 기반으로 하는 주가 평균 지수를 의미한다. 이는 한국 주식 시장의 전반적인 트렌드와 상황을 파악하는데 사용되며, 특히 주식 투자자들이 투자 결정을 내릴 때 주요한 지표로 활용할 수 있다. 또한 모든 상장 주식을 포함한 종합 지수 외에도 특정 섹터 혹은 주식들로 구성된 세부 지표도 제공하는데, 대표적으로 KOSPI 200은 증권 거래소에서 거래량이 크고 시장 대표성이 높은 200개 회사의 주가를 기반으로 한다. KOSPI는 국내외 경제 동향, 기업 실적, 통화 정책, 국제 정세 등 다양한 요인에 의해 영향을 받으며, 이러한 요인들이 주식 데이터 예측을 어렵게하는 주요 요인들 중 하나이다. 투자자들은 자신의 투자 목표와 리스트 허용 수준에 맞게 KOSPI 지수를 활용하여 투자를 전략을 수립하고 실행할 수 있다.
ETF(Exchange Traded Fund)는 거래소에 상장되어 주식처럼 거래되는 펀드로, 특정 지수를 추적하여 그 지수의 성과를 반영하는 것이 주요 목표이다. 투자자들은 ETF를 통해 자신이 원하는 지수나 섹터에 대한 다양성을 확보하면서도 한 번의 거래로 편리하게 투자를 진행할 수 있다. 또한, 전통적인 펀드에 비해 운용 비용이 낮고, 거래소에서 거래되기 때문에 주식처럼 실시간으로 매매가 가능하다는 장점이 있다. 하지만, ETF는 특정 지수의 성과를 그대로 반영하기 때문에 지수가 하락하면 ETF의 가치도 함께 떨어진다는 단점도 존재한다.
3. 코스피 방향 예측을 위한 하이브리드 머신러닝 모델
우리는 논문에서 사용한 데이터의 트렌드와 용어에 대해 탐색해보았다. 이제부터 논문의 목적 및 방법론에 대해 살펴보자. 논문에서는 KOSPI에 연동한 ETF의 거래를 목적으로, KOSPI의 방향을 예측한다. MLP, SVM, RF, LGBM, XGB 5개의 기계학습 알고리즘을 사용하여 상승 및 하락 예측 모델을 각각 구현하고, 개별 예측모델보다 개선된 예측 정밀도를 얻기 위해 하이브리드 예측 모델을 제안하였다. 우선, 각각의 모델에 대해 먼저 알아보자.
1. MLP(Multi-Layer Perceptrions)
MLP는 인공신경망의 한 형태로, 주로 딥러닝 모델에 사용되는 기본적인 알고리즘이다. 이름에서 알 수 있듯이, MLP는 여러 층(layer)로 구성된 퍼셉트론(perceptrons)의 네트워크를 의미한다. 각각의 퍼셉트론은 일종의 인공 뉴련으로, 여러 입력값을 받아 이를 가중치와 곱한 후 모두 합쳐 하나의 출력값을 만드는 단순한 연산 단위이다. 이 출력값은 비선형 함수인 활성화 함수를 거치게 된다. 여기서 이진 분류는 sigmoid, 다중 분류는 softmax를 쓰는데, 차후 활성화 함수(activation function)는 별도로 포스팅 하겠다. MLP는 이러한 퍼셉트론들을 여러 층으로 쌓아 올려서 구성되며, 일반적으로 입력층(input layer), 은닉층(hidden layer), 출력층(output layer)의 세 부분으로 나뉜다. 그림으로 보면 보다 직관적으로 볼 수 있기 때문에, python으로 MLP를 그려보았다.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrow
# Define the number of neurons in each layer
n_input = 4
n_hidden = 8
n_output = 3
# Set up figure and axis
fig, ax = plt.subplots(figsize=(8, 8))
# Define positions for neurons in each layer
input_neuron_positions = np.linspace(0.1, 0.9, n_input)
hidden_neuron_positions = np.linspace(0.1, 0.9, n_hidden)
output_neuron_positions = np.linspace(0.1, 0.9, n_output)
# Draw neurons
for i in range(n_input):
circle = plt.Circle((0.2, input_neuron_positions[i]), 0.05, edgecolor='black', facecolor='green')
ax.add_patch(circle)
for i in range(n_hidden):
circle = plt.Circle((0.5, hidden_neuron_positions[i]), 0.05, edgecolor='black', facecolor='red')
ax.add_patch(circle)
for i in range(n_output):
circle = plt.Circle((0.8, output_neuron_positions[i]), 0.05, edgecolor='black', facecolor='blue')
ax.add_patch(circle)
# Draw connections
for i in range(n_input):
for j in range(n_hidden):
arrow = FancyArrow(0.25, input_neuron_positions[i], 0.2, hidden_neuron_positions[j] - input_neuron_positions[i],
width=0.001, shape='full', length_includes_head=True, head_width=0.01, edgecolor='gray', facecolor='gray')
ax.add_patch(arrow)
for i in range(n_hidden):
for j in range(n_output):
arrow = FancyArrow(0.55, hidden_neuron_positions[i], 0.2, output_neuron_positions[j] - hidden_neuron_positions[i],
width=0.001, shape='full', length_includes_head=True, head_width=0.01, edgecolor='gray', facecolor='gray')
ax.add_patch(arrow)
# Add layer labels
plt.text(0.2, 1.05, 'Input Layer', horizontalalignment='center', fontsize=14)
plt.text(0.5, 1.05, 'Hidden Layer', horizontalalignment='center', fontsize=14)
plt.text(0.8, 1.05, 'Output Layer', horizontalalignment='center', fontsize=14)
# Remove axis
plt.axis('off')
# Show the plot
plt.show()

- 입력층(input layer) : 초기 데이터가 입력되고, 개별 노드는 데이터의 하나의 특성을 나타낸다.
- 은닉층(hidden layer) : 입력층과 출력층 사이에 위치한 층으로, 이곳에서 주로 복잡한 패턴을 학습한다. 은닉층은 여러 개의 층으로 구성될 수 있다.
- 출력층(output layer) : 마지막 층으로, 최종 결과가 출력된다. 출력층의 노드 수는 문제의 종류에 따라 달라진다. 이진 분류에서는 2가지 중 하나를 분류하기 때문에 하나의 노드만 필요하고, 다중 class 분류에서는 클래스 수 만큼의 노드가 필요하다. 위의 그림에는 3개의 출력층이 존재한다.
그림을 보면 각 층의 노드들이 그 이전 층의 모든 노드와 연결되어 있으며, 이러한 구조를 완전 연결 계층 혹은 Dense 계층이라고 부른다. 이러한 구조는 신경망의 가중치를 경사 하강법(gradient descent) 등의 최적화 알고리즘(optimization)을 사용하여 학습 데이터에 대한 손실 함수(loss function)을 최소화하는 방향으로 복잡한 패턴을 학습할 수 있게 해주지만, 모델이 복잡해짐에 따라 연산 시간이 오래걸리고, 과적합(overfitting) 문제를 일으킬 가능성이 존재한다. 또한 고차원이거나 복잡한 데이터의 경우 좋은 성능을 내기 힘들기 때문에, MLP보다는 MLP를 기반으로 발전된 딥러닝 아키텍처(CNN, RNN 등)을 사용하는 경우가 다반사다. 다만, 해당 논문은 머신러닝을 기반으로 하는 모델들이기 때문에 딥러닝은 차후에 따로 포스팅하도록 하겠다.
2. SVM(Support-Vector Mechine)
SVM은 분류와 회귀 분석에 사용되는 지도학습 모델로, 데이터를 분류하는데 사용되는 초평면(hyperplane)을 찾는 과정으로 동작한다. SVM을 이해하려면 먼저 초평면이 무엇인지 먼저 알아야한다. 아래에는 SVM의 주요 구성 요소와 작동 원리에 대해 정리하였다.
주요 구성 요소
초평면(hyperplane) : SVM의 목적은 데이터의 클래스를 구분하는 최적의 초평면(결정 경계)을 찾는 것이다. 초평면은 n차원의 공간에서 (n-1)차원의 평면으로, 2차원에서는 선, 3차원에서는 평면이 된다고 이해할 수 있다. 즉, 선형 혹은 비선형 결정경계를 만들 수 있다.
서포트 벡터(Support Vector) : Support vector는 초평면과 가장 가까운 훈련 데이터 포인트로, 초평면의 위치와 방향을 결정하는데 중요한 역할을 수행한다. 또한, margin의 결정에도 영향을 끼친다.
마진(Margin) : Margin은 Support Vector와 초평면 사이의 거리로, SVM은 margin을 최대화시켜 초평면의 안정성과 일반화 성능을 향상시킨다.
하이퍼 파라미터
커널 트릭(Kernel Trick) : 2차원 좌표평면상에 존재하는 복잡한 데이터는 단순한 직선으로 분리하기에는 어려움이 존재한다. 이러한 비선형 데이터를 처리할 때, SVM은 커널 함수를 사용하여 입력 공간을 더 높은 차원의 특성 공간으로 변환한다. 대표적인 커널 함수로는 linear kernel, polynomial kernel, RBF kernel, sigmoid kernel 등이 있으며, 이를 통해 비선형 문제를 선형 문제로 변환할 수 있다.
C(오차 비용) : SVM의 주요 하이퍼 파라미터(Hyperparameter)로, 소프트 마진(soft margin)의 강도를 제어하며 오차를 얼마나 허용할 것인지를 결정한다. C가 크면 오분류를 더 엄격하게 판단하여 모델은 훈련 데이터에 최대한 정확하게 맞추려고 노력하지만, 이는 과적합(overfitting)의 위험이 존재한다. 반대로 C가 작으면 일부 오분류를 허용하는 soft margin이 형성되어 모델이 유연해지고 일반화 능력이 향상될 수 있지만, 훈련 데이터에 대한 정확도가 감소할 수 있다.
Gamma(결정 경계 복잡도) : Gamma는 RBF(Radial Basis Function) kernel에서 사용되며, 결정 경계(decision boundary)의 형태를 제어한다. gamma가 크면 각 데이터 포인트의 영향 범위가 작아져서 결정 경계가 더 복잡해진다. 이렇게 되면 훈련 데이터에 대한 정확도가 높아지지만, 새로운 데이터에 대한 예측 성능은 저하되어 overfitting이 발생할 수 있다. 반대로 gamma가 작으면 개별 데이터 포인트의 영향 범위가 커지며, 결정 경계가 더 부드럽고 단순해진다. 다. 즉, C와 동일하게 모델의 일반화 능력을 향상시킬 수 있지만, 훈련 데이터에 대한 정확도가 떨어질 수 있다.
iris data를 사용하여 간단하게 SVM을 사용하여 분류하는 예제를 만들어 보았다. 정확도는 73% 정도로, 그렇게 정확하지는 않지만 특성값의 개수를 조절하고 C값을 조절하면 보다 높은 성능이 나오는 것을 확인할 수 있었다.
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
import matplotlib.pyplot as plt
iris = datasets.load_iris()
X = iris.data[:, :2] # 특성 2개만 사용
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify = y)
svm_model = SVC(kernel='linear', C=0.8)
svm_model.fit(X_train, y_train)
accuracy = svm_model.score(X_test, y_test)
print(f'Accuracy: {round(accuracy*100,2)}%') # 73.33%
xx, yy = np.meshgrid(np.linspace(X[:, 0].min(), X[:, 0].max(), 100),
np.linspace(X[:, 1].min(), X[:, 1].max(), 100))
# 그리드 포인트에서의 예측 클래스 라벨 계산
Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 컨투어 레벨(2차원 공간에서 동일한 값을 가지는 지점들을 연결한 선)을 정의하여 결정 경계를 더 세밀하게 표시
contour_levels = np.linspace(Z.min(), Z.max(), 4)
# 훈련 데이터, 테스트 데이터, 서포트 벡터를 명확하게 구분하기 위해 마커와 색상을 조정
plt.figure(figsize=(10, 6))
plt.contourf(xx, yy, Z, alpha=0.8, levels=contour_levels, cmap='coolwarm')
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='autumn', marker='o', label='Training Data')
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap='autumn', marker='x', label='Test Data')
plt.scatter(svm_model.support_vectors_[:, 0], svm_model.support_vectors_[:, 1], s=150, facecolors='none', edgecolors='k', label='Support Vectors')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title(f'SVM with Linear Kernel (Accuracy: {round(accuracy*100,2)}%)')
plt.legend(loc='lower right')
plt.colorbar(label='Class Label')
plt.show()

적다보니 글이 너무 길어져서, RF, LGBM, XGB는 다음 주에 배깅과 부스팅에 대해 먼저 알아보고 이어서 진행하도록 하겠다.
출처
황희수,「코스피 방향 예측을 위한 하이브리드 머신러닝 모델」,한국융합학회,한국융합학회논문지 제12권 제6호, 9-16 쪽(2021)
'데이터 분석 > 주식 선행연구 분석' 카테고리의 다른 글
| [주식] 기계학습을 활용한 주식 데이터 분석 - 6주차 (0) | 2023.08.14 |
|---|---|
| [주식] 기계학습을 활용한 주식 데이터 분석 - 5주차 (0) | 2023.08.08 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 4주차 (0) | 2023.08.06 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 2주차 (0) | 2023.08.04 |
| [주식] 기계학습을 활용한 주식 데이터 분석 - 1주차 (0) | 2023.08.04 |