SVM Classifier - 기본전략
이번 포스팅에서는 서포트벡터머신 분류기를 이용해서 일일주가트렌드 분석을 분석해본다.
데이터는 2000년도부터의 삼성전자 일일 주가데이터를 사용한다.
dataframe = fdr.DataReader('005930', '2000')
dataframe.dropna(inplace=True) # 결측치제거
dataframe
Date | Open | High | Low | Close | Volume | Change |
---|---|---|---|---|---|---|
2000-01-04 | 6000 | 6110 | 5660 | 6110 | 1483967 | 0.148496 |
2000-01-05 | 5800 | 6060 | 5520 | 5580 | 1493604 | -0.086743 |
2000-01-06 | 5750 | 5780 | 5580 | 5620 | 1087810 | 0.007168 |
2000-01-07 | 5560 | 5670 | 5360 | 5540 | 806195 | -0.014235 |
2000-01-10 | 5600 | 5770 | 5580 | 5770 | 937615 | 0.041516 |
… | … | … | … | … | … | … |
2021-11-29 | 71700 | 73000 | 71400 | 72300 | 16682559 | 0.000000 |
2021-11-30 | 73200 | 73900 | 70500 | 71300 | 30364841 | -0.013831 |
2021-12-01 | 72000 | 74800 | 71600 | 74400 | 21954856 | 0.043478 |
2021-12-02 | 73900 | 75800 | 73800 | 75800 | 23652940 | 0.018817 |
2021-12-03 | 75600 | 76000 | 74100 | 75600 | 17616621 | -0.002639 |
따로 전처리과정없이 데이터에 있는 모든 특성을 변수로 이용한다.
def trend_separater(x):
if x > 0.0016639: # 상승과 하락 트렌드의 절대적인 개수를 비슷하게 맞춰주기 위한 기준점을 선정한다.
return 1
elif x < -0.001:
return -1
def updown(dataframe):
dataframe['UD_Trend'] = dataframe['Change'].map(lambda x : trend_separater(x))
dataframe['UD_Trend'] = dataframe['UD_Trend'].shift(-1) # 다음날 트렌드를 예측해야하므로 다음날 트렌드를 앞으로 한 행 당긴다
dataframe.dropna(inplace=True) # 결측치 제거
return dataframe
다음날 변화율을 상승하락 트렌드로 변환하여 전날의 레코드에 추가한다. UD_Trend 특성이 다음날 주가의 변화 트렌드이다.
labeled_df = dataframe.copy()
labeled_df = updown(labeled_df)
total_count = labeled_df.UD_Trend.count()
labeled_df['UD_Trend'].value_counts()
target_df = labeled_df.copy()
target_df.reset_index(inplace=True)
target_df
Date | Open | High | Low | Close | Volume | Change | UD_Trend | |
---|---|---|---|---|---|---|---|---|
0 | 2000-01-04 | 6000 | 6110 | 5660 | 6110 | 1483967 | 0.148496 | -1.0 |
1 | 2000-01-05 | 5800 | 6060 | 5520 | 5580 | 1493604 | -0.086743 | 1.0 |
2 | 2000-01-06 | 5750 | 5780 | 5580 | 5620 | 1087810 | 0.007168 | -1.0 |
3 | 2000-01-07 | 5560 | 5670 | 5360 | 5540 | 806195 | -0.014235 | 1.0 |
4 | 2000-01-10 | 5600 | 5770 | 5580 | 5770 | 937615 | 0.041516 | -1.0 |
… | … | … | … | … | … | … | … | … |
5407 | 2021-11-26 | 73500 | 74100 | 72000 | 72300 | 13002242 | -0.018996 | -1.0 |
5408 | 2021-11-29 | 71700 | 73000 | 71400 | 72300 | 16682559 | 0.000000 | -1.0 |
5409 | 2021-11-30 | 73200 | 73900 | 70500 | 71300 | 30364841 | -0.013831 | 1.0 |
5410 | 2021-12-01 | 72000 | 74800 | 71600 | 74400 | 21954856 | 0.043478 | 1.0 |
5411 | 2021-12-02 | 73900 | 75800 | 73800 | 75800 | 23652940 | 0.018817 | -1.0 |
레코드 개수가 5411개이다. 임의대로 앞에 4000개를 훈련세트로 사용하고 그 뒤의 데이터를 검증세트로 사용하겠다.
# 전체 세트
X_all = np.array(target_df.loc[:, target_df.drop(['UD_Trend', 'Date'], axis=1).columns])
y_all = np.array(target_df.loc[:, ['UD_Trend']])
# 훈련 세트
X_train = X_all[:4000]
y_train = y_all[:4000]
# 검증 세트
X_test = X_all[4000:]
y_test = y_all[4000:]
StandardScaler로 스케일링한 데이터를 사용하는 SVC 모델을 파이프라인으로 생성한다.
svm_cla = Pipeline([
("scaler", StandardScaler()),
("svc", SVC()),
])
훈련세트로 훈련을 진행하고 훈련세트와 검증세트에서의 점수를 측정한다.
svm_cla.fit(X_train, y_train) # 훈련 세트로 훈련진행
print("train_set score: ", svm_cla.score(X_train, y_train)) # 훈련세트 점수
print("test_set score : ", svm_cla.score(X_test, y_test)) # 검증세트 점수
sample = target_df.loc[4000:,].copy()
sample['predicted'] = svm_cla.predict(X_all[4000:])
sample
검증세트에서 예측한 array를 원래 검증세트부분의 데이터프레임에 column 으로 추가시키자
Date | Open | High | Low | Close | Volume | Change | UD_Trend | predicted | |
---|---|---|---|---|---|---|---|---|---|
4000 | 2017-04-26 | 42700 | 42800 | 42520 | 42800 | 295896 | 0.002342 | 1.0 | 1.0 |
4001 | 2017-04-27 | 42700 | 44520 | 41960 | 43840 | 460645 | 0.024299 | 1.0 | 1.0 |
4002 | 2017-04-28 | 45780 | 45800 | 44520 | 44620 | 453714 | 0.017792 | 1.0 | 1.0 |
4003 | 2017-05-02 | 45500 | 45500 | 44760 | 44900 | 281366 | 0.006275 | 1.0 | 1.0 |
4004 | 2017-05-04 | 45700 | 45700 | 44860 | 45520 | 273802 | 0.013808 | 1.0 | 1.0 |
… | … | … | … | … | … | … | … | … | … |
5024 | 2021-11-25 | 75100 | 75100 | 73600 | 73700 | 12559258 | -0.014706 | -1.0 | 1.0 |
5025 | 2021-11-29 | 71700 | 73000 | 71400 | 72300 | 16682559 | 0.000000 | -1.0 | 1.0 |
5026 | 2021-11-30 | 73200 | 73900 | 70500 | 71300 | 30364841 | -0.013831 | 1.0 | 1.0 |
5027 | 2021-12-01 | 72000 | 74800 | 71600 | 74400 | 21954856 | 0.043478 | 1.0 | 1.0 |
5028 | 2021-12-02 | 73900 | 75800 | 73800 | 75800 | 23652940 | 0.018817 | -1.0 | 1.0 |
이상한 점이 발견되었는데 예측한 값이 모두 1이다. 훈련세트에 과적합되어서 올바른 예측을 하지 못한것이다. 다음 포스팅에서는 하이퍼파라미터 조정을 통해 이 현상을 조절한다.