목차
이번에는 인공지능 기술을 직접 체험해 볼 수 있는 콘텐츠를 고민 중 머신러닝 기술을 이용하여 비트코인 주가를 예측하는 방법에 대해 작성해 보고자 합니다. 이번 글을 포함하여 3~4편으로 이루어질 것 같은데요, 이 글을 통해 머신러닝을 직접 체험해 보고 어떻게 일상생활에 적용할 수 있을지 생각할 수 있도록 살펴보도록 하겠습니다.
이번 글에서는 머신러닝을 접하는 처음 시간이므로, 비트코인 주가 예측을 위해 적용했던 두 가지 모델을 Prophet 모델과 XGBoost에 대해 설명하는 것부터 시작하도록 하겠습니다.
머신러닝 기반 비트코인 추세 예측
비트코인과 같은 암호화폐의 가격 변동성은 매우 높아 예측이 어렵지만, 다양한 머신러닝 모델을 통해 가격을 예측할 수 있는 가능성을 탐구할 수 있습니다. 이번에는 Prophet과 XGBoost 모델을 활용하여 비트코인 가격을 예측하는 방법에 대해 살펴보겠습니다.
Prophet 모델
Prophet 모델은 페이스북에서 개발한 시계열 예측 모델입니다. 시계열 데이터는 시간의 흐름에 따라 변하는 데이터를 말하며, Prophet 모델은 이러한 데이터를 분석하여 미래를 예측하는 데 사용되므로 비트코인 가격 추세를 예측하기 위해 선정했습니다.
주요 특징
- 추세 예측 (Trend Prediction): 데이터를 장기적으로 분석하여 시간이 지남에 따라 증가하거나 감소하는 경향을 포착합니다. 예를 들어, 회사의 매출이 시간이 지남에 따라 꾸준히 증가하는 추세를 예측할 수 있습니다.
- 주기성 및 시즌성 (Seasonality): 데이터에 주기적으로 반복되는 패턴이 있을 때 이를 감지합니다. 예를 들어, 아이스크림 판매량은 여름에 증가하고 겨울에 감소하는 경향이 있습니다. Prophet 모델은 이러한 시즌성을 반영하여 예측을 수행합니다.
- 특별 이벤트 효과 (Holiday Effects): 공휴일이나 특별 이벤트가 데이터에 미치는 영향을 고려합니다. 예를 들어, 크리스마스 시즌에는 쇼핑 매출이 급증할 수 있는데, Prophet 모델은 이러한 이벤트를 반영하여 예측을 더욱 정확하게 만듭니다.
- 변화점 감지 (Changepoint Detection): 데이터의 갑작스러운 변화 시점을 자동으로 감지합니다. 예를 들어, 새로운 제품 출시 후 매출이 급증하는 경우, Prophet 모델은 이러한 변화를 반영하여 예측을 조정합니다.
작동 방식
Prophet 모델은 다음과 같은 구성 요소로 이루어져 있습니다:
- 추세 (Trend): 시간에 따라 데이터가 어떻게 변화하는지 나타냅니다. 예를 들어, 매출이 매년 10%씩 증가하는 패턴을 나타낼 수 있습니다.
- 주기성 (Seasonality): 데이터가 일정 주기로 반복되는 패턴을 포착합니다. 예를 들어, 주말마다 방문객 수가 증가하는 패턴을 예측합니다.
- 이벤트 효과 (Holiday Effects): 특정 이벤트가 데이터에 미치는 영향을 반영합니다. 예를 들어, 블랙프라이데이와 같은 특별 이벤트가 매출에 미치는 영향을 예측합니다.
- 잔차 (Residuals): 위의 요소들로 설명되지 않는 데이터의 변동을 나타냅니다. 이는 노이즈로 간주되며, 모델의 예측 정확도를 높이기 위해 최소화됩니다.
Prophet 모델의 사용 예
실제 데이터에 Prophet 모델을 적용하는 과정은 비교적 간단합니다. 다음은 예시 코드와 함께 각 단계별 설명입니다:
- 데이터 준비: 비트코인 가격 데이터의 날짜와 종가를 Prophet 모델이 이해할 수 있는 형식으로 변환합니다.
#데이터 준비
df = btc_data.rename(columns={‘Date’: ‘ds’, ‘Close’: ‘y’})
- Prophet 모델 생성 및 설정: Prophet 모델을 생성하고, 필요한 설정을 추가합니다. 여기서는 데이터의 갑작스러운 변화를 감지하는 매개변수(changepoint_prior_scale)와 시즌성을 반영하는 매개변수(seasonality_prior_scale)를 설정합니다.
#Prophet 모델 생성 및 설정
prophet_model = Prophet(changepoint_prior_scale=0.5, seasonality_prior_scale=20)
- 모델 학습: 준비된 비트코인 가격 데이터를 사용하여 모델을 학습시킵니다.
#모델 학습
prophet_model.fit(df)
- 미래 데이터프레임 생성 및 예측: 미래 데이터를 포함하는 데이터프레임을 생성하고, 모델을 사용하여 예측을 수행합니다.
#미래 데이터프레임 생성
future = prophet_model.make_future_dataframe(periods=365) # 1년치 예측
#예측 수행
forecast = prophet_model.predict(future)
- 예측 결과 시각화: 예측 결과를 시각화하여 쉽게 이해할 수 있도록 합니다.
#예측 결과 시각화
fig = prophet_model.plot(forecast)
plt.show()
이와 같이 Prophet 모델은 데이터의 시간적 패턴을 분석하여 미래를 예측하는 데 매우 유용합니다. 이를 통해 비즈니스 계획을 세우거나, 재고를 관리하거나, 매출을 예측하는 등 다양한 실생활 문제를 해결할 수 있습니다.
XGBoost 모델
XGBoost는 “Extreme Gradient Boosting”의 약자로, 머신러닝에서 회귀 및 분류 문제를 해결하는 데 매우 강력한 알고리즘입니다.
주요 특징
- 성능 및 속도: XGBoost는 기존의 부스팅 알고리즘보다 더 빠르고 효율적입니다. 병렬 처리를 통해 학습 속도를 크게 향상시켰습니다.
- 정확도: XGBoost는 여러 개의 약한 학습기(주로 결정 트리)를 결합하여 강한 학습기를 만듭니다. 이 과정에서 각 트리가 순차적으로 학습하며 이전 트리의 오류를 보완해 나가므로 매우 높은 예측 정확도를 보입니다.
- 과적합 방지: XGBoost는 과적합(overfitting)을 방지하기 위해 정규화(regularization) 기법을 사용합니다. 이는 모델이 학습 데이터에 너무 과도하게 맞춰지는 것을 방지하여 일반화 성능을 높입니다.
- 유연성: XGBoost는 회귀, 분류, 순위 매김 등 다양한 문제 유형을 다룰 수 있습니다. 또한 다양한 커스텀 목적 함수와 평가 함수를 지원합니다.
작동 방식
XGBoost는 여러 개의 결정 트리를 결합하여 예측을 수행하는 앙상블 기법입니다. 각 트리는 데이터를 학습하고 예측하지만, 단독으로는 약한 성능을 가집니다. 그러나 여러 트리를 결합함으로써 강력한 예측 모델을 만들어냅니다. XGBoost는 이 과정에서 경사 하강법을 사용하여 각 트리의 예측 오류를 점진적으로 줄입니다.
- 결정 트리 (Decision Tree):
- 데이터를 분할하여 예측을 수행하는 기본 모델입니다. 각 트리는 여러 개의 분기점을 가지고 데이터를 분류하거나 예측합니다.
- 부스팅 (Boosting):
- 여러 개의 약한 학습기를 결합하여 강력한 학습기를 만드는 기법입니다. 각 트리는 순차적으로 학습하며 이전 트리의 오류를 보완합니다.
- 경사 하강법 (Gradient Descent):
- XGBoost는 경사 하강법을 사용하여 각 트리의 가중치를 조정합니다. 이를 통해 모델의 예측 오류를 점진적으로 줄입니다.
- 정규화 (Regularization):
- 모델이 학습 데이터에 너무 과도하게 맞춰지는 것을 방지하기 위해 정규화 기법을 사용합니다. 이는 모델의 일반화 성능을 높여 새로운 데이터에서도 좋은 성능을 발휘하게 합니다.
XGBoost의 사용 예
XGBoost 모델을 실제 데이터에 적용하는 과정은 다음과 같습니다:
- 데이터 준비: 먼저, 사용할 비트코인 가격 데이터를 준비합니다. 예를 들어, 비트코인 가격 데이터를 사용한다고 가정해 보겠습니다.
#데이터 준비
import pandas as pd
#비트코인 가격 데이터 로드 (실시간 데이터가 아닌 저장된 파일 이용)
btc_data = pd.read_excel(‘bitcoin.xlsx’, engine=’openpyxl’)
#필요한 특성 생성
btc_data[‘returns’] = btc_data[‘Close’].pct_change()
btc_data[‘volatility’] = btc_data[‘returns’].rolling(window=28).std()
btc_data = btc_data.dropna().reset_index(drop=True)
- 학습 및 테스트 데이터 분할: 비트코인 가격 데이터를 학습용 데이터와 테스트용 데이터로 나눕니다.
#학습 및 테스트 데이터 분할
train_data = btc_data[btc_data[‘Date’] <= ‘2024-06-16’] test_data = btc_data[btc_data[‘Date’] > ‘2024-06-16’]
x_train = train_data[[‘Volume’, ‘High’, ‘Low’, ‘returns’, ‘volatility’]]
y_train = train_data[‘Close’]
x_test = test_data[[‘Volume’, ‘High’, ‘Low’, ‘returns’, ‘volatility’]]
y_test = test_data[‘Close’]
- XGBoost 모델 학습: XGBoost 모델을 생성하고 학습시킵니다.
import xgboost as xgb
#XGBoost 모델 생성
xg_model = xgb.XGBRegressor(objective=’reg:squarederror’, n_estimators=1000)
#모델 학습
xg_model.fit(x_train, y_train)
- 예측 수행: 학습된 모델을 사용하여 테스트 데이터에 대한 예측을 수행합니다.
#예측 수행
xg_predictions = xg_model.predict(x_test)
- 성능 평가: 예측 결과를 실제 값과 비교하여 성능을 평가합니다. 여기서는 평균 절대 오차(MAE)를 사용합니다.
from sklearn.metrics import mean_absolute_error
#성능 평가
mae = mean_absolute_error(y_test, xg_predictions)
print(f’Mean Absolute Error: {mae:.2f}’)
XGBoost 모델은 이처럼 데이터를 효과적으로 학습하여 높은 정확도의 예측을 제공할 수 있습니다. 이를 통해 다양한 비즈니스 문제를 해결하고, 데이터 기반의 의사 결정을 지원할 수 있습니다.
데이터 준비 및 전처리
비트코인 가격을 예측하기 위해 가장 먼저 해야 할 일은 데이터를 준비하고 전처리하는 것입니다. 데이터 준비 및 전처리는 모델 학습의 기초가 되며, 예측 성능에 큰 영향을 미칩니다. 여기서는 비트코인 가격 데이터를 엑셀 파일에서 불러와서 필요한 데이터 전처리 과정을 설명하겠습니다.
1) 데이터 수집
우선, 비트코인 가격 데이터를 엑셀 파일에서 불러옵니다. 이 비트코인 가격 데이터는 날짜, 종가(마감 가격), 거래량, 최고가, 최저가 등 여러 가지 속성을 포함하고 있습니다. 엑셀 파일을 불러오기 위해 pandas
라이브러리를 사용합니다.
import pandas as pd
#엑셀 파일에서 비트코인 가격 데이터 불러오기
file_path = ‘bitcoin_upbit_2400.xlsx’
btc_data = pd.read_excel(file_path, engine=’openpyxl’)
2) 날짜 변환
엑셀 파일에서 불러온 비트코인 가격 데이터의 날짜 형식을 pandas
에서 처리할 수 있는 형식으로 변환합니다. 이렇게 변환하면 나중에 시계열 분석을 수행할 수 있습니다.
#날짜 형식 변환
btc_data[‘Date’] = pd.to_datetime(btc_data[‘Date’])
3) 기술 지표 계산
가격 데이터를 분석하기 위해 몇 가지 중요한 기술 지표를 계산합니다. 기술 지표는 주로 가격과 거래량 데이터를 기반으로 계산되며, 예측 모델에 유용한 정보를 제공합니다.
(1) RSI (상대 강도 지수): RSI는 주식이나 암호화폐의 가격 변동성을 측정하는 지표로, 가격이 과매수 또는 과매도 상태인지를 나타냅니다.
def compute_RSI(data, window):
delta = data.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
RS = gain / loss
RSI = 100 – (100 / (1 + RS))
return RSIbtc_data[‘RSI’] = compute_RSI(btc_data[‘Close’], window=28)
(2) MACD (이동 평균 수렴 발산 지표): MACD는 두 개의 이동 평균 간의 관계를 분석하여 가격 추세를 파악하는 데 사용됩니다.
def compute_MACD(data, short_window=12, long_window=26, signal_window=9):
short_ema = data.ewm(span=short_window, adjust=False).mean()
long_ema = data.ewm(span=long_window, adjust=False).mean()
MACD = short_ema – long_ema
signal = MACD.ewm(span=signal_window, adjust=False).mean()
return MACD, signal, MACD – signalbtc_data[‘MACD’], btc_data[‘MACD_signal’], btc_data[‘MACD_hist’] = compute_MACD(btc_data[‘Close’])
(3) 볼린저 밴드 (Bollinger Bands): 볼린저 밴드는 가격의 이동 평균과 표준 편차를 사용하여 가격 변동 범위를 나타냅니다.
def compute_BB(data, window=20, num_sd=2):
rolling_mean = data.rolling(window=window).mean()
rolling_std = data.rolling(window=window).std()
upper_band = rolling_mean + (rolling_std * num_sd)
lower_band = rolling_mean – (rolling_std * num_sd)
return upper_band, rolling_mean, lower_bandbtc_data[‘BB_upper’], btc_data[‘BB_middle’], btc_data[‘BB_lower’] = compute_BB(btc_data[‘Close’])
4) 결측값 처리
계산된 기술 지표에는 일부 결측값이 발생할 수 있습니다. 결측값은 데이터를 채우거나 제거하여 분석에 문제가 없도록 처리합니다. 여기서는 이전 값으로 결측값을 채우는 방법을 사용합니다.
#결측값 처리 (이전 값으로 채우기)
btc_data = btc_data.fillna(method=’bfill’)
5) 데이터프레임 구성
모델 학습에 필요한 데이터 프레임을 구성합니다. Prophet 모델과 XGBoost 모델 모두 사용할 수 있도록 적절한 형식으로 데이터를 변환합니다. 여기서는 날짜와 종가를 Prophet 모델이 이해할 수 있는 형식으로 변환하고, 기술 지표를 추가합니다.
#Prophet 모델을 위한 데이터프레임 구성
df = btc_data.rename(columns={‘Date’: ‘ds’, ‘Close’: ‘y’})
df[‘volume’] = btc_data[‘Volume’]
df[‘price_range’] = btc_data[‘High’] – btc_data[‘Low’]
df[‘returns’] = btc_data[‘Close’].pct_change()
df[‘volatility’] = df[‘returns’].rolling(window=28).std()
df[‘avg_price’] = (btc_data[‘High’] + btc_data[‘Low’]) / 2
df[‘moving_avg_20’] = btc_data[‘Close’].rolling(window=20).mean()
df[‘moving_avg_50’] = btc_data[‘Close’].rolling(window=50).mean()
df[‘RSI’] = btc_data[‘RSI’]
df[‘MACD’] = btc_data[‘MACD’]
df[‘MACD_signal’] = btc_data[‘MACD_signal’]
df[‘MACD_hist’] = btc_data[‘MACD_hist’]
df[‘BB_upper’] = btc_data[‘BB_upper’]
df[‘BB_middle’] = btc_data[‘BB_middle’]
df[‘BB_lower’] = btc_data[‘BB_lower’]#결측값 제거 및 인덱스 리셋
df = df.dropna().reset_index(drop=True)
이제 데이터를 준비하고 전처리하는 과정을 마쳤습니다.데이터 준비 및 전처리는 매우 중요한 과정으로, 잘못된 데이터는 잘못된 예측을 초래할 수 있습니다. 따라서 데이터를 철저히 전처리하는 것이 중요합니다.
다음에는 모델 학습과 예측에 대해 정리해 보도록 하겠습니다.